typehandlers.base: abstract base classes for type handlers and wrapper generators

Base classes for all parameter/return type handlers, and base interfaces for wrapper generators.

class pybindgen.typehandlers.base.BuildValueParameters

Bases: object

Object to keep track of Py_BuildValue (or similar) parameters

>>> bld = BuildValueParameters()
>>> bld.add_parameter('i', [123, 456])
>>> bld.add_parameter('s', ["hello"])
>>> bld.get_parameters()
['"is"', 123, 456, 'hello']
>>> bld = BuildValueParameters()
>>> bld.add_parameter('i', [123])
>>> bld.add_parameter('s', ["hello"], prepend=True)
>>> bld.get_parameters()
['"si"', 'hello', 123]
add_parameter(param_template, param_values, prepend=False, cancels_cleanup=None)

Adds a new parameter to the Py_BuildValue (or similar) statement.

Parameters:
  • param_template – template item, see documentation for Py_BuildValue for more information
  • param_values – list of C expressions to use as value, see documentation for Py_BuildValue for more information
  • prepend – whether this parameter should come first in the tuple being built
  • cancels_cleanup – optional handle to a cleanup action, that is removed after the call. Typically this is used for ‘N’ parameters, which already consume an object reference
clear()
get_cleanups()

Get a list of handles to cleanup actions

get_parameters(force_tuple_creation=False)

returns a list of parameters to pass into a Py_BuildValue-style function call, the first paramter in the list being the template string.

Parameters:force_tuple_creation – if True, Py_BuildValue is instructed to always create a tuple, even for zero or 1 values.
class pybindgen.typehandlers.base.CodeBlock(error_return, declarations, predecessor=None)

Bases: object

An intelligent code block that keeps track of cleanup actions. This object is to be used by TypeHandlers when generating code.

CodeBlock constructor

>>> block = CodeBlock("return NULL;", DeclarationsScope())
>>> block.write_code("foo();")
>>> cleanup1 = block.add_cleanup_code("clean1();")
>>> cleanup2 = block.add_cleanup_code("clean2();")
>>> cleanup3 = block.add_cleanup_code("clean3();")
>>> cleanup2.cancel()
>>> block.write_error_check("error()", "error_clean()")
>>> block.write_code("bar();")
>>> block.write_cleanup()
>>> print block.sink.flush().rstrip()
foo();
if (error()) {
    error_clean()
    clean3();
    clean1();
    return NULL;
}
bar();
clean3();
clean1();
Parameters:
  • error_return – code that is generated on error conditions (detected by write_error_check()); normally it returns from the wrapper function, e.g. return NULL;
  • predecessor – optional predecessor code block; a predecessor is used to search for additional cleanup actions.
class CleanupHandle(code_block, position)

Bases: object

Handle for some cleanup code

Create a handle given code_block and position

cancel()

Cancel the cleanup code

code_block
get_position()

returns the cleanup code relative position

position
CodeBlock.add_cleanup_code(cleanup_code)

Add a chunk of code used to cleanup previously allocated resources

Returns a handle used to cancel the cleanup code

CodeBlock.clear()
CodeBlock.declare_variable(type_, name, initializer=None, array=None)

Calls declare_variable() on the associated DeclarationsScope object.

CodeBlock.get_cleanup_code()

return a new list with all cleanup actions, including the ones from predecessor code blocks; Note: cleanup actions are executed in reverse order than when they were added.

CodeBlock.indent(level=4)

Add a certain ammount of indentation to all lines written from now on and until unindent() is called

CodeBlock.remove_cleanup_code(handle)

Remove cleanup code previously added with add_cleanup_code()

CodeBlock.unindent()

Revert indentation level to the value before last indent() call

CodeBlock.write_cleanup()

Write the current cleanup code.

CodeBlock.write_code(code)

Write out some simple code

CodeBlock.write_error_check(failure_expression, failure_cleanup=None)

Add a chunk of code that checks for a possible error

Parameters:
  • failure_expression – C boolean expression that is true when an error occurred
  • failure_cleanup – optional extra cleanup code to write only for the the case when failure_expression is true; this extra cleanup code comes before all other cleanup code previously registered.
CodeBlock.write_error_return()

Add a chunk of code that cleans up and returns an error.

exception pybindgen.typehandlers.base.CodeGenerationError

Bases: pybindgen.typehandlers.base.CodegenErrorBase

Exception that is raised when wrapper generation fails for some reason.

exception pybindgen.typehandlers.base.CodegenErrorBase

Bases: exceptions.Exception

class pybindgen.typehandlers.base.DeclarationsScope(parent_scope=None)

Bases: object

Manages variable declarations in a given scope.

Constructor

>>> scope = DeclarationsScope()
>>> scope.declare_variable('int', 'foo')
'foo'
>>> scope.declare_variable('char*', 'bar')
'bar'
>>> scope.declare_variable('int', 'foo')
'foo2'
>>> scope.declare_variable('int', 'foo', '1')
'foo3'
>>> scope.declare_variable('const char *', 'kwargs', '{"hello", NULL}', '[]')
'kwargs'
>>> print scope.get_code_sink().flush().rstrip()
int foo;
char *bar;
int foo2;
int foo3 = 1;
const char *kwargs[] = {"hello", NULL};
Parameters:parent_scope – optional ‘parent scope’; if given, declarations in this scope will avoid clashing with names in the parent scope, and vice versa.
clear()
declare_variable(type_, name, initializer=None, array=None)

Add code to declare a variable. Returns the actual variable name used (uses ‘name’ as base, with a number in case of conflict.)

Parameters:
  • type – C type name of the variable
  • name – base name of the variable; actual name used can be slightly different in case of name conflict.
  • initializer – optional, value to initialize the variable with
  • array – optional, array size specifiction, e.g. ‘[]’, or ‘[100]’
get_code_sink()

Returns the internal MemoryCodeSink that holds all declararions.

reserve_variable(name)

Reserve a variable name, to be used later.

Parameters:name – base name of the variable; actual name used can be slightly different in case of name conflict.
class pybindgen.typehandlers.base.ForwardWrapperBase(return_value, parameters, parse_error_return, error_return, force_parse=None, no_c_retval=False, unblock_threads=False)

Bases: object

Generic base for all forward wrapper generators.

Forward wrappers all have the following general structure in common:

  1. ‘declarations’ – variable declarations; for compatibility

    with older C compilers it is very important that all declarations come before any simple statement. Declarations can be added with the add_declaration() method on the ‘declarations’ attribute. Two standard declarations are always predeclared: ‘<return-type> retval’, unless return-type is void, and ‘PyObject *py_retval’;

  2. ‘code before parse’ – code before the

    PyArg_ParseTupleAndKeywords call; code can be freely added to it by accessing the ‘before_parse’ (a CodeBlock instance) attribute;

  3. A PyArg_ParseTupleAndKeywords call; uses items from the

    parse_params object;

  4. ‘code before call’ – this is a code block dedicated to contain

    all code that is needed before calling the C function; code can be freely added to it by accessing the ‘before_call’ (a CodeBlock instance) attribute;

  5. ‘call into C’ – this is realized by a C/C++ call; the list of

    parameters that should be used is in the ‘call_params’ wrapper attribute;

  6. ‘code after call’ – this is a code block dedicated to contain

    all code that must come after calling into Python; code can be freely added to it by accessing the ‘after_call’ (a CodeBlock instance) attribute;

  7. A py_retval = Py_BuildValue(...) call; this call can be customized, so that out/inout parameters can add additional return values, by accessing the ‘build_params’ (a BuildValueParameters instance) attribute;

  8. Cleanup and return.

Object constructors cannot return values, and so the step 7 is to be omitted for them.

Base constructor

Parameters:
  • return_value – type handler for the return value
  • parameters – a list of type handlers for the parameters
  • parse_error_return – statement to return an error during parameter parsing
  • error_return – statement to return an error after parameter parsing
  • force_parse – force generation of code to parse parameters even if there are none
  • no_c_retval – force the wrapper to not have a C return value
  • unblock_threads – generate code to unblock python threads during the C function call
HAVE_RETURN_VALUE = False
PARSE_TUPLE = 1
PARSE_TUPLE_AND_KEYWORDS = 2
generate_body(code_sink, gen_call_params=())

Generate the wrapper function body code_sink – a CodeSink object that will receive the code

generate_call()

Generates the code (into self.before_call) to call into Python, storing the result in the variable ‘py_retval’; should also check for call error.

get_py_method_def_flags()

Get a list of PyMethodDef flags that should be used for this wrapper.

reset_code_generation_state()
set_parse_error_return(parse_error_return)
write_close_wrapper(code_sink)
write_open_wrapper(code_sink, add_static=False)
exception pybindgen.typehandlers.base.NotSupportedError

Bases: pybindgen.typehandlers.base.CodegenErrorBase

Exception that is raised when declaring an interface configuration that is not supported or not implemented.

class pybindgen.typehandlers.base.NullTypeTransformation

Bases: object

Null type transformation, returns everything unchanged.

create_type_handler(type_handler_class, *args, **kwargs)

identity transformation

get_untransformed_name(name)

identity transformation

transform(type_handler, declarations, code_block, value)

identity transformation

untransform(type_handler, declarations, code_block, value)

identity transformation

