Esempio n. 1
0
    def add_include(self, include):
        """
        Adds an additional include directive, needed to compile this python module

        :param include: the name of the header file to include, including
                   surrounding "" or <>.
        """
        include = utils.ascii(include)
        assert include.startswith('"') or include.startswith('<')
        assert include.endswith('"') or include.endswith('>')
        if include not in self.includes:
            self.includes.append(include)
Esempio n. 2
0
    def add_include(self, include):
        """
        Adds an additional include directive, needed to compile this python module

        :param include: the name of the header file to include, including
                   surrounding "" or <>.
        """
        include = utils.ascii(include)
        assert include.startswith('"') or include.startswith('<')
        assert include.endswith('"') or include.endswith('>')
        if include not in self.includes:
            self.includes.append(include)
Esempio n. 3
0
 def _add_function_obj(self, wrapper):
     assert isinstance(wrapper, Function)
     name = utils.ascii(wrapper.custom_name)
     if name is None:
         name = self.c_function_name_transformer(wrapper.function_name)
         name = utils.get_mangled_name(name, wrapper.template_parameters)
     try:
         overload = self.functions[name]
     except KeyError:
         overload = OverloadedFunction(name)
         self.functions[name] = overload
     wrapper.module = self
     wrapper.section = self.current_section
     overload.add(wrapper)
Esempio n. 4
0
 def _add_function_obj(self, wrapper):
     assert isinstance(wrapper, Function)
     name = utils.ascii(wrapper.custom_name)
     if name is None:
         name = self.c_function_name_transformer(wrapper.function_name)
         name = utils.get_mangled_name(name, wrapper.template_parameters)
     try:
         overload = self.functions[name]
     except KeyError:
         overload = OverloadedFunction(name)
         self.functions[name] = overload
     wrapper.module = self
     wrapper.section = self.current_section
     overload.add(wrapper)
Esempio n. 5
0
    def add_typedef(self, wrapper, alias):
        """
        Declares an equivalent to a typedef in C::
          typedef Foo Bar;

        :param wrapper: the wrapper object to alias (Foo in the example)
        :param alias: name of the typedef alias

        @note: only typedefs for CppClass objects have been
        implemented so far; others will be implemented in the future.
        """
        assert isinstance(wrapper, CppClass)
        alias = utils.ascii(alias)
        self.typedefs.append((wrapper, alias))
        self.register_type(alias, alias, wrapper)
        wrapper.register_alias(alias)
        full_name = '::'.join(self.get_namespace_path() + [alias])
        wrapper.register_alias(full_name)
Esempio n. 6
0
    def add_typedef(self, wrapper, alias):
        """
        Declares an equivalent to a typedef in C::
          typedef Foo Bar;

        :param wrapper: the wrapper object to alias (Foo in the example)
        :param alias: name of the typedef alias

        @note: only typedefs for CppClass objects have been
        implemented so far; others will be implemented in the future.
        """
        assert isinstance(wrapper, CppClass)
        alias = utils.ascii(alias)
        self.typedefs.append((wrapper, alias))
        self.register_type(alias, alias, wrapper)
        wrapper.register_alias(alias)
        full_name = '::'.join(self.get_namespace_path() + [alias])
        wrapper.register_alias(full_name)
Esempio n. 7
0
    def add_cpp_namespace(self, name):
        """
        Add a nested module namespace corresponding to a C++
        namespace.  If the requested namespace was already added, the
        existing module is returned instead of creating a new one.

        :param name: name of C++ namespace (just the last component,
        not full scoped name); this also becomes the name of the
        submodule.

        :return: a L{SubModule} object that maps to this namespace.
        """
        name = utils.ascii(name)
        try:
            return self.get_submodule(name)
        except ValueError:
            module = SubModule(name, parent=self, cpp_namespace=name)
            module.stack_where_defined = traceback.extract_stack()
            return module
Esempio n. 8
0
    def add_cpp_namespace(self, name):
        """
        Add a nested module namespace corresponding to a C++
        namespace.  If the requested namespace was already added, the
        existing module is returned instead of creating a new one.

        :param name: name of C++ namespace (just the last component,
        not full scoped name); this also becomes the name of the
        submodule.

        :return: a L{SubModule} object that maps to this namespace.
        """
        name = utils.ascii(name)
        try:
            return self.get_submodule(name)
        except ValueError:
            module = SubModule(name, parent=self, cpp_namespace=name)
            module.stack_where_defined = traceback.extract_stack()
            return module
Esempio n. 9
0
    def declare_one_time_definition(self, definition_name):
        """
        Internal helper method for code geneneration to coordinate
        generation of code that can only be defined once per compilation unit

        (note: assuming here one-to-one mapping between 'module' and
        'compilation unit').

        :param definition_name: a string that uniquely identifies the code
        definition that will be added.  If the given definition was
        already declared KeyError is raised.
        
        >>> module = Module('foo')
        >>> module.declare_one_time_definition("zbr")
        >>> module.declare_one_time_definition("zbr")
        Traceback (most recent call last):
        ...
        KeyError: 'zbr'
        >>> module.declare_one_time_definition("bar")
        """
        definition_name = utils.ascii(definition_name)
        if definition_name in self.one_time_definitions:
            raise KeyError(definition_name)
        self.one_time_definitions[definition_name] = None
