[prev in list] [next in list] [prev in thread] [next in thread]
List: pypy-svn
Subject: [pypy-svn] r8734 - pypy/dist/pypy/lib
From: tismer () codespeak ! net
Date: 2005-01-29 17:07:23
Message-ID: 20050129170723.AF2CA27B5C () code1 ! codespeak ! net
[Download RAW message or body]
Author: tismer
Date: Sat Jan 29 18:07:23 2005
New Revision: 8734
Modified:
pypy/dist/pypy/lib/_classobj.py
Log:
a first implementation works quite fine, already
and runs some of the standard tests. (Samuele+Chris)
Modified: pypy/dist/pypy/lib/_classobj.py
==============================================================================
--- pypy/dist/pypy/lib/_classobj.py (original)
+++ pypy/dist/pypy/lib/_classobj.py Sat Jan 29 18:07:23 2005
@@ -1,4 +1,9 @@
-import sys
+import sys, operator
+
+def coerce(left, right):
+ # XXX this is just a surrogate for now
+ # XXX the builtin coerce needs to be implemented by PyPy
+ return None
obj_setattr = object.__setattr__
obj_getattribute = object.__getattribute__
@@ -32,8 +37,8 @@
dic['__bases__'] = cls.__bases__
obj_setattr(cls, '__dict__', dic)
-def retrieve(cls, attr):
- dic = obj_getattribute(cls, '__dict__')
+def retrieve(obj, attr):
+ dic = obj_getattribute(obj, '__dict__')
try:
return dic[attr]
except KeyError:
@@ -51,6 +56,15 @@
return v, found
return None, None
+def get_class_module(cls):
+ try:
+ mod = retrieve(cls, "__module__")
+ except AttributeError:
+ mod = None
+ if not isinstance(mod, str):
+ return "?"
+ return mod
+
def mro_lookup(v, name):
try:
mro = type(v).__mro__
@@ -140,32 +154,214 @@
return v
return descr_get(v, None, self)
- def __repr__(self):
- try:
- mod = retrieve(self, '__module__')
- if not isinstance(mod, str):
- mod = None
- except AttributeError:
- mod = None
- if mod is None:
- return "<class ?.%s at 0x%x>" % (self.__name__, uid(self))
- else:
- return "<class %s.%s at 0x%x>" % (mod, self.__name__, uid(self))
+ def __repr__(self):
+ mod = get_class_module(self)
+ return "<class %s.%s at 0x%x>" % (mod, self.__name__, uid(self))
def __str__(self):
- try:
- mod = retrieve(self, '__module__')
- if not isinstance(mod, str):
- mod = None
- except AttributeError:
- mod = None
- if mod is None:
+ mod = get_class_module(self)
+ if mod == "?":
return self.__name__
else:
return "%s.%s" % (mod, self.__name__)
-
+
+ def __call__(self, *args, **kwds):
+ inst = object.__new__(instance)
+ dic = inst.__dict__
+ dic['__class__'] = self
+ try:
+ init = self.__init__
+ except AttributeError:
+ pass
+ else:
+ ret = init(inst, *args, **kwds)
+ if ret is not None:
+ raise TypeError("__init__() should return None")
+ return inst
+
+# first we use the object's dict for the instance dict.
+# with a little more effort, it should be possible
+# to provide a clean extra dict with no other attributes
+# in it.
+
+def instance_getattr1(inst, name, exc=True):
+ if name == "__dict__":
+ return obj_getattribute(inst, name)
+ elif name == "__class__":
+ # for now, it lives in the instance dict
+ return retrieve(inst, name)
+ try:
+ return retrieve(inst, name)
+ except AttributeError:
+ cls = retrieve(inst, "__class__")
+ v, found = lookup(cls, name)
+ if not found:
+ if exc:
+ raise AttributeError, "%s instance has no attribute %s" % (cls.__name__, name)
+ else:
+ return None
+ descr_get = mro_lookup(v, '__get__')
+ if descr_get is None:
+ return v
+ return descr_get(v, inst, cls)
class instance(object):
- pass
-
+ def __getattribute__(self, name):
+ try:
+ return instance_getattr1(self, name)
+ except AttributeError:
+ getattr = instance_getattr1(self, '__getattr__', exc=False)
+ if getattr is not None:
+ return getattr(name)
+ raise
+ def __new__(typ, klass, dic=None):
+ # typ is not used at all
+ if not isinstance(klass,classobj):
+ raise TypeError("instance() first arg must be class")
+ if dic is None:
+ dic = {}
+ elif not isinstance(dic, dict):
+ raise TypeError("instance() second arg must be dictionary or None")
+ inst = object.__new__(instance)
+ dic['__class__'] = klass
+ obj_setattr(inst, '__dict__', dic)
+ return inst
+
+ def __setattr__(self, name, value):
+ if name == '__dict__':
+ if not isinstance(value, dict):
+ raise TypeError("__dict__ must be set to a dictionary")
+ # for now, we need to copy things, because we are using
+ # the __dict__for our class as well. This will vanish!
+ value['__class__'] = self.__class__
+ obj_setattr(inst, '__dict__', value)
+ elif name == '__class__':
+ if not isinstance(value, classobj):
+ raise TypeError("__class__ must be set to a class")
+ self.__dict__['__class__'] = value
+ else:
+ setattr = instance_getattr1(self, '__setattr__', exc=False)
+ if setattr is not None:
+ setattr(name, value)
+ else:
+ self.__dict__[name] = value
+
+ def __delattr__(self, name):
+ # abuse __setattr__ to get the complaints :-)
+ # this is as funny as in CPython
+ if name in ('__dict__', '__class__'):
+ instance.__setattr__(self, name, None)
+ else:
+ delattr = instance_getattr1(self, '__delattr__', exc=False)
+ if delattr is not None:
+ delattr(name)
+ else:
+ try:
+ del self.__dict__[name]
+ except KeyError, ex:
+ raise AttributeError("%s instance has no attribute '%s'" % (
+ self.__class__.__name__,name) )
+
+ def __repr__(self):
+ try:
+ func = instance_getattr1(self, '__repr__')
+ except AttributeError:
+ klass = self.__class__
+ mod = get_class_module(klass)
+ return "<%s.%s instance at 0x%x>" % (mod, klass.__name__, uid(self))
+ return func()
+
+ def __str__(self):
+ try:
+ func = instance_getattr1(self, '__str__')
+ except AttributeError:
+ return instance.__repr__(self)
+ return func()
+
+ def __hash__(self):
+ _eq = instance_getattr1(self, "__eq__", False)
+ _cmp = instance_getattr1(self, "__cmp__", False)
+ _hash = instance_getattr1(self, "__hash__", False)
+ if (_eq or _cmp) and not _hash:
+ raise TypeError("unhashable instance")
+ if _hash:
+ ret = _hash()
+ if not isinstance(ret, int):
+ raise TypeError("__hash__() should return an int")
+ else:
+ return id(self)
+
+ def __len__(self):
+ ret = instance_getattr1(self,'__len__')()
+ if isinstance(ret, int):
+ if ret < 0:
+ raise ValueError("__len__() should return >= 0")
+ return ret
+ else:
+ raise TypeError("__len__() should return an int")
+
+ def __getitem__(self, key):
+ if isinstance(key, slice) and key.step is None:
+ func = instance_getattr1(self, '__getslice__', False)
+ if func:
+ return func(key.start, key.end)
+ return instance_getattr1(self, '__getitem__')(key)
+
+ def __setitem__(self, key, value):
+ if isinstance(key, slice) and key.step is None:
+ func = instance_getattr1(self, '__setslice__', False)
+ if func:
+ func(key.start, key.end, value)
+ instance_getattr1(self, '__setitem__')(key, value)
+
+ def __delitem__(self, key):
+ if isinstance(key, slice) and key.step is None:
+ func = instance_getattr1(self, '__delslice__', False)
+ if func:
+ func(key.start, key.end)
+ instance_getattr1(self, '__delitem__')(key)
+
+ def __contains__(self, obj):
+ func = instance_getattr1(self, '__contains__', False)
+ if func:
+ return bool(func(obj))
+ # now do it ourselves
+ for x in self:
+ if x == obj:
+ return True
+ return False
+
+ # unary operators
+ def __neg__(self):
+ return instance_getattr1(self, '__neg__')()
+ def __pos__(self):
+ return instance_getattr1(self, '__abs__')()
+ def __abs__(self):
+ return instance_getattr1(self, '__abs__')()
+
+ # binary operators
+ for op in "or and xor lshift rshift add sub mul div mod divmod floordiv truediv".split():
+ exec("""
+def __%(op)s__(self, other):
+ coerced = coerce(self, other)
+ if coerced is None or coerced[0] is self:
+ func = instance_getattr1(self, '__%(op)s__', False)
+ if func:
+ return func(other)
+ return NotImplemented
+ else:
+ return operator.%(op2)s(self, other)
+
+def __r%(op)s__(self, other):
+ coerced = coerce(self, other)
+ if coerced is None or coerced[0] is self:
+ func = instance_getattr1(self, '__r%(op)s__', False)
+ if func:
+ return func(other)
+ return NotImplemented
+ else:
+ return operator.%(op2)s(other, self)
+""") % {"op": op, "op2": (op, op+'_')[op in ('and', 'or', 'not')]}
+ del op
+
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic