Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch:
Changeset: r94630:622b5969fe73
Date: 2018-05-21 16:03 +0200
http://bitbucket.org/pypy/pypy/changeset/622b5969fe73/
Log: merge
diff --git a/pypy/interpreter/astcompiler/ast.py
b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -39,6 +39,9 @@
def mutate_over(self, visitor):
raise AssertionError("mutate_over() implementation not provided")
+ def to_object(self, space):
+ raise NotImplementedError("abstract base class")
+
class NodeVisitorNotImplemented(Exception):
pass
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py
b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -435,6 +435,9 @@
def mutate_over(self, visitor):
raise AssertionError("mutate_over() implementation not provided")
+ def to_object(self, space):
+ raise NotImplementedError("abstract base class")
+
class NodeVisitorNotImplemented(Exception):
pass
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -33,6 +33,7 @@
__slots__ = ('__weakref__',)
_must_be_light_finalizer_ = True
user_overridden_class = False
+ _settled_ = True
def getdict(self, space):
return None
@@ -197,6 +198,8 @@
# hooks that the mapdict implementations needs:
def _get_mapdict_map(self):
return None
+ def _mapdict_init_empty(self, terminator):
+ return None
def _set_mapdict_map(self, map):
raise NotImplementedError
def _mapdict_read_storage(self, index):
@@ -913,9 +916,11 @@
"""Unpack an iterable into a real (interpreter-level) list.
Raise an OperationError(w_ValueError) if the length is wrong."""
+ from pypy.interpreter.generator import GeneratorIterator
w_iterator = self.iter(w_iterable)
if expected_length == -1:
if self.is_generator(w_iterator):
+ assert isinstance(w_iterator, GeneratorIterator)
# special hack for speed
lst_w = []
w_iterator.unpack_into(lst_w)
diff --git a/pypy/objspace/std/dictmultiobject.py
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -301,6 +301,7 @@
"""
strategy = self.get_strategy()
strategy.move_to_end(self, w_key, last_flag)
+ # XXX this should be in the default move_to_end method!
def nondescr_popitem_first(self, space):
"""Not exposed directly to app-level, but via __pypy__.popitem_first().
@@ -498,6 +499,9 @@
def get_empty_storage(self):
raise NotImplementedError
+ def switch_to_object_strategy(self, w_dict):
+ raise NotImplementedError
+
@jit.look_inside_iff(lambda self, w_dict:
w_dict_unrolling_heuristic(w_dict))
def w_keys(self, w_dict):
@@ -584,6 +588,36 @@
def prepare_update(self, w_dict, num_extra):
pass
+ def length(self, w_dict):
+ raise NotImplementedError
+
+ def getitem(self, w_dict, w_key):
+ raise NotImplementedError
+
+ def getitem_str(self, w_dict, key):
+ raise NotImplementedError
+
+ def setitem(self, w_dict, w_key, w_value):
+ raise NotImplementedError
+
+ def setitem_str(self, w_dict, key, w_value):
+ raise NotImplementedError
+
+ def delitem(self, w_dict, w_key):
+ raise NotImplementedError
+
+ def setdefault(self, w_dict, w_key, w_default):
+ raise NotImplementedError
+
+ def iterkeys(self, w_dict):
+ raise NotImplementedError
+
+ def itervalues(self, w_dict):
+ raise NotImplementedError
+
+ def iteritems(self, w_dict):
+ raise NotImplementedError
+
def move_to_end(self, w_dict, w_key, last_flag):
# fall-back
w_value = w_dict.getitem(w_key)
@@ -807,12 +841,22 @@
class BaseKeyIterator(BaseIteratorImplementation):
next_key = _new_next('key')
+ def next_key_entry(self):
+ raise NotImplementedError
+
+
class BaseValueIterator(BaseIteratorImplementation):
next_value = _new_next('value')
+ def next_value_entry(self):
+ raise NotImplementedError
+
class BaseItemIterator(BaseIteratorImplementation):
next_item = _new_next('item')
+ def next_item_entry(self):
+ raise NotImplementedError
+
def create_iterator_classes(dictimpl):
if not hasattr(dictimpl, 'wrapkey'):
@@ -1447,6 +1491,7 @@
class W_DictMultiIterKeysObject(W_BaseDictMultiIterObject):
def descr_next(self, space):
iteratorimplementation = self.iteratorimplementation
+ assert isinstance(iteratorimplementation, BaseKeyIterator)
w_key = iteratorimplementation.next_key()
if w_key is not None:
return w_key
@@ -1455,6 +1500,7 @@
class W_DictMultiIterValuesObject(W_BaseDictMultiIterObject):
def descr_next(self, space):
iteratorimplementation = self.iteratorimplementation
+ assert isinstance(iteratorimplementation, BaseValueIterator)
w_value = iteratorimplementation.next_value()
if w_value is not None:
return w_value
@@ -1463,6 +1509,7 @@
class W_DictMultiIterItemsObject(W_BaseDictMultiIterObject):
def descr_next(self, space):
iteratorimplementation = self.iteratorimplementation
+ assert isinstance(iteratorimplementation, BaseItemIterator)
w_key, w_value = iteratorimplementation.next_item()
if w_key is not None:
return space.newtuple([w_key, w_value])
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -769,6 +769,9 @@
def __init__(self, space):
self.space = space
+ def get_empty_storage(self, sizehint):
+ raise NotImplementedError
+
def get_sizehint(self):
return -1
@@ -808,6 +811,9 @@
def getitems(self, w_list):
return self.getitems_copy(w_list)
+ def getitems_fixedsize(self, w_list):
+ raise NotImplementedError
+
def getitems_copy(self, w_list):
raise NotImplementedError
@@ -823,6 +829,9 @@
def getitems_float(self, w_list):
return None
+ def getitems_unroll(self, w_list):
+ raise NotImplementedError
+
def getstorage_copy(self, w_list):
raise NotImplementedError
@@ -856,11 +865,13 @@
raise NotImplementedError
def extend(self, w_list, w_any):
+ from pypy.interpreter.generator import GeneratorIterator
space = self.space
if type(w_any) is W_ListObject or (isinstance(w_any, W_ListObject) and
space._uses_list_iter(w_any)):
self._extend_from_list(w_list, w_any)
elif space.is_generator(w_any):
+ assert isinstance(w_any, GeneratorIterator)
w_any.unpack_into_w(w_list)
else:
self._extend_from_iterable(w_list, w_any)
@@ -1075,6 +1086,16 @@
strategy = w_list.strategy = self.space.fromcache(IntegerListStrategy)
w_list.lstorage = strategy.erase(items)
+ def step(self, w_list):
+ raise NotImplementedError
+
+ def _getitems_range(self, w_list, wrap_items):
+ raise NotImplementedError
+ _getitems_range_unroll = _getitems_range
+
+ def _getitem_range_unwrapped(self, w_list, i):
+ raise NotImplementedError
+
def wrap(self, intval):
return self.space.newint(intval)
@@ -1099,7 +1120,7 @@
w_other.lstorage = w_list.lstorage
def getitem(self, w_list, i):
- return self.wrap(self._getitem_unwrapped(w_list, i))
+ return self.wrap(self._getitem_range_unwrapped(w_list, i))
def getitems_int(self, w_list):
return self._getitems_range(w_list, False)
@@ -1189,7 +1210,7 @@
def step(self, w_list):
return 1
- def _getitem_unwrapped(self, w_list, i):
+ def _getitem_range_unwrapped(self, w_list, i):
length = self.unerase(w_list.lstorage)[0]
if i < 0:
i += length
@@ -1267,7 +1288,7 @@
def step(self, w_list):
return self.unerase(w_list.lstorage)[1]
- def _getitem_unwrapped(self, w_list, i):
+ def _getitem_range_unwrapped(self, w_list, i):
v = self.unerase(w_list.lstorage)
start = v[0]
step = v[1]
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -31,6 +31,9 @@
reprlist = [repr(w_item) for w_item in self.getkeys()]
return "<%s(%s)(%s)>" % (self.__class__.__name__, self.strategy, ',
'.join(reprlist))
+ def _newobj(self, space, w_iterable):
+ raise NotImplementedError
+
def from_storage_and_strategy(self, storage, strategy):
obj = self._newobj(self.space, None)
assert isinstance(obj, W_BaseSetObject)
@@ -702,6 +705,12 @@
#def unerase(self, storage):
# raise NotImplementedError
+ def may_contain_equal_elements(self, strategy):
+ return True
+
+ def _intersect_wrapped(self, w_set, w_other):
+ raise NotImplementedError
+
# __________________ methods called on W_SetObject _________________
def clear(self, w_set):
@@ -1622,8 +1631,8 @@
if type(w_item) is not W_IntObject:
break
else:
- w_set.strategy = space.fromcache(IntegerSetStrategy)
- w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+ strategy = w_set.strategy = space.fromcache(IntegerSetStrategy)
+ w_set.sstorage = strategy.get_storage_from_list(iterable_w)
return
# check for strings
@@ -1631,8 +1640,8 @@
if type(w_item) is not W_BytesObject:
break
else:
- w_set.strategy = space.fromcache(BytesSetStrategy)
- w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+ strategy = w_set.strategy = space.fromcache(BytesSetStrategy)
+ w_set.sstorage = strategy.get_storage_from_list(iterable_w)
return
# check for unicode
@@ -1640,8 +1649,8 @@
if type(w_item) is not W_UnicodeObject:
break
else:
- w_set.strategy = space.fromcache(UnicodeSetStrategy)
- w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+ strategy = w_set.strategy = space.fromcache(UnicodeSetStrategy)
+ w_set.sstorage = strategy.get_storage_from_list(iterable_w)
return
# check for compares by identity
@@ -1649,12 +1658,12 @@
if not space.type(w_item).compares_by_identity():
break
else:
- w_set.strategy = space.fromcache(IdentitySetStrategy)
- w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+ strategy = w_set.strategy = space.fromcache(IdentitySetStrategy)
+ w_set.sstorage = strategy.get_storage_from_list(iterable_w)
return
- w_set.strategy = space.fromcache(ObjectSetStrategy)
- w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+ strategy = w_set.strategy = space.fromcache(ObjectSetStrategy)
+ w_set.sstorage = strategy.get_storage_from_list(iterable_w)
create_set_driver = jit.JitDriver(name='create_set',
diff --git a/rpython/annotator/classdesc.py b/rpython/annotator/classdesc.py
--- a/rpython/annotator/classdesc.py
+++ b/rpython/annotator/classdesc.py
@@ -102,13 +102,24 @@
def validate(self, homedef):
s_newvalue = self.s_value
- # check for after-the-fact method additions
+ homedesc = homedef.classdesc
+ # check for method demotion and after-the-fact method additions
if isinstance(s_newvalue, SomePBC):
attr = self.name
if s_newvalue.getKind() == MethodDesc:
# is method
if homedef.classdesc.read_attribute(attr, None) is None:
- homedef.check_missing_attribute_update(attr)
+ if not homedef.check_missing_attribute_update(attr):
+ for desc in s_newvalue.descriptions:
+ if desc.selfclassdef is None:
+ print AnnotatorError(
+ "demoting method %s from %s to class "
+ "%s not allowed\n" % (self.name,
desc.originclassdef, homedef) +
+ "either you need to add an abstract method
to the base class\n" +
+ "or you need an assert isinstance(...) to
ensure the annotator " +
+ "that the instance is of the right class"
+ )
+ break
# check for attributes forbidden by slots or _attrs_
if homedef.classdesc.all_enforced_attrs is not None:
@@ -489,6 +500,7 @@
knowntype = type
instance_level = False
all_enforced_attrs = None # or a set
+ settled = False
_detect_invalid_attrs = None
def __init__(self, bookkeeper, cls,
@@ -559,6 +571,9 @@
if base is not object:
self.basedesc = bookkeeper.getdesc(base)
+ if '_settled_' in cls.__dict__:
+ self.settled = bool(cls.__dict__['_settled_'])
+
if '__slots__' in cls.__dict__ or '_attrs_' in cls.__dict__:
attrs = {}
for decl in ('__slots__', '_attrs_'):
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -2374,7 +2374,8 @@
def test_stored_bound_method_2(self):
# issue 129
class H:
- pass
+ def h(self):
+ raise NotImplementedError("abstract method")
class H1(H):
def h(self):
return 42
@@ -3049,6 +3050,7 @@
def test_slots_check(self):
class Base(object):
__slots__ = 'x'
+ def m(self): raise NotImplementedError("abstract")
class A(Base):
__slots__ = 'y'
def m(self):
@@ -3098,6 +3100,7 @@
def test_enforced_attrs_check(self):
class Base(object):
_attrs_ = 'x'
+ def m(self): raise NotImplementedError("abstract")
class A(Base):
_attrs_ = 'y'
def m(self):
@@ -3167,6 +3170,45 @@
a = self.RPythonAnnotator()
a.build_types(f, [bool])
+ def test_enforce_settled(self):
+ class A(object):
+ _settled_ = True
+
+ def m(self):
+ raise NotImplementedError
+
+ class B(A):
+
+ def m(self):
+ return 1
+
+ def n(self):
+ return 1
+
+ def fun(x):
+ if x:
+ a = A()
+ else:
+ a = B()
+
+ return a.m()
+
+ a = self.RPythonAnnotator()
+ s = a.build_types(fun, [bool])
+ assert s.knowntype == int
+
+ def fun(x):
+ if x:
+ a = A()
+ else:
+ a = B()
+
+ return a.n()
+
+ a = self.RPythonAnnotator()
+ with py.test.raises(AnnotatorError):
+ a.build_types(fun, [bool])
+
def test_float_cmp(self):
def fun(x, y):
return (x < y,
diff --git a/rpython/memory/gc/inspector.py b/rpython/memory/gc/inspector.py
--- a/rpython/memory/gc/inspector.py
+++ b/rpython/memory/gc/inspector.py
@@ -103,6 +103,9 @@
self.seen = AddressDict()
self.pending = AddressStack()
+ def processobj(self, obj):
+ raise NotImplementedError("abstract base class")
+
def delete(self):
if self.gcflag == 0:
self.seen.delete()
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -57,6 +57,9 @@
"""Return the size in bytes."""
raise NotImplementedError
+ def get_raw_address(self):
+ raise NotImplementedError
+
def __len__(self):
res = self.getlength()
assert res >= 0
@@ -163,7 +166,7 @@
def decorate(targetcls):
"""
Create and attach specialized versions of typed_{read,write}. We need
to
- do this becase the JIT codewriters mandates that base_ofs is an
+ do this because the JIT codewriters mandates that base_ofs is an
RPython constant.
"""
if targetcls.__bases__ != (GCBuffer,):
diff --git a/rpython/translator/test/snippet.py
b/rpython/translator/test/snippet.py
--- a/rpython/translator/test/snippet.py
+++ b/rpython/translator/test/snippet.py
@@ -375,7 +375,9 @@
return _getstuff(d), _getstuff(e)
class F:
- pass
+ def m(self, x):
+ raise NotImplementedError("abstract base")
+
class G(F):
def m(self, x):
return self.m2(x)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit