jetpytools 2.0.1__py3-none-any.whl → 2.1.0__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.

Potentially problematic release.


This version of jetpytools might be problematic. Click here for more details.

jetpytools/_metadata.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Collection of stuff that's useful in general python programming"""
2
2
 
3
- __version__ = "2.0.1"
3
+ __version__ = "2.1.0"
4
4
 
5
5
  __author_name__, __author_email__ = "Jaded Encoding Thaumaturgy", "jaded.encoding.thaumaturgy@gmail.com"
6
6
  __maintainer_name__, __maintainer_email__ = __author_name__, __author_email__
jetpytools/enums/base.py CHANGED
@@ -1,23 +1,24 @@
1
1
  from __future__ import annotations
2
2
 
3
- from enum import Enum
3
+ from abc import ABCMeta
4
+ from enum import Enum, EnumMeta
4
5
  from typing import Any, Self
5
6
 
6
- from ..exceptions import CustomValueError, NotFoundEnumValue
7
+ from ..exceptions import NotFoundEnumValueError
7
8
  from ..types import FuncExcept
8
9
 
9
- __all__ = ["CustomEnum", "CustomIntEnum", "CustomStrEnum"]
10
+ __all__ = ["CustomEnum", "CustomIntEnum", "CustomStrEnum", "EnumABCMeta"]
11
+
12
+
13
+ class EnumABCMeta(EnumMeta, ABCMeta):
14
+ """Metaclass combining EnumMeta and ABCMeta to support abstract enumerations."""
10
15
 
11
16
 
12
17
  class CustomEnum(Enum):
13
18
  """Base class for custom enums."""
14
19
 
15
20
  @classmethod
16
- def _missing_(cls, value: Any) -> Self | None:
17
- return cls.from_param(value)
18
-
19
- @classmethod
20
- def from_param(cls, value: Any, func_except: FuncExcept | None = None) -> Self | None:
21
+ def from_param(cls, value: Any, func_except: FuncExcept | None = None) -> Self:
21
22
  """
22
23
  Return the enum value from a parameter.
23
24
 
@@ -28,44 +29,37 @@ class CustomEnum(Enum):
28
29
 
29
30
  :raises NotFoundEnumValue: Variable not found in the given enum.
30
31
  """
31
-
32
- if value is None:
33
- return None
34
-
35
- if func_except is None:
36
- func_except = cls.from_param
37
-
38
- if isinstance(value, cls):
39
- return value
40
-
41
- if value is cls:
42
- raise CustomValueError("You must select a member, not pass the enum!", func_except)
32
+ func_except = func_except or cls.from_param
43
33
 
44
34
  try:
45
35
  return cls(value)
46
- except Exception:
36
+ except (ValueError, TypeError):
47
37
  pass
48
38
 
49
39
  if isinstance(func_except, tuple):
50
40
  func_name, var_name = func_except
51
41
  else:
52
- func_name, var_name = func_except, str(cls)
42
+ func_name, var_name = func_except, repr(cls)
53
43
 
54
- raise NotFoundEnumValue(
44
+ raise NotFoundEnumValueError(
55
45
  'The given value for "{var_name}" argument must be a valid {enum_name}, not "{value}"!\n'
56
46
  "Valid values are: [{readable_enum}].",
57
47
  func_name,
58
48
  var_name=var_name,
59
49
  enum_name=cls,
60
50
  value=value,
61
- readable_enum=iter([f"{x.name} ({x.value})" for x in cls]),
51
+ readable_enum=(f"{name} ({value!r})" for name, value in cls.__members__.items()),
62
52
  reason=value,
63
- )
53
+ ) from None
64
54
 
65
55
 
66
56
  class CustomIntEnum(int, CustomEnum):
67
57
  """Base class for custom int enums."""
68
58
 
59
+ _value_: int
60
+
69
61
 
70
62
  class CustomStrEnum(str, CustomEnum):
71
63
  """Base class for custom str enums."""
64
+
65
+ _value_: str
jetpytools/types/utils.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import sys
4
4
  from contextlib import suppress
5
5
  from functools import wraps