class pybindgen.typehandlers.base.Parameter(ctype, name, direction=1, is_const=False, default_value=None)

Bases: pybindgen.typehandlers.base.TypeHandler

Abstract base class for all classes dedicated to handle specific parameter types

Creates a parameter object

Parameters:
  • ctype – actual C/C++ type being used
  • name – parameter name
  • direction – direction of the parameter transfer, valid values are DIRECTION_IN, DIRECTION_OUT, and DIRECTION_IN|DIRECTION_OUT
CTYPES = NotImplemented
DIRECTIONS = NotImplemented
DIRECTION_IN = 1
DIRECTION_INOUT = 3
DIRECTION_OUT = 2
SUPPORTS_TRANSFORMATIONS = False
convert_c_to_python(wrapper)

Write some code before calling the Python method.

convert_python_to_c(wrapper)

Write some code before calling the C method.

classmethod new(*args, **kwargs)
>>> import inttype
>>> isinstance(Parameter.new('int', 'name'), inttype.IntParam)
True
class pybindgen.typehandlers.base.ParseTupleParameters

Bases: object

Object to keep track of PyArg_ParseTuple (or similar) parameters

>>> tuple_params = ParseTupleParameters()
>>> tuple_params.add_parameter('i', ['&foo'], 'foo')
1
>>> tuple_params.add_parameter('s', ['&bar'], 'bar', optional=True)
2
>>> tuple_params.get_parameters()
['"i|s"', '&foo', '&bar']
>>> tuple_params.get_keywords()
['foo', 'bar']
>>> tuple_params = ParseTupleParameters()
>>> tuple_params.add_parameter('i', ['&foo'], 'foo')
1
>>> tuple_params.add_parameter('s', ['&bar'], 'bar', prepend=True)
2
>>> tuple_params.get_parameters()
['"si"', '&bar', '&foo']
>>> tuple_params.get_keywords()
['bar', 'foo']
>>> tuple_params = ParseTupleParameters()
>>> tuple_params.add_parameter('i', ['&foo'])
1
>>> print tuple_params.get_keywords()
None
add_parameter(param_template, param_values, param_name=None, prepend=False, optional=False)

Adds a new parameter specification

Parameters:
  • param_template – template item, see documentation for PyArg_ParseTuple for more information
  • param_values – list of parameters, see documentation for PyArg_ParseTuple for more information
  • prepend – whether this parameter should be parsed first
  • optional – whether the parameter is optional; note that after the first optional parameter, all remaining parameters must also be optional
clear()
get_keywords()

returns list of keywords (parameter names), or None if none of the parameters had a name; should only be called if names were given for all parameters or none of them.

get_parameters()

returns a list of parameters to pass into a PyArg_ParseTuple-style function call, the first paramter in the list being the template string.

is_empty()
class pybindgen.typehandlers.base.PointerParameter(ctype, name, direction=1, is_const=False, default_value=None, transfer_ownership=False)

Bases: pybindgen.typehandlers.base.Parameter

Base class for all pointer-to-something handlers

CTYPES = NotImplemented
class pybindgen.typehandlers.base.PointerReturnValue(ctype, is_const=False, caller_owns_return=None)

Bases: pybindgen.typehandlers.base.ReturnValue

Base class for all pointer-to-something handlers

CTYPES = NotImplemented
class pybindgen.typehandlers.base.ReturnValue(ctype, is_const=False)

Bases: pybindgen.typehandlers.base.TypeHandler

Abstract base class for all classes dedicated to handle specific return value types

Creates a return value object

Keywork Arguments:

Parameters:ctype – actual C/C++ type being used
CTYPES = NotImplemented
REQUIRES_ASSIGNMENT_CONSTRUCTOR = False
SUPPORTS_TRANSFORMATIONS = False
convert_c_to_python(wrapper)

Writes code to convert the C return value the Python return.

convert_python_to_c(wrapper)

Writes code to convert the Python return value into the C “retval” variable.

get_c_error_return()

Return a “return <value>” code string, for use in case of error

classmethod new(*args, **kwargs)
>>> import inttype
>>> isinstance(ReturnValue.new('int'), inttype.IntReturn)
True
class pybindgen.typehandlers.base.ReverseWrapperBase(return_value, parameters, error_return=None)

Bases: object

Generic base for all reverse wrapper generators.

