dataclass-extensions 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@ from datetime import datetime
8
8
  from enum import Enum
9
9
  from typing import Any, Callable, ClassVar, Type, TypeVar
10
10
 
11
+ from .registrable import Registrable
11
12
  from .types import *
12
13
 
13
14
  C = TypeVar("C", bound=Dataclass)
@@ -163,6 +164,10 @@ def _coerce(
163
164
  # e.g. TypedDict
164
165
  or _safe_issubclass(allowed_type, dict)
165
166
  ) and _safe_isinstance(value, dict):
167
+ if _safe_issubclass(allowed_type, Registrable):
168
+ type_name = value.get("type", allowed_type._default_type)
169
+ if type_name is not None:
170
+ allowed_type = allowed_type.get_registered_class(type_name)
166
171
  type_hints = typing.get_type_hints(allowed_type)
167
172
  kwargs = {}
168
173
  for k, v in value.items():
@@ -1,16 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
+ import sys
4
5
  import typing
5
6
  from dataclasses import dataclass
6
7
  from typing import Callable, ClassVar, Type, TypeVar
7
8
 
8
9
  R = TypeVar("R", bound="Registrable")
9
10
 
11
+ if sys.version_info < (3, 11):
12
+ # HACK: work-around for https://stackoverflow.com/q/70400639/4151392
13
+ dataclasses.InitVar.__call__ = lambda *_: None # type: ignore
14
+
10
15
 
11
16
  @dataclass
12
17
  class Registrable:
13
18
  _registry: ClassVar[dict[str, Type[Registrable]]]
19
+ _default_type: ClassVar[str | None]
14
20
 
15
21
  type: dataclasses.InitVar[str | None] = dataclasses.field(
16
22
  default=None, kw_only=True, repr=False
@@ -27,16 +33,20 @@ class Registrable:
27
33
  f"Available choices are: {list(cls._registry.keys())}"
28
34
  )
29
35
  return super().__new__(cls._registry[type])
36
+ elif cls._default_type is not None and not hasattr(cls, "registered_name"):
37
+ return super().__new__(cls._registry[cls._default_type])
30
38
  else:
31
39
  return super().__new__(cls)
32
40
 
33
41
  def __init_subclass__(cls, **kwargs):
34
42
  super().__init_subclass__(**kwargs)
35
- if not hasattr(cls, "_choice_registry"):
43
+ if not hasattr(cls, "_registry"):
36
44
  cls._registry = {}
45
+ if not hasattr(cls, "_default_type"):
46
+ cls._default_type = None
37
47
 
38
48
  @classmethod
39
- def register(cls, name: str) -> Callable[[Type[R]], Type[R]]:
49
+ def register(cls, name: str, default: bool = False) -> Callable[[Type[R]], Type[R]]:
40
50
  def register_subclass(subclass: Type[R]) -> Type[R]:
41
51
  if not issubclass(subclass, cls):
