Author: Yannick Jadoul <[email protected]>
Branch: py3.7-bpo-31333
Changeset: r97914:4ad607fdca5d
Date: 2019-10-20 02:12 +0200
http://bitbucket.org/pypy/pypy/changeset/4ad607fdca5d/

Log:    Not importing _weakrefset anymore to implement _abc module, and
        added '_abc' to essential_modules list

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -17,7 +17,7 @@
 essential_modules = set([
     "exceptions", "_io", "sys", "builtins", "posix", "_warnings",
     "itertools", "_frozen_importlib", "operator", "_locale", "struct",
-    "thread",
+    "thread", "_abc",
 ])
 if sys.platform == "win32":
     essential_modules.add("_winreg")
diff --git a/pypy/module/_abc/app_abc.py b/pypy/module/_abc/app_abc.py
--- a/pypy/module/_abc/app_abc.py
+++ b/pypy/module/_abc/app_abc.py
@@ -3,10 +3,41 @@
 Plain Python definition of the builtin ABC-related functions.
 """
 
-from _weakrefset import WeakSet
+# Cannot use _weakrefset like in _py_abc.py, since it is not a built-in module
+from _weakref import ref
 
+# We'll make our own WeakSet instead, with only the functionality that's needed
+# This replaces the easily-forgetable calls to '_add_to_weak_set' and
+# '_in_weak_set' from the CPython implementation
+class SimpleWeakSet:
+    def __init__(self, data=None):
+        self.data = set()
+        def _remove(item, selfref=ref(self)):
+            self = selfref()
+            if self is not None:
+                self.data.discard(item)
+        self._remove = _remove
 
-_abc_invalidation_counter = 0
+    def __iter__(self):
+        # Weakref callback may remove entry from set.
+        # So we make a copy first.
+        copy = list(self.data)
+        for itemref in copy:
+            item = itemref()
+            yield item
+
+    def __contains__(self, item):
+        try:
+            wr = ref(item)
+        except TypeError:
+            return False
+        return wr in self.data
+
+    def add(self, item):
+        self.data.add(ref(item, self._remove))
+
+
+abc_invalidation_counter = 0
 
 
 def get_cache_token():
@@ -16,7 +47,7 @@
     current version of the ABC cache for virtual subclasses. The token changes
     with every call to ``register()`` on any ABC.
     """
-    return _abc_invalidation_counter
+    return abc_invalidation_counter
 
 
 def _abc_init(cls):
@@ -33,10 +64,10 @@
                 abstracts.add(name)
     cls.__abstractmethods__ = frozenset(abstracts)
     # Set up inheritance registry
-    cls._abc_registry = WeakSet()
-    cls._abc_cache = WeakSet()
-    cls._abc_negative_cache = WeakSet()
-    cls._abc_negative_cache_version = _abc_invalidation_counter
+    cls._abc_registry = SimpleWeakSet()
+    cls._abc_cache = SimpleWeakSet()
+    cls._abc_negative_cache = SimpleWeakSet()
+    cls._abc_negative_cache_version = abc_invalidation_counter
 
 
 def _abc_register(cls, subclass):
@@ -51,8 +82,8 @@
         # This would create a cycle, which is bad for the algorithm below
         raise RuntimeError("Refusing to create an inheritance cycle")
     cls._abc_registry.add(subclass)
-    global _abc_invalidation_counter
-    _abc_invalidation_counter += 1  # Invalidate negative cache
+    global abc_invalidation_counter
+    abc_invalidation_counter += 1  # Invalidate negative cache
     return subclass
 
 
@@ -64,8 +95,7 @@
         return True
     subtype = type(instance)
     if subtype is subclass:
-        if (cls._abc_negative_cache_version ==
-            _abc_invalidation_counter and
+        if (cls._abc_negative_cache_version == abc_invalidation_counter and
             subclass in cls._abc_negative_cache):
             return False
         # Fall back to the subclass check.
@@ -81,10 +111,10 @@
     if subclass in cls._abc_cache:
         return True
     # Check negative cache; may have to invalidate
-    if cls._abc_negative_cache_version < _abc_invalidation_counter:
+    if cls._abc_negative_cache_version < abc_invalidation_counter:
         # Invalidate the negative cache
-        cls._abc_negative_cache = WeakSet()
-        cls._abc_negative_cache_version = _abc_invalidation_counter
+        cls._abc_negative_cache = SimpleWeakSet()
+        cls._abc_negative_cache_version = abc_invalidation_counter
     elif subclass in cls._abc_negative_cache:
         return False
     # Check the subclass hook
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to