Author: Manuel Jacob
Branch: kill-multimethod
Changeset: r69426:c13b140abc63
Date: 2014-02-25 17:56 +0100
http://bitbucket.org/pypy/pypy/changeset/c13b140abc63/
Log: Kill most of pypy.objspace.std.model, move the type registration to
pypy.objspace.std.objspace.
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -584,6 +584,16 @@
_divmod, ovf2small=_divmod_ovf2small)
+def setup_prebuilt(space):
+ if space.config.objspace.std.withprebuiltint:
+ W_IntObject.PREBUILT = []
+ for i in range(space.config.objspace.std.prebuiltintfrom,
+ space.config.objspace.std.prebuiltintto):
+ W_IntObject.PREBUILT.append(W_IntObject(i))
+ else:
+ W_IntObject.PREBUILT = None
+
+
def wrapint(space, x):
if not space.config.objspace.std.withprebuiltint:
return W_IntObject(x)
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -1,232 +1,19 @@
-"""
-The full list of which Python types and which implementation we want
-to provide in this version of PyPy, along with conversion rules.
-"""
+from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.baseobjspace import W_Root, ObjSpace
-import pypy.interpreter.pycode
-import pypy.interpreter.special
-
-option_to_typename = {
- "withsmalllong" : ["smalllongobject.W_SmallLongObject"],
- "withstrbuf" : ["strbufobject.W_StringBufferObject"],
-}
IDTAG_INT = 1
IDTAG_LONG = 3
IDTAG_FLOAT = 5
IDTAG_COMPLEX = 7
-class StdTypeModel:
-
- def __init__(self, config):
- """NOT_RPYTHON: inititialization only"""
- self.config = config
- # All the Python types that we want to provide in this StdObjSpace
-
- # The object implementations that we want to 'link' into PyPy must be
- # imported here. This registers them into the multimethod tables,
- # *before* the type objects are built from these multimethod tables.
- from pypy.objspace.std import objectobject
- from pypy.objspace.std import boolobject
- from pypy.objspace.std import intobject
- from pypy.objspace.std import floatobject
- from pypy.objspace.std import complexobject
- from pypy.objspace.std import tupleobject
- from pypy.objspace.std import listobject
- from pypy.objspace.std import dictmultiobject
- from pypy.objspace.std import setobject
- from pypy.objspace.std import basestringtype
- from pypy.objspace.std import bytesobject
- from pypy.objspace.std import bytearrayobject
- from pypy.objspace.std import typeobject
- from pypy.objspace.std import sliceobject
- from pypy.objspace.std import longobject
- from pypy.objspace.std import noneobject
- from pypy.objspace.std import iterobject
- from pypy.objspace.std import unicodeobject
- from pypy.objspace.std import dictproxyobject
- from pypy.objspace.std import proxyobject
-
-
- self.pythontypes = []
- self.pythontypes.append(objectobject.W_ObjectObject.typedef)
- self.pythontypes.append(typeobject.W_TypeObject.typedef)
- self.pythontypes.append(noneobject.W_NoneObject.typedef)
- self.pythontypes.append(tupleobject.W_TupleObject.typedef)
- self.pythontypes.append(listobject.W_ListObject.typedef)
- self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
- self.pythontypes.append(setobject.W_SetObject.typedef)
- self.pythontypes.append(setobject.W_FrozensetObject.typedef)
- self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef)
- self.pythontypes.append(basestringtype.basestring_typedef)
- self.pythontypes.append(bytesobject.W_BytesObject.typedef)
- self.pythontypes.append(bytearrayobject.W_BytearrayObject.typedef)
- self.pythontypes.append(unicodeobject.W_UnicodeObject.typedef)
- self.pythontypes.append(intobject.W_IntObject.typedef)
- self.pythontypes.append(boolobject.W_BoolObject.typedef)
- self.pythontypes.append(longobject.W_LongObject.typedef)
- self.pythontypes.append(floatobject.W_FloatObject.typedef)
- self.pythontypes.append(complexobject.W_ComplexObject.typedef)
- self.pythontypes.append(sliceobject.W_SliceObject.typedef)
-
- # the set of implementation types
- self.typeorder = {
- objectobject.W_ObjectObject: [],
- # XXX: Bool/Int/Long are pythontypes but still included here
- # for delegation to Float/Complex
- boolobject.W_BoolObject: [],
- intobject.W_IntObject: [],
- floatobject.W_FloatObject: [],
- typeobject.W_TypeObject: [],
- sliceobject.W_SliceObject: [],
- longobject.W_LongObject: [],
- noneobject.W_NoneObject: [],
- complexobject.W_ComplexObject: [],
- pypy.interpreter.pycode.PyCode: [],
- pypy.interpreter.special.Ellipsis: [],
- }
-
- self.imported_but_not_registered = {
- bytesobject.W_BytesObject: True,
- }
- for option, value in config.objspace.std:
- if option.startswith("with") and option in option_to_typename:
- for classname in option_to_typename[option]:
- modname = classname[:classname.index('.')]
- classname = classname[classname.index('.')+1:]
- d = {}
- exec "from pypy.objspace.std.%s import %s" % (
- modname, classname) in d
- implcls = d[classname]
- if value:
- self.typeorder[implcls] = []
- else:
- self.imported_but_not_registered[implcls] = True
-
-
- for type in self.typeorder:
- self.typeorder[type].append((type, None))
-
- # register the order in which types are converted into each others
- # when trying to dispatch multimethods.
- # XXX build these lists a bit more automatically later
-
- if config.objspace.std.withsmalllong:
- from pypy.objspace.std import smalllongobject
- self.typeorder[smalllongobject.W_SmallLongObject] += [
- (floatobject.W_FloatObject,
smalllongobject.delegate_SmallLong2Float),
- (complexobject.W_ComplexObject,
smalllongobject.delegate_SmallLong2Complex),
- ]
-
- if config.objspace.std.withstrbuf:
- from pypy.objspace.std import strbufobject
-
- # put W_Root everywhere
- self.typeorder[W_Root] = []
- for type in self.typeorder:
- from pypy.objspace.std import stdtypedef
- if type is not W_Root and isinstance(type.typedef,
stdtypedef.StdTypeDef):
- self.typeorder[type].append((type.typedef.any, None))
- self.typeorder[type].append((W_Root, None))
-
- self._typeorder_with_empty_usersubcls = None
-
- # ____________________________________________________________
- # Prebuilt common integer values
-
- if config.objspace.std.withprebuiltint:
- intobject.W_IntObject.PREBUILT = []
- for i in range(config.objspace.std.prebuiltintfrom,
- config.objspace.std.prebuiltintto):
- intobject.W_IntObject.PREBUILT.append(intobject.W_IntObject(i))
- del i
- else:
- intobject.W_IntObject.PREBUILT = None
-
- # ____________________________________________________________
-
- def get_typeorder_with_empty_usersubcls(self):
- if self._typeorder_with_empty_usersubcls is None:
- from pypy.interpreter.typedef import enum_interplevel_subclasses
- from pypy.objspace.std import stdtypedef
- result = self.typeorder.copy()
- for cls in self.typeorder:
- if (hasattr(cls, 'typedef') and cls.typedef is not None and
- cls.typedef.acceptable_as_base_class):
- subclslist = enum_interplevel_subclasses(self.config, cls)
- for subcls in subclslist:
- if cls in subcls.__bases__: # only direct subclasses
- # for user subclasses we only accept "generic"
- # matches: "typedef.any" is the applevel-type-based
- # matching, and "W_Root" is ANY.
- matches = []
- if isinstance(cls.typedef, stdtypedef.StdTypeDef):
- matches.append((cls.typedef.any, None))
- matches.append((W_Root, None))
- result[subcls] = matches
- self._typeorder_with_empty_usersubcls = result
- return self._typeorder_with_empty_usersubcls
-
-def _op_negated(function):
- def op(space, w_1, w_2):
- return space.not_(function(space, w_1, w_2))
- return op
-
-def _op_swapped(function):
- def op(space, w_1, w_2):
- return function(space, w_2, w_1)
- return op
-
-def _op_swapped_negated(function):
- def op(space, w_1, w_2):
- return space.not_(function(space, w_2, w_1))
- return op
-
CMP_OPS = dict(lt='<', le='<=', eq='==', ne='!=', gt='>', ge='>=')
-CMP_CORRESPONDANCES = [
- ('eq', 'ne', _op_negated),
- ('lt', 'gt', _op_swapped),
- ('le', 'ge', _op_swapped),
- ('lt', 'ge', _op_negated),
- ('le', 'gt', _op_negated),
- ('lt', 'le', _op_swapped_negated),
- ('gt', 'ge', _op_swapped_negated),
- ]
-for op1, op2, value in CMP_CORRESPONDANCES[:]:
- i = CMP_CORRESPONDANCES.index((op1, op2, value))
- CMP_CORRESPONDANCES.insert(i+1, (op2, op1, value))
BINARY_BITWISE_OPS = {'and': '&', 'lshift': '<<', 'or': '|', 'rshift': '>>',
'xor': '^'}
BINARY_OPS = dict(add='+', div='/', floordiv='//', mod='%', mul='*', sub='-',
truediv='/', **BINARY_BITWISE_OPS)
COMMUTATIVE_OPS = ('add', 'mul', 'and', 'or', 'xor')
-def add_extra_comparisons():
- """
- Add the missing comparison operators if they were not explicitly
- defined: eq <-> ne and lt <-> le <-> gt <-> ge.
- We try to add them in the order defined by the CMP_CORRESPONDANCES
- table, thus favouring swapping the arguments over negating the result.
- """
- originalentries = {}
- for op in CMP_OPS.iterkeys():
- originalentries[op] = getattr(MM, op).signatures()
-
- for op1, op2, correspondance in CMP_CORRESPONDANCES:
- mirrorfunc = getattr(MM, op2)
- for types in originalentries[op1]:
- t1, t2 = types
- if t1 is t2:
- if not mirrorfunc.has_signature(types):
- functions = getattr(MM, op1).getfunctions(types)
- assert len(functions) == 1, ('Automatic'
- ' registration of comparison functions'
- ' only work when there is a single method for'
- ' the operation.')
- mirrorfunc.register(correspondance(functions[0]), *types)
-
# ____________________________________________________________
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
@@ -1,5 +1,4 @@
import __builtin__
-import types
from pypy.interpreter import special
from pypy.interpreter.baseobjspace import ObjSpace, W_Root
from pypy.interpreter.error import OperationError, oefmt
@@ -10,32 +9,29 @@
from rpython.rlib.objectmodel import instantiate, specialize,
is_annotation_constant
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib.rarithmetic import base_int, widen, is_valid_int
-from rpython.rlib.objectmodel import we_are_translated, import_from_mixin
+from rpython.rlib.objectmodel import import_from_mixin
from rpython.rlib import jit
# Object imports
+from pypy.objspace.std.basestringtype import basestring_typedef
from pypy.objspace.std.boolobject import W_BoolObject
+from pypy.objspace.std.bytearrayobject import W_BytearrayObject
from pypy.objspace.std.bytesobject import W_AbstractBytesObject,
W_BytesObject, wrapstr
-from pypy.objspace.std.bytearrayobject import W_BytearrayObject
from pypy.objspace.std.complexobject import W_ComplexObject
from pypy.objspace.std.dictmultiobject import W_DictMultiObject
from pypy.objspace.std.floatobject import W_FloatObject
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
+from pypy.objspace.std.intobject import W_IntObject, setup_prebuilt, wrapint
+from pypy.objspace.std.iterobject import W_AbstractSeqIterObject,
W_SeqIterObject
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.longobject import W_LongObject, newlong
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.objectobject import W_ObjectObject
-from pypy.objspace.std.iterobject import W_SeqIterObject
from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
from pypy.objspace.std.sliceobject import W_SliceObject
-from pypy.objspace.std.unicodeobject import W_UnicodeObject
-from pypy.objspace.std.tupleobject import W_AbstractTupleObject
+from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject
from pypy.objspace.std.typeobject import W_TypeObject
+from pypy.objspace.std.unicodeobject import W_UnicodeObject, wrapunicode
-# types
-from pypy.objspace.std.intobject import wrapint
-from pypy.objspace.std.unicodeobject import wrapunicode
class StdObjSpace(ObjSpace):
"""The standard object space, implementing a general-purpose object
@@ -43,13 +39,14 @@
import_from_mixin(DescrOperation)
def initialize(self):
- "NOT_RPYTHON: only for initializing the space."
- # setup all the object types and implementations
- self.model = model.StdTypeModel(self.config)
+ """NOT_RPYTHON: only for initializing the space
+ Setup all the object types and implementations.
+ """
+
+ setup_prebuilt(self)
self.FrameClass = frame.build_frame(self)
self.StringObjectCls = W_BytesObject
-
self.UnicodeObjectCls = W_UnicodeObject
# singletons
@@ -60,13 +57,40 @@
self.w_Ellipsis = self.wrap(special.Ellipsis(self))
# types
+ builtin_type_classes = {
+ W_BoolObject.typedef: W_BoolObject,
+ W_BytearrayObject.typedef: W_BytearrayObject,
+ W_BytesObject.typedef: W_BytesObject,
+ W_ComplexObject.typedef: W_ComplexObject,
+ W_DictMultiObject.typedef: W_DictMultiObject,
+ W_FloatObject.typedef: W_FloatObject,
+ W_IntObject.typedef: W_IntObject,
+ W_AbstractSeqIterObject.typedef: W_AbstractSeqIterObject,
+ W_ListObject.typedef: W_ListObject,
+ W_LongObject.typedef: W_LongObject,
+ W_NoneObject.typedef: W_NoneObject,
+ W_ObjectObject.typedef: W_ObjectObject,
+ W_SetObject.typedef: W_SetObject,
+ W_FrozensetObject.typedef: W_FrozensetObject,
+ W_SliceObject.typedef: W_SliceObject,
+ W_TupleObject.typedef: W_TupleObject,
+ W_TypeObject.typedef: W_TypeObject,
+ W_UnicodeObject.typedef: W_UnicodeObject,
+ }
+ if self.config.objspace.std.withstrbuf:
+ builtin_type_classes[W_BytesObject.typedef] = W_AbstractBytesObject
+
self.builtin_types = {}
- for typedef in self.model.pythontypes:
+ self._interplevel_classes = {}
+ for typedef, cls in builtin_type_classes.items():
w_type = self.gettypeobject(typedef)
self.builtin_types[typedef.name] = w_type
setattr(self, 'w_' + typedef.name, w_type)
+ self._interplevel_classes[w_type] = cls
self.builtin_types["NotImplemented"] = self.w_NotImplemented
self.builtin_types["Ellipsis"] = self.w_Ellipsis
+ self.w_basestring = self.builtin_types['basestring'] = \
+ self.gettypeobject(basestring_typedef)
# exceptions & builtins
self.make_builtins()
@@ -80,8 +104,6 @@
if self.config.objspace.std.withtproxy:
transparent.setup(self)
- self.setup_isinstance_cache()
-
def get_builtin_types(self):
return self.builtin_types
@@ -319,13 +341,6 @@
if cls.typedef.applevel_subclasses_base is not None:
cls = cls.typedef.applevel_subclasses_base
#
- if not we_are_translated():
- if issubclass(cls, model.W_Object):
- # If cls is missing from model.typeorder, then you
- # need to add it there (including the inheritance
- # relationship, if any)
- assert cls in self.model.typeorder, repr(cls)
- #
if (self.config.objspace.std.withmapdict and cls is W_ObjectObject
and not w_subtype.needsdel):
from pypy.objspace.std.mapdict import
get_subclass_of_correct_size
@@ -601,78 +616,6 @@
return True
return self.type(w_inst).issubtype(w_type)
- def setup_isinstance_cache(self):
- # This assumes that all classes in the stdobjspace implementing a
- # particular app-level type are distinguished by a common base class.
- # Alternatively, you can turn off the cache on specific classes,
- # like e.g. proxyobject. It is just a bit less performant but
- # should not have any bad effect.
- from pypy.objspace.std.model import W_Root, W_Object
- #
- # Build a dict {class: w_typeobject-or-None}. The value None is used
- # on classes that are known to be abstract base classes.
- class2type = {}
- class2type[W_Root] = None
- class2type[W_Object] = None
- for cls in self.model.typeorder.keys():
- if getattr(cls, 'typedef', None) is None:
- continue
- if getattr(cls, 'ignore_for_isinstance_cache', False):
- continue
- w_type = self.gettypefor(cls)
- w_oldtype = class2type.setdefault(cls, w_type)
- assert w_oldtype is w_type
- #
- # Build the real dict {w_typeobject: class-or-base-class}. For every
- # w_typeobject we look for the most precise common base class of all
- # the registered classes. If no such class is found, we will find
- # W_Object or W_Root, and complain. Then you must either add an
- # artificial common base class, or disable caching on one of the
- # two classes with ignore_for_isinstance_cache.
- def getmro(cls):
- while True:
- yield cls
- if cls is W_Root:
- break
- cls = cls.__bases__[0]
- self._interplevel_classes = {}
- for cls, w_type in class2type.items():
- if w_type is None:
- continue
- if w_type not in self._interplevel_classes:
- self._interplevel_classes[w_type] = cls
- else:
- cls1 = self._interplevel_classes[w_type]
- mro1 = list(getmro(cls1))
- for base in getmro(cls):
- if base in mro1:
- break
- if base in class2type and class2type[base] is not w_type:
- if class2type.get(base) is None:
- msg = ("cannot find a common interp-level base class"
- " between %r and %r" % (cls1, cls))
- else:
- msg = ("%s is a base class of both %r and %r" % (
- class2type[base], cls1, cls))
- raise AssertionError("%r: %s" % (w_type, msg))
- class2type[base] = w_type
- self._interplevel_classes[w_type] = base
-
- # register other things
- # XXX: fix automatic registration
- self._interplevel_classes[self.w_dict] = W_DictMultiObject
- self._interplevel_classes[self.w_list] = W_ListObject
- self._interplevel_classes[self.w_set] = W_SetObject
- self._interplevel_classes[self.w_tuple] = W_AbstractTupleObject
- self._interplevel_classes[self.w_sequenceiterator] = \
- W_AbstractSeqIterObject
- if self.config.objspace.std.withstrbuf:
- self._interplevel_classes[self.w_str] = W_AbstractBytesObject
- else:
- self._interplevel_classes[self.w_str] = W_BytesObject
- self._interplevel_classes[self.w_bytearray] = W_BytearrayObject
- self._interplevel_classes[self.w_unicode] = W_UnicodeObject
-
@specialize.memo()
def _get_interplevel_cls(self, w_type):
if not hasattr(self, "_interplevel_classes"):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit