[pypy-svn] r10280 - pypy/dist/pypy/module/builtin
arigo at codespeak.net
arigo at codespeak.net
Mon Apr 4 14:19:39 CEST 2005
Author: arigo
Date: Mon Apr 4 14:19:39 2005
New Revision: 10280
Modified:
pypy/dist/pypy/module/builtin/app_descriptor.py
Log:
Cleaned up the propertydoc hack. Now a general class docstring which behaves
like, well, a docstring when put in a class, but also allows to capture and
behave like an instance slot.
Modified: pypy/dist/pypy/module/builtin/app_descriptor.py
==============================================================================
--- pypy/dist/pypy/module/builtin/app_descriptor.py (original)
+++ pypy/dist/pypy/module/builtin/app_descriptor.py Mon Apr 4 14:19:39 2005
@@ -2,26 +2,95 @@
Plain Python definition of the builtin descriptors.
"""
-# Don't look! This is needed for the property class, which has a slot
-# called __doc__ but also needs a __doc__ string for itself.
-class propertydoc(object):
+# Descriptor code, shamelessly stolen to Raymond Hettinger:
+# http://users.rcn.com/python/download/Descriptor.htm
+
+
+# XXX there is an interp-level pypy.interpreter.function.StaticMethod
+# XXX because __new__ needs to be a StaticMethod early.
+class staticmethod(object):
+ __slots__ = ['_f']
+
+ def __init__(self, f):
+ self._f = f
+
+ def __get__(self, obj, objtype=None):
+ return self._f
+
+
+class classmethod(object):
+ __slots__ = ['_f']
+
+ def __init__(self, f):
+ self._f = f
+
+ def __get__(self, obj, klass=None):
+ if klass is None:
+ klass = type(obj)
+ def newfunc(*args, **kwargs):
+ return self._f(klass, *args, **kwargs)
+ return newfunc
+
+
+# It's difficult to have a class that has both a docstring and a slot called
+# '__doc__', but not impossible...
+class docstring(object):
+
+ def __init__(self, classdocstring):
+ self.classdocstring = classdocstring
+ self.slot = None
+
+ def capture(cls, slotname):
+ self = cls.__dict__['__doc__']
+ slot = cls.__dict__[slotname]
+ if not isinstance(self, docstring):
+ raise TypeError, "the class __doc__ must be a docstring instance"
+ self.slot = slot
+ delattr(cls, slotname)
+ capture = staticmethod(capture)
+
def __get__(self, p, cls=None):
if p is None:
- return PROPERTY_DOCSTRING # getting __doc__ on the class
+ return self.classdocstring # getting __doc__ on the class
+ elif self.slot is None:
+ raise AttributeError, "'%s' instance has no __doc__" % (
+ p.__class__.__name__,)
else:
- return PROPERTY_DOCSLOT.__get__(p) # on an instance
+ return self.slot.__get__(p) # getting __doc__ on an instance
+
+ def __set__(self, p, value):
+ if hasattr(self.slot, '__set__'):
+ return self.slot.__set__(p, value)
+ else:
+ raise AttributeError, "cannot write __doc__"
+
+ def __delete__(self, p):
+ if hasattr(self.slot, '__delete__'):
+ return self.slot.__delete__(p)
+ else:
+ raise AttributeError, "cannot write __doc__"
+
-# Descriptor code, shamelessly stolen to Raymond Hettinger:
-# http://users.rcn.com/python/download/Descriptor.htm
class property(object):
- __slots__ = ['fget', 'fset', 'fdel', 'doc'] # NB. 'doc' hacked away below
- __doc__ = propertydoc()
+ __doc__ = docstring(
+ '''property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
+
+fget is a function to be used for getting an attribute value, and likewise
+fset is a function for setting, and fdel a function for deleting, an
+attribute. Typical use is to define a managed attribute x:
+class C(object):
+ def getx(self): return self.__x
+ def setx(self, value): self.__x = value
+ def delx(self): del self.__x
+ x = property(getx, setx, delx, "I am the 'x' property.")''')
+
+ __slots__ = ['fget', 'fset', 'fdel', 'slot__doc__']
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
- PROPERTY_DOCSLOT.__set__(self, doc)
+ self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
@@ -40,45 +109,8 @@
raise AttributeError, "can't delete attribute"
self.fdel(obj)
-PROPERTY_DOCSTRING = '''property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
-
-fget is a function to be used for getting an attribute value, and likewise
-fset is a function for setting, and fdel a function for deleting, an
-attribute. Typical use is to define a managed attribute x:
-class C(object):
- def getx(self): return self.__x
- def setx(self, value): self.__x = value
- def delx(self): del self.__x
- x = property(getx, setx, delx, "I am the 'x' property.")'''
-
-PROPERTY_DOCSLOT = property.doc
-del property.doc
-
-
-# XXX there is an interp-level pypy.interpreter.function.StaticMethod
-# XXX because __new__ needs to be a StaticMethod early.
-class staticmethod(object):
- __slots__ = ['_f']
-
- def __init__(self, f):
- self._f = f
-
- def __get__(self, obj, objtype=None):
- return self._f
-
-
-class classmethod(object):
- __slots__ = ['_f']
-
- def __init__(self, f):
- self._f = f
+docstring.capture(property, 'slot__doc__')
- def __get__(self, obj, klass=None):
- if klass is None:
- klass = type(obj)
- def newfunc(*args, **kwargs):
- return self._f(klass, *args, **kwargs)
- return newfunc
# super is a modified version from Guido's tutorial
# http://www.python.org/2.2.3/descrintro.html
More information about the Pypy-commit
mailing list