Esempio n. 10
0
    def declare_one_time_definition(self, definition_name):
        """
        Internal helper method for code geneneration to coordinate
        generation of code that can only be defined once per compilation unit

        (note: assuming here one-to-one mapping between 'module' and
        'compilation unit').

        :param definition_name: a string that uniquely identifies the code
        definition that will be added.  If the given definition was
        already declared KeyError is raised.
        
        >>> module = Module('foo')
        >>> module.declare_one_time_definition("zbr")
        >>> module.declare_one_time_definition("zbr")
        Traceback (most recent call last):
        ...
        KeyError: 'zbr'
        >>> module.declare_one_time_definition("bar")
        """
        definition_name = utils.ascii(definition_name)
        if definition_name in self.one_time_definitions:
            raise KeyError(definition_name)
        self.one_time_definitions[definition_name] = None
Esempio n. 11
0
    def __init__(self,
                 function_name,
                 return_value,
                 parameters,
                 docstring=None,
                 unblock_threads=None,
                 template_parameters=(),
                 custom_name=None,
                 deprecated=False,
                 foreign_cpp_namespace=None,
                 throw=()):
        """
        :param function_name: name of the C function
        :param return_value: the function return value
        :type return_value: L{ReturnValue}
        :param parameters: the function parameters
        :type parameters: list of L{Parameter}

        :param custom_name: an alternative name to give to this
           function at python-side; if omitted, the name of the
           function in the python module will be the same name as the
           function in C++ (minus namespace).

        :param deprecated: deprecation state for this API:
          - False: Not deprecated
          - True: Deprecated
          - "message": Deprecated, and deprecation warning contains the given message

        :param foreign_cpp_namespace: if set, the function is assumed
          to belong to the given C++ namespace, regardless of the C++
          namespace of the python module it will be added to.

        :param throw: list of C++ exceptions that the function may throw
        :type throw: list of L{CppException}
        """
        self.stack_where_defined = traceback.extract_stack()

        if unblock_threads is None:
            unblock_threads = settings.unblock_threads

        ## backward compatibility check
        if isinstance(return_value, string_types) and isinstance(
                function_name, ReturnValue):
            warnings.warn(
                "Function has changed API; see the API documentation (but trying to correct...)",
                DeprecationWarning,
                stacklevel=2)
            function_name, return_value = return_value, function_name

        if return_value is None:
            return_value = ReturnValue.new('void')

        return_value = utils.eval_retval(return_value, self)
        parameters = [utils.eval_param(param, self) for param in parameters]

        super(Function, self).__init__(return_value,
                                       parameters,
                                       parse_error_return="return NULL;",
                                       error_return="return NULL;",
                                       unblock_threads=unblock_threads)
        self.deprecated = deprecated
        self.foreign_cpp_namespace = foreign_cpp_namespace
        self._module = None
        function_name = utils.ascii(function_name)
        self.function_name = function_name
        self.wrapper_base_name = None
        self.wrapper_actual_name = None
        self.docstring = docstring
        self.self_parameter_pystruct = None
        self.template_parameters = template_parameters
        self.custom_name = custom_name
        for t in throw:
            assert isinstance(t, CppException)
        self.throw = list(throw)
        self.custodians_and_wards = []  # list of (custodian, ward, postcall)
        from pybindgen import cppclass
        cppclass.scan_custodians_and_wards(self)
Esempio n. 12
0
    def __init__(self, function_name, return_value, parameters, docstring=None, unblock_threads=None,
                 template_parameters=(), custom_name=None, deprecated=False, foreign_cpp_namespace=None,
                 throw=()):
        """
        :param function_name: name of the C function
        :param return_value: the function return value
        :type return_value: L{ReturnValue}
        :param parameters: the function parameters
        :type parameters: list of L{Parameter}

        :param custom_name: an alternative name to give to this
           function at python-side; if omitted, the name of the
           function in the python module will be the same name as the
           function in C++ (minus namespace).

        :param deprecated: deprecation state for this API:
          - False: Not deprecated
          - True: Deprecated
          - "message": Deprecated, and deprecation warning contains the given message

        :param foreign_cpp_namespace: if set, the function is assumed
          to belong to the given C++ namespace, regardless of the C++
          namespace of the python module it will be added to.

        :param throw: list of C++ exceptions that the function may throw
        :type throw: list of L{CppException}
        """
        self.stack_where_defined = traceback.extract_stack()

        if unblock_threads is None:
            unblock_threads = settings.unblock_threads
        
        ## backward compatibility check
        if isinstance(return_value, string_types) and isinstance(function_name, ReturnValue):
            warnings.warn("Function has changed API; see the API documentation (but trying to correct...)",
                          DeprecationWarning, stacklevel=2)
            function_name, return_value = return_value, function_name
            
        if return_value is None:
            return_value = ReturnValue.new('void')

        return_value = utils.eval_retval(return_value, self)
        parameters = [utils.eval_param(param, self) for param in parameters]

        super(Function, self).__init__(
            return_value, parameters,
            parse_error_return="return NULL;",
            error_return="return NULL;",
            unblock_threads=unblock_threads)
        self.deprecated = deprecated
        self.foreign_cpp_namespace = foreign_cpp_namespace
        self._module = None
        function_name = utils.ascii(function_name)
        self.function_name = function_name
        self.wrapper_base_name = None
        self.wrapper_actual_name = None
        self.docstring = docstring
        self.self_parameter_pystruct = None
        self.template_parameters = template_parameters
        self.custom_name = custom_name
        for t in throw:
            assert isinstance(t, CppException)
        self.throw = list(throw)
        self.custodians_and_wards = [] # list of (custodian, ward, postcall)
        from pybindgen import cppclass
        cppclass.scan_custodians_and_wards(self)