[pypy-commit] pypy py3k: Remove old-style classobj.
amauryfa
noreply at buildbot.pypy.org
Tue Dec 20 01:32:46 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r50740:46d9c473055c
Date: 2011-12-19 23:28 +0100
http://bitbucket.org/pypy/pypy/changeset/46d9c473055c/
Log: Remove old-style classobj.
diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -45,9 +45,6 @@
'open' : 'state.get(space).w_open',
- # default __metaclass__: old-style class
- '__metaclass__' : 'interp_classobj.W_ClassObject',
-
# interp-level function definitions
'abs' : 'operation.abs',
'ascii' : 'operation.ascii',
diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py
--- a/pypy/module/__builtin__/abstractinst.py
+++ b/pypy/module/__builtin__/abstractinst.py
@@ -9,8 +9,6 @@
from pypy.rlib import jit
from pypy.interpreter.error import OperationError
-from pypy.module.__builtin__.interp_classobj import W_ClassObject
-from pypy.module.__builtin__.interp_classobj import W_InstanceObject
from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace
def _get_bases(space, w_cls):
@@ -87,12 +85,6 @@
else:
return space.is_true(w_result)
- # -- case (old-style instance, old-style class)
- oldstyleclass = space.interpclass_w(w_klass_or_tuple)
- if isinstance(oldstyleclass, W_ClassObject):
- oldstyleinst = space.interpclass_w(w_obj)
- if isinstance(oldstyleinst, W_InstanceObject):
- return oldstyleinst.w_class.is_subclass_of(oldstyleclass)
return _abstract_isinstance_w_helper(space, w_obj, w_klass_or_tuple)
@jit.dont_look_inside
@@ -151,14 +143,7 @@
else:
return space.is_true(w_result)
- # -- case (old-style class, old-style class)
- oldstylederived = space.interpclass_w(w_derived)
- if isinstance(oldstylederived, W_ClassObject):
- oldstyleklass = space.interpclass_w(w_klass_or_tuple)
- if isinstance(oldstyleklass, W_ClassObject):
- return oldstylederived.is_subclass_of(oldstyleklass)
- else:
- check_class(space, w_derived, "issubclass() arg 1 must be a class")
+ check_class(space, w_derived, "issubclass() arg 1 must be a class")
# from here on, we are sure that w_derived is a class-like object
# -- case (class-like-object, abstract-class)
@@ -171,32 +156,15 @@
# Exception helpers
def exception_is_valid_obj_as_class_w(space, w_obj):
- obj = space.interpclass_w(w_obj)
- if isinstance(obj, W_ClassObject):
- return True
return BaseObjSpace.exception_is_valid_obj_as_class_w(space, w_obj)
def exception_is_valid_class_w(space, w_cls):
- cls = space.interpclass_w(w_cls)
- if isinstance(cls, W_ClassObject):
- return True
return BaseObjSpace.exception_is_valid_class_w(space, w_cls)
def exception_getclass(space, w_obj):
- obj = space.interpclass_w(w_obj)
- if isinstance(obj, W_InstanceObject):
- return obj.w_class
return BaseObjSpace.exception_getclass(space, w_obj)
def exception_issubclass_w(space, w_cls1, w_cls2):
- cls1 = space.interpclass_w(w_cls1)
- cls2 = space.interpclass_w(w_cls2)
- if isinstance(cls1, W_ClassObject):
- if isinstance(cls2, W_ClassObject):
- return cls1.is_subclass_of(cls2)
- return False
- if isinstance(cls2, W_ClassObject):
- return False
return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2)
# ____________________________________________________________
diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py
deleted file mode 100644
--- a/pypy/module/__builtin__/interp_classobj.py
+++ /dev/null
@@ -1,768 +0,0 @@
-import new
-from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.gateway import interp2app
-from pypy.interpreter.typedef import TypeDef, make_weakref_descr
-from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, descr_set_dict
-from pypy.rlib.objectmodel import compute_identity_hash
-from pypy.rlib.debug import make_sure_not_resized
-from pypy.rlib import jit
-
-
-def raise_type_err(space, argument, expected, w_obj):
- type_name = space.type(w_obj).getname(space)
- raise operationerrfmt(space.w_TypeError,
- "argument %s must be %s, not %s",
- argument, expected, type_name)
-
-def unwrap_attr(space, w_attr):
- try:
- return space.str_w(w_attr)
- except OperationError, e:
- if not e.match(space, space.w_TypeError):
- raise
- return "?" # any string different from "__dict__" & co. is fine
- # XXX it's not clear that we have to catch the TypeError...
-
-def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict):
- if not space.is_true(space.isinstance(w_bases, space.w_tuple)):
- raise_type_err(space, 'bases', 'tuple', w_bases)
-
- if not space.is_true(space.isinstance(w_dict, space.w_dict)):
- raise_type_err(space, 'bases', 'tuple', w_bases)
-
- if not space.is_true(space.contains(w_dict, space.wrap("__doc__"))):
- space.setitem(w_dict, space.wrap("__doc__"), space.w_None)
-
- # XXX missing: lengthy and obscure logic about "__module__"
-
- bases_w = space.fixedview(w_bases)
- for w_base in bases_w:
- if not isinstance(w_base, W_ClassObject):
- w_metaclass = space.type(w_base)
- if space.is_true(space.callable(w_metaclass)):
- return space.call_function(w_metaclass, w_name,
- w_bases, w_dict)
- raise OperationError(space.w_TypeError,
- space.wrap("base must be class"))
-
- return W_ClassObject(space, w_name, bases_w, w_dict)
-
-class W_ClassObject(Wrappable):
- def __init__(self, space, w_name, bases, w_dict):
- self.name = space.str_w(w_name)
- make_sure_not_resized(bases)
- self.bases_w = bases
- self.w_dict = w_dict
-
- def instantiate(self, space):
- cache = space.fromcache(Cache)
- if self.lookup(space, '__del__') is not None:
- w_inst = cache.cls_with_del(space, self)
- else:
- w_inst = cache.cls_without_del(space, self)
- return w_inst
-
- def getdict(self, space):
- return self.w_dict
-
- def setdict(self, space, w_dict):
- if not space.is_true(space.isinstance(w_dict, space.w_dict)):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__dict__ must be a dictionary object"))
- self.w_dict = w_dict
-
- def setname(self, space, w_newname):
- if not space.is_true(space.isinstance(w_newname, space.w_str)):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__name__ must be a string object"))
- self.name = space.str_w(w_newname)
-
- def setbases(self, space, w_bases):
- # XXX in theory, this misses a check against inheritance cycles
- # although on pypy we don't get a segfault for infinite
- # recursion anyway
- if not space.is_true(space.isinstance(w_bases, space.w_tuple)):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__bases__ must be a tuple object"))
- bases_w = space.fixedview(w_bases)
- for w_base in bases_w:
- if not isinstance(w_base, W_ClassObject):
- raise OperationError(space.w_TypeError,
- space.wrap("__bases__ items must be classes"))
- self.bases_w = bases_w
-
- def is_subclass_of(self, other):
- assert isinstance(other, W_ClassObject)
- if self is other:
- return True
- for base in self.bases_w:
- assert isinstance(base, W_ClassObject)
- if base.is_subclass_of(other):
- return True
- return False
-
- @jit.unroll_safe
- def lookup(self, space, attr):
- # returns w_value or interplevel None
- w_result = space.finditem_str(self.w_dict, attr)
- if w_result is not None:
- return w_result
- for base in self.bases_w:
- # XXX fix annotation of bases_w to be a list of W_ClassObjects
- assert isinstance(base, W_ClassObject)
- w_result = base.lookup(space, attr)
- if w_result is not None:
- return w_result
- return None
-
- def descr_getattribute(self, space, w_attr):
- name = unwrap_attr(space, w_attr)
- if name and name[0] == "_":
- if name == "__dict__":
- return self.w_dict
- elif name == "__name__":
- return space.wrap(self.name)
- elif name == "__bases__":
- return space.newtuple(self.bases_w)
- w_value = self.lookup(space, name)
- if w_value is None:
- raise operationerrfmt(
- space.w_AttributeError,
- "class %s has no attribute '%s'",
- self.name, name)
-
- w_descr_get = space.lookup(w_value, '__get__')
- if w_descr_get is None:
- return w_value
- return space.call_function(w_descr_get, w_value, space.w_None, self)
-
- def descr_setattr(self, space, w_attr, w_value):
- name = unwrap_attr(space, w_attr)
- if name and name[0] == "_":
- if name == "__dict__":
- self.setdict(space, w_value)
- return
- elif name == "__name__":
- self.setname(space, w_value)
- return
- elif name == "__bases__":
- self.setbases(space, w_value)
- return
- elif name == "__del__":
- if self.lookup(space, name) is None:
- msg = ("a __del__ method added to an existing class "
- "will not be called")
- space.warn(msg, space.w_RuntimeWarning)
- space.setitem(self.w_dict, w_attr, w_value)
-
- def descr_delattr(self, space, w_attr):
- name = unwrap_attr(space, w_attr)
- if name in ("__dict__", "__name__", "__bases__"):
- raise operationerrfmt(
- space.w_TypeError,
- "cannot delete attribute '%s'", name)
- try:
- space.delitem(self.w_dict, w_attr)
- except OperationError, e:
- if not e.match(space, space.w_KeyError):
- raise
- raise operationerrfmt(
- space.w_AttributeError,
- "class %s has no attribute '%s'",
- self.name, name)
-
- def descr_repr(self, space):
- mod = self.get_module_string(space)
- return self.getrepr(space, "class %s.%s" % (mod, self.name))
-
- def descr_str(self, space):
- mod = self.get_module_string(space)
- if mod == "?":
- return space.wrap(self.name)
- else:
- return space.wrap("%s.%s" % (mod, self.name))
-
- def get_module_string(self, space):
- try:
- w_mod = self.descr_getattribute(space, space.wrap("__module__"))
- except OperationError, e:
- if not e.match(space, space.w_AttributeError):
- raise
- return "?"
- if space.is_true(space.isinstance(w_mod, space.w_str)):
- return space.str_w(w_mod)
- return "?"
-
- def __repr__(self):
- # NOT_RPYTHON
- return '<W_ClassObject(%s)>' % self.name
-
-class Cache:
- def __init__(self, space):
- from pypy.interpreter.typedef import _usersubclswithfeature
- # evil
- self.cls_without_del = _usersubclswithfeature(
- space.config, W_InstanceObject, "dict", "weakref")
- self.cls_with_del = _usersubclswithfeature(
- space.config, self.cls_without_del, "del")
-
-
-def class_descr_call(space, w_self, __args__):
- self = space.interp_w(W_ClassObject, w_self)
- w_inst = self.instantiate(space)
- w_init = w_inst.getattr_from_class(space, '__init__')
- if w_init is not None:
- w_result = space.call_args(w_init, __args__)
- if not space.is_w(w_result, space.w_None):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__init__() should return None"))
- elif __args__.arguments_w or __args__.keywords:
- raise OperationError(
- space.w_TypeError,
- space.wrap("this constructor takes no arguments"))
- return w_inst
-
-W_ClassObject.typedef = TypeDef("classobj",
- __new__ = interp2app(descr_classobj_new),
- __repr__ = interp2app(W_ClassObject.descr_repr),
- __str__ = interp2app(W_ClassObject.descr_str),
- __call__ = interp2app(class_descr_call),
- __getattribute__ = interp2app(W_ClassObject.descr_getattribute),
- __setattr__ = interp2app(W_ClassObject.descr_setattr),
- __delattr__ = interp2app(W_ClassObject.descr_delattr),
- __weakref__ = make_weakref_descr(W_ClassObject),
-)
-W_ClassObject.typedef.acceptable_as_base_class = False
-
-
-def make_unary_instance_method(name):
- def unaryop(self, space):
- w_meth = self.getattr(space, name, True)
- return space.call_function(w_meth)
- unaryop.func_name = name
- return unaryop
-
-def make_binary_returning_notimplemented_instance_method(name):
- def binaryop(self, space, w_other):
- try:
- w_meth = self.getattr(space, name, False)
- except OperationError, e:
- if e.match(space, space.w_AttributeError):
- return space.w_NotImplemented
- raise
- else:
- if w_meth is None:
- return space.w_NotImplemented
- return space.call_function(w_meth, w_other)
- binaryop.func_name = name
- return binaryop
-
-def make_binary_instance_method(name):
- specialname = "__%s__" % (name, )
- rspecialname = "__r%s__" % (name, )
- objspacename = name
- if name in ['and', 'or']:
- objspacename = name + '_'
-
- def binaryop(self, space, w_other):
- w_a, w_b = _coerce_helper(space, self, w_other)
- if w_a is None:
- w_a = self
- w_b = w_other
- if w_a is self:
- w_meth = self.getattr(space, specialname, False)
- if w_meth is None:
- return space.w_NotImplemented
- return space.call_function(w_meth, w_b)
- else:
- return getattr(space, objspacename)(w_a, w_b)
- binaryop.func_name = name
-
- def rbinaryop(self, space, w_other):
- w_a, w_b = _coerce_helper(space, self, w_other)
- if w_a is None or w_a is self:
- w_meth = self.getattr(space, rspecialname, False)
- if w_meth is None:
- return space.w_NotImplemented
- return space.call_function(w_meth, w_other)
- else:
- return getattr(space, objspacename)(w_b, w_a)
- rbinaryop.func_name = "r" + name
- return binaryop, rbinaryop
-
-def _coerce_helper(space, w_self, w_other):
- try:
- w_tup = space.coerce(w_self, w_other)
- except OperationError, e:
- if not e.match(space, space.w_TypeError):
- raise
- return [None, None]
- return space.fixedview(w_tup, 2)
-
-def descr_instance_new(space, w_type, w_class, w_dict=None):
- # w_type is not used at all
- if not isinstance(w_class, W_ClassObject):
- raise OperationError(
- space.w_TypeError,
- space.wrap("instance() first arg must be class"))
- w_result = w_class.instantiate(space)
- if not space.is_w(w_dict, space.w_None):
- w_result.setdict(space, w_dict)
- return w_result
-
-class W_InstanceObject(Wrappable):
- def __init__(self, space, w_class):
- # note that user_setup is overridden by the typedef.py machinery
- self.user_setup(space, space.gettypeobject(self.typedef))
- assert isinstance(w_class, W_ClassObject)
- self.w_class = w_class
-
- def user_setup(self, space, w_subtype):
- self.space = space
-
- def set_oldstyle_class(self, space, w_class):
- if w_class is None or not isinstance(w_class, W_ClassObject):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__class__ must be set to a class"))
- self.w_class = w_class
-
- def getattr_from_class(self, space, name):
- # Look up w_name in the class dict, and call its __get__.
- # This method ignores the instance dict and the __getattr__.
- # Returns None if not found.
- assert isinstance(name, str)
- w_value = self.w_class.lookup(space, name)
- if w_value is None:
- return None
- w_descr_get = space.lookup(w_value, '__get__')
- if w_descr_get is None:
- return w_value
- return space.call_function(w_descr_get, w_value, self, self.w_class)
-
- def getattr(self, space, name, exc=True):
- # Normal getattr rules: look up w_name in the instance dict,
- # in the class dict, and then via a call to __getatttr__.
- assert isinstance(name, str)
- w_result = self.getdictvalue(space, name)
- if w_result is not None:
- return w_result
- w_result = self.getattr_from_class(space, name)
- if w_result is not None:
- return w_result
- w_meth = self.getattr_from_class(space, '__getattr__')
- if w_meth is not None:
- try:
- return space.call_function(w_meth, space.wrap(name))
- except OperationError, e:
- if not exc and e.match(space, space.w_AttributeError):
- return None # eat the AttributeError
- raise
- # not found at all
- if exc:
- raise operationerrfmt(
- space.w_AttributeError,
- "%s instance has no attribute '%s'",
- self.w_class.name, name)
- else:
- return None
-
- def descr_getattribute(self, space, w_attr):
- name = space.str_w(w_attr)
- if len(name) >= 8 and name[0] == '_':
- if name == "__dict__":
- return self.getdict(space)
- elif name == "__class__":
- return self.w_class
- return self.getattr(space, name)
-
- def descr_setattr(self, space, w_name, w_value):
- name = unwrap_attr(space, w_name)
- w_meth = self.getattr_from_class(space, '__setattr__')
- if name and name[0] == "_":
- if name == '__dict__':
- self.setdict(space, w_value)
- return
- if name == '__class__':
- self.set_oldstyle_class(space, w_value)
- return
- if name == '__del__' and w_meth is None:
- cache = space.fromcache(Cache)
- if (not isinstance(self, cache.cls_with_del)
- and self.getdictvalue(space, '__del__') is None):
- msg = ("a __del__ method added to an instance "
- "with no __del__ in the class will not be called")
- space.warn(msg, space.w_RuntimeWarning)
- if w_meth is not None:
- space.call_function(w_meth, w_name, w_value)
- else:
- self.setdictvalue(space, name, w_value)
-
- def descr_delattr(self, space, w_name):
- name = unwrap_attr(space, w_name)
- if name and name[0] == "_":
- if name == '__dict__':
- # use setdict to raise the error
- self.setdict(space, space.w_None)
- return
- elif name == '__class__':
- # use set_oldstyle_class to raise the error
- self.set_oldstyle_class(space, None)
- return
- w_meth = self.getattr_from_class(space, '__delattr__')
- if w_meth is not None:
- space.call_function(w_meth, w_name)
- else:
- if not self.deldictvalue(space, name):
- raise operationerrfmt(
- space.w_AttributeError,
- "%s instance has no attribute '%s'",
- self.w_class.name, name)
-
- def descr_repr(self, space):
- w_meth = self.getattr(space, '__repr__', False)
- if w_meth is None:
- w_class = self.w_class
- mod = w_class.get_module_string(space)
- return self.getrepr(space, "%s.%s instance" % (mod, w_class.name))
- return space.call_function(w_meth)
-
- def descr_str(self, space):
- w_meth = self.getattr(space, '__str__', False)
- if w_meth is None:
- return self.descr_repr(space)
- return space.call_function(w_meth)
-
- def descr_unicode(self, space):
- w_meth = self.getattr(space, '__unicode__', False)
- if w_meth is None:
- return self.descr_str(space)
- return space.call_function(w_meth)
-
- def descr_format(self, space, w_format_spec):
- w_meth = self.getattr(space, "__format__", False)
- if w_meth is not None:
- return space.call_function(w_meth, w_format_spec)
- else:
- if space.isinstance_w(w_format_spec, space.w_unicode):
- w_as_str = self.descr_unicode(space)
- else:
- w_as_str = self.descr_str(space)
- if space.len_w(w_format_spec) > 0:
- space.warn(
- ("object.__format__ with a non-empty format string is "
- "deprecated"),
- space.w_PendingDeprecationWarning
- )
- return space.format(w_as_str, w_format_spec)
-
- def descr_len(self, space):
- w_meth = self.getattr(space, '__len__')
- w_result = space.call_function(w_meth)
- if space.is_true(space.isinstance(w_result, space.w_int)):
- if space.is_true(space.lt(w_result, space.wrap(0))):
- raise OperationError(
- space.w_ValueError,
- space.wrap("__len__() should return >= 0"))
- return w_result
- raise OperationError(
- space.w_TypeError,
- space.wrap("__len__() should return an int"))
-
- def descr_getitem(self, space, w_key):
- w_meth = self.getattr(space, '__getitem__')
- return space.call_function(w_meth, w_key)
-
- def descr_setitem(self, space, w_key, w_value):
- w_meth = self.getattr(space, '__setitem__')
- space.call_function(w_meth, w_key, w_value)
-
- def descr_delitem(self, space, w_key):
- w_meth = self.getattr(space, '__delitem__')
- space.call_function(w_meth, w_key)
-
- def descr_iter(self, space):
- w_meth = self.getattr(space, '__iter__', False)
- if w_meth is not None:
- return space.call_function(w_meth)
- w_meth = self.getattr(space, '__getitem__', False)
- if w_meth is None:
- raise OperationError(
- space.w_TypeError,
- space.wrap("iteration over non-sequence"))
- return space.newseqiter(self)
- # XXX do I really need a __next__ method? the old implementation
- # had one, but I don't see the point
-
- def descr_call(self, space, __args__):
- w_meth = self.getattr(space, '__call__')
- return space.call_args(w_meth, __args__)
-
- def descr_nonzero(self, space):
- w_func = self.getattr(space, '__nonzero__', False)
- if w_func is None:
- w_func = self.getattr(space, '__len__', False)
- if w_func is None:
- return space.w_True
- w_result = space.call_function(w_func)
- if space.is_true(space.isinstance(w_result, space.w_int)):
- if space.is_true(space.lt(w_result, space.wrap(0))):
- raise OperationError(
- space.w_ValueError,
- space.wrap("__nonzero__() should return >= 0"))
- return w_result
- raise OperationError(
- space.w_TypeError,
- space.wrap("__nonzero__() should return an int"))
-
- def descr_cmp(self, space, w_other): # do all the work here like CPython
- w_a, w_b = _coerce_helper(space, self, w_other)
- if w_a is None:
- w_a = self
- w_b = w_other
- else:
- if (not isinstance(w_a, W_InstanceObject) and
- not isinstance(w_b, W_InstanceObject)):
- return space.cmp(w_a, w_b)
- if isinstance(w_a, W_InstanceObject):
- w_func = w_a.getattr(space, '__cmp__', False)
- if w_func is not None:
- w_res = space.call_function(w_func, w_b)
- if space.is_w(w_res, space.w_NotImplemented):
- return w_res
- try:
- res = space.int_w(w_res)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__cmp__ must return int"))
- raise
- if res > 0:
- return space.wrap(1)
- if res < 0:
- return space.wrap(-1)
- return space.wrap(0)
- if isinstance(w_b, W_InstanceObject):
- w_func = w_b.getattr(space, '__cmp__', False)
- if w_func is not None:
- w_res = space.call_function(w_func, w_a)
- if space.is_w(w_res, space.w_NotImplemented):
- return w_res
- try:
- res = space.int_w(w_res)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__cmp__ must return int"))
- raise
- if res < 0:
- return space.wrap(1)
- if res > 0:
- return space.wrap(-1)
- return space.wrap(0)
- return space.w_NotImplemented
-
- def descr_hash(self, space):
- w_func = self.getattr(space, '__hash__', False)
- if w_func is None:
- w_eq = self.getattr(space, '__eq__', False)
- w_cmp = self.getattr(space, '__cmp__', False)
- if w_eq is not None or w_cmp is not None:
- raise OperationError(space.w_TypeError,
- space.wrap("unhashable instance"))
- else:
- return space.wrap(compute_identity_hash(self))
- w_ret = space.call_function(w_func)
- if (not space.is_true(space.isinstance(w_ret, space.w_int)) and
- not space.is_true(space.isinstance(w_ret, space.w_long))):
- raise OperationError(
- space.w_TypeError,
- space.wrap("__hash__ must return int or long"))
- return w_ret
-
- def descr_int(self, space):
- w_func = self.getattr(space, '__int__', False)
- if w_func is not None:
- return space.call_function(w_func)
-
- w_truncated = space.trunc(self)
- # int() needs to return an int
- try:
- return space.int(w_truncated)
- except OperationError:
- # Raise a different error
- raise OperationError(
- space.w_TypeError,
- space.wrap("__trunc__ returned non-Integral"))
-
- def descr_long(self, space):
- w_func = self.getattr(space, '__long__', False)
- if w_func is not None:
- return space.call_function(w_func)
- return self.descr_int(space)
-
- def descr_index(self, space):
- w_func = self.getattr(space, '__index__', False)
- if w_func is not None:
- return space.call_function(w_func)
- raise OperationError(
- space.w_TypeError,
- space.wrap("object cannot be interpreted as an index"))
-
- def descr_contains(self, space, w_obj):
- w_func = self.getattr(space, '__contains__', False)
- if w_func is not None:
- return space.wrap(space.is_true(space.call_function(w_func, w_obj)))
- # now do it ourselves
- w_iter = space.iter(self)
- while 1:
- try:
- w_x = space.next(w_iter)
- except OperationError, e:
- if e.match(space, space.w_StopIteration):
- return space.w_False
- raise
- if space.eq_w(w_x, w_obj):
- return space.w_True
-
-
- def descr_pow(self, space, w_other, w_modulo=None):
- if space.is_w(w_modulo, space.w_None):
- w_a, w_b = _coerce_helper(space, self, w_other)
- if w_a is None:
- w_a = self
- w_b = w_other
- if w_a is self:
- w_func = self.getattr(space, '__pow__', False)
- if w_func is not None:
- return space.call_function(w_func, w_other)
- return space.w_NotImplemented
- else:
- return space.pow(w_a, w_b, space.w_None)
- else:
- # CPython also doesn't try coercion in this case
- w_func = self.getattr(space, '__pow__', False)
- if w_func is not None:
- return space.call_function(w_func, w_other, w_modulo)
- return space.w_NotImplemented
-
- def descr_rpow(self, space, w_other, w_modulo=None):
- if space.is_w(w_modulo, space.w_None):
- w_a, w_b = _coerce_helper(space, self, w_other)
- if w_a is None:
- w_a = self
- w_b = w_other
- if w_a is self:
- w_func = self.getattr(space, '__rpow__', False)
- if w_func is not None:
- return space.call_function(w_func, w_other)
- return space.w_NotImplemented
- else:
- return space.pow(w_b, w_a, space.w_None)
- else:
- # CPython also doesn't try coercion in this case
- w_func = self.getattr(space, '__rpow__', False)
- if w_func is not None:
- return space.call_function(w_func, w_other, w_modulo)
- return space.w_NotImplemented
-
- def descr_next(self, space):
- w_func = self.getattr(space, '__next__', False)
- if w_func is None:
- raise OperationError(space.w_TypeError, space.wrap(
- "instance has no __next__() method"))
- return space.call_function(w_func)
-
- def descr_del(self, space):
- # Note that this is called from executioncontext.UserDelAction
- # via the space.userdel() method.
- w_func = self.getdictvalue(space, '__del__')
- if w_func is None:
- w_func = self.getattr_from_class(space, '__del__')
- if w_func is not None:
- space.call_function(w_func)
-
- def descr_exit(self, space, w_type, w_value, w_tb):
- w_func = self.getattr(space, '__exit__', False)
- if w_func is not None:
- return space.call_function(w_func, w_type, w_value, w_tb)
-
-rawdict = {}
-
-# unary operations
-for op in "neg pos abs invert trunc float oct hex enter reversed".split():
- specialname = "__%s__" % (op, )
- # fool the gateway logic by giving it a real unbound method
- meth = new.instancemethod(
- make_unary_instance_method(specialname),
- None,
- W_InstanceObject)
- rawdict[specialname] = interp2app(meth)
-
-# binary operations that return NotImplemented if they fail
-# e.g. rich comparisons, coerce and inplace ops
-for op in 'eq ne gt lt ge le coerce imod iand ipow itruediv ilshift ixor irshift ifloordiv idiv isub imul iadd ior'.split():
- specialname = "__%s__" % (op, )
- # fool the gateway logic by giving it a real unbound method
- meth = new.instancemethod(
- make_binary_returning_notimplemented_instance_method(specialname),
- None,
- W_InstanceObject)
- rawdict[specialname] = interp2app(meth)
-
-for op in "or and xor lshift rshift add sub mul div mod divmod floordiv truediv".split():
- specialname = "__%s__" % (op, )
- rspecialname = "__r%s__" % (op, )
- func, rfunc = make_binary_instance_method(op)
- # fool the gateway logic by giving it a real unbound method
- meth = new.instancemethod(func, None, W_InstanceObject)
- rawdict[specialname] = interp2app(meth)
- rmeth = new.instancemethod(rfunc, None, W_InstanceObject)
- rawdict[rspecialname] = interp2app(rmeth)
-
-
-def descr_del_dict(space, w_inst):
- # use setdict to raise the error
- w_inst.setdict(space, space.w_None)
-
-dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict)
-dict_descr.name = '__dict__'
-
-W_InstanceObject.typedef = TypeDef("instance",
- __new__ = interp2app(descr_instance_new),
- __getattribute__ = interp2app(W_InstanceObject.descr_getattribute),
- __setattr__ = interp2app(W_InstanceObject.descr_setattr),
- __delattr__ = interp2app(W_InstanceObject.descr_delattr),
- __repr__ = interp2app(W_InstanceObject.descr_repr),
- __str__ = interp2app(W_InstanceObject.descr_str),
- __unicode__ = interp2app(W_InstanceObject.descr_unicode),
- __format__ = interp2app(W_InstanceObject.descr_format),
- __len__ = interp2app(W_InstanceObject.descr_len),
- __getitem__ = interp2app(W_InstanceObject.descr_getitem),
- __setitem__ = interp2app(W_InstanceObject.descr_setitem),
- __delitem__ = interp2app(W_InstanceObject.descr_delitem),
- __iter__ = interp2app(W_InstanceObject.descr_iter),
- __call__ = interp2app(W_InstanceObject.descr_call),
- __nonzero__ = interp2app(W_InstanceObject.descr_nonzero),
- __cmp__ = interp2app(W_InstanceObject.descr_cmp),
- __hash__ = interp2app(W_InstanceObject.descr_hash),
- __int__ = interp2app(W_InstanceObject.descr_int),
- __long__ = interp2app(W_InstanceObject.descr_long),
- __index__ = interp2app(W_InstanceObject.descr_index),
- __contains__ = interp2app(W_InstanceObject.descr_contains),
- __pow__ = interp2app(W_InstanceObject.descr_pow),
- __rpow__ = interp2app(W_InstanceObject.descr_rpow),
- __next__ = interp2app(W_InstanceObject.descr_next),
- __del__ = interp2app(W_InstanceObject.descr_del),
- __exit__ = interp2app(W_InstanceObject.descr_exit),
- __dict__ = dict_descr,
- **rawdict
-)
-W_InstanceObject.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/__builtin__/test/test_classobj.py b/pypy/module/__builtin__/test/test_classobj.py
deleted file mode 100644
--- a/pypy/module/__builtin__/test/test_classobj.py
+++ /dev/null
@@ -1,1083 +0,0 @@
-from __future__ import with_statement
-import py
-from pypy.conftest import gettestobjspace, option
-from pypy.interpreter import gateway
-
-
-class AppTestOldstyle(object):
-
- def test_simple(self):
- class A:
- a = 1
- assert A.__name__ == 'A'
- assert A.__bases__ == ()
- assert A.a == 1
- assert A.__dict__['a'] == 1
- a = A()
- a.b = 2
- assert a.b == 2
- assert a.a == 1
- assert a.__class__ is A
- assert a.__dict__ == {'b': 2}
-
- def test_isinstance(self):
- class A:
- pass
- class B(A):
- pass
- class C(A):
- pass
- assert isinstance(B(), A)
- assert isinstance(B(), B)
- assert not isinstance(B(), C)
- assert not isinstance(A(), B)
- assert isinstance(B(), (A, C))
- assert isinstance(B(), (C, (), (C, B)))
- assert not isinstance(B(), ())
-
- def test_issubclass(self):
- class A:
- pass
- class B(A):
- pass
- class C(A):
- pass
- assert issubclass(A, A)
- assert not issubclass(A, B)
- assert not issubclass(A, C)
- assert issubclass(B, A)
- assert issubclass(B, B)
- assert not issubclass(B, C)
-
- def test_mutate_class_special(self):
- class A:
- a = 1
- A.__name__ = 'B'
- assert A.__name__ == 'B'
- assert A.a == 1
- A.__dict__ = {'a': 5}
- assert A.a == 5
- class B:
- a = 17
- b = 18
- class C(A):
- c = 19
- assert C.a == 5
- assert C.c == 19
- C.__bases__ = (B, )
- assert C.a == 17
- assert C.b == 18
- assert C.c == 19
- C.__bases__ = (B, A)
- assert C.a == 17
- assert C.b == 18
- assert C.c == 19
- C.__bases__ = (A, B)
- assert C.a == 5
- assert C.b == 18
- assert C.c == 19
-
- def test_class_repr(self):
- d = {}
- exec "class A: pass" in d # to have no __module__
- A = d['A']
- assert repr(A).startswith("<class __builtin__.A at 0x")
- A.__name__ = 'B'
- assert repr(A).startswith("<class __builtin__.B at 0x")
- A.__module__ = 'foo'
- assert repr(A).startswith("<class foo.B at 0x")
- A.__module__ = None
- assert repr(A).startswith("<class ?.B at 0x")
- del A.__module__
- assert repr(A).startswith("<class ?.B at 0x")
-
- def test_class_str(self):
- d = {}
- exec "class A: pass" in d # to have no __module__
- A = d['A']
- assert str(A) == "__builtin__.A"
- A.__name__ = 'B'
- assert str(A) == "__builtin__.B"
- A.__module__ = 'foo'
- assert str(A) == "foo.B"
- A.__module__ = None
- assert str(A) == "B"
- del A.__module__
- assert str(A) == "B"
-
- def test_del_error_class_special(self):
- class A:
- a = 1
- raises(TypeError, "del A.__name__")
- raises(TypeError, "del A.__dict__")
- raises(TypeError, "del A.__bases__")
-
- def test_mutate_instance_special(self):
- class A:
- a = 1
- class B:
- a = 17
- b = 18
- a = A()
- assert isinstance(a, A)
- a.__class__ = B
- assert isinstance(a, B)
- assert a.a == 17
- assert a.b == 18
-
-
- def test_init(self):
- class A:
- a = 1
- def __init__(self, a):
- self.a = a
- a = A(2)
- assert a.a == 2
- class B:
- def __init__(self, a):
- return a
-
- raises(TypeError, B, 2)
-
- def test_method(self):
- class A:
- a = 1
- def f(self, a):
- return self.a + a
- a = A()
- assert a.f(2) == 3
- assert A.f(a, 2) == 3
- a.a = 5
- assert A.f(a, 2) == 7
-
- def test_inheritance(self):
- class A:
- a = 1
- b = 2
- def af(self):
- return 1
- def bf(self):
- return 2
- assert A.a == 1
- assert A.b == 2
- a = A()
- assert a.a == 1
- assert a.b == 2
- assert a.af() == 1
- assert a.bf() == 2
- assert A.af(a) == 1
- assert A.bf(a) == 2
-
- class B(A):
- a = 3
- c = 4
- def af(self):
- return 3
- def cf(self):
- return 4
- assert B.__bases__ == (A, )
- assert B.a == 3
- assert B.b == 2
- assert B.c == 4
- b = B()
- assert b.a == 3
- assert b.b == 2
- assert b.c == 4
- assert b.af() == 3
- assert b.bf() == 2
- assert b.cf() == 4
- assert B.af(b) == 3
- assert B.bf(b) == 2
- assert B.cf(b) == 4
-
- def test_inheritance_unbound_method(self):
- class A:
- def f(self):
- return 1
- raises(TypeError, A.f, 1)
- assert A.f(A()) == 1
- class B(A):
- pass
- raises(TypeError, B.f, 1)
- raises(TypeError, B.f, A())
- assert B.f(B()) == 1
-
- def test_len_getsetdelitem(self):
- class A:
- pass
- a = A()
- raises(AttributeError, len, a)
- raises(AttributeError, "a[5]")
- raises(AttributeError, "a[5] = 5")
- raises(AttributeError, "del a[5]")
- class A:
- def __init__(self):
- self.list = [1, 2, 3, 4, 5]
- def __len__(self):
- return len(self.list)
- def __getitem__(self, i):
- return self.list[i]
- def __setitem__(self, i, v):
- self.list[i] = v
- def __delitem__(self, i):
- del self.list[i]
-
- a = A()
- assert len(a) == 5
- del a[0]
- assert len(a) == 4
- assert a[0] == 2
- a[0] = 5
- assert a[0] == 5
- assert a
- assert bool(a) == True
- del a[0]
- del a[0]
- del a[0]
- del a[0]
- assert len(a) == 0
- assert not a
- assert bool(a) == False
- a = A()
- assert a[1:3] == [2, 3]
- a[1:3] = [1, 2, 3]
- assert a.list == [1, 1, 2, 3, 4, 5]
- del a[1:4]
- assert a.list == [1, 4, 5]
-
- def test_len_errors(self):
- class A:
- def __len__(self):
- return long(10)
- raises(TypeError, len, A())
- class A:
- def __len__(self):
- return -1
- raises(ValueError, len, A())
-
- def test_call(self):
- class A:
- pass
- a = A()
- raises(AttributeError, a)
- class A:
- def __call__(self, a, b):
- return a + b
- a = A()
- assert a(1, 2) == 3
-
- def test_nonzero(self):
- class A:
- pass
- a = A()
- assert a
- assert bool(a) == True
- class A:
- def __init__(self, truth):
- self.truth = truth
- def __nonzero__(self):
- return self.truth
- a = A(1)
- assert a
- assert bool(a) == True
- a = A(42)
- assert a
- assert bool(a) == True
- a = A(True)
- assert a
- assert bool(a) == True
- a = A(False)
- assert not a
- assert bool(a) == False
- a = A(0)
- assert not a
- assert bool(a) == False
- a = A(-1)
- raises(ValueError, "assert a")
- a = A("hello")
- raises(TypeError, "assert a")
-
- def test_repr(self):
- d = {}
- exec "class A: pass" in d # to have no __module__
- A = d['A']
- a = A()
- assert repr(a).startswith("<__builtin__.A instance at")
- assert str(a).startswith("<__builtin__.A instance at")
- A.__name__ = "Foo"
- assert repr(a).startswith("<__builtin__.Foo instance at")
- assert str(a).startswith("<__builtin__.Foo instance at")
- A.__module__ = "bar"
- assert repr(a).startswith("<bar.Foo instance at")
- assert str(a).startswith("<bar.Foo instance at")
- A.__module__ = None
- assert repr(a).startswith("<?.Foo instance at")
- assert str(a).startswith("<?.Foo instance at")
- del A.__module__
- assert repr(a).startswith("<?.Foo instance at")
- assert str(a).startswith("<?.Foo instance at")
- class A:
- def __repr__(self):
- return "foo"
- assert repr(A()) == "foo"
- assert str(A()) == "foo"
-
- def test_str(self):
- d = {}
- exec '''class A:
- def __str__(self):
- return "foo"
-''' in d # to have no __module__
- A = d['A']
- a = A()
- assert repr(a).startswith("<__builtin__.A instance at")
- assert str(a) == "foo"
-
- def test_iter(self):
- class A:
- def __init__(self):
- self.list = [1, 2, 3, 4, 5]
- def __iter__(self):
- return iter(self.list)
- for i, element in enumerate(A()):
- assert i + 1 == element
- class A:
- def __init__(self):
- self.list = [1, 2, 3, 4, 5]
- def __len__(self):
- return len(self.list)
- def __getitem__(self, i):
- return self.list[i]
- for i, element in enumerate(A()):
- assert i + 1 == element
-
- def test_getsetdelattr(self):
- class A:
- a = 1
- def __getattr__(self, attr):
- return attr.upper()
- a = A()
- assert a.a == 1
- a.__dict__['b'] = 4
- assert a.b == 4
- assert a.c == "C"
- class A:
- a = 1
- def __setattr__(self, attr, value):
- self.__dict__[attr.lower()] = value
- a = A()
- assert a.a == 1
- a.A = 2
- assert a.a == 2
- class A:
- a = 1
- def __delattr__(self, attr):
- del self.__dict__[attr.lower()]
- a = A()
- assert a.a == 1
- a.a = 2
- assert a.a == 2
- del a.A
- assert a.a == 1
-
- def test_instance_override(self):
- class A:
- def __str__(self):
- return "foo"
- def __str__():
- return "bar"
- a = A()
- assert str(a) == "foo"
- a.__str__ = __str__
- assert str(a) == "bar"
-
- def test_unary_method(self):
- class A:
- def __pos__(self):
- return -1
- a = A()
- assert +a == -1
-
- def test_cmp(self):
- class A:
- def __lt__(self, other):
- return True
- a = A()
- b = A()
- assert a < b
- assert b < a
- assert a < 1
-
- def test_coerce(self):
- class B:
- def __coerce__(self, other):
- return other, self
- b = B()
- assert coerce(b, 1) == (1, b)
- class B:
- pass
- raises(TypeError, coerce, B(), [])
-
- def test_binaryop(self):
- class A:
- def __add__(self, other):
- return 1 + other
- a = A()
- assert a + 1 == 2
- assert a + 1.1 == 2.1
-
- def test_binaryop_coerces(self):
- class A:
- def __add__(self, other):
- return 1 + other
- def __coerce__(self, other):
- return self, int(other)
-
- a = A()
- assert a + 1 == 2
- assert a + 1.1 == 2
-
-
- def test_binaryop_calls_coerce_always(self):
- l = []
- class A:
- def __coerce__(self, other):
- l.append(other)
-
- a = A()
- raises(TypeError, "a + 1")
- raises(TypeError, "a + 1.1")
- assert l == [1, 1.1]
-
- def test_binaryop_raises(self):
- class A:
- def __add__(self, other):
- raise this_exception
- def __iadd__(self, other):
- raise this_exception
-
- a = A()
- this_exception = ValueError
- raises(ValueError, "a + 1")
- raises(ValueError, "a += 1")
- this_exception = AttributeError
- raises(AttributeError, "a + 1")
- raises(AttributeError, "a += 1")
-
- def test_iadd(self):
- class A:
- def __init__(self):
- self.l = []
- def __iadd__(self, other):
- self.l.append(other)
- return self
- a1 = a = A()
- a += 1
- assert a is a1
- a += 2
- assert a is a1
- assert a.l == [1, 2]
-
- def test_cmp_and_coerce(self):
- class A:
- def __coerce__(self, other):
- return (1, 2)
- assert cmp(A(), 1) == -1
- class A:
- def __cmp__(self, other):
- return 1
- class B:
- pass
-
- a = A()
- b = B()
- assert cmp(a, b) == 1
- assert cmp(b, a) == -1
-
- class A:
- def __cmp__(self, other):
- return 1L
- a = A()
- assert cmp(a, b) == 1
-
- class A:
- def __cmp__(self, other):
- return "hello?"
- a = A()
- raises(TypeError, cmp, a, b)
-
- def test_hash(self):
- import sys
- class A:
- pass
- hash(A()) # does not crash
- class A:
- def __hash__(self):
- return "hello?"
- a = A()
- raises(TypeError, hash, a)
- class A:
- def __hash__(self):
- return 1
- a = A()
- assert hash(a) == 1
- class A:
- def __cmp__(self, other):
- return 1
- a = A()
- raises(TypeError, hash, a)
- class A:
- def __eq__(self, other):
- return 1
- a = A()
- raises(TypeError, hash, a)
- bigint = sys.maxint + 1
- class A: # can return long
- def __hash__(self):
- return long(bigint)
- a = A()
- assert hash(a) == -bigint
-
- def test_index(self):
- import sys
- if sys.version_info < (2, 5):
- skip("this is not supported by CPython before version 2.4")
- class A:
- def __index__(self):
- return 1
- l = [1, 2, 3]
- assert l[A()] == 2
- class A:
- pass
- raises(TypeError, "l[A()]")
-
- def test_contains(self):
- class A:
- def __contains__(self, other):
- return True
- a = A()
- assert 1 in a
- assert None in a
- class A:
- pass
- a = A()
- raises(TypeError, "1 in a")
- class A:
- def __init__(self):
- self.list = [1, 2, 3, 4, 5]
- def __iter__(self):
- return iter(self.list)
- a = A()
- for i in range(1, 6):
- assert i in a
- class A:
- def __init__(self):
- self.list = [1, 2, 3, 4, 5]
- def __len__(self):
- return len(self.list)
- def __getitem__(self, i):
- return self.list[i]
- a = A()
- for i in range(1, 6):
- assert i in a
-
- def test_pow(self):
- class A:
- def __pow__(self, other, mod=None):
- if mod is None:
- return 2 ** other
- return mod ** other
- a = A()
- assert a ** 4 == 16
- assert pow(a, 4) == 16
- assert pow(a, 4, 5) == 625
- raises(TypeError, "4 ** a")
- class A:
- def __rpow__(self, other, mod=None):
- if mod is None:
- return 2 ** other
- return mod ** other
- a = A()
- assert 4 ** a == 16
- assert pow(4, a) == 16
- raises(TypeError, "a ** 4")
- import sys
- if not hasattr(sys, 'pypy_objspaceclass'):
- skip("__rpow__(self, other, mod) seems not to work on CPython")
- assert pow(4, a, 5) == 625
-
- def test_contains_bug(self):
- class A:
- def __iter__(self):
- return self
- raises(TypeError, "1 in A()")
-
- def test_class_instantiation_bug(self):
- class A:
- pass
- _classobj = type(A)
- raises(TypeError, "class A(1, 2): pass")
- raises(TypeError, "_classobj(1, (), {})")
- raises(TypeError, "_classobj('abc', 1, {})")
- raises(TypeError, "_classobj('abc', (1, ), {})")
- raises(TypeError, "_classobj('abc', (), 3)")
-
- def test_instance_new(self):
- class A:
- b = 1
- a = A()
- a = type(a).__new__(type(a), A)
- assert a.b == 1
- a = type(a).__new__(type(a), A, None)
- assert a.b == 1
- a = type(a).__new__(type(a), A, {'c': 2})
- assert a.b == 1
- assert a.c == 2
- raises(TypeError, type(a).__new__, type(a), A, 1)
-
- def test_del(self):
- import gc
- l = []
- class A:
- def __del__(self):
- l.append(1)
- a = A()
- a = None
- gc.collect()
- gc.collect()
- gc.collect()
- assert l == [1]
- class B(A):
- pass
- b = B()
- b = None
- gc.collect()
- gc.collect()
- gc.collect()
- assert l == [1, 1]
-
- def test_catch_attributeerror_of_descriptor(self):
- def booh(self):
- raise this_exception, "booh"
-
- class E:
- __eq__ = property(booh)
- __iadd__ = property(booh)
-
- e = E()
- this_exception = AttributeError
- raises(TypeError, "e += 1")
- # does not crash
- E() == E()
- class I:
- __init__ = property(booh)
- raises(AttributeError, I)
-
- this_exception = ValueError
- raises(ValueError, "e += 1")
-
- def test_multiple_inheritance_more(self):
- l = []
- class A: # classic class
- def save(self):
- l.append("A")
- class B(A):
- pass
- class C(A):
- def save(self):
- l.append("C")
- class D(B, C):
- pass
-
- D().save()
- assert l == ['A']
-
- def test_weakref(self):
- import weakref, gc
- class A:
- pass
- a = A()
- ref = weakref.ref(a)
- assert ref() is a
- a = None
- gc.collect()
- gc.collect()
- gc.collect()
- assert ref() is None
-
- def test_next(self):
- class X:
- def __iter__(self):
- return Y()
-
- class Y:
- def next(self):
- return 3
-
- for i in X():
- assert i == 3
- break
-
- def test_cmp_returning_notimplemented(self):
- class X:
- def __cmp__(self, other):
- return NotImplemented
-
- class Y:
- pass
-
- assert X() != 5
- assert Y() != X()
-
- def test_assignment_to_del(self):
- import sys
- if not hasattr(sys, 'pypy_objspaceclass'):
- skip("assignment to __del__ doesn't give a warning in CPython")
-
- import warnings
-
- warnings.simplefilter('error', RuntimeWarning)
- try:
- class X:
- pass
- raises(RuntimeWarning, "X.__del__ = lambda self: None")
- class Y:
- pass
- raises(RuntimeWarning, "Y().__del__ = lambda self: None")
- # but the following works
- class Z:
- def __del__(self):
- pass
- Z().__del__ = lambda : None
- finally:
- warnings.simplefilter('default', RuntimeWarning)
-
- def test_context_manager(self):
- class Context:
- def __enter__(self):
- self.got_enter = True
- return 23
- def __exit__(self, exc, value, tp):
- self.got_exit = True
- c = Context()
- with c as a:
- assert c.got_enter
- assert a == 23
- assert c.got_exit
-
- def test_reverse(self):
- class X:
- def __reversed__(self):
- return [1, 2]
- assert reversed(X()) == [1, 2]
-
- def test_special_method_via_getattr(self):
- class A:
- def __getattr__(self, attr):
- print 'A getattr:', attr
- def callable(*args):
- print 'A called:', attr + repr(args)
- return attr + repr(args)
- return callable
- class B:
- def __getattr__(self, attr):
- print 'B getattr:', attr
- def callable(*args):
- print 'B called:', attr, args
- self.called = attr, args
- if attr == '__coerce__':
- return self, args[0]
- return 42
- return callable
- a = A()
- a.instancevalue = 42 # does not go via __getattr__('__setattr__')
- a.__getattr__ = "hi there, ignore me, I'm in a"
- a.__setattr__ = "hi there, ignore me, I'm in a too"
- assert a.instancevalue == 42
- A.classvalue = 123
- assert a.classvalue == 123
- assert a.foobar(5) == 'foobar(5,)'
- assert a.__dict__ == {'instancevalue': 42,
- '__getattr__': a.__getattr__,
- '__setattr__': a.__setattr__}
- assert a.__class__ is A
- # This follows the Python 2.5 rules, more precisely.
- # It is still valid in Python 2.7 too.
- assert repr(a) == '__repr__()'
- assert str(a) == '__str__()'
- assert unicode(a) == u'__unicode__()'
- b = B()
- b.__getattr__ = "hi there, ignore me, I'm in b"
- b.__setattr__ = "hi there, ignore me, I'm in b too"
- assert 'called' not in b.__dict__ # and not e.g. ('__init__', ())
- assert len(b) == 42
- assert b.called == ('__len__', ())
- assert a[5] == '__getitem__(5,)'
- b[6] = 7
- assert b.called == ('__setitem__', (6, 7))
- del b[8]
- assert b.called == ('__delitem__', (8,))
- #
- class C:
- def __getattr__(self, name):
- if name == '__iter__':
- return lambda: iter([3, 33, 333])
- raise AttributeError
- assert list(iter(C())) == [3, 33, 333]
- #
- class C:
- def __getattr__(self, name):
- if name == '__getitem__':
- return lambda n: [3, 33, 333][n]
- raise AttributeError
- assert list(iter(C())) == [3, 33, 333]
- #
- assert a[:6] == '__getslice__(0, 6)'
- b[3:5] = 7
- assert b.called == ('__setslice__', (3, 5, 7))
- del b[:-1000]
- assert b.called == ('__delslice__', (0, -958)) # adds len(b)...
- assert a(5) == '__call__(5,)'
- raises(TypeError, bool, a) # "should return an int"
- assert not not b
- #
- class C:
- def __getattr__(self, name):
- if name == '__nonzero__':
- return lambda: False
- raise AttributeError
- assert not C()
- #
- class C:
- def __getattr__(self, name):
- if name == '__len__':
- return lambda: 0
- raise AttributeError
- assert not C()
- #
- #assert cmp(b, 43) == 0 # because __eq__(43) returns 42, so True...
- # ... I will leave this case as XXX implement me
- assert hash(b) == 42
- assert range(100, 200)[b] == 142
- assert "foo" in b
- #
- class C:
- def __iter__(self):
- return self
- def __getattr__(self, name):
- if name == 'next':
- return lambda: 'the next item'
- raise AttributeError
- for x in C():
- assert x == 'the next item'
- break
- #
- # XXX a really corner case: '__del__'
- #
- import operator
- op_by_name = {"neg": operator.neg,
- "pos": operator.pos,
- "abs": abs,
- "invert": operator.invert,
- "int": int,
- "long": long}
- for opname, opfunc in op_by_name.items():
- assert opfunc(b) == 42
- called = b.called
- assert called == ("__" + opname + "__", ())
- assert oct(a) == '__oct__()'
- assert hex(a) == '__hex__()'
- #
- class JustTrunc:
- def __trunc__(self):
- return 42
- assert int(JustTrunc()) == 42
- assert long(JustTrunc()) == 42
- #
- #
- class C:
- def __getattr__(self, name):
- return lambda: 5.5
- raises(TypeError, float, b)
- assert float(C()) == 5.5
- #
- op_by_name = {'eq': operator.eq,
- 'ne': operator.ne,
- 'gt': operator.gt,
- 'lt': operator.lt,
- 'ge': operator.ge,
- 'le': operator.le,
- 'imod': operator.imod,
- 'iand': operator.iand,
- 'ipow': operator.ipow,
- 'itruediv': operator.itruediv,
- 'ilshift': operator.ilshift,
- 'ixor': operator.ixor,
- 'irshift': operator.irshift,
- 'ifloordiv': operator.ifloordiv,
- 'idiv': operator.idiv,
- 'isub': operator.isub,
- 'imul': operator.imul,
- 'iadd': operator.iadd,
- 'ior': operator.ior,
- 'or': operator.or_,
- 'and': operator.and_,
- 'xor': operator.xor,
- 'lshift': operator.lshift,
- 'rshift': operator.rshift,
- 'add': operator.add,
- 'sub': operator.sub,
- 'mul': operator.mul,
- 'div': operator.div,
- 'mod': operator.mod,
- 'divmod': divmod,
- 'floordiv': operator.floordiv,
- 'truediv': operator.truediv}
- for opname, opfunc in op_by_name.items():
- assert opfunc(b, 5) == 42
- assert b.called == ("__" + opname + "__", (5,))
- x, y = coerce(b, 5)
- assert x is b
- assert y == 5
-
- def test_cant_subclass_instance(self):
- class A:
- pass
- try:
- class B(type(A())):
- pass
- except TypeError:
- pass
- else:
- assert 0, "should have raised"
-
- def test_dict_descriptor(self):
- import sys
- if not hasattr(sys, 'pypy_objspaceclass'):
- skip("on CPython old-style instances don't have a __dict__ descriptor")
- class A:
- pass
- a = A()
- a.x = 1
- descr = type(a).__dict__['__dict__']
- assert descr.__get__(a) == {'x': 1}
- descr.__set__(a, {'x': 2})
- assert a.x == 2
- raises(TypeError, descr.__delete__, a)
-
- def test_partial_ordering(self):
- class A:
- def __lt__(self, other):
- return self
- a1 = A()
- a2 = A()
- assert (a1 < a2) is a1
- assert (a1 > a2) is a2
-
- def test_eq_order(self):
- # this gives the ordering of equality-related functions on top of
- # CPython **for old-style classes**.
- class A:
- def __eq__(self, other): return self.__class__.__name__+':A.eq'
- def __ne__(self, other): return self.__class__.__name__+':A.ne'
- def __lt__(self, other): return self.__class__.__name__+':A.lt'
- def __le__(self, other): return self.__class__.__name__+':A.le'
- def __gt__(self, other): return self.__class__.__name__+':A.gt'
- def __ge__(self, other): return self.__class__.__name__+':A.ge'
- class B:
- def __eq__(self, other): return self.__class__.__name__+':B.eq'
- def __ne__(self, other): return self.__class__.__name__+':B.ne'
- def __lt__(self, other): return self.__class__.__name__+':B.lt'
- def __le__(self, other): return self.__class__.__name__+':B.le'
- def __gt__(self, other): return self.__class__.__name__+':B.gt'
- def __ge__(self, other): return self.__class__.__name__+':B.ge'
- #
- assert (A() == B()) == 'A:A.eq'
- assert (A() != B()) == 'A:A.ne'
- assert (A() < B()) == 'A:A.lt'
- assert (A() <= B()) == 'A:A.le'
- assert (A() > B()) == 'A:A.gt'
- assert (A() >= B()) == 'A:A.ge'
- #
- assert (B() == A()) == 'B:B.eq'
- assert (B() != A()) == 'B:B.ne'
- assert (B() < A()) == 'B:B.lt'
- assert (B() <= A()) == 'B:B.le'
- assert (B() > A()) == 'B:B.gt'
- assert (B() >= A()) == 'B:B.ge'
- #
- class C(A):
- def __eq__(self, other): return self.__class__.__name__+':C.eq'
- def __ne__(self, other): return self.__class__.__name__+':C.ne'
- def __lt__(self, other): return self.__class__.__name__+':C.lt'
- def __le__(self, other): return self.__class__.__name__+':C.le'
- def __gt__(self, other): return self.__class__.__name__+':C.gt'
- def __ge__(self, other): return self.__class__.__name__+':C.ge'
- #
- assert (A() == C()) == 'A:A.eq'
- assert (A() != C()) == 'A:A.ne'
- assert (A() < C()) == 'A:A.lt'
- assert (A() <= C()) == 'A:A.le'
- assert (A() > C()) == 'A:A.gt'
- assert (A() >= C()) == 'A:A.ge'
- #
- assert (C() == A()) == 'C:C.eq'
- assert (C() != A()) == 'C:C.ne'
- assert (C() < A()) == 'C:C.lt'
- assert (C() <= A()) == 'C:C.le'
- assert (C() > A()) == 'C:C.gt'
- assert (C() >= A()) == 'C:C.ge'
- #
- class D(A):
- pass
- #
- assert (A() == D()) == 'A:A.eq'
- assert (A() != D()) == 'A:A.ne'
- assert (A() < D()) == 'A:A.lt'
- assert (A() <= D()) == 'A:A.le'
- assert (A() > D()) == 'A:A.gt'
- assert (A() >= D()) == 'A:A.ge'
- #
- assert (D() == A()) == 'D:A.eq'
- assert (D() != A()) == 'D:A.ne'
- assert (D() < A()) == 'D:A.lt'
- assert (D() <= A()) == 'D:A.le'
- assert (D() > A()) == 'D:A.gt'
- assert (D() >= A()) == 'D:A.ge'
-
-
-class AppTestOldStyleClassStrDict(object):
- def setup_class(cls):
- if option.runappdirect:
- py.test.skip("can only be run on py.py")
- def is_strdict(space, w_class):
- from pypy.objspace.std.dictmultiobject import StringDictStrategy
- w_d = w_class.getdict(space)
- return space.wrap(isinstance(w_d.strategy, StringDictStrategy))
-
- cls.w_is_strdict = cls.space.wrap(gateway.interp2app(is_strdict))
-
- def test_strdict(self):
- class A:
- a = 1
- b = 2
- assert self.is_strdict(A)
-
-class AppTestOldStyleMapDict(AppTestOldstyle):
- def setup_class(cls):
- cls.space = gettestobjspace(**{"objspace.std.withmapdict": True})
- if option.runappdirect:
- py.test.skip("can only be run on py.py")
- def has_mapdict(space, w_inst):
- return space.wrap(w_inst._get_mapdict_map() is not None)
- cls.w_has_mapdict = cls.space.wrap(gateway.interp2app(has_mapdict))
-
-
- def test_has_mapdict(self):
- class A:
- def __init__(self):
- self.x = 42
- a = A()
- assert a.x == 42
- assert self.has_mapdict(a)
-
diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -60,7 +60,6 @@
import pypy.module.cpyext.weakrefobject
import pypy.module.cpyext.funcobject
import pypy.module.cpyext.frameobject
-import pypy.module.cpyext.classobject
import pypy.module.cpyext.pypyintf
import pypy.module.cpyext.memoryobject
import pypy.module.cpyext.codecs
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -395,7 +395,7 @@
}.items():
GLOBALS['Py%s_Type#' % (cpyname, )] = ('PyTypeObject*', pypyexpr)
- for cpyname in 'Method List Int Long Dict Tuple Class'.split():
+ for cpyname in 'Method List Int Long Dict Tuple'.split():
FORWARD_DECLS.append('typedef struct { PyObject_HEAD } '
'Py%sObject' % (cpyname, ))
build_exported_objects()
diff --git a/pypy/module/cpyext/classobject.py b/pypy/module/cpyext/classobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/classobject.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (
- PyObjectFields, CANNOT_FAIL,
- cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
-from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref, Py_DecRef, make_typedescr
-from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.module.__builtin__.interp_classobj import W_ClassObject, W_InstanceObject
-
-PyClass_Check, PyClass_CheckExact = build_type_checkers("Class", W_ClassObject)
-PyInstance_Check, PyInstance_CheckExact = build_type_checkers("Instance", W_InstanceObject)
-
- at cpython_api([PyObject, PyObject], PyObject)
-def PyInstance_NewRaw(space, w_class, w_dict):
- """Create a new instance of a specific class without calling its constructor.
- class is the class of new object. The dict parameter will be used as the
- object's __dict__; if NULL, a new dictionary will be created for the
- instance."""
- if not isinstance(w_class, W_ClassObject):
- return PyErr_BadInternalCall(space)
- w_result = w_class.instantiate(space)
- if w_dict is not None:
- w_result.setdict(space, w_dict)
- return w_result
-
- at cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL)
-def _PyInstance_Lookup(space, w_instance, w_name):
- name = space.str_w(w_name)
- assert isinstance(w_instance, W_InstanceObject)
- w_result = w_instance.getdictvalue(space, name)
- if w_result is not None:
- return w_result
- return w_instance.w_class.lookup(space, name)
-
- at cpython_api([PyObject, PyObject, PyObject], PyObject)
-def PyClass_New(space, w_bases, w_dict, w_name):
- w_classobj = space.gettypefor(W_ClassObject)
- return space.call_function(w_classobj,
- w_name, w_bases, w_dict)
-
diff --git a/pypy/module/cpyext/include/pyerrors.h b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -8,7 +8,7 @@
#endif
#define PyExceptionClass_Check(x) \
- (PyClass_Check((x)) || (PyType_Check((x)) && \
+ ((PyType_Check((x)) && \
PyObject_IsSubclass((x), PyExc_BaseException)))
PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict);
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -32,7 +32,6 @@
from pypy.rlib.rstring import rsplit
from pypy.rlib.objectmodel import specialize
from pypy.module.__builtin__.abstractinst import abstract_issubclass_w
-from pypy.module.__builtin__.interp_classobj import W_ClassObject
from pypy.rlib import jit
WARN_ABOUT_MISSING_SLOT_FUNCTIONS = False
@@ -551,9 +550,6 @@
w_winner = None
w_base = None
for w_base_i in bases_w:
- if isinstance(w_base_i, W_ClassObject):
- # old-style base
- continue
assert isinstance(w_base_i, W_TypeObject)
w_candidate = solid_base(space, w_base_i)
if not w_winner:
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -5,7 +5,6 @@
from pypy.interpreter.argument import Arguments
from pypy.interpreter.typedef import default_identity_hash
from pypy.tool.sourcetools import compile2, func_with_new_name
-from pypy.module.__builtin__.interp_classobj import W_InstanceObject
from pypy.rlib.objectmodel import specialize
def object_getattribute(space):
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -410,10 +410,8 @@
self._become(new_obj)
def user_setup(self, space, w_subtype):
- from pypy.module.__builtin__.interp_classobj import W_InstanceObject
self.space = space
- assert (not self.typedef.hasdict or
- self.typedef is W_InstanceObject.typedef)
+ assert not self.typedef.hasdict
self._init_empty(w_subtype.terminator)
def getslotvalue(self, index):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -79,9 +79,6 @@
# exceptions & builtins
self.make_builtins()
- # the type of old-style classes
- self.w_classobj = self.builtin.get('__metaclass__')
-
# final setup
self.setup_builtin_modules()
# Adding transparent proxy call
diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py
--- a/pypy/objspace/std/typetype.py
+++ b/pypy/objspace/std/typetype.py
@@ -35,8 +35,6 @@
w_winner = w_typetype
for base in bases_w:
w_typ = space.type(base)
- if space.is_w(w_typ, space.w_classobj):
- continue # special-case old-style classes
if space.is_true(space.issubtype(w_winner, w_typ)):
continue
if space.is_true(space.issubtype(w_typ, w_winner)):
diff --git a/pypy/translator/geninterplevel.py b/pypy/translator/geninterplevel.py
--- a/pypy/translator/geninterplevel.py
+++ b/pypy/translator/geninterplevel.py
@@ -892,7 +892,7 @@
# XXX there seems to be no working support for member descriptors ???
type(types.GeneratorType.gi_frame):
(eval_helper, "member_descriptor", 'type(property.fdel)'),
- types.ClassType: 'space.w_classobj',
+ types.ClassType: 'space.w_type',
types.MethodType: (eval_helper, "instancemethod",
"type((lambda:42).__get__(42))"),
type(Ellipsis): (eval_helper, 'EllipsisType', 'types.EllipsisType'),
More information about the pypy-commit
mailing list