diff --git a/pyste/NEWS b/pyste/NEWS
new file mode 100644
index 00000000..19ce6b2e
--- /dev/null
+++ b/pyste/NEWS
@@ -0,0 +1,16 @@
+24 Mar 2003
+Default policy for functions/methods that return const T& is now
+return_value_policy
Pyste supports the following features:
-
+
+
+Note that, for functions/methods that return const T&, the policy
+return_value_policy<copy_const_reference>() wil be used by default, because
+that's normally what you want. You can change it to something else if you need
+to, thought.
|
-But you don't want to export a vector<string>, you want this function to return -a python list of strings. -Boost.Python has an excellent support for that:
+But you don't want to export std::vector<string>, you want this function +to return a python list of strings. +Boost.Python has an excellent support for +that:
list names_wrapper()
{
list result;
+ // call original function
vector<string> v = names();
// put each string from the vector in the list
return result;
@@ -48,9 +50,8 @@ Boost.Python has an excellent support for that:
}
-Nice heh? -Pyste supports this mechanism too. You declare the names_wrapper function in a -header, like "test_wrappers.h", and in the interface file:
+Nice heh? Pyste supports this mechanism too. You declare the names_wrapper +function in a header named "test_wrappers.h" and in the interface file:
Include("test_wrappers.h")
names = Function("names", "test.h")
diff --git a/pyste/example/basic.h b/pyste/example/basic.h
index a618c192..93e49d36 100644
--- a/pyste/example/basic.h
+++ b/pyste/example/basic.h
@@ -1,3 +1,5 @@
+#include
+
namespace basic {
struct C
@@ -10,6 +12,10 @@ struct C
int foo(int x=1){
return x+1;
}
+
+ const std::string& name() { return _name; }
+ void set_name(const std::string& name) { _name = name; }
+ std::string _name;
};
int call_f(C& c)
diff --git a/pyste/src/ClassExporter.py b/pyste/src/ClassExporter.py
index 6a2d58d7..1de4bf51 100644
--- a/pyste/src/ClassExporter.py
+++ b/pyste/src/ClassExporter.py
@@ -7,6 +7,7 @@ from CodeUnit import CodeUnit
from EnumExporter import EnumExporter
from makeid import makeid
from copy import deepcopy
+import exporterutils
#==============================================================================
# ClassExporter
@@ -246,24 +247,6 @@ class ClassExporter(Exporter):
code = '%s("%s", &%s)' % (def_, name, fullname)
self.Add('inside', code)
-
- printed_policy_warnings = {}
-
- def CheckPolicy(self, m):
- 'Warns the user if this method needs a policy'
- def IsString(type):
- return type.const and type.name == 'char' and isinstance(type, PointerType)
- needs_policy = isinstance(m.result, (ReferenceType, PointerType))
- if IsString(m.result):
- needs_policy = False
- has_policy = self.info[m.name].policy is not None
- if needs_policy and not has_policy:
- warning = '---> Error: Method "%s" needs a policy.' % m.FullName()
- if warning not in self.printed_policy_warnings:
- print warning
- print
- self.printed_policy_warnings[warning] = 1
-
def ExportMethods(self):
'Export all the non-virtual methods of this class'
@@ -305,24 +288,28 @@ class ClassExporter(Exporter):
methods = [x for x in self.public_members if IsExportable(x)]
for method in methods:
- if self.info[method.name].exclude:
- continue # skip this method
+ method_info = self.info[method.name]
+
+ # skip this method if it was excluded by the user
+ if method_info.exclude:
+ continue
- name = self.info[method.name].rename or method.name
+ # rename the method if the user requested
+ name = method_info.rename or method.name
# warn the user if this method needs a policy and doesn't have one
- self.CheckPolicy(method)
+ method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
# check for policies
- policy = self.info[method.name].policy or ''
+ policy = method_info.policy or ''
if policy:
policy = ', %s%s()' % (namespaces.python, policy.Code())
# check for overloads
overload = ''
if method.minArgs != method.maxArgs:
# add the overloads for this method
- overload_name = OverloadName(method)
DeclareOverloads(method)
+ overload_name = OverloadName(method)
overload = ', %s%s()' % (namespaces.pyste, overload_name)
# build the .def string to export the method
@@ -337,7 +324,7 @@ class ClassExporter(Exporter):
code = '.staticmethod("%s")' % name
self.Add('inside', code)
# add wrapper code if this method has one
- wrapper = self.info[method.name].wrapper
+ wrapper = method_info.wrapper
if wrapper and wrapper.code:
self.Add('declaration', wrapper.code)
diff --git a/pyste/src/FunctionExporter.py b/pyste/src/FunctionExporter.py
index 60735ca0..e72c1392 100644
--- a/pyste/src/FunctionExporter.py
+++ b/pyste/src/FunctionExporter.py
@@ -2,8 +2,12 @@ from Exporter import Exporter
from policies import *
from declarations import *
from settings import *
+import exporterutils
+#==============================================================================
+# FunctionExporter
+#==============================================================================
class FunctionExporter(Exporter):
'Generates boost.python code to export the given function.'
@@ -14,7 +18,7 @@ class FunctionExporter(Exporter):
def Export(self, codeunit, exported_names):
decls = self.GetDeclarations(self.info.name)
for decl in decls:
- self.CheckPolicy(decl)
+ self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
self.ExportDeclaration(decl, len(decls) == 1, codeunit)
self.GenerateOverloads(decls, codeunit)
@@ -23,17 +27,6 @@ class FunctionExporter(Exporter):
return self.info.name
- def CheckPolicy(self, func):
- 'Warns the user if this function needs a policy'
- def IsString(type):
- return type.const and type.name == 'char' and isinstance(type, PointerType)
- needs_policy = isinstance(func.result, (ReferenceType, PointerType))
- if IsString(func.result):
- needs_policy = False
- if needs_policy and self.info.policy is None:
- print '---> Error: Function "%s" needs a policy.' % func.FullName()
- print
-
def ExportDeclaration(self, decl, unique, codeunit):
name = self.info.rename or decl.name
defs = namespaces.python + 'def("%s", ' % name
diff --git a/pyste/src/exporterutils.py b/pyste/src/exporterutils.py
index 5134a1e5..d7ded496 100644
--- a/pyste/src/exporterutils.py
+++ b/pyste/src/exporterutils.py
@@ -3,6 +3,8 @@ Various helpers for interface files.
'''
from settings import *
+from policies import *
+from declarations import *
#==============================================================================
# FunctionWrapper
@@ -24,3 +26,39 @@ class FunctionWrapper(object):
return namespaces.pyste + self.name
else:
return self.name
+
+
+#==============================================================================
+# HandlePolicy
+#==============================================================================
+def HandlePolicy(function, policy):
+ '''Show a warning to the user if the function needs a policy and doesn't
+ have one. Return a policy to the function, which is the given policy itself
+ if it is not None, or a default policy for this method.
+ '''
+
+ def IsString(type):
+ 'Return True if the Type instance can be considered a string'
+ return type.const and type.name == 'char' and isinstance(type, PointerType)
+
+ result = function.result
+ # basic test if the result type demands a policy
+ needs_policy = isinstance(result, (ReferenceType, PointerType))
+ # if the function returns const char*, a policy is not needed
+ if IsString(result):
+ needs_policy = False
+ # if returns a const T&, set the default policy
+ if policy is None and result.const and isinstance(result, ReferenceType):
+ policy = return_value_policy(copy_const_reference)
+ # show a warning to the user, if needed
+ if needs_policy and policy is None:
+ global _printed_warnings
+ warning = '---> Error: Method "%s" needs a policy.' % m.FullName()
+ if warning not in _printed_warnings:
+ print warning
+ print
+ # avoid double prints of the same warning
+ _printed_warnings[warning] = 1
+ return policy
+
+_printed_warnings = {} # used to avoid double-prints in HandlePolicy
diff --git a/pyste/src/pyste.py b/pyste/src/pyste.py
index 34afdecd..28f3d497 100644
--- a/pyste/src/pyste.py
+++ b/pyste/src/pyste.py
@@ -25,13 +25,8 @@ import exporterutils
import settings
from policies import *
from CppParser import CppParser, CppParserError
-from Exporter import Exporter
-from FunctionExporter import FunctionExporter
-from ClassExporter import ClassExporter
-from IncludeExporter import IncludeExporter
-from HeaderExporter import HeaderExporter
-__VERSION__ = '0.5.9'
+__VERSION__ = '0.6'
def GetDefaultIncludes():
if 'INCLUDE' in os.environ: