-
-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathdescription.py
More file actions
66 lines (54 loc) · 2.09 KB
/
description.py
File metadata and controls
66 lines (54 loc) · 2.09 KB
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
"""Human-readable descriptions"""
from __future__ import annotations
from typing import Any
__all__ = [
"Description",
"is_description",
"register_description",
"unregister_description",
]
class Description:
"""Type checker for human-readable descriptions.
By default, only ordinary strings are accepted as descriptions,
but you can register() other classes that will also be allowed,
e.g. to support lazy string objects that are evaluated only at runtime.
If you register(object), any object will be allowed as description.
"""
bases: type | tuple[type, ...] = str
@classmethod
def isinstance(cls, obj: Any) -> bool:
"""Check whether this is an instance of a description."""
return isinstance(obj, cls.bases)
@classmethod
def register(cls, base: type) -> None:
"""Register a class that shall be accepted as a description."""
if not isinstance(base, type):
msg = "Only types can be registered."
raise TypeError(msg)
if base is object:
cls.bases = object
elif cls.bases is object:
cls.bases = base
elif not isinstance(cls.bases, tuple):
if base is not cls.bases:
cls.bases = (cls.bases, base)
elif base not in cls.bases:
cls.bases += (base,)
@classmethod
def unregister(cls, base: type) -> None:
"""Unregister a class that shall no more be accepted as a description."""
if not isinstance(base, type):
msg = "Only types can be unregistered."
raise TypeError(msg)
if isinstance(cls.bases, tuple):
if base in cls.bases: # pragma: no branch
cls.bases = tuple(b for b in cls.bases if b is not base)
if not cls.bases:
cls.bases = object
elif len(cls.bases) == 1:
cls.bases = cls.bases[0]
elif cls.bases is base:
cls.bases = object
is_description = Description.isinstance
register_description = Description.register
unregister_description = Description.unregister