[pypy-svn] r26812 - in pypy/dist/pypy: interpreter module/_weakref/test objspace/std
arigo at codespeak.net
arigo at codespeak.net
Fri May 5 14:38:19 CEST 2006
Author: arigo
Date: Fri May 5 14:38:18 2006
New Revision: 26812
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
pypy/dist/pypy/interpreter/typedef.py
pypy/dist/pypy/module/_weakref/test/test_weakref.py
pypy/dist/pypy/objspace/std/typeobject.py
pypy/dist/pypy/objspace/std/typetype.py
Log:
WeakrefableMixin causes trouble: in general we assume that mixins are not
before the normal base class. Factored it out in a way that still allows
a nice implementation of weakrefable built-in objects. Made functions,
methods and generators weakrefable.
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Fri May 5 14:38:18 2006
@@ -7,8 +7,7 @@
from pypy.rpython.rarithmetic import r_uint, intmask
import os
-__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root',
- 'WeakrefableMixin']
+__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root']
class W_Root(object):
@@ -78,16 +77,6 @@
def __spacebind__(self, space):
return self
-class WeakrefableMixin(object):
- _mixin_ = True
- __lifeline__ = None
-
- def getweakref(self):
- return self.__lifeline__
-
- def setweakref(self, space, weakreflifeline):
- self.__lifeline__ = weakreflifeline
-
class InternalSpaceCache(Cache):
"""A generic cache for an object space. Arbitrary information can
be attached to the space by defining a function or class 'f' which
Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py (original)
+++ pypy/dist/pypy/interpreter/typedef.py Fri May 5 14:38:18 2006
@@ -5,7 +5,7 @@
import py
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.argument import Arguments
-from pypy.interpreter.baseobjspace import Wrappable, W_Root, ObjSpace, WeakrefableMixin
+from pypy.interpreter.baseobjspace import Wrappable, W_Root, ObjSpace
from pypy.interpreter.error import OperationError
from pypy.tool.sourcetools import compile2
from pypy.rpython.objectmodel import instantiate
@@ -16,8 +16,10 @@
self.name = __name
self.base = __base
self.hasdict = '__dict__' in rawdict
+ self.weakrefable = '__weakref__' in rawdict
if __base is not None:
self.hasdict |= __base.hasdict
+ self.weakrefable |= __base.weakrefable
self.rawdict = {}
self.acceptable_as_base_class = True
# xxx used by faking
@@ -38,7 +40,6 @@
def get_unique_interplevel_subclass(cls, hasdict, wants_slots, needsdel=False,
weakrefable=False):
- weakrefable = weakrefable and not issubclass(cls, WeakrefableMixin)
key = cls, hasdict, wants_slots, needsdel, weakrefable
try:
return _subclass_cache[key]
@@ -54,8 +55,10 @@
typedef = cls.typedef
if hasdict and typedef.hasdict:
- return get_unique_interplevel_subclass(cls, False, wants_slots, wants_del, weakrefable)
-
+ hasdict = False
+ if weakrefable and typedef.weakrefable:
+ weakrefable = False
+
name = ['User']
if not hasdict:
name.append('NoDict')
@@ -69,7 +72,16 @@
name.append(cls.__name__)
name = ''.join(name)
- if wants_del:
+ if weakrefable:
+ supercls = get_unique_interplevel_subclass(cls, hasdict, wants_slots,
+ wants_del, False)
+ class Proto(object):
+ _lifeline_ = None
+ def getweakref(self):
+ return self._lifeline_
+ def setweakref(self, space, weakreflifeline):
+ self._lifeline_ = weakreflifeline
+ elif wants_del:
supercls = get_unique_interplevel_subclass(cls, hasdict, wants_slots,
False, False)
parent_destructor = getattr(cls, '__del__', None)
@@ -135,13 +147,8 @@
body = dict([(key, value)
for key, value in Proto.__dict__.items()
- if not key.startswith('_') or key == '__del__'])
-
- if weakrefable and not issubclass(supercls, WeakrefableMixin):
- subcls = type(name, (WeakrefableMixin, supercls), body)
- else:
- subcls = type(name, (supercls,), body)
-
+ if not key.startswith('__') or key == '__del__'])
+ subcls = type(name, (supercls,), body)
return subcls
def make_descr_typecheck_wrapper(func, extraargs=(), cls=None):
@@ -414,6 +421,17 @@
weakref_descr = GetSetProperty(descr_get_weakref)
weakref_descr.name = '__weakref__'
+def make_weakref_descr(cls):
+ # force the interface into the given cls
+ def getweakref(self):
+ return self._lifeline_
+ def setweakref(self, space, weakreflifeline):
+ self._lifeline_ = weakreflifeline
+ cls._lifeline_ = None
+ cls.getweakref = getweakref
+ cls.setweakref = setweakref
+ return weakref_descr
+
Code.typedef = TypeDef('internal-code',
co_name = interp_attrproperty('co_name', cls=Code),
@@ -516,6 +534,7 @@
__name__ = getset_func_name,
__dict__ = getset_func_dict,
__module__ = getset___module__,
+ __weakref__ = make_weakref_descr(Function),
# XXX func_closure, etc.pp
)
@@ -533,6 +552,7 @@
__repr__ = interp2app(Method.descr_method_repr),
__reduce__ = interp2app(Method.descr_method__reduce__,
unwrap_spec=['self', ObjSpace]),
+ __weakref__ = make_weakref_descr(Method),
# XXX getattribute/setattribute etc.pp
)
@@ -563,6 +583,7 @@
__iter__ = interp2app(GeneratorIterator.descr__iter__),
gi_running = interp_attrproperty('running', cls=GeneratorIterator),
gi_frame = interp_attrproperty('frame', cls=GeneratorIterator),
+ __weakref__ = make_weakref_descr(GeneratorIterator),
)
Cell.typedef = TypeDef("cell",
Modified: pypy/dist/pypy/module/_weakref/test/test_weakref.py
==============================================================================
--- pypy/dist/pypy/module/_weakref/test/test_weakref.py (original)
+++ pypy/dist/pypy/module/_weakref/test/test_weakref.py Fri May 5 14:38:18 2006
@@ -169,32 +169,32 @@
assert b.a == 42
def test_function_weakrefable(self):
- skip("wip")
import _weakref
def f(x):
return 42
wf = _weakref.ref(f)
- assert wf()() == 42
+ assert wf()(63) == 42
del f
assert wf() is None
def test_method_weakrefable(self):
- skip("wip")
import _weakref
class A(object):
def f(self):
return 42
a = A()
- w_unbound = _weakref.ref(A.f)
+ meth = A.f
+ w_unbound = _weakref.ref(meth)
assert w_unbound()(A()) == 42
- w_bound = _weakref.ref(A().f)
+ meth = A().f
+ w_bound = _weakref.ref(meth)
assert w_bound()() == 42
- del A
+ del meth
assert w_unbound() is None
assert w_bound() is None
def test_set_weakrefable(self):
- skip("wip")
+ skip("missing: weakrefs to interp-level sets")
import _weakref
s = set([1, 2, 3, 4])
w = _weakref.ref(s)
@@ -203,11 +203,10 @@
assert w() is None
def test_generator_weakrefable(self):
- skip("wip")
import _weakref
def f(x):
for i in range(x):
- yield x
+ yield i
g = f(10)
w = _weakref.ref(g)
r = w().next()
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Fri May 5 14:38:18 2006
@@ -2,7 +2,7 @@
from pypy.interpreter.function import Function, StaticMethod
from pypy.interpreter.argument import Arguments
from pypy.interpreter import gateway
-from pypy.interpreter.typedef import WeakrefableMixin, weakref_descr
+from pypy.interpreter.typedef import weakref_descr
from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member
from pypy.objspace.std.objecttype import object_typedef
from pypy.objspace.std.dictproxyobject import W_DictProxyObject
@@ -38,7 +38,7 @@
return "_%s%s" % (klass, name)
-class W_TypeObject(WeakrefableMixin, W_Object):
+class W_TypeObject(W_Object):
from pypy.objspace.std.typetype import type_typedef as typedef
lazyloaders = {} # can be overridden by specific instances
@@ -52,7 +52,6 @@
w_self.ensure_static__new__()
w_self.nslots = 0
w_self.needsdel = False
- w_self.weakrefable = False
w_self.w_bestbase = None
# make sure there is a __doc__ in dict_w
@@ -62,6 +61,7 @@
if overridetypedef is not None:
w_self.instancetypedef = overridetypedef
w_self.hasdict = overridetypedef.hasdict
+ w_self.weakrefable = overridetypedef.weakrefable
w_self.__flags__ = 0 # not a heaptype
if overridetypedef.base is not None:
w_self.w_bestbase = space.gettypeobject(overridetypedef.base)
@@ -102,6 +102,7 @@
instancetypedef.name))
w_self.instancetypedef = instancetypedef
w_self.hasdict = False
+ w_self.weakrefable = False
hasoldstylebase = False
w_most_derived_base_with_slots = None
w_newstyle = None
@@ -171,7 +172,7 @@
space.wrap("__dict__ slot disallowed: we already got one"))
wantdict = True
elif slot_name == '__weakref__':
- if w_self.weakrefable:
+ if wantweakref or w_self.weakrefable:
raise OperationError(space.w_TypeError,
space.wrap("__weakref__ slot disallowed: we already got one"))
@@ -313,7 +314,14 @@
return w_self.dict_w['__module__']
else:
return space.wrap('__builtin__')
-
+
+ # for now, weakref support for W_TypeObject is hard to get automatically
+ _lifeline_ = None
+ def getweakref(self):
+ return self._lifeline_
+ def setweakref(self, space, weakreflifeline):
+ self._lifeline_ = weakreflifeline
+
def call__Type(space, w_type, __args__):
# special case for type(x)
Modified: pypy/dist/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typetype.py (original)
+++ pypy/dist/pypy/objspace/std/typetype.py Fri May 5 14:38:18 2006
@@ -1,5 +1,6 @@
from pypy.interpreter.error import OperationError
from pypy.interpreter import gateway
+from pypy.interpreter.typedef import weakref_descr
from pypy.objspace.std.stdtypedef import *
def descr__new__(space, w_typetype, w_name, w_bases, w_dict):
@@ -150,4 +151,5 @@
mro = gateway.interp2app(descr_mro),
__flags__ = GetSetProperty(descr__flags),
__module__ = GetSetProperty(descr_get__module, descr_set__module),
+ __weakref__ = weakref_descr,
)
More information about the Pypy-commit
mailing list