-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathtypes.py
93 lines (61 loc) · 2.06 KB
/
types.py
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import types
import abc
import collections.abc
import functools
import operator
import godot
import godot.variant_types
__all__ = (
'strname',
'StringType',
'ArrryType',
'VariantType',
'StringLikeType',
'CustomCallable',
)
def _type_union_from_iter(it) -> types.UnionType:
return functools.reduce(operator.or_, it)
# XXX
strname = godot.strname
# type unions
StringType = godot.String | godot.StringName
ArrayType = _type_union_from_iter(
getattr(godot, type_name)
for type_name in sorted(godot.variant_types.__all__)
if 'Array' in type_name
)
VariantType = _type_union_from_iter(
getattr(godot, type_name)
for type_name in sorted(godot.variant_types.__all__)
)
# abstract base classes
class StringLikeType(abc.ABC):
pass
StringLikeType.register(str)
StringLikeType.register(godot.String)
StringLikeType.register(godot.StringName)
class _CustomCallableMeta(abc.ABCMeta):
def __call__(cls, *args, **kwargs):
return cls._class_call(cls, *args, **kwargs)
class CustomCallable(collections.abc.Callable, metaclass=_CustomCallableMeta):
'''Abstract base class that represents all `collections.abc.Callable`s that are not `godot.Callable`s.
If called as a function with a single argument, returns that callable unmodified, or retrieves
the custom callable from that `godot.Callable` if any.
'''
def _class_call(cls, *args, **kwargs):
# if the first argument is a `godot.Callable` try to get the custom callable from it
if args and isinstance(args[0], godot.Callable):
args = args[0].get_custom(), *args[1:]
if cls is __class__ and args and isinstance(args[0], godot.Callable | collections.abc.Callable):
# if `CustomCallable` is called directly and the first argument is a callable return it
return args[0]
else:
# otherwise create the object normally
return super(type(cls), type(cls)).__call__(cls, *args, **kwargs)
@classmethod
def __subclasshook__(cls, subclass):
if cls is __class__:
if issubclass(subclass, godot.Callable):
return False
return collections.abc.Callable.__subclasshook__(subclass)
return NotImplemented