6
- from inspect import Signature
6
+ from inspect import Signature, get_annotations
7
7
  from typing import (
8
8
  TYPE_CHECKING,
9
9
  Any,
@@ -498,13 +498,13 @@ class inject_kwargs_params(_InjectKwargsParamsBase[_T_co, _P, _R_co]):
498
498
 
499
499
 
500
500
  class _ComplexHash[**P, R]:
501
- __slots__ = "func"
501
+ __slots__ = "_func"
502
502
 
503
503
  def __init__(self, func: Callable[P, R]) -> None:
504
- self.func = func
504
+ self._func = func
505
505
 
506
506
  def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
507
- return self.func(*args, **kwargs)
507
+ return self._func(*args, **kwargs)
508
508
 
509
509
  @staticmethod
510
510
  def hash(*args: Any) -> int:
@@ -515,8 +515,8 @@ class _ComplexHash[**P, R]:
515
515
 
516
516
  :return: Hash of all the combined objects' hashes.
517
517
  """
518
-
519
518
  values = list[str]()
519
+
520
520
  for value in args:
521
521
  try:
522
522
  new_hash = hash(value)
@@ -531,18 +531,21 @@ class _ComplexHash[**P, R]:
531
531
  @_ComplexHash
532
532
  def complex_hash[T](cls: type[T]) -> type[T]:
533
533
  """
534
- Decorator for classes to add a ``__hash__`` method to them.
534
+ Class decorator that automatically adds a ``__hash__`` method to the target class.
535
535
 
536
- Especially useful for NamedTuples.
536
+ The generated ``__hash__`` method computes a hash value derived from:
537
+ - the class's name
538
+ - the values of all attributes listed in its type annotations.
539
+
540
+ This is particularly useful for immutable data structures (e.g., NamedTuples or dataclasses).
537
541
  """
538
542
 
539
543
  def __hash__(self: T) -> int: # noqa: N807
540
- return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in self.__annotations__))
544
+ return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in get_annotations(cls)))
541
545
 
542
- ns = cls.__dict__.copy()
543
- ns["__hash__"] = __hash__
546
+ setattr(cls, __hash__.__name__, __hash__)
544
547
 
545
- return type(cls.__name__, (cls,), ns) # pyright: ignore[reportReturnType]
548
+ return cls
546
549
 
547
550
 
548
551
  def get_subclasses[T](family: type[T], exclude: Sequence[type[T]] = []) -> list[type[T]]:
@@ -794,22 +797,33 @@ class KwargsNotNone(KwargsT):
794
797
 
795
798
 
796
799
  class SingletonMeta(type):
797
- _instances: ClassVar[dict[type[Any], Any]] = {}
800
+ _instances: ClassVar[dict[SingletonMeta, Any]] = {}
798
801
  _singleton_init: bool
799
802
 
800
803
  def __new__[MetaSelf: SingletonMeta](
801
- mcls: type[MetaSelf], name: str, bases: tuple[type, ...], namespace: dict[str, Any], **kwargs: Any
804
+ mcls: type[MetaSelf],
805
+ name: str,
806
+ bases: tuple[type, ...],
807
+ namespace: dict[str, Any],
808
+ *,
809
+ init: bool = False,
810
+ **kwargs: Any,
802
811
  ) -> MetaSelf:
803
- namespace["_singleton_init"] = kwargs.pop("init", False)
804
- return super().__new__(mcls, name, bases, namespace, **kwargs)
812
+ cls = super().__new__(mcls, name, bases, namespace, **kwargs)
813
+ cls._singleton_init = init
814
+ return cls
815
+
816
+ if not TYPE_CHECKING:
817
+
818
+ def __call__(cls, *args: Any, **kwargs: Any) -> Any:
819
+ if cls not in cls._instances:
820
+ cls._instances[cls] = obj = super().__call__(*args, **kwargs)
821
+ return obj
805
822
 
806
- def __call__(cls, *args: Any, **kwargs: Any) -> SingletonMeta:
807
- if cls not in cls._instances:
808
- cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
809
- elif cls._singleton_init:
810
- cls._instances[cls].__init__(*args, **kwargs)
823
+ if cls._singleton_init:
824
+ cls._instances[cls].__init__(*args, **kwargs)
811
825
 
812
- return cls._instances[cls]
826
+ return cls._instances[cls]
813
827
 
814
828
 
815
829
  class Singleton(metaclass=SingletonMeta):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jetpytools
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: Collection of stuff that's useful in general python programming
5
5
  Project-URL: Source Code, https://github.com/Jaded-Encoding-Thaumaturgy/jetpytools
6
6
  Project-URL: Contact, https://discord.gg/XTpc6Fa9eB
@@ -1,8 +1,8 @@
1
1
  jetpytools/__init__.py,sha256=ha_pCOMqfeIbipDRrtqKOqH3NQEpX4KwN2SskpsCGb4,114
2
- jetpytools/_metadata.py,sha256=Sh6w1MTmnsiXSW7bySj3rvnKAj6r6vq0Jf8-TqTi00Q,414
2
+ jetpytools/_metadata.py,sha256=U80yRxxkWvE0J7Cx3_B7F5QU7GPamHpYbuASsOrNYPI,414
3
3
  jetpytools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  jetpytools/enums/__init__.py,sha256=TvEt3TWmnzf2TWS_Gd6llyyXAGDKxdhdJsDgSvT7xys,41
5
- jetpytools/enums/base.py,sha256=Vuzlv84jXUCje7-yoyjucPcgkmfVkLHuuLXcmx4z1Yw,1970
5
+ jetpytools/enums/base.py,sha256=KDKzxj-nN0t6JUTZ7D0ZVqOFEgZEYUEFxkmB_7lDZ5Y,1850
6
6
  jetpytools/enums/other.py,sha256=Fwf8J98cqFQbnDsOPV90RTOJ_Ltd72Y3qVbSDzOl5Eg,1346
7
7
  jetpytools/exceptions/__init__.py,sha256=0rNEfnOuoSRUyKsutGzHFWQkgiFaK7diOT4VbRVKt9c,105
8
8
  jetpytools/exceptions/base.py,sha256=cKvND21z0McwbhpOg9oVYyMvLVa8MDs9m1g4FUbEHvM,6949
@@ -21,13 +21,13 @@ jetpytools/types/file.py,sha256=6hV332qbBtvg3p3g6tNHiSnZGp4DhtcTZm-Vap7M72k,6400
21
21
  jetpytools/types/funcs.py,sha256=arlykyVyosdjBhUTrJDfAoGBdkI5zhoJc0yINMQEonw,2804
22
22
  jetpytools/types/generic.py,sha256=LlYiD54GPi5ghjdw4wJmulrZiqv5IUnfPfyr-fk-RlA,1138
23
23
  jetpytools/types/supports.py,sha256=uZ2N7XxAa5H3QcOKStCH8fp2x6EXvoKwLQZue5xTLFY,3400
24
- jetpytools/types/utils.py,sha256=GoRx3fjHRbdQ27L4jkUb_oUXAtupGUI2FHHWp8ccEWw,29599
24
+ jetpytools/types/utils.py,sha256=aLepdNRRs5lbuTghqz7Jt_l_sstXl0wJapbUZiqUMI8,29908
25
25
  jetpytools/utils/__init__.py,sha256=_rJ-mY5PsGjBfy8Fihx_FYJfAIGSrYAYzI6Td9oFh9A,83
26
26
  jetpytools/utils/file.py,sha256=3fJxAHjIN5zdyzO0guc3jDspcs5HPG4t4cwB_ZrAhh4,10622
27
27
  jetpytools/utils/funcs.py,sha256=2jOOIUQpifQ_kTuVUSrCAi8hvCmmvieBpMTfF8XuM24,979
28
28
  jetpytools/utils/math.py,sha256=ZqsAyVNBT4LD-zqP7QxEkGwWdVfrR7YAkdv87NQTMV0,3460
29
29
  jetpytools/utils/ranges.py,sha256=RAknSZkTAYxAXdFn_CKY8xGASu7xS7Gu039DX89ugDc,1293
30
- jetpytools-2.0.1.dist-info/METADATA,sha256=c0AIK2JpabO43aUHc_3G-4wYSF4X19hcJw2goRGb-Oc,1198
31
- jetpytools-2.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- jetpytools-2.0.1.dist-info/licenses/LICENSE,sha256=l0PN-qDtXcgOB5aXP_nSUsvCK5V3o9pQCGsTzyZhKL0,1071
33
- jetpytools-2.0.1.dist-info/RECORD,,
30
+ jetpytools-2.1.0.dist-info/METADATA,sha256=Ciw5glQuXiHMS8gkV_vkkS8tp11qmy-Cbz7fa0OIc1Q,1198
31
+ jetpytools-2.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ jetpytools-2.1.0.dist-info/licenses/LICENSE,sha256=l0PN-qDtXcgOB5aXP_nSUsvCK5V3o9pQCGsTzyZhKL0,1071
33
+ jetpytools-2.1.0.dist-info/RECORD,,