16 class Coverage(object):
17 def __init__(self, name):
22 def declare_wrapped(self):
25 def declare_not_wrapped(self):
29 total = self.wrapped + self.not_wrapped
32 fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
34 float(self.wrapped*100)/total,
38 fd.write("***INFO*** There are no declared %s.\n" % self.name)
40 functions_coverage = Coverage("global functions")
41 methods_coverage = Coverage("methods")
42 vproxies_coverage = Coverage("virtual proxies")
43 vaccessors_coverage = Coverage("virtual accessors")
44 iproxies_coverage = Coverage("interface proxies")
47 warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
48 #traceback.print_exc()
49 etype, value, tb = sys.exc_info()
53 if etype == argtypes.ArgTypeError:
54 ret = "No ArgType for %s" % (sval,)
62 if keyword.iskeyword(name):
67 '''Simple wrapper for file object, that makes writing #line
68 statements easier.''' # "
69 def __init__(self, fp, filename=None):
73 self.filename = filename
75 self.filename = self.fp.name
76 # handle writing to the file, and keep track of the line number ...
79 self.lineno = self.lineno + string.count(str, '\n')
80 def writelines(self, sequence):
88 def setline(self, linenum, filename):
89 '''writes out a #line statement, for use by the C
91 self.write('#line %d "%s"\n' % (linenum, filename))
93 '''resets line numbering to the original file'''
94 self.setline(self.lineno + 1, self.filename)
98 'PyTypeObject G_GNUC_INTERNAL Py%(typename)s_Type = {\n'
99 ' PyObject_HEAD_INIT(NULL)\n'
100 ' 0, /* ob_size */\n'
101 ' "%(classname)s", /* tp_name */\n'
102 ' sizeof(%(tp_basicsize)s), /* tp_basicsize */\n'
103 ' 0, /* tp_itemsize */\n'
105 ' (destructor)%(tp_dealloc)s, /* tp_dealloc */\n'
106 ' (printfunc)0, /* tp_print */\n'
107 ' (getattrfunc)%(tp_getattr)s, /* tp_getattr */\n'
108 ' (setattrfunc)%(tp_setattr)s, /* tp_setattr */\n'
109 ' (cmpfunc)%(tp_compare)s, /* tp_compare */\n'
110 ' (reprfunc)%(tp_repr)s, /* tp_repr */\n'
111 ' (PyNumberMethods*)%(tp_as_number)s, /* tp_as_number */\n'
112 ' (PySequenceMethods*)%(tp_as_sequence)s, /* tp_as_sequence */\n'
113 ' (PyMappingMethods*)%(tp_as_mapping)s, /* tp_as_mapping */\n'
114 ' (hashfunc)%(tp_hash)s, /* tp_hash */\n'
115 ' (ternaryfunc)%(tp_call)s, /* tp_call */\n'
116 ' (reprfunc)%(tp_str)s, /* tp_str */\n'
117 ' (getattrofunc)%(tp_getattro)s, /* tp_getattro */\n'
118 ' (setattrofunc)%(tp_setattro)s, /* tp_setattro */\n'
119 ' (PyBufferProcs*)%(tp_as_buffer)s, /* tp_as_buffer */\n'
120 ' %(tp_flags)s, /* tp_flags */\n'
121 ' %(tp_doc)s, /* Documentation string */\n'
122 ' (traverseproc)%(tp_traverse)s, /* tp_traverse */\n'
123 ' (inquiry)%(tp_clear)s, /* tp_clear */\n'
124 ' (richcmpfunc)%(tp_richcompare)s, /* tp_richcompare */\n'
125 ' %(tp_weaklistoffset)s, /* tp_weaklistoffset */\n'
126 ' (getiterfunc)%(tp_iter)s, /* tp_iter */\n'
127 ' (iternextfunc)%(tp_iternext)s, /* tp_iternext */\n'
128 ' (struct PyMethodDef*)%(tp_methods)s, /* tp_methods */\n'
129 ' (struct PyMemberDef*)0, /* tp_members */\n'
130 ' (struct PyGetSetDef*)%(tp_getset)s, /* tp_getset */\n'
131 ' NULL, /* tp_base */\n'
132 ' NULL, /* tp_dict */\n'
133 ' (descrgetfunc)%(tp_descr_get)s, /* tp_descr_get */\n'
134 ' (descrsetfunc)%(tp_descr_set)s, /* tp_descr_set */\n'
135 ' %(tp_dictoffset)s, /* tp_dictoffset */\n'
136 ' (initproc)%(tp_init)s, /* tp_init */\n'
137 ' (allocfunc)%(tp_alloc)s, /* tp_alloc */\n'
138 ' (newfunc)%(tp_new)s, /* tp_new */\n'
139 ' (freefunc)%(tp_free)s, /* tp_free */\n'
140 ' (inquiry)%(tp_is_gc)s /* tp_is_gc */\n'
145 'tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
146 'tp_compare', 'tp_repr',
147 'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
148 'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
149 'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
150 'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
151 'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags', 'tp_doc'
155 'static PyObject *\n'
156 '%(funcname)s(PyObject *self, void *closure)\n'
159 ' ret = %(field)s;\n'
165 ' if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
166 '"%(typecodes)s:%(name)s"%(parselist)s))\n'
167 ' return %(errorreturn)s;\n'
171 ' if (PyErr_Warn(PyExc_DeprecationWarning, '
172 '"%(deprecationmsg)s") < 0)\n'
173 ' return %(errorreturn)s;\n'
177 ' { "%(name)s", (PyCFunction)%(cname)s, %(flags)s,\n'
178 ' %(docstring)s },\n'
183 'pygobject_no_constructor(PyObject *self, PyObject *args, '
184 'PyObject *kwargs)\n'
188 ' g_snprintf(buf, sizeof(buf), "%s is an abstract widget", '
189 'self->ob_type->tp_name);\n'
190 ' PyErr_SetString(PyExc_NotImplementedError, buf);\n'
196 'static PyObject *\n'
197 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
202 ' %(begin_allow_threads)s\n'
203 ' %(setreturn)s%(cname)s(%(arglist)s);\n'
204 ' %(end_allow_threads)s\n'
209 virtual_accessor_tmpl = (
210 'static PyObject *\n'
211 '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
217 ' klass = g_type_class_ref(pyg_type_from_object(cls));\n'
218 ' if (%(class_cast_macro)s(klass)->%(virtual)s)\n'
219 ' %(setreturn)s%(class_cast_macro)s(klass)->'
220 '%(virtual)s(%(arglist)s);\n'
222 ' PyErr_SetString(PyExc_NotImplementedError, '
223 '"virtual method %(name)s not implemented");\n'
224 ' g_type_class_unref(klass);\n'
227 ' g_type_class_unref(klass);\n'
232 # template for method calls
233 constructor_tmpl = None
236 def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
238 self.objinfo = objinfo
239 self.overrides = overrides
242 def get_lower_name(self):
243 return string.lower(string.replace(self.objinfo.typecode,
246 def get_field_accessor(self, fieldname):
247 raise NotImplementedError
249 def get_initial_class_substdict(self): return {}
251 def get_initial_constructor_substdict(self, constructor):
252 return { 'name': '%s.__init__' % self.objinfo.py_name,
253 'errorreturn': '-1' }
255 def get_initial_method_substdict(self, method):
256 substdict = { 'name': '%s.%s' % (self.objinfo.py_name, method.name) }
257 if method.unblock_threads:
258 substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
259 substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
261 substdict['begin_allow_threads'] = ''
262 substdict['end_allow_threads'] = ''
265 def write_class(self):
266 if self.overrides.is_type_ignored(self.objinfo.c_name):
268 self.fp.write('\n/* ----------- %s ----------- */\n\n' %
270 substdict = self.get_initial_class_substdict()
271 if not substdict.has_key('tp_flags'):
272 substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
273 substdict['typename'] = self.objinfo.c_name
274 if self.overrides.modulename:
275 substdict['classname'] = '%s.%s' % (self.overrides.modulename,
278 substdict['classname'] = self.objinfo.name
279 substdict['tp_doc'] = self.objinfo.docstring
281 # Maybe this could be done in a nicer way, but I'll leave it as it is
283 if not self.overrides.slot_is_overriden('%s.tp_init' %
284 self.objinfo.c_name):
285 substdict['tp_init'] = self.write_constructor()
286 substdict['tp_methods'] = self.write_methods()
287 substdict['tp_getset'] = self.write_getsets()
290 for slot in self.slots_list:
292 slotname = '%s.%s' % (self.objinfo.c_name, slot)
293 slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
294 if slot[:6] == 'tp_as_':
295 slotfunc = '&' + slotfunc
296 if self.overrides.slot_is_overriden(slotname):
297 data = self.overrides.slot_override(slotname)
298 self.write_function(slotname, data)
299 substdict[slot] = slotfunc
301 if not substdict.has_key(slot):
302 substdict[slot] = '0'
304 self.fp.write(self.type_tmpl % substdict)
306 self.write_virtuals()
308 def write_function_wrapper(self, function_obj, template,
309 handle_return=0, is_method=0, kwargs_needed=0,
311 '''This function is the guts of all functions that generate
312 wrappers for functions, methods and constructors.'''
313 if not substdict: substdict = {}
315 info = argtypes.WrapperInfo()
317 substdict.setdefault('errorreturn', 'NULL')
319 # for methods, we want the leading comma
321 info.arglist.append('')
323 if function_obj.varargs:
324 raise argtypes.ArgTypeNotFoundError("varargs functions not supported")
326 for param in function_obj.params:
327 if param.pdflt != None and '|' not in info.parsestr:
328 info.add_parselist('|', [], [])
329 handler = argtypes.matcher.get(param.ptype)
330 handler.write_param(param.ptype, param.pname, param.pdflt,
333 substdict['setreturn'] = ''
335 if function_obj.ret not in ('none', None):
336 substdict['setreturn'] = 'ret = '
337 handler = argtypes.matcher.get(function_obj.ret)
338 handler.write_return(function_obj.ret,
339 function_obj.caller_owns_return, info)
341 if function_obj.deprecated != None:
342 deprecated = self.deprecated_tmpl % {
343 'deprecationmsg': function_obj.deprecated,
344 'errorreturn': substdict['errorreturn'] }
348 # if name isn't set, set it to function_obj.name
349 substdict.setdefault('name', function_obj.name)
351 if function_obj.unblock_threads:
352 substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
353 substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
355 substdict['begin_allow_threads'] = ''
356 substdict['end_allow_threads'] = ''
359 substdict['typename'] = self.objinfo.c_name
360 substdict.setdefault('cname', function_obj.c_name)
361 substdict['varlist'] = info.get_varlist()
362 substdict['typecodes'] = info.parsestr
363 substdict['parselist'] = info.get_parselist()
364 substdict['arglist'] = info.get_arglist()
365 substdict['codebefore'] = deprecated + (
366 string.replace(info.get_codebefore(),
367 'return NULL', 'return ' + substdict['errorreturn'])
369 substdict['codeafter'] = (
370 string.replace(info.get_codeafter(),
372 'return ' + substdict['errorreturn']))
374 if info.parsestr or kwargs_needed:
375 substdict['parseargs'] = self.parse_tmpl % substdict
376 substdict['extraparams'] = ', PyObject *args, PyObject *kwargs'
377 flags = 'METH_VARARGS|METH_KEYWORDS'
379 # prepend the keyword list to the variable list
380 substdict['varlist'] = info.get_kwlist() + substdict['varlist']
382 substdict['parseargs'] = ''
383 substdict['extraparams'] = ''
384 flags = 'METH_NOARGS'
386 return template % substdict, flags
388 def write_constructor(self):
390 constructor = self.parser.find_constructor(self.objinfo,self.overrides)
392 return self.write_default_constructor()
394 funcname = constructor.c_name
396 if self.overrides.is_overriden(funcname):
397 data = self.overrides.override(funcname)
398 self.write_function(funcname, data)
399 self.objinfo.has_new_constructor_api = (
400 self.objinfo.typecode in
401 self.overrides.newstyle_constructors)
403 # ok, a hack to determine if we should use
404 # new-style constructores :P
405 property_based = getattr(self,
406 'write_property_based_constructor',
409 if (len(constructor.params) == 0 or
410 isinstance(constructor.params[0],
411 definitions.Property)):
412 # write_property_based_constructor is only
413 # implemented in GObjectWrapper
414 return self.write_property_based_constructor(
418 "Warning: generating old-style constructor for:" +
419 constructor.c_name + '\n')
421 # write constructor from template ...
422 code = self.write_function_wrapper(constructor,
423 self.constructor_tmpl,
424 handle_return=0, is_method=0, kwargs_needed=1,
425 substdict=self.get_initial_constructor_substdict(
428 initfunc = '_wrap_' + funcname
429 except argtypes.ArgTypeError, ex:
430 sys.stderr.write('Could not write constructor for %s: %s\n'
431 % (self.objinfo.c_name, str(ex)))
433 initfunc = self.write_noconstructor()
436 def write_noconstructor(self):
438 if not hasattr(self.overrides, 'no_constructor_written'):
439 self.fp.write(self.noconstructor)
440 self.overrides.no_constructor_written = 1
441 initfunc = 'pygobject_no_constructor'
444 def write_default_constructor(self):
445 return self.write_noconstructor()
447 def get_methflags(self, funcname):
448 if self.overrides.wants_kwargs(funcname):
449 flags = 'METH_VARARGS|METH_KEYWORDS'
450 elif self.overrides.wants_noargs(funcname):
451 flags = 'METH_NOARGS'
452 elif self.overrides.wants_onearg(funcname):
455 flags = 'METH_VARARGS'
456 if self.overrides.is_staticmethod(funcname):
457 flags += '|METH_STATIC'
458 elif self.overrides.is_classmethod(funcname):
459 flags += '|METH_CLASS'
462 def write_function(self, funcname, data):
463 lineno, filename = self.overrides.getstartline(funcname)
464 self.fp.setline(lineno, filename)
467 self.fp.write('\n\n')
469 def _get_class_virtual_substdict(self, meth, cname, parent):
470 substdict = self.get_initial_method_substdict(meth)
471 substdict['virtual'] = meth.name
472 substdict['cname'] = cname
473 substdict['class_cast_macro'] = parent.typecode.replace(
474 '_TYPE_', '_', 1) + "_CLASS"
475 substdict['typecode'] = self.objinfo.typecode
476 substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
479 def write_methods(self):
481 klass = self.objinfo.c_name
482 # First, get methods from the defs files
483 for meth in self.parser.find_methods(self.objinfo):
484 method_name = meth.c_name
485 if self.overrides.is_ignored(method_name):
488 if self.overrides.is_overriden(method_name):
489 if not self.overrides.is_already_included(method_name):
490 data = self.overrides.override(method_name)
491 self.write_function(method_name, data)
493 methflags = self.get_methflags(method_name)
495 # write constructor from template ...
496 code, methflags = self.write_function_wrapper(meth,
497 self.method_tmpl, handle_return=1, is_method=1,
498 substdict=self.get_initial_method_substdict(meth))
500 methods.append(self.methdef_tmpl %
501 { 'name': fixname(meth.name),
502 'cname': '_wrap_' + method_name,
504 'docstring': meth.docstring })
505 methods_coverage.declare_wrapped()
506 except argtypes.ArgTypeError, ex:
507 methods_coverage.declare_not_wrapped()
508 sys.stderr.write('Could not write method %s.%s: %s\n'
509 % (klass, meth.name, str(ex)))
511 # Now try to see if there are any defined in the override
512 for method_name in self.overrides.get_defines_for(klass):
513 c_name = override.class2cname(klass, method_name)
514 if self.overrides.is_already_included(method_name):
518 data = self.overrides.define(klass, method_name)
519 self.write_function(method_name, data)
520 methflags = self.get_methflags(method_name)
522 methods.append(self.methdef_tmpl %
523 { 'name': method_name,
524 'cname': '_wrap_' + c_name,
526 'docstring': 'NULL' })
527 methods_coverage.declare_wrapped()
528 except argtypes.ArgTypeError, ex:
529 methods_coverage.declare_not_wrapped()
530 sys.stderr.write('Could not write method %s.%s: %s\n'
531 % (klass, method_name, str(ex)))
533 # Add GObject virtual method accessors, for chaining to parent
534 # virtuals from subclasses
535 methods += self.write_virtual_accessors()
538 methoddefs = '_Py%s_methods' % self.objinfo.c_name
539 # write the PyMethodDef structure
540 methods.append(' { NULL, NULL, 0, NULL }\n')
541 self.fp.write('static const PyMethodDef %s[] = {\n' % methoddefs)
542 self.fp.write(string.join(methods, ''))
543 self.fp.write('};\n\n')
548 def write_virtual_accessors(self):
549 klass = self.objinfo.c_name
551 for meth in self.parser.find_virtuals(self.objinfo):
552 method_name = self.objinfo.c_name + "__do_" + meth.name
553 if self.overrides.is_ignored(method_name):
556 if self.overrides.is_overriden(method_name):
557 if not self.overrides.is_already_included(method_name):
558 data = self.overrides.override(method_name)
559 self.write_function(method_name, data)
560 methflags = self.get_methflags(method_name)
562 # temporarily add a 'self' parameter as first argument
563 meth.params.insert(0, definitions.Parameter(
564 ptype=(self.objinfo.c_name + '*'),
565 pname='self', pdflt=None, pnull=None))
567 # write method from template ...
568 code, methflags = self.write_function_wrapper(
569 meth, self.virtual_accessor_tmpl,
570 handle_return=True, is_method=False,
571 substdict=self._get_class_virtual_substdict(
572 meth, method_name, self.objinfo))
576 methods.append(self.methdef_tmpl %
577 { 'name': "do_" + fixname(meth.name),
578 'cname': '_wrap_' + method_name,
579 'flags': methflags + '|METH_CLASS',
580 'docstring': 'NULL'})
581 vaccessors_coverage.declare_wrapped()
582 except argtypes.ArgTypeError, ex:
583 vaccessors_coverage.declare_not_wrapped()
585 'Could not write virtual accessor method %s.%s: %s\n'
586 % (klass, meth.name, str(ex)))
589 def write_virtuals(self):
591 Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for
594 klass = self.objinfo.c_name
596 for meth in self.parser.find_virtuals(self.objinfo):
597 method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
598 if self.overrides.is_ignored(method_name):
601 if self.overrides.is_overriden(method_name):
602 if not self.overrides.is_already_included(method_name):
603 data = self.overrides.override(method_name)
604 self.write_function(method_name, data)
606 # write virtual proxy ...
607 ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
608 wrapper = reversewrapper.ReverseWrapper(
609 '_wrap_' + method_name, is_static=True)
610 wrapper.set_return_type(ret(wrapper, **props))
611 wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
612 wrapper, "self", method_name="do_" + meth.name,
613 c_type=(klass + ' *')))
614 for param in meth.params:
615 handler, props = argtypes.matcher.get_reverse(
617 props["direction"] = param.pdir
618 props["nullok"] = param.pnull
619 wrapper.add_parameter(handler(wrapper,
620 param.pname, **props))
621 buf = reversewrapper.MemoryCodeSink()
622 wrapper.generate(buf)
623 self.fp.write(buf.flush())
624 virtuals.append((fixname(meth.name), '_wrap_' + method_name))
625 vproxies_coverage.declare_wrapped()
626 except argtypes.ArgTypeError, ex:
627 vproxies_coverage.declare_not_wrapped()
628 virtuals.append((fixname(meth.name), None))
629 sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
630 % (klass, meth.name, str(ex)))
632 # Write a 'pygtk class init' function for this object,
633 # except when the object type is explicitly ignored (like
634 # GtkPlug and GtkSocket on win32).
635 if self.overrides.is_ignored(self.objinfo.typecode):
637 class_cast_macro = self.objinfo.typecode.replace(
638 '_TYPE_', '_', 1) + "_CLASS"
639 cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
640 funcname = "__%s_class_init" % klass
641 self.objinfo.class_init_func = funcname
642 have_implemented_virtuals = not not [True
643 for name, cname in virtuals
644 if cname is not None]
647 '%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
650 if have_implemented_virtuals:
651 self.fp.write(' PyObject *o;\n')
653 ' %(klass)sClass *klass = '
654 '%(class_cast_macro)s(gclass);\n'
655 ' PyObject *gsignals = '
656 'PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");\n'
659 for name, cname in virtuals:
660 do_name = 'do_' + name
662 self.fp.write('\n /* overriding %(do_name)s '
663 'is currently not supported */\n' % vars())
666 o = PyObject_GetAttrString((PyObject *) pyclass, "%(do_name)s");
670 if (!PyObject_TypeCheck(o, &PyCFunction_Type)
671 && !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
672 klass->%(name)s = %(cname)s;
676 self.fp.write(' return 0;\n}\n')
678 def write_getsets(self):
679 lower_name = self.get_lower_name()
680 getsets_name = lower_name + '_getsets'
681 getterprefix = '_wrap_' + lower_name + '__get_'
682 setterprefix = '_wrap_' + lower_name + '__set_'
684 # no overrides for the whole function. If no fields,
686 if not self.objinfo.fields:
689 for ftype, cfname in self.objinfo.fields:
690 fname = cfname.replace('.', '_')
693 attrname = self.objinfo.c_name + '.' + fname
694 if self.overrides.attr_is_overriden(attrname):
695 code = self.overrides.attr_override(attrname)
696 self.write_function(attrname, code)
697 if string.find(code, getterprefix + fname) >= 0:
698 gettername = getterprefix + fname
699 if string.find(code, setterprefix + fname) >= 0:
700 settername = setterprefix + fname
701 if gettername == '0':
703 funcname = getterprefix + fname
704 info = argtypes.WrapperInfo()
705 handler = argtypes.matcher.get(ftype)
706 # for attributes, we don't own the "return value"
707 handler.write_return(ftype, 0, info)
708 self.fp.write(self.getter_tmpl %
709 { 'funcname': funcname,
710 'varlist': info.varlist,
711 'field': self.get_field_accessor(cfname),
712 'codeafter': info.get_codeafter() })
713 gettername = funcname
714 except argtypes.ArgTypeError, ex:
716 "Could not write getter for %s.%s: %s\n"
717 % (self.objinfo.c_name, fname, str(ex)))
718 if gettername != '0' or settername != '0':
719 getsets.append(' { "%s", (getter)%s, (setter)%s },\n' %
720 (fixname(fname), gettername, settername))
724 self.fp.write('static const PyGetSetDef %s[] = {\n' % getsets_name)
725 for getset in getsets:
726 self.fp.write(getset)
727 self.fp.write(' { NULL, (getter)0, (setter)0 },\n')
728 self.fp.write('};\n\n')
732 def _write_get_symbol_names(self, writer, functions):
733 self.fp.write("""static PyObject *
734 _wrap__get_symbol_names(PyObject *self)
736 PyObject *pylist = PyList_New(0);
739 for obj, bases in writer.get_classes():
740 self.fp.write(' PyList_Append(pylist, '
741 'PyString_FromString("%s"));\n' % (obj.name))
743 for name, cname, flags, docstring in functions:
744 self.fp.write(' PyList_Append(pylist, '
745 'PyString_FromString("%s"));\n' % (name))
747 for enum in writer.get_enums():
748 self.fp.write(' PyList_Append(pylist, '
749 'PyString_FromString("%s"));\n' % (enum.name))
750 for nick, value in enum.values:
751 name = value[len(self.overrides.modulename)+1:]
752 self.fp.write(' PyList_Append(pylist, '
753 'PyString_FromString("%s"));\n' % (name))
755 self.fp.write(" return pylist;\n}\n\n");
757 def _write_get_symbol(self, writer, functions):
758 self.fp.write("""static PyObject *
759 _wrap__get_symbol(PyObject *self, PyObject *args)
763 static PyObject *modulename = NULL;
764 static PyObject *module = NULL;
765 static char *strip_prefix = "%s";
767 if (!PyArg_ParseTuple(args, "Os", &d, &name))
771 modulename = PyString_FromString("%s");
774 module = PyDict_GetItemString(d, "__module__");
776 """ % (self.overrides.modulename.upper() + '_',
777 self.overrides.modulename))
781 for obj, bases in writer.get_classes():
783 self.fp.write(' if (!strcmp(name, "%s")) {\n' % obj.name)
786 self.fp.write(' } else if (!strcmp(name, "%s")) {\n' % obj.name)
788 ' return (PyObject*)pygobject_lookup_class(%s);\n' %
790 self.fp.write(' }\n')
793 for name, cname, flags, docstring in functions:
794 self.fp.write(' else if (!strcmp(name, "%s")) {\n' % name)
795 self.fp.write(' static PyMethodDef ml = { '
796 '"%s", (PyCFunction)%s, %s, "%s"};\n' % (
797 name, cname, flags, docstring))
798 self.fp.write(' return PyCFunction_NewEx(&ml, NULL, modulename);\n')
799 self.fp.write(' }\n')
802 def write_enum(enum, returnobj=False):
807 if enum.deftype == 'enum':
809 ' %spyg_enum_add(module, "%s", strip_prefix, %s);\n'
810 % (ret, enum.name, enum.typecode))
813 ' %spyg_flags_add(module, "%s", strip_prefix, %s);\n'
814 % (ret, enum.name, enum.typecode))
816 strip_len = len(self.overrides.modulename)+1 # GTK_
817 for enum in writer.get_enums():
818 # XXX: Implement without typecodes
819 self.fp.write(' else if (!strcmp(name, "%s")) {\n' % enum.name)
820 write_enum(enum, returnobj=True)
821 self.fp.write(' }\n')
823 for nick, value in enum.values:
824 value = value[strip_len:]
825 self.fp.write(' else if (!strcmp(name, "%s")) {\n' % value)
827 self.fp.write(' return PyObject_GetAttrString(module, "%s");\n' %
829 self.fp.write(' }\n')
831 self.fp.write(' return Py_None;\n}\n\n');
833 def _write_function_bodies(self):
835 # First, get methods from the defs files
836 for func in self.parser.find_functions():
837 funcname = func.c_name
838 if self.overrides.is_ignored(funcname):
841 if self.overrides.is_overriden(funcname):
842 data = self.overrides.override(funcname)
843 self.write_function(funcname, data)
845 methflags = self.get_methflags(funcname)
847 # write constructor from template ...
848 code, methflags = self.write_function_wrapper(func,
849 self.function_tmpl, handle_return=1, is_method=0)
851 functions.append((func.name, '_wrap_' + funcname,
852 methflags, func.docstring))
853 functions_coverage.declare_wrapped()
854 except argtypes.ArgTypeError, ex:
855 functions_coverage.declare_not_wrapped()
856 sys.stderr.write('Could not write function %s: %s\n'
857 % (func.name, str(ex)))
859 # Now try to see if there are any defined in the override
860 for funcname in self.overrides.get_functions():
862 data = self.overrides.function(funcname)
863 self.write_function(funcname, data)
864 methflags = self.get_methflags(funcname)
865 functions.append((funcname, '_wrap_' + funcname,
867 functions_coverage.declare_wrapped()
868 except argtypes.ArgTypeError, ex:
869 functions_coverage.declare_not_wrapped()
870 sys.stderr.write('Could not write function %s: %s\n'
871 % (funcname, str(ex)))
874 def write_functions(self, writer, prefix):
875 self.fp.write('\n/* ----------- functions ----------- */\n\n')
877 func_infos = self._write_function_bodies()
879 # If we have a dynamic namespace, write symbol and attribute getter
880 if self.overrides.dynamicnamespace:
881 self._write_get_symbol_names(writer, func_infos)
882 self._write_get_symbol(writer, func_infos)
883 for obj, bases in writer.get_classes():
884 self.fp.write("""static PyTypeObject *
885 %s_register_type(const gchar *name, PyObject *unused)
887 PyObject *m = PyImport_ImportModule("gtk");
888 PyObject *d = PyModule_GetDict(m);
890 writer.write_class(obj, bases, indent=1)
892 ' return (%s)PyDict_GetItemString(d, "%s");\n' % (
893 'PyTypeObject*', obj.name))
896 functions.append(' { "_get_symbol_names", '
897 '(PyCFunction)_wrap__get_symbol_names, '
898 'METH_NOARGS, NULL },\n')
899 functions.append(' { "_get_symbol", '
900 '(PyCFunction)_wrap__get_symbol, '
901 'METH_VARARGS, NULL },\n')
903 for name, cname, flags, docstring in func_infos:
904 functions.append(self.methdef_tmpl % dict(name=name,
907 docstring=docstring))
909 # write the PyMethodDef structure
910 functions.append(' { NULL, NULL, 0, NULL }\n')
912 self.fp.write('const PyMethodDef ' + prefix + '_functions[] = {\n')
913 self.fp.write(string.join(functions, ''))
914 self.fp.write('};\n\n')
916 class GObjectWrapper(Wrapper):
919 '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
924 ' self->obj = (GObject *)%(cname)s(%(arglist)s);\n'
926 ' if (!self->obj) {\n'
927 ' PyErr_SetString(PyExc_RuntimeError, '
928 '"could not create %(typename)s object");\n'
932 ' pygobject_register_wrapper((PyObject *)self);\n'
938 'static PyObject *\n'
939 '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
944 ' %(begin_allow_threads)s\n'
945 ' %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
946 ' %(end_allow_threads)s\n'
950 def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
951 Wrapper.__init__(self, parser, objinfo, overrides, fp)
953 self.castmacro = string.replace(self.objinfo.typecode,
956 def get_initial_class_substdict(self):
957 return { 'tp_basicsize' : 'PyGObject',
958 'tp_weaklistoffset' : 'offsetof(PyGObject, weakreflist)',
959 'tp_dictoffset' : 'offsetof(PyGObject, inst_dict)' }
961 def get_field_accessor(self, fieldname):
962 castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
963 return '%s(pygobject_get(self))->%s' % (castmacro, fieldname)
965 def get_initial_constructor_substdict(self, constructor):
966 substdict = Wrapper.get_initial_constructor_substdict(self,
968 if not constructor.caller_owns_return:
969 substdict['aftercreate'] = " g_object_ref(self->obj);\n"
971 substdict['aftercreate'] = ''
974 def get_initial_method_substdict(self, method):
975 substdict = Wrapper.get_initial_method_substdict(self, method)
976 substdict['cast'] = string.replace(self.objinfo.typecode,
980 def write_default_constructor(self):
982 parent = self.parser.find_object(self.objinfo.parent)
985 if parent is not None:
986 ## just like the constructor is inheritted, we should
987 # inherit the new API compatibility flag
988 self.objinfo.has_new_constructor_api = (
989 parent.has_new_constructor_api)
990 elif self.objinfo.parent == 'GObject':
991 self.objinfo.has_new_constructor_api = True
994 def write_property_based_constructor(self, constructor):
995 self.objinfo.has_new_constructor_api = True
997 print >> out, "static int"
998 print >> out, '_wrap_%s(PyGObject *self, PyObject *args,' \
999 ' PyObject *kwargs)\n{' % constructor.c_name
1000 if constructor.params:
1001 s = " GType obj_type = pyg_type_from_object((PyObject *) self);"
1004 def py_str_list_to_c(arg):
1006 return "{" + ", ".join(
1007 map(lambda s: '"' + s + '"', arg)) + ", NULL }"
1011 classname = '%s.%s' % (self.overrides.modulename,
1014 if constructor.params:
1015 mandatory_arguments = [param for param in constructor.params
1016 if not param.optional]
1017 optional_arguments = [param for param in constructor.params
1019 arg_names = py_str_list_to_c(
1021 for param in mandatory_arguments + optional_arguments])
1023 prop_names = py_str_list_to_c(
1025 for param in mandatory_arguments + optional_arguments])
1027 print >> out, " GParameter params[%i];" % \
1028 len(constructor.params)
1029 print >> out, " PyObject *parsed_args[%i] = {NULL, };" % \
1030 len(constructor.params)
1031 print >> out, " char *arg_names[] = %s;" % arg_names
1032 print >> out, " char *prop_names[] = %s;" % prop_names
1033 print >> out, " guint nparams, i;"
1035 if constructor.deprecated is not None:
1037 ' if (PyErr_Warn(PyExc_DeprecationWarning, '
1039 constructor.deprecated)
1040 print >> out, ' return -1;'
1042 out.write(" if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
1044 if mandatory_arguments:
1045 template += "O"*len(mandatory_arguments)
1046 if optional_arguments:
1047 template += "|" + "O"*len(optional_arguments)
1048 template += ':%s.__init__"' % classname
1049 print >> out, template, ", arg_names",
1050 for i in range(len(constructor.params)):
1051 print >> out, ", &parsed_args[%i]" % i,
1057 " memset(params, 0, sizeof(GParameter)*%i);\n"
1058 " if (!pyg_parse_constructor_args(obj_type, arg_names,\n"
1059 " prop_names, params, \n"
1060 " &nparams, parsed_args))\n"
1062 " pygobject_constructv(self, nparams, params);\n"
1063 " for (i = 0; i < nparams; ++i)\n"
1064 " g_value_unset(¶ms[i].value);\n"
1065 % len(constructor.params))
1068 " static char* kwlist[] = { NULL };\n"
1071 if constructor.deprecated is not None:
1073 ' if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)\n'
1075 '\n' % constructor.deprecated)
1078 ' if (!PyArg_ParseTupleAndKeywords(args, kwargs,\n'
1079 ' ":%s.__init__",\n'
1083 ' pygobject_constructv(self, 0, NULL);\n' % classname)
1085 ' if (!self->obj) {\n'
1086 ' PyErr_SetString(\n'
1087 ' PyExc_RuntimeError, \n'
1088 ' "could not create %s object");\n'
1092 if not constructor.caller_owns_return:
1093 print >> out, " g_object_ref(self->obj);\n"
1099 return "_wrap_%s" % constructor.c_name
1102 class GInterfaceWrapper(GObjectWrapper):
1103 virtual_accessor_tmpl = (
1104 'static PyObject *\n'
1105 '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
1107 ' %(vtable)s *iface;\n'
1111 ' iface = g_type_interface_peek('
1112 'g_type_class_peek(pyg_type_from_object(cls)), %(typecode)s);\n'
1113 ' if (iface->%(virtual)s)\n'
1114 ' %(setreturn)siface->%(virtual)s(%(arglist)s);\n'
1116 ' PyErr_SetString(PyExc_NotImplementedError, '
1117 '"interface method %(name)s not implemented");\n'
1124 def get_initial_class_substdict(self):
1125 return { 'tp_basicsize' : 'PyObject',
1126 'tp_weaklistoffset' : '0',
1127 'tp_dictoffset' : '0'}
1129 def write_constructor(self):
1130 # interfaces have no constructors ...
1132 def write_getsets(self):
1133 # interfaces have no fields ...
1136 def _get_class_virtual_substdict(self, meth, cname, parent):
1137 substdict = self.get_initial_method_substdict(meth)
1138 substdict['virtual'] = meth.name
1139 substdict['cname'] = cname
1140 substdict['typecode'] = self.objinfo.typecode
1141 substdict['vtable'] = self.objinfo.vtable
1144 def write_virtuals(self):
1145 ## Now write reverse method wrappers, which let python code
1146 ## implement interface methods.
1147 # First, get methods from the defs files
1148 klass = self.objinfo.c_name
1150 for meth in self.parser.find_virtuals(self.objinfo):
1151 method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
1152 if self.overrides.is_ignored(method_name):
1155 if self.overrides.is_overriden(method_name):
1156 if not self.overrides.is_already_included(method_name):
1157 data = self.overrides.override(method_name)
1158 self.write_function(method_name, data)
1161 ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
1162 wrapper = reversewrapper.ReverseWrapper(
1163 '_wrap_' + method_name, is_static=True)
1164 wrapper.set_return_type(ret(wrapper, **props))
1165 wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
1166 wrapper, "self", method_name="do_" + meth.name,
1167 c_type=(klass + ' *')))
1168 for param in meth.params:
1169 handler, props = argtypes.matcher.get_reverse(
1171 props["direction"] = param.pdir
1172 props["nullok"] = param.pnull
1173 wrapper.add_parameter(
1174 handler(wrapper, param.pname, **props))
1175 buf = reversewrapper.MemoryCodeSink()
1176 wrapper.generate(buf)
1177 self.fp.write(buf.flush())
1178 proxies.append((fixname(meth.name), '_wrap_' + method_name))
1179 iproxies_coverage.declare_wrapped()
1180 except argtypes.ArgTypeError, ex:
1181 iproxies_coverage.declare_not_wrapped()
1182 proxies.append((fixname(meth.name), None))
1183 sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
1184 % (klass, meth.name, str(ex)))
1186 if not proxies or not [cname for name, cname in proxies if cname]:
1189 ## Write an interface init function for this object
1190 funcname = "__%s__interface_init" % klass
1191 vtable = self.objinfo.vtable
1194 '%(funcname)s(%(vtable)s *iface, PyTypeObject *pytype)\n'
1196 ' %(vtable)s *parent_iface = '
1197 'g_type_interface_peek_parent(iface);\n'
1198 ' PyObject *py_method;\n'
1202 for name, cname in proxies:
1203 do_name = 'do_' + name
1208 ' py_method = pytype? PyObject_GetAttrString('
1209 '(PyObject *) pytype, "%(do_name)s") : NULL;\n'
1210 ' if (py_method && !PyObject_TypeCheck(py_method, '
1211 '&PyCFunction_Type)) {\n'
1212 ' iface->%(name)s = %(cname)s;\n'
1215 ' if (parent_iface) {\n'
1216 ' iface->%(name)s = parent_iface->%(name)s;\n'
1218 ' Py_XDECREF(py_method);\n'
1221 self.fp.write('}\n\n')
1222 interface_info = "__%s__iinfo" % klass
1224 static const GInterfaceInfo %s = {
1225 (GInterfaceInitFunc) %s,
1229 ''' % (interface_info, funcname))
1230 self.objinfo.interface_info = interface_info
1232 class GBoxedWrapper(Wrapper):
1233 constructor_tmpl = (
1235 '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n'
1240 ' self->gtype = %(typecode)s;\n'
1241 ' self->free_on_dealloc = FALSE;\n'
1242 ' self->boxed = %(cname)s(%(arglist)s);\n'
1244 ' if (!self->boxed) {\n'
1245 ' PyErr_SetString(PyExc_RuntimeError, '
1246 '"could not create %(typename)s object");\n'
1249 ' self->free_on_dealloc = TRUE;\n'
1255 'static PyObject *\n'
1256 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
1261 ' %(begin_allow_threads)s\n'
1262 ' %(setreturn)s%(cname)s(pyg_boxed_get(self, '
1263 '%(typename)s)%(arglist)s);\n'
1264 ' %(end_allow_threads)s\n'
1269 def get_initial_class_substdict(self):
1270 return { 'tp_basicsize' : 'PyGBoxed',
1271 'tp_weaklistoffset' : '0',
1272 'tp_dictoffset' : '0' }
1274 def get_field_accessor(self, fieldname):
1275 return 'pyg_boxed_get(self, %s)->%s' % (self.objinfo.c_name, fieldname)
1277 def get_initial_constructor_substdict(self, constructor):
1278 substdict = Wrapper.get_initial_constructor_substdict(
1280 substdict['typecode'] = self.objinfo.typecode
1283 class GPointerWrapper(GBoxedWrapper):
1284 constructor_tmpl = (
1286 '_wrap_%(cname)s(PyGPointer *self%(extraparams)s)\n'
1291 ' self->gtype = %(typecode)s;\n'
1292 ' self->pointer = %(cname)s(%(arglist)s);\n'
1294 ' if (!self->pointer) {\n'
1295 ' PyErr_SetString(PyExc_RuntimeError, '
1296 '"could not create %(typename)s object");\n'
1304 'static PyObject *\n'
1305 '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
1310 ' %(setreturn)s%(cname)s(pyg_pointer_get(self, '
1311 '%(typename)s)%(arglist)s);\n'
1316 def get_initial_class_substdict(self):
1317 return { 'tp_basicsize' : 'PyGPointer',
1318 'tp_weaklistoffset' : '0',
1319 'tp_dictoffset' : '0' }
1321 def get_field_accessor(self, fieldname):
1322 return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name,
1325 def get_initial_constructor_substdict(self, constructor):
1326 substdict = Wrapper.get_initial_constructor_substdict(
1328 substdict['typecode'] = self.objinfo.typecode
1332 def __init__(self, parser, overrides, prefix, fp=FileOutput(sys.stdout)):
1333 self.parser = parser
1334 self.overrides = overrides
1335 self.prefix = prefix
1338 def write(self, py_ssize_t_clean=False):
1339 argtypes.py_ssize_t_clean = py_ssize_t_clean
1341 self.write_headers(py_ssize_t_clean)
1342 self.write_imports()
1343 self.write_type_declarations()
1345 self.write_classes()
1347 wrapper = Wrapper(self.parser, None, self.overrides, self.fp)
1348 wrapper.write_functions(self, self.prefix)
1350 if not self.overrides.dynamicnamespace:
1352 self.write_extension_init()
1353 self.write_registers()
1355 argtypes.py_ssize_t_clean = False
1357 def write_headers(self, py_ssize_t_clean):
1358 self.fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
1359 self.fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
1360 if py_ssize_t_clean:
1361 self.fp.write('#define PY_SSIZE_T_CLEAN\n')
1362 self.fp.write('#include <Python.h>\n\n\n')
1363 if py_ssize_t_clean:
1366 #if PY_VERSION_HEX < 0x02050000
1367 typedef int Py_ssize_t;
1368 #define PY_SSIZE_T_MAX INT_MAX
1369 #define PY_SSIZE_T_MIN INT_MIN
1370 typedef inquiry lenfunc;
1371 typedef intargfunc ssizeargfunc;
1372 typedef intobjargproc ssizeobjargproc;
1376 self.fp.write(self.overrides.get_headers())
1378 self.fp.write('\n\n')
1380 def write_imports(self):
1381 self.fp.write('/* ---------- types from other modules ---------- */\n')
1382 for module, pyname, cname, importing_for in self.overrides.get_imports():
1383 if importing_for is None or is_registered_object(importing_for):
1384 self.fp.write('static PyTypeObject *_%s;\n' % cname)
1385 self.fp.write('#define %s (*_%s)\n' % (cname, cname))
1386 self.fp.write('\n\n')
1388 def write_type_declarations(self):
1389 #todo use 'static' if used only in one file
1390 self.fp.write('/* ---------- forward type declarations ---------- */\n')
1391 for obj in self.parser.boxes:
1392 if not self.overrides.is_type_ignored(obj.c_name):
1393 self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
1394 for obj in self.parser.objects:
1395 if not self.overrides.is_type_ignored(obj.c_name):
1396 self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
1397 for interface in self.parser.interfaces:
1398 if not self.overrides.is_type_ignored(interface.c_name):
1399 self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + interface.c_name + '_Type;\n')
1402 def write_body(self):
1403 self.fp.write(self.overrides.get_body())
1405 self.fp.write('\n\n')
1407 def _sort_parent_children(self, objects):
1408 objects = list(objects)
1414 for i, obj in enumerate(objects):
1415 if obj.parent == 'GObject':
1417 if obj.parent not in [info.c_name for info in objects[:i]]:
1418 for j, info in enumerate(objects[i+1:]):
1419 if info.c_name == obj.parent:
1420 parent_index = i + 1 + j
1426 if child_index is not None and parent_index is not None:
1427 if child_index != parent_index:
1428 objects.insert(child_index, objects.pop(parent_index))
1432 def write_classes(self):
1433 ## Sort the objects, so that we generate code for the parent types
1434 ## before their children.
1435 objects = self._sort_parent_children(self.parser.objects)
1437 for klass, items in ((GBoxedWrapper, self.parser.boxes),
1438 (GPointerWrapper, self.parser.pointers),
1439 (GObjectWrapper, objects),
1440 (GInterfaceWrapper, self.parser.interfaces)):
1442 instance = klass(self.parser, item, self.overrides, self.fp)
1443 instance.write_class()
1446 def get_enums(self):
1448 for enum in self.parser.enums:
1449 if self.overrides.is_type_ignored(enum.c_name):
1454 def write_enums(self):
1455 if not self.parser.enums:
1458 self.fp.write('\n/* ----------- enums and flags ----------- */\n\n')
1460 'void\n' + self.prefix +
1461 '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
1465 ' PyModule_AddStringConstant(module, "__version__", VERSION);\n'
1468 for enum in self.get_enums():
1469 if enum.typecode is None:
1470 for nick, value in enum.values:
1472 ' PyModule_AddIntConstant(module, '
1473 '(char *) pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
1476 if enum.deftype == 'enum':
1477 self.fp.write(' pyg_enum_add(module, "%s", strip_prefix, %s);\n'
1478 % (enum.name, enum.typecode))
1480 self.fp.write(' pyg_flags_add(module, "%s", strip_prefix, %s);\n'
1481 % (enum.name, enum.typecode))
1484 self.fp.write(' if (PyErr_Occurred())\n')
1485 self.fp.write(' PyErr_Print();\n')
1486 self.fp.write('}\n\n')
1488 def write_object_imports(self, retval=''):
1489 imports = self.overrides.get_imports()[:]
1494 for module, pyname, cname, importing_for in imports:
1495 if importing_for is None or is_registered_object(importing_for):
1496 bymod.setdefault(module, []).append((pyname, cname))
1497 self.fp.write(' PyObject *module;\n\n')
1498 for module in bymod:
1500 ' if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
1503 # ' PyObject *moddict = PyModule_GetDict(module);\n\n')
1504 for pyname, cname in bymod[module]:
1506 # ' _%s = (PyTypeObject *)PyDict_GetItemString('
1507 # 'moddict, "%s");\n' % (cname, pyname))
1509 ' _%s = (PyTypeObject *)PyObject_GetAttrString('
1510 'module, "%s");\n' % (cname, pyname))
1511 self.fp.write(' if (_%s == NULL) {\n' % cname)
1512 self.fp.write(' PyErr_SetString(PyExc_ImportError,\n')
1513 self.fp.write(' "cannot import name %s from %s");\n'
1515 self.fp.write(' return %s;\n' % retval)
1516 self.fp.write(' }\n')
1517 self.fp.write(' } else {\n')
1518 self.fp.write(' PyErr_SetString(PyExc_ImportError,\n')
1519 self.fp.write(' "could not import %s");\n' % module)
1520 self.fp.write(' return %s;\n' % retval)
1521 self.fp.write(' }\n')
1524 def write_extension_init(self):
1525 self.fp.write('/* initialise stuff extension classes */\n')
1526 self.fp.write('void\n' + self.prefix + '_register_classes(PyObject *d)\n{\n')
1527 self.write_object_imports()
1528 self.fp.write(self.overrides.get_init() + '\n')
1531 def get_classes(self):
1532 objects = self.parser.objects[:]
1534 while pos < len(objects):
1535 parent = objects[pos].parent
1536 for i in range(pos+1, len(objects)):
1537 if objects[i].c_name == parent:
1538 objects.insert(i+1, objects[pos])
1546 if self.overrides.is_type_ignored(obj.c_name):
1549 if obj.parent != None:
1550 bases.append(obj.parent)
1551 bases = bases + obj.implements
1552 retval.append((obj, bases))
1556 def write_registers(self):
1557 for boxed in self.parser.boxes:
1558 if not self.overrides.is_type_ignored(boxed.c_name):
1559 self.fp.write(' pyg_register_boxed(d, "' + boxed.name +
1560 '", ' + boxed.typecode +
1561 ', &Py' + boxed.c_name +
1563 for pointer in self.parser.pointers:
1564 if not self.overrides.is_type_ignored(pointer.c_name):
1565 self.fp.write(' pyg_register_pointer(d, "' + pointer.name +
1566 '", ' + pointer.typecode +
1567 ', &Py' + pointer.c_name + '_Type);\n')
1568 for interface in self.parser.interfaces:
1569 if not self.overrides.is_type_ignored(interface.c_name):
1570 self.fp.write(' pyg_register_interface(d, "'
1571 + interface.name + '", '+ interface.typecode
1572 + ', &Py' + interface.c_name + '_Type);\n')
1573 if interface.interface_info is not None:
1574 self.fp.write(' pyg_register_interface_info(%s, &%s);\n' %
1575 (interface.typecode, interface.interface_info))
1577 if not self.overrides.dynamicnamespace:
1578 for obj, bases in self.get_classes():
1579 self.write_class(obj, bases)
1581 for obj, bases in self.get_classes():
1583 ' pyg_type_register_custom_callback("%s", '
1584 '(PyGTypeRegistrationFunction)%s_register_type, d);\n' %
1585 (obj.c_name, obj.c_name))
1587 self.fp.write('}\n')
1589 def _can_direct_ref(self, base):
1590 if not self.overrides.dynamicnamespace:
1592 if base == 'GObject':
1594 obj = get_object_by_name(base)
1595 if obj.module.lower() != self.overrides.modulename:
1599 def write_class(self, obj, bases, indent=1):
1600 indent_str = ' ' * (indent * 4)
1602 bases_str = 'Py_BuildValue("(%s)"' % (len(bases) * 'O')
1605 if self._can_direct_ref(base):
1606 bases_str += ', &Py%s_Type' % base
1608 baseobj = get_object_by_name(base)
1609 bases_str += ', PyObject_GetAttrString(m, "%s")' % baseobj.name
1615 '%(indent)spygobject_register_class(d, "%(c_name)s", %(typecode)s, &Py%(c_name)s_Type, %(bases)s);\n'
1616 % dict(indent=indent_str, c_name=obj.c_name, typecode=obj.typecode, bases=bases_str))
1618 if obj.has_new_constructor_api:
1620 indent_str + 'pyg_set_object_has_new_constructor(%s);\n' %
1623 print >> sys.stderr, (
1624 "Warning: Constructor for %s needs to be updated to new API\n"
1625 " See http://live.gnome.org/PyGTK_2fWhatsNew28"
1626 "#update-constructors") % obj.c_name
1628 if obj.class_init_func is not None:
1630 indent_str + 'pyg_register_class_init(%s, %s);\n' %
1631 (obj.typecode, obj.class_init_func))
1635 def is_registered_object(c_name):
1636 return c_name in _objects
1638 def get_object_by_name(c_name):
1640 return _objects[c_name]
1642 def register_types(parser):
1644 for boxed in parser.boxes:
1645 argtypes.matcher.register_boxed(boxed.c_name, boxed.typecode)
1646 _objects[boxed.c_name] = boxed
1647 for pointer in parser.pointers:
1648 argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode)
1649 for obj in parser.objects:
1650 argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode)
1651 _objects[obj.c_name] = obj
1652 for iface in parser.interfaces:
1653 argtypes.matcher.register_object(iface.c_name, None, iface.typecode)
1654 _objects[iface.c_name] = iface
1655 for enum in parser.enums:
1656 if enum.deftype == 'flags':
1657 argtypes.matcher.register_flag(enum.c_name, enum.typecode)
1659 argtypes.matcher.register_enum(enum.c_name, enum.typecode)
1661 usage = 'usage: codegen.py [-o overridesfile] [-p prefix] defsfile'
1663 o = override.Overrides()
1666 errorfilename = None
1667 opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:I:",
1668 ["override=", "prefix=", "register=", "outfilename=",
1669 "load-types=", "errorfilename=", "py_ssize_t-clean"])
1670 defines = {} # -Dkey[=val] options
1671 py_ssize_t_clean = False
1672 for opt, arg in opts:
1673 if opt in ('-o', '--override'):
1674 o = override.Overrides(arg)
1675 elif opt in ('-p', '--prefix'):
1677 elif opt in ('-r', '--register'):
1678 # Warning: user has to make sure all -D options appear before -r
1679 p = defsparser.DefsParser(arg, defines)
1683 elif opt == '--outfilename':
1685 elif opt == '--errorfilename':
1687 elif opt in ('-t', '--load-types'):
1689 execfile(arg, globals)
1691 nameval = arg.split('=')
1693 defines[nameval[0]] = nameval[1]
1695 defines[nameval[0]] = None
1697 defsparser.include_path.insert(0, arg)
1698 elif opt == '--py_ssize_t-clean':
1699 py_ssize_t_clean = True
1701 print >> sys.stderr, usage
1704 sys.stderr = open(errorfilename, "w")
1705 p = defsparser.DefsParser(args[0], defines)
1707 outfilename = os.path.splitext(args[0])[0] + '.c'
1712 sw = SourceWriter(p, o, prefix, FileOutput(sys.stdout, outfilename))
1713 sw.write(py_ssize_t_clean)
1715 functions_coverage.printstats()
1716 methods_coverage.printstats()
1717 vproxies_coverage.printstats()
1718 vaccessors_coverage.printstats()
1719 iproxies_coverage.printstats()
1721 if __name__ == '__main__':
1722 sys.exit(main(sys.argv))