Reverse wrappers all have the following general structure in common:

  1. ‘declarations’ – variable declarations; for compatibility with older C compilers it is very important that all declarations come before any simple statement. Declarations can be added with the add_declaration() method on the ‘declarations’ attribute. Two standard declarations are always predeclared: ‘<return-type> retval’, unless return-type is void, and ‘PyObject *py_retval’;
  2. ‘code before call’ – this is a code block dedicated to contain all code that is needed before calling into Python; code can be freely added to it by accessing the ‘before_call’ (a CodeBlock instance) attribute;
  3. ‘call into python’ – this is realized by a PyObject_CallMethod(...) or similar Python API call; the list of parameters used in this call can be customized by accessing the ‘build_params’ (a BuildValueParameters instance) attribute;
  4. ‘code after call’ – this is a code block dedicated to contain all code that must come after calling into Python; code can be freely added to it by accessing the ‘after_call’ (a CodeBlock instance) attribute;
  5. A ‘return retval’ statement (or just ‘return’ if return_value is void)

Base constructor

Parameters:
  • return_value – type handler for the return value
  • parameters – a list of type handlers for the parameters
NO_GIL_LOCKING = False
generate(code_sink, wrapper_name, decl_modifiers=('static', ), decl_post_modifiers=())

Generate the wrapper

Parameters:
  • code_sink – a CodeSink object that will receive the code
  • wrapper_name – C/C++ identifier of the function/method to generate
  • decl_modifiers – list of C/C++ declaration modifiers, e.g. ‘static’
generate_python_call()

Generates the code (into self.before_call) to call into Python, storing the result in the variable ‘py_retval’; should also check for call error.

reset_code_generation_state()
set_error_return(error_return)
exception pybindgen.typehandlers.base.TypeConfigurationError

Bases: pybindgen.typehandlers.base.CodegenErrorBase

Exception that is raised when a type handler does not find some information it needs, such as owernship transfer semantics.

class pybindgen.typehandlers.base.TypeHandler(ctype, is_const=False)

Bases: object

SUPPORTS_TRANSFORMATIONS = False
ctype_no_const
set_tranformation(transformation, untransformed_ctype)
set_transformation(transformation, untransformed_ctype)

Set the type transformation to use in this type handler

exception pybindgen.typehandlers.base.TypeLookupError

Bases: pybindgen.typehandlers.base.CodegenErrorBase

Exception that is raised when lookup of a type handler fails

class pybindgen.typehandlers.base.TypeMatcher

Bases: object

Type matcher object: maps C type names to classes that handle those types.

Constructor

add_type_alias(from_type_name, to_type_name)
items()

Returns an iterator over all registered items

lookup(name) → type_handler, type_transformation, type_traits
Parameters:name – C type name, possibly transformed (e.g. MySmartPointer<Foo> looks up Foo*)
Returns:a handler with the given ctype name, or raises KeyError.

Supports type transformations.

register(name, type_handler)

Register a new handler class for a given C type

Parameters:
  • name – C type name
  • type_handler – class to handle this C type
register_transformation(transformation)

Register a type transformation object

class pybindgen.typehandlers.base.TypeTransformation

Bases: object

Type transformations are used to register handling of special types that are simple transformation over another type that is already registered. This way, only the original type is registered, and the type transformation only does the necessary adjustments over the original type handler to make it handle the transformed type as well.

This is typically used to get smart pointer templated types working.

create_type_handler(type_handler_class, *args, **kwargs)

Given a type_handler class, create an instance with proper customization.

Parameters:
  • type_handler_class – type handler class
  • args – arguments
  • kwargs – keywords arguments
get_untransformed_name(name)

Given a transformed named, get the original C type name. E.g., given a smart pointer transformation, MySmartPointer:

get_untransformed_name('MySmartPointer<Foo>') -> 'Foo\*'
transform(type_handler, declarations, code_block, value)

Transforms a value expression of the original type to an equivalent value expression in the transformed type.

Example, with the transformation::
‘T*’ -> ‘boost::shared_ptr<T>’
Then::
transform(wrapper, ‘foo’) -> ‘boost::shared_ptr<%s>(foo)’ % type_handler.untransformed_ctype
untransform(type_handler, declarations, code_block, value)

Transforms a value expression of the transformed type to an equivalent value expression in the original type.

Example, with the transformation::
‘T*’ -> ‘boost::shared_ptr<T>’
Then::
untransform(wrapper, ‘foo’) -> ‘foo->get_pointer()’
pybindgen.typehandlers.base.add_type_alias(from_type_name, to_type_name)
pybindgen.typehandlers.base.join_ctype_and_name(ctype, name)

Utility method that joins a C type and a variable name into a single string

>>> join_ctype_and_name('void*', 'foo')
'void *foo'
>>> join_ctype_and_name('void *', 'foo')
'void *foo'
>>> join_ctype_and_name("void**", "foo")
'void **foo'
>>> join_ctype_and_name("void **", "foo")
'void **foo'
>>> join_ctype_and_name('C*', 'foo')
'C *foo'

Previous topic

utils: internal utilities

Next topic

cppclass_typehandlers: type handlers for C++ classes (or C structures)

This Page