1""" 2Objects that represent -- and generate code for -- C/C++ Python extension modules. 3 4Modules and Sub-modules 5======================= 6 7A L{Module} object takes care of generating the code for a Python 8module. The way a Python module is organized is as follows. There is 9one "root" L{Module} object. There can be any number of 10L{SubModule}s. Sub-modules themselves can have additional sub-modules. 11Calling L{Module.generate} on the root module will trigger code 12generation for the whole module, not only functions and types, but 13also all its sub-modules. 14 15In Python, a sub-module will appear as a I{built-in} Python module 16that is available as an attribute of its parent module. For instance, 17a module I{foo} having a sub-module I{xpto} appears like this:: 18 19 |>>> import foo 20 |>>> foo.xpto 21 |<module 'foo.xpto' (built-in)> 22 23Modules and C++ namespaces 24========================== 25 26Modules can be associated with specific C++ namespaces. This means, 27for instance, that any C++ class wrapped inside that module must 28belong to that C++ namespace. Example:: 29 30 |>>> from cppclass import * 31 |>>> mod = Module("foo", cpp_namespace="::foo") 32 |>>> mod.add_class("Bar") 33 |<pybindgen.CppClass 'foo::Bar'> 34 35When we have a toplevel C++ namespace which contains another nested 36namespace, we want to wrap the nested namespace as a Python 37sub-module. The method L{ModuleBase.add_cpp_namespace} makes it easy 38to create sub-modules for wrapping nested namespaces. For instance:: 39 40 |>>> from cppclass import * 41 |>>> mod = Module("foo", cpp_namespace="::foo") 42 |>>> submod = mod.add_cpp_namespace('xpto') 43 |>>> submod.add_class("Bar") 44 |<pybindgen.CppClass 'foo::xpto::Bar'> 45 46""" 47 48from pybindgen.function import Function, OverloadedFunction, CustomFunctionWrapper 49from pybindgen.typehandlers.base import CodeBlock, DeclarationsScope, ReturnValue, TypeHandler 50from pybindgen.typehandlers.codesink import MemoryCodeSink, CodeSink, FileCodeSink, NullCodeSink 51from pybindgen.cppclass import CppClass 52from pybindgen.cppexception import CppException 53from pybindgen.enum import Enum 54from pybindgen.container import Container 55from pybindgen.converter_functions import PythonToCConverter, CToPythonConverter 56from pybindgen import utils 57import warnings 58import traceback 59import collections 60 61class MultiSectionFactory(object): 62 """ 63 Abstract base class for objects providing support for 64 multi-section code generation, i.e., splitting the generated C/C++ 65 code into multiple files. The generated code will generally have 66 the following structure: 67 68 1. For each section there is one source file specific to that section; 69 70 2. There is a I{main} source file, e.g. C{foomodule.cc}. Code 71 that does not belong to any section will be included in this 72 main file; 73 74 3. Finally, there is a common header file, (e.g. foomodule.h), 75 which is included by the main file and section files alike. 76 Typically this header file contains function prototypes and 77 type definitions. 78 79 @see: L{Module.generate} 80 81 """ 82 def get_section_code_sink(self, section_name): 83 """ 84 Create and/or return a code sink for a given section. 85 86 :param section_name: name of the section 87 :return: a L{CodeSink} object that will receive generated code belonging to the section C{section_name} 88 """ 89 raise NotImplementedError 90 def get_main_code_sink(self): 91 """ 92 Create and/or return a code sink for the main file. 93 """ 94 raise NotImplementedError 95 def get_common_header_code_sink(self): 96 """ 97 Create and/or return a code sink for the common header. 98 """ 99 raise NotImplementedError 100 def get_common_header_include(self): 101 """ 102 Return the argument for an #include directive to include the common header. 103 104 :returns: a string with the header name, including surrounding 105 "" or <>. For example, '"foomodule.h"'. 106 """ 107 raise NotImplementedError 108 109 110class _SinkManager(object): 111 """ 112 Internal abstract base class for bridging differences between 113 multi-file and single-file code generation. 114 """ 115 def get_code_sink_for_wrapper(self, wrapper): 116 """ 117 :param wrapper: wrapper object 118 :returns: (body_code_sink, header_code_sink) 119 """ 120 raise NotImplementedError 121 def get_includes_code_sink(self): 122 raise NotImplementedError 123 def get_main_code_sink(self): 124 raise NotImplementedError 125 def close(self): 126 raise NotImplementedError 127 128class _MultiSectionSinkManager(_SinkManager): 129 """ 130 Sink manager that deals with multi-section code generation. 131 """ 132 def __init__(self, multi_section_factory): 133 super(_MultiSectionSinkManager, self).__init__() 134 self.multi_section_factory = multi_section_factory 135 utils.write_preamble(self.multi_section_factory.get_common_header_code_sink()) 136 self.multi_section_factory.get_main_code_sink().writeln( 137 "#include %s" % self.multi_section_factory.get_common_header_include()) 138 self._already_initialized_sections = {} 139 self._already_initialized_sections['__main__'] = True 140 141 def get_code_sink_for_wrapper(self, wrapper): 142 header_sink = self.multi_section_factory.get_common_header_code_sink() 143 section = getattr(wrapper, "section", None) 144 if section is None: 145 return self.multi_section_factory.get_main_code_sink(), header_sink 146 else: 147 section_sink = self.multi_section_factory.get_section_code_sink(section) 148 if section not in self._already_initialized_sections: 149 self._already_initialized_sections[section] = True 150 section_sink.writeln("#include %s" % self.multi_section_factory.get_common_header_include()) 151 return section_sink, header_sink 152 def get_includes_code_sink(self): 153 return self.multi_section_factory.get_common_header_code_sink() 154 def get_main_code_sink(self): 155 return self.multi_section_factory.get_main_code_sink() 156 def close(self): 157 pass 158 159class _MonolithicSinkManager(_SinkManager): 160 """ 161 Sink manager that deals with single-section monolithic code generation. 162 """ 163 def __init__(self, code_sink): 164 super(_MonolithicSinkManager, self).__init__() 165 self.final_code_sink = code_sink 166 self.null_sink = NullCodeSink() 167 self.includes = MemoryCodeSink() 168 self.code_sink = MemoryCodeSink() 169 170 utils.write_preamble(code_sink) 171 def get_code_sink_for_wrapper(self, dummy_wrapper): 172 return self.code_sink, self.code_sink 173 def get_includes_code_sink(self): 174 return self.includes 175 def get_main_code_sink(self): 176 return self.code_sink 177 def close(self): 178 self.includes.flush_to(self.final_code_sink) 179 self.code_sink.flush_to(self.final_code_sink) 180 181 182class ModuleBase(dict): 183 """ 184 ModuleBase objects can be indexed dictionary style to access contained types. Example:: 185 186 >>> from enum import Enum 187 >>> from cppclass import CppClass 188 >>> m = Module("foo", cpp_namespace="foo") 189 >>> subm = m.add_cpp_namespace("subm") 190 >>> c1 = m.add_class("Bar") 191 >>> c2 = subm.add_class("Zbr") 192 >>> e1 = m.add_enum("En1", ["XX"]) 193 >>> e2 = subm.add_enum("En2", ["XX"]) 194 >>> m["Bar"] is c1 195 True 196 >>> m["foo::Bar"] is c1 197 True 198 >>> m["En1"] is e1 199 True 200 >>> m["foo::En1"] is e1 201 True 202 >>> m["badname"] 203 Traceback (most recent call last): 204 File "<stdin>", line 1, in <module> 205 KeyError: 'badname' 206 >>> m["foo::subm::Zbr"] is c2 207 True 208 >>> m["foo::subm::En2"] is e2 209 True 210 211 """ 212 213 def __init__(self, name, parent=None, docstring=None, cpp_namespace=None): 214 """ 215 Note: this is an abstract base class, see L{Module} 216 217 :param name: module name 218 :param parent: parent L{module<Module>} (i.e. the one that contains this submodule) or None if this is a root module 219 :param docstring: docstring to use for this module 220 :param cpp_namespace: C++ namespace prefix associated with this module 221 :return: a new module object 222 """ 223 super(ModuleBase, self).__init__() 224 self.parent = parent 225 self.docstring = docstring 226 self.submodules = [] 227 self.enums = [] 228 self.typedefs = [] # list of (wrapper, alias) tuples 229 self._forward_declarations_declared = False 230 231 self.cpp_namespace = cpp_namespace 232 if self.parent is None: 233 error_return = 'return MOD_ERROR;' 234 self.after_forward_declarations = MemoryCodeSink() 235 else: 236 self.after_forward_declarations = None 237 self.parent.submodules.append(self) 238 error_return = 'return NULL;' 239 240 self.prefix = None 241 self.init_function_name = None 242 self._name = None 243 self.name = name 244 245 path = self.get_namespace_path() 246 if path and path[0] == '::': 247 del path[0] 248 self.cpp_namespace_prefix = '::'.join(path) 249 250 self.declarations = DeclarationsScope() 251 self.functions = collections.OrderedDict() # name => OverloadedFunction 252 self.classes = [] 253 self.containers = [] 254 self.exceptions = [] 255 self.before_init = CodeBlock(error_return, self.declarations) 256 self.after_init = CodeBlock(error_return, self.declarations, 257 predecessor=self.before_init) 258 self.c_function_name_transformer = None 259 self.set_strip_prefix(name + '_') 260 if parent is None: 261 self.header = MemoryCodeSink() 262 self.body = MemoryCodeSink() 263 self.one_time_definitions = {} 264 self.includes = [] 265 else: 266 self.header = parent.header 267 self.body = parent.body 268 self.one_time_definitions = parent.one_time_definitions 269 self.includes = parent.includes 270 271 self._current_section = '__main__' 272 273 def get_current_section(self): 274 return self.get_root()._current_section 275 current_section = property(get_current_section) 276 277 def begin_section(self, section_name): 278 """ 279 Declare that types and functions registered with the module in 280 the future belong to the section given by that section_name 281 parameter, until a matching end_section() is called. 282 283 .. note:: 284 285 :meth:`begin_section`/:meth:`end_section` are silently ignored 286 unless a :class:`MultiSectionFactory` object is used as code 287 generation output. 288 """ 289 if self.current_section != '__main__': 290 raise ValueError("begin_section called while current section not ended") 291 if section_name == '__main__': 292 raise ValueError ("__main__ not allowed as section name") 293 assert self.parent is None 294 self._current_section = section_name 295 296 def end_section(self, section_name): 297 """ 298 Declare the end of a section, i.e. further types and functions 299 will belong to the main module. 300 301 :param section_name: name of section; must match the one in 302 the previous :meth:`begin_section` call. 303 """ 304 assert self.parent is None 305 if self._current_section != section_name: 306 raise ValueError("end_section called for wrong section: expected %r, got %r" 307 % (self._current_section, section_name)) 308 self._current_section = '__main__' 309 310 def get_name(self): 311 return self._name 312 313 def set_name(self, name): 314 self._name = name 315 316 if self.parent is None: 317 self.prefix = self.name.replace('.', '_') 318 self.init_function_name = "init%s" % (self.name.split('.')[-1],) 319 else: 320 self.prefix = self.parent.prefix + "_" + self.name 321 self.init_function_name = "init%s" % (self.prefix,) 322 323 name = property(get_name, set_name) 324 325 def get_submodule(self, submodule_name): 326 "get a submodule by its name" 327 for submodule in self.submodules: 328 if submodule.name == submodule_name: 329 return submodule 330 raise ValueError("submodule %s not found" % submodule_name) 331 332 def get_root(self): 333 ":return: the root :class:`Module` (even if it is self)" 334 root = self 335 while root.parent is not None: 336 root = root.parent 337 return root 338 339 def set_strip_prefix(self, prefix): 340 """Sets the prefix string to be used when transforming a C 341 function name into the python function name; the given prefix 342 string is removed from the C function name.""" 343 344 def strip_prefix(c_name): 345 """A C funtion name transformer that simply strips a 346 common prefix from the name""" 347 if c_name.startswith(prefix): 348 return c_name[len(prefix):] 349 else: 350 return c_name 351 self.c_function_name_transformer = strip_prefix 352 353 def set_c_function_name_transformer(self, transformer): 354 """Sets the function to be used when transforming a C function 355 name into the python function name; the given given function 356 is called like this:: 357 358 python_name = transformer(c_name) 359 """ 360 self.c_function_name_transformer = transformer 361 362 def add_include(self, include): 363 """ 364 Adds an additional include directive, needed to compile this python module 365 366 :param include: the name of the header file to include, including 367 surrounding "" or <>. 368 """ 369 include = utils.ascii(include) 370 assert include.startswith('"') or include.startswith('<') 371 assert include.endswith('"') or include.endswith('>') 372 if include not in self.includes: 373 self.includes.append(include) 374 375 def _add_function_obj(self, wrapper): 376 assert isinstance(wrapper, Function) 377 name = utils.ascii(wrapper.custom_name) 378 if name is None: 379 name = self.c_function_name_transformer(wrapper.function_name) 380 name = utils.get_mangled_name(name, wrapper.template_parameters) 381 try: 382 overload = self.functions[name] 383 except KeyError: 384 overload = OverloadedFunction(name) 385 self.functions[name] = overload 386 wrapper.module = self 387 wrapper.section = self.current_section 388 overload.add(wrapper) 389 390 def add_function(self, *args, **kwargs): 391 """ 392 Add a function to the module/namespace. See the documentation for 393 :meth:`Function.__init__` for information on accepted parameters. 394 """ 395 if len(args) >= 1 and isinstance(args[0], Function): 396 func = args[0] 397 warnings.warn("add_function has changed API; see the API documentation", 398 DeprecationWarning, stacklevel=2) 399 if len(args) == 2: 400 func.custom_name = args[1] 401 elif 'name' in kwargs: 402 assert len(args) == 1 403 func.custom_name = kwargs['name'] 404 else: 405 assert len(args) == 1 406 assert len(kwargs) == 0 407 else: 408 try: 409 func = Function(*args, **kwargs) 410 except utils.SkipWrapper: 411 return None 412 self._add_function_obj(func) 413 return func 414 415 def add_custom_function_wrapper(self, *args, **kwargs): 416 """ 417 Add a function, using custom wrapper code, to the module/namespace. See the documentation for 418 :class:`pybindgen.function.CustomFunctionWrapper` for information on accepted parameters. 419 """ 420 try: 421 func = CustomFunctionWrapper(*args, **kwargs) 422 except utils.SkipWrapper: 423 return None 424 self._add_function_obj(func) 425 return func 426 427 def register_type(self, name, full_name, type_wrapper): 428 """ 429 Register a type wrapper with the module, for easy access in 430 the future. Normally should not be called by the programmer, 431 as it is meant for internal pybindgen use and called automatically. 432 433 :param name: type name without any C++ namespace prefix, or None 434 :param full_name: type name with a C++ namespace prefix, or None 435 :param type_wrapper: the wrapper object for the type (e.g. L{CppClass} or L{Enum}) 436 """ 437 module = self 438 if name: 439 module[name] = type_wrapper 440 if full_name: 441 while module is not None: 442 module[full_name] = type_wrapper 443 module = module.parent 444 445 def _add_class_obj(self, class_): 446 """ 447 Add a class to the module. 448 449 :param class_: a CppClass object 450 """ 451 assert isinstance(class_, CppClass) 452 class_.module = self 453 class_.section = self.current_section 454 self.classes.append(class_) 455 self.register_type(class_.name, class_.full_name, class_) 456 457 def add_class(self, *args, **kwargs): 458 """ 459 Add a class to the module. See the documentation for 460 L{CppClass.__init__} for information on accepted parameters. 461 """ 462 if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], CppClass): 463 cls = args[0] 464 warnings.warn("add_class has changed API; see the API documentation", 465 DeprecationWarning, stacklevel=2) 466 else: 467 cls = CppClass(*args, **kwargs) 468 self._add_class_obj(cls) 469 return cls 470 471 def add_struct(self, *args, **kwargs): 472 """ 473 Add a struct to the module. 474 475 In addition to the parameters accepted by 476 L{CppClass.__init__}, this method accepts the following 477 keyword parameters: 478 479 - no_constructor (bool): if True, the structure will not 480 have a constructor by default (if omitted, it will be 481 considered to have a trivial constructor). 482 483 - no_copy (bool): if True, the structure will not 484 have a copy constructor by default (if omitted, it will be 485 considered to have a simple copy constructor). 486 487 """ 488 489 try: 490 no_constructor = kwargs['no_constructor'] 491 except KeyError: 492 no_constructor = False 493 else: 494 del kwargs['no_constructor'] 495 496 try: 497 no_copy = kwargs['no_copy'] 498 except KeyError: 499 no_copy = False 500 else: 501 del kwargs['no_copy'] 502 503 struct = CppClass(*args, **kwargs) 504 struct.stack_where_defined = traceback.extract_stack() 505 self._add_class_obj(struct) 506 if not no_constructor: 507 struct.add_constructor([]) 508 if not no_copy: 509 struct.add_copy_constructor() 510 return struct 511 512 513 def add_cpp_namespace(self, name): 514 """ 515 Add a nested module namespace corresponding to a C++ 516 namespace. If the requested namespace was already added, the 517 existing module is returned instead of creating a new one. 518 519 :param name: name of C++ namespace (just the last component, 520 not full scoped name); this also becomes the name of the 521 submodule. 522 523 :return: a L{SubModule} object that maps to this namespace. 524 """ 525 name = utils.ascii(name) 526 try: 527 return self.get_submodule(name) 528 except ValueError: 529 module = SubModule(name, parent=self, cpp_namespace=name) 530 module.stack_where_defined = traceback.extract_stack() 531 return module 532 533 def _add_enum_obj(self, enum): 534 """ 535 Add an enumeration. 536 """ 537 assert isinstance(enum, Enum) 538 self.enums.append(enum) 539 enum.module = self 540 enum.section = self.current_section 541 self.register_type(enum.name, enum.full_name, enum) 542 543 def add_enum(self, *args, **kwargs): 544 """ 545 Add an enumeration to the module. See the documentation for 546 L{Enum.__init__} for information on accepted parameters. 547 """ 548 if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], Enum): 549 enum = args[0] 550 warnings.warn("add_enum has changed API; see the API documentation", 551 DeprecationWarning, stacklevel=2) 552 else: 553 enum = Enum(*args, **kwargs) 554 enum.stack_where_defined = traceback.extract_stack() 555 self._add_enum_obj(enum) 556 return enum 557 558 559 def _add_container_obj(self, container): 560 """ 561 Add a container to the module. 562 563 :param container: a L{Container} object 564 """ 565 assert isinstance(container, Container) 566 container.module = self 567 container.section = self.current_section 568 self.containers.append(container) 569 self.register_type(container.name, container.full_name, container) 570 571 def add_container(self, *args, **kwargs): 572 """ 573 Add a container to the module. See the documentation for 574 L{Container.__init__} for information on accepted parameters. 575 """ 576 try: 577 container = Container(*args, **kwargs) 578 except utils.SkipWrapper: 579 return None 580 container.stack_where_defined = traceback.extract_stack() 581 self._add_container_obj(container) 582 return container 583 584 def _add_exception_obj(self, exc): 585 assert isinstance(exc, CppException) 586 exc.module = self 587 exc.section = self.current_section 588 self.exceptions.append(exc) 589 self.register_type(exc.name, exc.full_name, exc) 590 591 def add_exception(self, *args, **kwargs): 592 """ 593 Add a C++ exception to the module. See the documentation for 594 L{CppException.__init__} for information on accepted parameters. 595 """ 596 exc = CppException(*args, **kwargs) 597 self._add_exception_obj(exc) 598 return exc 599 600 def declare_one_time_definition(self, definition_name): 601 """ 602 Internal helper method for code geneneration to coordinate 603 generation of code that can only be defined once per compilation unit 604 605 (note: assuming here one-to-one mapping between 'module' and 606 'compilation unit'). 607 608 :param definition_name: a string that uniquely identifies the code 609 definition that will be added. If the given definition was 610 already declared KeyError is raised. 611 612 >>> module = Module('foo') 613 >>> module.declare_one_time_definition("zbr") 614 >>> module.declare_one_time_definition("zbr") 615 Traceback (most recent call last): 616 ... 617 KeyError: 'zbr' 618 >>> module.declare_one_time_definition("bar") 619 """ 620 definition_name = utils.ascii(definition_name) 621 if definition_name in self.one_time_definitions: 622 raise KeyError(definition_name) 623 self.one_time_definitions[definition_name] = None 624 625 def generate_forward_declarations(self, code_sink): 626 """(internal) generate forward declarations for types""" 627 assert not self._forward_declarations_declared 628 if self.classes or self.containers or self.exceptions: 629 code_sink.writeln('/* --- forward declarations --- */') 630 code_sink.writeln() 631 632 for class_ in [c for c in self.classes if c.import_from_module]: 633 class_.generate_forward_declarations(code_sink, self) 634 635 for class_ in [c for c in self.classes if not c.import_from_module]: 636 class_.generate_forward_declarations(code_sink, self) 637 638 for container in self.containers: 639 container.generate_forward_declarations(code_sink, self) 640 for exc in self.exceptions: 641 exc.generate_forward_declarations(code_sink, self) 642 ## recurse to submodules 643 for submodule in self.submodules: 644 submodule.generate_forward_declarations(code_sink) 645 self._forward_declarations_declared = True 646 647 def get_module_path(self): 648 """Get the full [module, submodule, submodule,...] path """ 649 names = [self.name] 650 parent = self.parent 651 while parent is not None: 652 names.insert(0, parent.name) 653 parent = parent.parent 654 return names 655 656 def get_namespace_path(self): 657 """Get the full [root_namespace, namespace, namespace,...] path (C++)""" 658 if not self.cpp_namespace: 659 names = [] 660 else: 661 if self.cpp_namespace == '::': 662 names = [] 663 else: 664 names = self.cpp_namespace.split('::') 665 if not names[0]: 666 del names[0] 667 parent = self.parent 668 while parent is not None: 669 if parent.cpp_namespace and parent.cpp_namespace != '::': 670 parent_names = parent.cpp_namespace.split('::') 671 if not parent_names[0]: 672 del parent_names[0] 673 names = parent_names + names 674 parent = parent.parent 675 return names 676 677 def do_generate(self, out, module_file_base_name=None): 678 """(internal) Generates the module.""" 679 assert isinstance(out, _SinkManager) 680 681 if self.parent is None: 682 ## generate the include directives (only the root module) 683 684 forward_declarations_sink = MemoryCodeSink() 685 686 if not self._forward_declarations_declared: 687 self.generate_forward_declarations(forward_declarations_sink) 688 self.after_forward_declarations.flush_to(forward_declarations_sink) 689 690 if self.parent is None: 691 for include in self.includes: 692 out.get_includes_code_sink().writeln("#include %s" % include) 693 self.includes = None 694 695 forward_declarations_sink.flush_to(out.get_includes_code_sink()) 696 697 else: 698 assert module_file_base_name is None, "only root modules can generate with alternate module_file_base_name" 699 700 ## generate the submodules 701 for submodule in self.submodules: 702 submodule.do_generate(out) 703 704 m = self.declarations.declare_variable('PyObject*', 'm') 705 assert m == 'm' 706 if module_file_base_name is None: 707 mod_init_name = '.'.join(self.get_module_path()) 708 else: 709 mod_init_name = module_file_base_name 710 self.before_init.write_code('#if PY_VERSION_HEX >= 0x03000000') 711 self.before_init.write_code( 712 "m = PyModule_Create(&%s_moduledef);" 713 % (self.prefix)) 714 self.before_init.write_code('#else') 715 self.before_init.write_code( 716 "m = Py_InitModule3((char *) \"%s\", %s_functions, %s);" 717 % (mod_init_name, self.prefix, 718 self.docstring and '"'+self.docstring+'"' or 'NULL')) 719 self.before_init.write_code('#endif') 720 self.before_init.write_error_check("m == NULL") 721 722 main_sink = out.get_main_code_sink() 723 724 ## generate the function wrappers 725 py_method_defs = [] 726 if self.functions: 727 main_sink.writeln('/* --- module functions --- */') 728 main_sink.writeln() 729 for func_name, overload in self.functions.items(): 730 sink, header_sink = out.get_code_sink_for_wrapper(overload) 731 sink.writeln() 732 try: 733 utils.call_with_error_handling(overload.generate, (sink,), {}, overload) 734 except utils.SkipWrapper: 735 continue 736 try: 737 utils.call_with_error_handling(overload.generate_declaration, (main_sink,), {}, overload) 738 except utils.SkipWrapper: 739 continue 740 741 sink.writeln() 742 py_method_defs.append(overload.get_py_method_def(func_name)) 743 del sink 744 745 ## generate the function table 746 main_sink.writeln("static PyMethodDef %s_functions[] = {" 747 % (self.prefix,)) 748 main_sink.indent() 749 for py_method_def in py_method_defs: 750 main_sink.writeln(py_method_def) 751 main_sink.writeln("{NULL, NULL, 0, NULL}") 752 main_sink.unindent() 753 main_sink.writeln("};") 754 755 ## generate the classes 756 if self.classes: 757 main_sink.writeln('/* --- classes --- */') 758 main_sink.writeln() 759 for class_ in [c for c in self.classes if c.import_from_module]: 760 sink, header_sink = out.get_code_sink_for_wrapper(class_) 761 sink.writeln() 762 class_.generate(sink, self) 763 sink.writeln() 764 for class_ in [c for c in self.classes if not c.import_from_module]: 765 sink, header_sink = out.get_code_sink_for_wrapper(class_) 766 sink.writeln() 767 class_.generate(sink, self) 768 sink.writeln() 769 770 ## generate the containers 771 if self.containers: 772 main_sink.writeln('/* --- containers --- */') 773 main_sink.writeln() 774 for container in self.containers: 775 sink, header_sink = out.get_code_sink_for_wrapper(container) 776 sink.writeln() 777 container.generate(sink, self) 778 sink.writeln() 779 780 ## generate the exceptions 781 if self.exceptions: 782 main_sink.writeln('/* --- exceptions --- */') 783 main_sink.writeln() 784 for exc in self.exceptions: 785 sink, header_sink = out.get_code_sink_for_wrapper(exc) 786 sink.writeln() 787 exc.generate(sink, self) 788 sink.writeln() 789 790 # typedefs 791 for (wrapper, alias) in self.typedefs: 792 if isinstance(wrapper, CppClass): 793 cls = wrapper 794 cls.generate_typedef(self, alias) 795 796 ## generate the enums 797 if self.enums: 798 main_sink.writeln('/* --- enumerations --- */') 799 main_sink.writeln() 800 for enum in self.enums: 801 sink, header_sink = out.get_code_sink_for_wrapper(enum) 802 sink.writeln() 803 enum.generate(sink) 804 enum.generate_declaration(header_sink, self) 805 sink.writeln() 806 807 ## register the submodules 808 if self.submodules: 809 submodule_var = self.declarations.declare_variable('PyObject*', 'submodule') 810 for submodule in self.submodules: 811 self.after_init.write_code('%s = %s();' % ( 812 submodule_var, submodule.init_function_name)) 813 self.after_init.write_error_check('%s == NULL' % submodule_var) 814 self.after_init.write_code('Py_INCREF(%s);' % (submodule_var,)) 815 self.after_init.write_code('PyModule_AddObject(m, (char *) "%s", %s);' 816 % (submodule.name, submodule_var,)) 817 818 ## flush the header section 819 self.header.flush_to(out.get_includes_code_sink()) 820 821 ## flush the body section 822 self.body.flush_to(main_sink) 823 824 ## now generate the module init function itself 825 main_sink.writeln('#if PY_VERSION_HEX >= 0x03000000\n' 826 'static struct PyModuleDef %s_moduledef = {\n' 827 ' PyModuleDef_HEAD_INIT,\n' 828 ' "%s",\n' 829 ' %s,\n' 830 ' -1,\n' 831 ' %s_functions,\n' 832 '};\n' 833 '#endif' % (self.prefix, mod_init_name, 834 self.docstring and '"'+self.docstring+'"' or 'NULL', 835 self.prefix)) 836 main_sink.writeln() 837 if self.parent is None: 838 main_sink.writeln(''' 839#if PY_VERSION_HEX >= 0x03000000 840 #define MOD_ERROR NULL 841 #define MOD_INIT(name) PyObject* PyInit_##name(void) 842 #define MOD_RETURN(val) val 843#else 844 #define MOD_ERROR 845 #define MOD_INIT(name) void init##name(void) 846 #define MOD_RETURN(val) 847#endif 848#if defined(__cplusplus) 849extern "C" 850#endif 851#if defined(__GNUC__) && __GNUC__ >= 4 852__attribute__ ((visibility("default"))) 853#endif 854 855''') 856 else: 857 main_sink.writeln("static PyObject *") 858 if self.parent is None: 859 main_sink.writeln("MOD_INIT(%s)" % (self.name,)) 860 elif module_file_base_name is None: 861 main_sink.writeln("%s(void)" % (self.init_function_name,)) 862 else: 863 main_sink.writeln("init%s(void)" % (module_file_base_name,)) 864 main_sink.writeln('{') 865 main_sink.indent() 866 self.declarations.get_code_sink().flush_to(main_sink) 867 self.before_init.sink.flush_to(main_sink) 868 self.after_init.write_cleanup() 869 self.after_init.sink.flush_to(main_sink) 870 if self.parent is not None: 871 main_sink.writeln("return m;") 872 else: 873 main_sink.writeln("return MOD_RETURN(m);") 874 main_sink.unindent() 875 main_sink.writeln('}') 876 877 878 def __repr__(self): 879 return "<pybindgen.module.Module %r>" % self.name 880 881 def add_typedef(self, wrapper, alias): 882 """ 883 Declares an equivalent to a typedef in C:: 884 typedef Foo Bar; 885 886 :param wrapper: the wrapper object to alias (Foo in the example) 887 :param alias: name of the typedef alias 888 889 @note: only typedefs for CppClass objects have been 890 implemented so far; others will be implemented in the future. 891 """ 892 assert isinstance(wrapper, CppClass) 893 alias = utils.ascii(alias) 894 self.typedefs.append((wrapper, alias)) 895 self.register_type(alias, alias, wrapper) 896 wrapper.register_alias(alias) 897 full_name = '::'.join(self.get_namespace_path() + [alias]) 898 wrapper.register_alias(full_name) 899 900 901class Module(ModuleBase): 902 def __init__(self, name, docstring=None, cpp_namespace=None): 903 """ 904 :param name: module name 905 :param docstring: docstring to use for this module 906 :param cpp_namespace: C++ namespace prefix associated with this module 907 """ 908 super(Module, self).__init__(name, docstring=docstring, cpp_namespace=cpp_namespace) 909 910 def generate(self, out, module_file_base_name=None): 911 """Generates the module 912 913 :type out: a file object, L{FileCodeSink}, or L{MultiSectionFactory} 914 915 :param module_file_base_name: base name of the module file. 916 This is useful when we want to produce a _foo module that will 917 be imported into a foo module, to avoid making all types 918 docstrings contain _foo.Xpto instead of foo.Xpto. 919 """ 920 if hasattr(out, 'write'): 921 out = FileCodeSink(out) 922 if isinstance(out, CodeSink): 923 sink_manager = _MonolithicSinkManager(out) 924 elif isinstance(out, MultiSectionFactory): 925 sink_manager = _MultiSectionSinkManager(out) 926 else: 927 raise TypeError 928 self.do_generate(sink_manager, module_file_base_name) 929 sink_manager.close() 930 931 def get_python_to_c_type_converter_function_name(self, value_type): 932 """ 933 Internal API, do not use. 934 """ 935 assert isinstance(value_type, TypeHandler) 936 ctype = value_type.ctype 937 mangled_ctype = utils.mangle_name(str(ctype)) 938 converter_function_name = "_wrap_convert_py2c__%s" % mangled_ctype 939 return converter_function_name 940 941 def generate_python_to_c_type_converter(self, value_type, code_sink): 942 """ 943 Generates a python-to-c converter function for a given type 944 and returns the name of the generated function. If called 945 multiple times with the same name only the first time is the 946 converter function generated. 947 948 Use: this method is to be considered pybindgen internal, used 949 by code generation modules. 950 951 :type value_type: L{ReturnValue} 952 :type code_sink: L{CodeSink} 953 :returns: name of the converter function 954 """ 955 assert isinstance(value_type, TypeHandler) 956 converter_function_name = self.get_python_to_c_type_converter_function_name(value_type) 957 try: 958 self.declare_one_time_definition(converter_function_name) 959 except KeyError: 960 return converter_function_name 961 else: 962 converter = PythonToCConverter(value_type, converter_function_name) 963 self.header.writeln("\n%s;\n" % converter.get_prototype()) 964 code_sink.writeln() 965 converter.generate(code_sink, converter_function_name) 966 code_sink.writeln() 967 return converter_function_name 968 969 970 def get_c_to_python_type_converter_function_name(self, value_type): 971 """ 972 Internal API, do not use. 973 """ 974 assert isinstance(value_type, TypeHandler) 975 ctype = value_type.ctype 976 mangled_ctype = utils.mangle_name(str(ctype)) 977 converter_function_name = "_wrap_convert_c2py__%s" % mangled_ctype 978 return converter_function_name 979 980 def generate_c_to_python_type_converter(self, value_type, code_sink): 981 """ 982 Generates a c-to-python converter function for a given type 983 and returns the name of the generated function. If called 984 multiple times with the same name only the first time is the 985 converter function generated. 986 987 Use: this method is to be considered pybindgen internal, used 988 by code generation modules. 989 990 :type value_type: L{ReturnValue} 991 :type code_sink: L{CodeSink} 992 :returns: name of the converter function 993 """ 994 assert isinstance(value_type, TypeHandler) 995 converter_function_name = self.get_c_to_python_type_converter_function_name(value_type) 996 try: 997 self.declare_one_time_definition(converter_function_name) 998 except KeyError: 999 return converter_function_name 1000 else: 1001 converter = CToPythonConverter(value_type, converter_function_name) 1002 self.header.writeln("\n%s;\n" % converter.get_prototype()) 1003 code_sink.writeln() 1004 converter.generate(code_sink) 1005 code_sink.writeln() 1006 return converter_function_name 1007 1008 1009class SubModule(ModuleBase): 1010 def __init__(self, name, parent, docstring=None, cpp_namespace=None): 1011 """ 1012 :param parent: parent L{module<Module>} (i.e. the one that contains this submodule) 1013 :param name: name of the submodule 1014 :param docstring: docstring to use for this module 1015 :param cpp_namespace: C++ namespace component associated with this module 1016 """ 1017 super(SubModule, self).__init__(name, parent, docstring=docstring, cpp_namespace=cpp_namespace) 1018 1019