# 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
  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

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

    Calls declare_variable() on the associated DeclarationsScope object.

  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.

  indent(level=4)

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

  remove_cleanup_code(handle)

    Remove cleanup code previously added with add_cleanup_code()

  unindent()

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

  write_cleanup()

    Write the current cleanup code.

  write_code(code)

    Write out some simple code

  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.

  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: `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.ParameterMeta(name, bases, dict_)

  Bases: `type`

  Metaclass for automatically registering parameter type handlers

  metaclass __init__

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: `types.Parameter`

  Base class for all pointer-to-something handlers

  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

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

  Bases: `types.ReturnValue`

  Base class for all pointer-to-something handlers

  Creates a return value object

  Keywork Arguments:

  Parameters

    ctype – actual C/C++ type being used

  CTYPES = NotImplemented

class pybindgen.typehandlers.base.ReturnValueMeta(name, bases, dict_)

  Bases: `type`

  Metaclass for automatically registering parameter type handlers

  metaclass __init__

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
  property 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'