42
52
  raise TypeError(
@@ -46,6 +56,13 @@ class Registrable:
46
56
  raise TypeError(
47
57
  f"class {subclass.__name__} must be a dataclass in order to register it"
48
58
  )
59
+ if default:
60
+ if cls._default_type is not None:
61
+ raise ValueError(
62
+ f"A default implementation for {cls.__name__} has already been registered"
63
+ )
64
+ else:
65
+ cls._default_type = name
49
66
 
50
67
  fields = [
51
68
  (f.name, f.type, f) for f in dataclasses.fields(subclass) if f.name != "type" # type: ignore
@@ -94,3 +111,9 @@ class Registrable:
94
111
  @classmethod
95
112
  def get_registered_names(cls) -> list[str]:
96
113
  return list(cls._registry.keys())
114
+
115
+ @classmethod
116
+ def get_default(cls: Type[R]) -> Type[R]:
117
+ if cls._default_type is None:
118
+ raise ValueError(f"A default implementation of {cls.__name__} has not been registered")
119
+ return cls.get_registered_class(cls._default_type)
@@ -1 +1 @@
1
- VERSION = "0.1.0"
1
+ VERSION = "0.2.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataclass-extensions
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Additional functionality for Python dataclasses
5
5
  Author-email: Pete Walsh <epwalsh10@gmail.com>
6
6
  License: Apache License
@@ -0,0 +1,13 @@
1
+ dataclass_extensions/__init__.py,sha256=jpgRh5jjj9jM1tkhTVvB-aDThI2v4tAlq_WpR0-NOSI,255
2
+ dataclass_extensions/decode.py,sha256=baPXLrWznJRA-JxPpSDFLB0y4OCvpnu1qNY13gIjnSo,6622
3
+ dataclass_extensions/encode.py,sha256=rctJHAwlSnjOw0rTGbHRWigb2BT4DI3FYGiDzAjDmEQ,3233
4
+ dataclass_extensions/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ dataclass_extensions/registrable.py,sha256=TWdJ0vLkOTsw5Zm8uOk7Ueh6ZODn-q_2jht1uWRkpzE,4608
6
+ dataclass_extensions/types.py,sha256=UwSV0MKjFDaK4dlgm72vJHHr6-8QNe8jMhbTZGOMIJM,247
7
+ dataclass_extensions/utils.py,sha256=8cigzY9JDEWexWXlcMxXyf27S50-1ZPMNmn4zUSrc6k,935
8
+ dataclass_extensions/version.py,sha256=Vdi6OffDRorPQeWjvXo2MPbidl7CNworxvziT78bjl0,18
9
+ dataclass_extensions-0.2.1.dist-info/licenses/LICENSE,sha256=YvuKOpYh3COIF0yqq-nCMXtpS7mh1GyYvPVlW2j1G-M,11359
10
+ dataclass_extensions-0.2.1.dist-info/METADATA,sha256=HfEEj5f6qnWVrx7LBzosDJ2dz7fkiQBQ_ktO_UeY81w,15215
11
+ dataclass_extensions-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ dataclass_extensions-0.2.1.dist-info/top_level.txt,sha256=njfdeqLtTThNGwqnoKu4JV8J1287xGAeEwyESpoU-k8,21
13
+ dataclass_extensions-0.2.1.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- dataclass_extensions/__init__.py,sha256=jpgRh5jjj9jM1tkhTVvB-aDThI2v4tAlq_WpR0-NOSI,255
2
- dataclass_extensions/decode.py,sha256=dstNb-RU8i3jGoTlo165UlSbyG3MhAgbc-O54mdlxqo,6329
3
- dataclass_extensions/encode.py,sha256=rctJHAwlSnjOw0rTGbHRWigb2BT4DI3FYGiDzAjDmEQ,3233
4
- dataclass_extensions/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- dataclass_extensions/registrable.py,sha256=QJN-QSzxC-vxm1w_wqzRkhRr-GcPFAlIGfbbw5m1o68,3572
6
- dataclass_extensions/types.py,sha256=UwSV0MKjFDaK4dlgm72vJHHr6-8QNe8jMhbTZGOMIJM,247
7
- dataclass_extensions/utils.py,sha256=8cigzY9JDEWexWXlcMxXyf27S50-1ZPMNmn4zUSrc6k,935
8
- dataclass_extensions/version.py,sha256=CpXi3jGlx23RvRyU7iytOMZrnspdWw4yofS8lpP1AJU,18
9
- dataclass_extensions-0.1.0.dist-info/licenses/LICENSE,sha256=YvuKOpYh3COIF0yqq-nCMXtpS7mh1GyYvPVlW2j1G-M,11359
10
- dataclass_extensions-0.1.0.dist-info/METADATA,sha256=UwZk8Z5EKDiN_rdxjsDqjYcNwQHiT7qpIVVPJxUsfqY,15215
11
- dataclass_extensions-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
- dataclass_extensions-0.1.0.dist-info/top_level.txt,sha256=njfdeqLtTThNGwqnoKu4JV8J1287xGAeEwyESpoU-k8,21
13
- dataclass_extensions-0.1.0.dist-info/RECORD,,