Skip to content

Commit 68f680b

Browse files
committed
Convert the Generic/ABC metaclass hack into a generic solution
Fixes gh-1092
1 parent 6e5000a commit 68f680b

File tree

2 files changed

+17
-18
lines changed

2 files changed

+17
-18
lines changed

trio/_channel.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,8 @@ def statistics(self):
102102
)
103103

104104

105-
try:
106-
from typing import GenericMeta
107-
except ImportError:
108-
from abc import ABCMeta
109-
110-
class _GenericNoPublicConstructor(NoPublicConstructor, ABCMeta):
111-
pass
112-
else:
113-
114-
class _GenericNoPublicConstructor(NoPublicConstructor, GenericMeta):
115-
pass
116-
117-
118105
@attr.s(cmp=False, repr=False)
119-
class MemorySendChannel(SendChannel, metaclass=_GenericNoPublicConstructor):
106+
class MemorySendChannel(SendChannel, metaclass=NoPublicConstructor):
120107
_state = attr.ib()
121108
_closed = attr.ib(default=False)
122109
# This is just the tasks waiting on *this* object. As compared to
@@ -234,9 +221,7 @@ async def aclose(self):
234221

235222

236223
@attr.s(cmp=False, repr=False)
237-
class MemoryReceiveChannel(
238-
ReceiveChannel, metaclass=_GenericNoPublicConstructor
239-
):
224+
class MemoryReceiveChannel(ReceiveChannel, metaclass=NoPublicConstructor):
240225
_state = attr.ib()
241226
_closed = attr.ib(default=False)
242227
_tasks = attr.ib(factory=set)

trio/_util.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,21 @@ def __getitem__(self, _):
257257
return self
258258

259259

260-
class Final(type):
260+
# If a new class inherits from any ABC, then the new class's metaclass has to
261+
# inherit from ABCMeta. If a new class inherits from typing.Generic, and
262+
# you're using Python 3.6 or earlier, then the new class's metaclass has to
263+
# inherit from typing.GenericMeta. Some of the classes that want to use Final
264+
# or NoPublicConstructor inherit from ABCs and generics, so Final has to
265+
# inherit from these metaclasses. Fortunately, GenericMeta inherits from
266+
# ABCMeta, so inheriting from GenericMeta alone is sufficient (when it
267+
# exists at all).
268+
if hasattr(t, "GenericMeta"):
269+
BaseMeta = t.GenericMeta
270+
else:
271+
BaseMeta = ABCMeta
272+
273+
274+
class Final(BaseMeta):
261275
"""Metaclass that enforces a class to be final (i.e., subclass not allowed).
262276
263277
If a class uses this metaclass like this::

0 commit comments

Comments
 (0)