robertwb / issues-import-test

0 stars 0 forks source link

Metaclasses to generate cdef'ed Classes #935

Open robertwb opened 12 years ago

robertwb commented 12 years ago

Here are some ideas of how this could be accomplished: * evaluate cdef-Classes which are using a Metaclass ''before any other classes'' * create temporary pyd and pyx files for any cdef-class that uses cdef-metaclasses * those temporary classes need to be re-evaluated if anything changes in the original

Example Scenario:

@cython.cclass
class FormMeta(type):
    @classmethod
    def __prepare__(metacls, name, bases, **kwargs):
        return OrderedDict()
    def __init__(cls, name, bases, attrs):
        # add some attributes and methods to cls, in order to
        # have less boilerplate to write for each form class
        return type.__init__(cls, name, bases, attrs)
@cython.cclass
class UserForm(metaclass=FormMeta):
    name = TextField()

Benefits: * Once the Extension Module is built, there would be no need to do process the creation/manipulation via metaclasses, thus reduce startup time for application * Have all the benefits of cdef-Classes, like lower memory footprint, when there might be hundreds of those classes with lots of data in them * Have all the benefits of python beeing both very dynamic and flexible and simple to use

I know there are many issues which have a higher priority right now, but a discussion about this would be very nice.

Migrated from http://trac.cython.org/ticket/777

robertwb commented 12 years ago

valmynd changed type from defect to enhancement A more precise example scenario, in which meta classes make sense:

@cython.cclass
class _Field(object):
   _parent = cython.declare(Form)
   cpdef void bind_parent(self, Form form):
      # handle group of fields recursively, e.g. radio buttons
      self._parent = form
@cython.cclass
class FormMeta(type):
   @classmethod
   def __prepare__(metacls, name, bases, **kwargs):
      return OrderedDict()
   def __init__(cls, name, bases, attrs):
      for objname, obj in attrs.items():
         if isinstance(obj, _Field):
            # Field objects need to know which Form or FieldGroup they belong to
            obj.bind_parent(cls)
            cls._fields.append(obj)
      return type.__init__(cls, name, bases, attrs)
@cython.cclass
class Form(metaclass=FormMeta):
   _fields = []
@cython.cclass
class UserForm(Form):
   name = TextField()