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

Reply via email to