Commit eb9cc5be authored by Jason Madden's avatar Jason Madden

Fix ABCs in the MRO of gevent.local. Fixes #1201

parent 1e4e22d8
......@@ -12,6 +12,9 @@
- Update autoconf's config.guess and config.sub to the latest versions
for c-ares and libev.
- :class:`gevent.local.local` subclasses that mix-in ABCs can be instantiated.
Reported in :issue:`1201` by Bob Jordan.
1.3b2 (2018-05-03)
==================
......
......@@ -102,7 +102,7 @@ cdef inline dict _local_get_dict(local self)
@cython.locals(entry=_localimpl_dict_entry)
cdef _local__copy_dict_from(local self, _localimpl impl, dict duplicate)
@cython.locals(mro=list, base=type, gets=set, dels=set, set_or_del=set,
@cython.locals(mro=list, gets=set, dels=set, set_or_del=set,
type_self=type, type_attr=type,
sets=set)
cdef tuple _local_find_descriptors(local self)
......
......@@ -538,8 +538,9 @@ def _local_find_descriptors(self):
# return other class attributes. So we can't use getattr, and instead
# walk up the dicts
for base in mro:
if attr_name in base.__dict__:
attr = base.__dict__[attr_name]
bd = base.__dict__
if attr_name in bd:
attr = bd[attr_name]
break
else:
raise AttributeError(attr_name)
......
......@@ -7,6 +7,10 @@ from gevent import monkey; monkey.patch_all()
from threading import local
from threading import Thread
try:
from collections.abc import Mapping
except ImportError:
from collections import Mapping
class ReadProperty(object):
"""A property that can be overridden"""
......@@ -68,6 +72,18 @@ class WithGetattr(local):
return 42
return super(WithGetattr, self).__getattr__(name)
class LocalWithABC(local, Mapping):
def __getitem__(self, name):
return self.d[name]
def __iter__(self):
return iter(self.d)
def __len__(self):
return len(self.d)
class TestGeventLocal(greentest.TestCase):
# pylint:disable=attribute-defined-outside-init,blacklisted-name
......@@ -325,6 +341,17 @@ class TestGeventLocal(greentest.TestCase):
self.assertEqual(results,
[((MyLocal, id(x)), {'foo': 42})])
def test_local_with_abc(self):
# an ABC (or generally any non-exact-type) in the MRO doesn't
# break things. See https://github.com/gevent/gevent/issues/1201
x = LocalWithABC()
x.d = {'a': 1}
self.assertEqual({'a': 1}, x.d)
# The ABC part works
self.assertIn('a', x.d)
self.assertEqual(['a'], list(x.keys()))
try:
from zope import interface
except ImportError:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment