blob: 1057bd7b48752c4d4bc53d4ac02083e0cc217573 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
from typing import Protocol, TYPE_CHECKING
from lib.utils import DotDict, Point
if TYPE_CHECKING:
from lib.sew_stack import SewStack
class LayerProtocol(Protocol):
paths: 'list[list[Point]]'
config: DotDict
element: 'SewStack'
def with_protocol(protocol):
"""Include a protocol in a Mixin only for type hinting.
Normally we'd use a protocol in a mixin to indicate that we
expect certain attributes to be available on self, as
described here:
https://mypy.readthedocs.io/en/stable/more_types.html#mixin-classes
However, for some reason type-checkers then _only_ allow use of
properties on self that are defined in the protocol. For example,
this doesn't work:
class MyMixin:
def foo(self):
return "hi"
def bar(self: LayerProtocol):
thing = self.foo()
if self.config.baz == thing:
...
This fails because mypy says that "self.foo()" references unknown
attribute "foo"... even though it's defined right there in MyMixin.
This feels a little weird, but that's how it works.
Instead, we do it like this:
class MyMixin(with_protocol(LayerProtocol)):
...
"""
if TYPE_CHECKING:
return protocol
else:
return object
|