Ticket #12808: trac_12808-classcall_cdef.patch

File trac_12808-classcall_cdef.patch, 7.1 KB (added by SimonKing, 10 years ago)

Make ClasscallMetaclass an extension type of type

  • sage/misc/classcall_metaclass.pxd

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1335369336 -7200
    # Node ID 889689d72e250311dd8b25034453d48a1bd34276
    # Parent  60bf4af4471841fd8711b08d0cd7c584dae2db14
    #12808: Make the ClasscallMetaclass an extension type of type.
    
    diff --git a/sage/misc/classcall_metaclass.pxd b/sage/misc/classcall_metaclass.pxd
    a b  
    99    ctypedef class __builtin__.type [object PyHeapTypeObject]:
    1010        pass
    1111
    12 cdef class ClasscallType(type):
     12from sage.misc.nested_class cimport NestedClassMetaclass
     13
     14cdef class ClasscallMetaclass(NestedClassMetaclass):
    1315    cdef object classcall
    1416    cdef object classget
    1517    cdef object classcontains
  • sage/misc/classcall_metaclass.pyx

    diff --git a/sage/misc/classcall_metaclass.pyx b/sage/misc/classcall_metaclass.pyx
    a b  
    2424        callfunc tp_call # needed to call type.__call__ at very high speed.
    2525    cdef PyTypeObject_call PyType_Type # Python's type
    2626
    27 __all__ = ['ClasscallType', 'ClasscallMetaclass', 'typecall', 'timeCall']
     27__all__ = ['ClasscallMetaclass', 'typecall', 'timeCall']
    2828
    29 cdef class ClasscallType(type):
    30     r"""
    31     Extension of ``type`` for class special methods
     29cdef class ClasscallMetaclass(NestedClassMetaclass):
     30    """
     31    A metaclass providing support for special methods for classes.
    3232
    33     This is the Cython base ``type`` for the metaclass
    34     :class:`ClasscallMetaclass`.  See there for more informations.
     33    From the Section :python:`Special method names
     34    <reference/datamodel.html#special-method-names>` of the Python Reference
     35    Manual:
     36
     37        \`a class ``cls`` can implement certain operations on its instances
     38        that are invoked by special syntax (such as arithmetic operations or
     39        subscripting and slicing) by defining methods with special
     40        names\'.
     41
     42    The purpose of this metaclass is to allow for the class ``cls`` to
     43    implement analogues of those special methods for the operations on the
     44    class itself.
     45
     46    Currently, the following special methods are supported:
     47
     48     - ``.__classcall__`` (and ``.__classcall_private__``) for
     49       customizing ``cls(...)`` (analogue of ``.__call__``).
     50
     51     - ``.__classcontains__`` for customizing membership testing
     52       ``x in cls`` (analogue of ``.__contains__``).
     53
     54     - ``.__classget__`` for customizing the binding behavior in
     55       ``foo.cls`` (analogue of ``.__get__``).
     56
     57    See the documentation of :meth:`.__call__` and of :meth:`.__get__`
     58    and :meth:`.__contains__` for the description of the respective
     59    protocols.
     60
     61    .. warning:: for technical reasons, ``__classcall__``,
     62        ``__classcall_private__``, ``__classcontains__``, and
     63        ``__classget__`` must be defined as :func:`staticmethod`'s, even
     64        though they receive the class itself as their first argument.
     65
     66    ``ClasscallMetaclass`` is an extension of the base :class:`type`.
     67
     68    TODO: find a good name for this metaclass.
     69
     70    TESTS::
     71
     72        sage: PerfectMatchings(2).list()
     73        [PerfectMatching [(2, 1)]]
     74
     75    .. note::
     76
     77        If a class is put in this metaclass it automatically becomes a
     78        new-style class::
     79
     80            sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
     81            sage: class Foo:
     82            ...       __metaclass__ = ClasscallMetaclass
     83            sage: x = Foo(); x
     84            <__main__.Foo object at 0x...>
     85            sage: issubclass(Foo, object)
     86            True
     87            sage: isinstance(Foo, type)
     88            True
    3589    """
    3690    _included_private_doc_ = ['__call__', '__contains__', '__get__']
    3791
     
    3993        r"""
    4094        TESTS::
    4195
    42             sage: from sage.misc.classcall_metaclass import ClasscallType
     96            sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
    4397            sage: class FOO(object):
    44             ...       __metaclass__ = ClasscallType
    45             sage: isinstance(FOO, ClasscallType)
     98            ...       __metaclass__ = ClasscallMetaclass
     99            sage: isinstance(FOO, ClasscallMetaclass)  # indirect doctest
    46100            True
    47101        """
    48102        if '__classcall_private__' in self.__dict__:
     
    375429        else:
    376430            return x in object
    377431
    378 from nested_class import NestedClassMetaclass
    379 class ClasscallMetaclass(ClasscallType, NestedClassMetaclass):
    380     """
    381     A metaclass providing support for special methods for classes.
    382 
    383     From the Section :python:`Special method names
    384     <reference/datamodel.html#special-method-names>` of the Python Reference
    385     Manual:
    386 
    387         \`a class ``cls`` can implement certain operations on its instances
    388         that are invoked by special syntax (such as arithmetic operations or
    389         subscripting and slicing) by defining methods with special
    390         names\'.
    391 
    392     The purpose of this metaclass is to allow for the class ``cls`` to
    393     implement analogues of those special methods for the operations on the
    394     class itself.
    395 
    396     Currently, the following special methods are supported:
    397 
    398      - ``.__classcall__`` (and ``.__classcall_private__``) for
    399        customizing ``cls(...)`` (analogue of ``.__call__``).
    400 
    401      - ``.__classcontains__`` for customizing membership testing
    402        ``x in cls`` (analogue of ``.__contains__``).
    403 
    404      - ``.__classget__`` for customizing the binding behavior in
    405        ``foo.cls`` (analogue of ``.__get__``).
    406 
    407     See the documentation of :meth:`.__call__` and of :meth:`.__get__`
    408     and :meth:`.__contains__` for the description of the respective
    409     protocols.
    410 
    411     .. warning:: for technical reasons, ``__classcall__``,
    412         ``__classcall_private__``, ``__classcontains__``, and
    413         ``__classget__`` must be defined as :func:`staticmethod`'s, even
    414         though they receive the class itself as their first argument.
    415 
    416     ``ClasscallMetaclass`` is implemented using an extension of the base
    417     :class:`type` called :class:`ClasscallType`.
    418 
    419     .. SEEALSO:: :class:`ClasscallType`
    420 
    421     TODO: find a good name for this metaclass.
    422 
    423     TESTS::
    424 
    425         sage: PerfectMatchings(2).list()
    426         [PerfectMatching [(2, 1)]]
    427 
    428     .. note::
    429 
    430         If a class is put in this metaclass it automatically becomes a
    431         new-style class::
    432 
    433             sage: from sage.misc.classcall_metaclass import ClasscallMetaclass
    434             sage: class Foo:
    435             ...       __metaclass__ = ClasscallMetaclass
    436             sage: x = Foo(); x
    437             <__main__.Foo object at 0x...>
    438             sage: issubclass(Foo, object)
    439             True
    440             sage: isinstance(Foo, type)
    441             True
    442     """
    443     pass
    444432
    445433def typecall(type cls, *args, **opts):
    446434    r"""
     
    475463            ...
    476464            TypeError: Argument 'cls' has incorrect type (expected type, got classobj)
    477465    """
    478     # See remarks in ClasscallType.__call__(cls, *args, **opts) for speed.
     466    # See remarks in ClasscallMetaclass.__call__(cls, *args, **opts) for speed.
    479467    res = <object> PyType_Type.tp_call(cls, args, opts)
    480468    Py_XDECREF(res) # During the cast to <object> Cython did INCREF(res)
    481469    return res