jetpytools 2.0.0__tar.gz → 2.0.2__tar.gz
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-2.0.0 → jetpytools-2.0.2}/PKG-INFO +1 -1
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/_metadata.py +1 -1
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/supports.py +3 -1
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/utils.py +71 -51
- {jetpytools-2.0.0 → jetpytools-2.0.2}/.gitignore +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/LICENSE +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/README.md +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/enums/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/enums/base.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/enums/other.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/base.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/enum.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/file.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/generic.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/exceptions/module.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/functions/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/functions/funcs.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/functions/normalize.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/functions/other.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/py.typed +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/builtins.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/check.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/file.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/funcs.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/types/generic.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/utils/__init__.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/utils/file.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/utils/funcs.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/utils/math.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/jetpytools/utils/ranges.py +0 -0
- {jetpytools-2.0.0 → jetpytools-2.0.2}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jetpytools
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
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,6 +1,6 @@
|
|
|
1
1
|
"""Collection of stuff that's useful in general python programming"""
|
|
2
2
|
|
|
3
|
-
__version__ = "2.0.
|
|
3
|
+
__version__ = "2.0.2"
|
|
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__
|
|
@@ -113,14 +113,16 @@ class ComparatorFunc(Protocol):
|
|
|
113
113
|
) -> T0 | T1: ...
|
|
114
114
|
|
|
115
115
|
|
|
116
|
+
@runtime_checkable
|
|
116
117
|
class SupportsIndexing[T](Protocol):
|
|
117
118
|
def __getitem__(self, k: int) -> T: ...
|
|
118
119
|
|
|
119
120
|
|
|
121
|
+
@runtime_checkable
|
|
120
122
|
class SupportsKeysAndGetItem[KT, VT](Protocol):
|
|
121
123
|
def keys(self) -> Iterable[KT]: ...
|
|
122
124
|
|
|
123
125
|
def __getitem__(self, k: KT) -> VT: ...
|
|
124
126
|
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
SupportsFloatOrIndex = SupportsFloat | SupportsIndex
|
|
@@ -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,
|
|
@@ -192,10 +192,12 @@ class _InjectSelfBase(Generic[_T_co, _P, _R_co]):
|
|
|
192
192
|
self.args = args
|
|
193
193
|
self.kwargs = kwargs
|
|
194
194
|
|
|
195
|
-
def __get__
|
|
195
|
+
def __get__(self, instance: Any | None, owner: type | None = None) -> _InjectedSelfFunc[_T_co, _P, _R_co]: # pyright: ignore[reportGeneralTypeIssues]
|
|
196
196
|
"""
|
|
197
197
|
Return a wrapped callable that automatically injects an instance as the first argument when called.
|
|
198
198
|
"""
|
|
199
|
+
if owner is None:
|
|
200
|
+
owner = type(instance)
|
|
199
201
|
|
|
200
202
|
@wraps(self._function)
|
|
201
203
|
def _wrapper(*args: Any, **kwargs: Any) -> _R_co:
|
|
@@ -263,6 +265,9 @@ class _InjectSelfBase(Generic[_T_co, _P, _R_co]):
|
|
|
263
265
|
|
|
264
266
|
return owner(*self.args, **self.kwargs), kwargs
|
|
265
267
|
|
|
268
|
+
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co: # type: ignore[misc] # noqa: N805
|
|
269
|
+
return self_.__get__(self, type(self))(*args, **kwargs)
|
|
270
|
+
|
|
266
271
|
@property
|
|
267
272
|
def __func__(self) -> Callable[Concatenate[_T_co, _P], _R_co]:
|
|
268
273
|
"""Return the original wrapped function."""
|
|
@@ -377,10 +382,10 @@ class _InjectKwargsParamsBase(Generic[_T_co, _P, _R_co]):
|
|
|
377
382
|
self._signature = None
|
|
378
383
|
|
|
379
384
|
@overload
|
|
380
|
-
def __get__(self, instance: None, owner: type
|
|
385
|
+
def __get__(self, instance: None, owner: type) -> Self: ...
|
|
381
386
|
@overload
|
|
382
|
-
def __get__(self, instance: Any, owner: type
|
|
383
|
-
def __get__(self, instance: Any | None, owner: type
|
|
387
|
+
def __get__(self, instance: Any, owner: type | None = None) -> Callable[_P, _R_co]: ...
|
|
388
|
+
def __get__(self, instance: Any | None, owner: type | None = None) -> Any:
|
|
384
389
|
"""
|
|
385
390
|
Descriptor binding logic.
|
|
386
391
|
|
|
@@ -435,6 +440,9 @@ class _InjectKwargsParamsBase(Generic[_T_co, _P, _R_co]):
|
|
|
435
440
|
|
|
436
441
|
return wrapper
|
|
437
442
|
|
|
443
|
+
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co: # type: ignore[misc] # noqa: N805
|
|
444
|
+
return self_.__get__(self, type(self))(*args, **kwargs)
|
|
445
|
+
|
|
438
446
|
@property
|
|
439
447
|
def __func__(self) -> Callable[Concatenate[_T_co, _P], _R_co]:
|
|
440
448
|
"""Return the original wrapped function."""
|
|
@@ -467,7 +475,7 @@ class _InjectKwargsParamsBase(Generic[_T_co, _P, _R_co]):
|
|
|
467
475
|
return _wrapper
|
|
468
476
|
|
|
469
477
|
|
|
470
|
-
class inject_kwargs_params
|
|
478
|
+
class inject_kwargs_params(_InjectKwargsParamsBase[_T_co, _P, _R_co]):
|
|
471
479
|
"""
|
|
472
480
|
Descriptor that injects parameters into functions based on an instance's keyword mapping.
|
|
473
481
|
|
|
@@ -478,7 +486,7 @@ class inject_kwargs_params[T, **P, R](_InjectKwargsParamsBase[T, P, R]):
|
|
|
478
486
|
|
|
479
487
|
__slots__ = ()
|
|
480
488
|
|
|
481
|
-
class add_to_kwargs
|
|
489
|
+
class add_to_kwargs(_InjectKwargsParamsBase[_T0_co, _P0, _R0_co]):
|
|
482
490
|
"""
|
|
483
491
|
Variant of `inject_kwargs_params` that merges unused entries from `self.kwargs` into the keyword arguments
|
|
484
492
|
passed to the target function.
|
|
@@ -490,13 +498,13 @@ class inject_kwargs_params[T, **P, R](_InjectKwargsParamsBase[T, P, R]):
|
|
|
490
498
|
|
|
491
499
|
|
|
492
500
|
class _ComplexHash[**P, R]:
|
|
493
|
-
__slots__ = "
|
|
501
|
+
__slots__ = "_func"
|
|
494
502
|
|
|
495
503
|
def __init__(self, func: Callable[P, R]) -> None:
|
|
496
|
-
self.
|
|
504
|
+
self._func = func
|
|
497
505
|
|
|
498
506
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
499
|
-
return self.
|
|
507
|
+
return self._func(*args, **kwargs)
|
|
500
508
|
|
|
501
509
|
@staticmethod
|
|
502
510
|
def hash(*args: Any) -> int:
|
|
@@ -507,8 +515,8 @@ class _ComplexHash[**P, R]:
|
|
|
507
515
|
|
|
508
516
|
:return: Hash of all the combined objects' hashes.
|
|
509
517
|
"""
|
|
510
|
-
|
|
511
518
|
values = list[str]()
|
|
519
|
+
|
|
512
520
|
for value in args:
|
|
513
521
|
try:
|
|
514
522
|
new_hash = hash(value)
|
|
@@ -523,18 +531,21 @@ class _ComplexHash[**P, R]:
|
|
|
523
531
|
@_ComplexHash
|
|
524
532
|
def complex_hash[T](cls: type[T]) -> type[T]:
|
|
525
533
|
"""
|
|
526
|
-
|
|
534
|
+
Class decorator that automatically adds a ``__hash__`` method to the target class.
|
|
535
|
+
|
|
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.
|
|
527
539
|
|
|
528
|
-
|
|
540
|
+
This is particularly useful for immutable data structures (e.g., NamedTuples or dataclasses).
|
|
529
541
|
"""
|
|
530
542
|
|
|
531
543
|
def __hash__(self: T) -> int: # noqa: N807
|
|
532
|
-
return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in
|
|
544
|
+
return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in get_annotations(cls)))
|
|
533
545
|
|
|
534
|
-
|
|
535
|
-
ns["__hash__"] = __hash__
|
|
546
|
+
setattr(cls, __hash__.__name__, __hash__)
|
|
536
547
|
|
|
537
|
-
return
|
|
548
|
+
return cls
|
|
538
549
|
|
|
539
550
|
|
|
540
551
|
def get_subclasses[T](family: type[T], exclude: Sequence[type[T]] = []) -> list[type[T]]:
|
|
@@ -584,61 +595,59 @@ class classproperty_base(Generic[_T, _R_co, _T_Any]):
|
|
|
584
595
|
def __set_name__(self, owner: object, name: str) -> None:
|
|
585
596
|
self.__name__ = name
|
|
586
597
|
|
|
587
|
-
def _get_cache(self,
|
|
598
|
+
def _get_cache(self, owner: type[_T]) -> dict[str, Any]:
|
|
588
599
|
cache_key = getattr(self, "cache_key")
|
|
589
600
|
|
|
590
|
-
if not hasattr(
|
|
591
|
-
setattr(
|
|
601
|
+
if not hasattr(owner, cache_key):
|
|
602
|
+
setattr(owner, cache_key, {})
|
|
592
603
|
|
|
593
|
-
return getattr(
|
|
604
|
+
return getattr(owner, cache_key)
|
|
594
605
|
|
|
595
|
-
def __get__(self,
|
|
596
|
-
if
|
|
597
|
-
|
|
598
|
-
elif type_ is None:
|
|
599
|
-
raise NotImplementedError("Both obj and type_ are None")
|
|
606
|
+
def __get__(self, instance: Any | None, owner: type | None = None) -> _R_co:
|
|
607
|
+
if owner is None:
|
|
608
|
+
owner = type(instance)
|
|
600
609
|
|
|
601
610
|
if not isinstance(self, classproperty.cached):
|
|
602
|
-
return self.fget(
|
|
611
|
+
return self.fget(owner)
|
|
603
612
|
|
|
604
|
-
if self.__name__ in (cache := self._get_cache(
|
|
613
|
+
if self.__name__ in (cache := self._get_cache(owner)):
|
|
605
614
|
return cache[self.__name__]
|
|
606
615
|
|
|
607
|
-
value = self.fget(
|
|
616
|
+
value = self.fget(owner)
|
|
608
617
|
cache[self.__name__] = value
|
|
609
618
|
return value
|
|
610
619
|
|
|
611
|
-
def __set__(self,
|
|
620
|
+
def __set__(self, instance: Any, value: _T_Any) -> None:
|
|
612
621
|
if not self.fset:
|
|
613
622
|
raise AttributeError(
|
|
614
|
-
f'classproperty with getter "{self.__name__}" of "{
|
|
623
|
+
f'classproperty with getter "{self.__name__}" of "{instance.__class__.__name__}" object has no setter.'
|
|
615
624
|
)
|
|
616
625
|
|
|
617
|
-
|
|
626
|
+
owner = type(instance)
|
|
618
627
|
|
|
619
628
|
if not isinstance(self, classproperty.cached):
|
|
620
|
-
return self.fset(
|
|
629
|
+
return self.fset(owner, value)
|
|
621
630
|
|
|
622
|
-
if self.__name__ in (cache := self._get_cache(
|
|
631
|
+
if self.__name__ in (cache := self._get_cache(owner)):
|
|
623
632
|
del cache[self.__name__]
|
|
624
633
|
|
|
625
|
-
self.fset(
|
|
634
|
+
self.fset(owner, value)
|
|
626
635
|
|
|
627
|
-
def __delete__(self,
|
|
636
|
+
def __delete__(self, instance: Any) -> None:
|
|
628
637
|
if not self.fdel:
|
|
629
638
|
raise AttributeError(
|
|
630
|
-
f'classproperty with getter "{self.__name__}" of "{
|
|
639
|
+
f'classproperty with getter "{self.__name__}" of "{instance.__class__.__name__}" object has no deleter.'
|
|
631
640
|
)
|
|
632
641
|
|
|
633
|
-
|
|
642
|
+
owner = type(instance)
|
|
634
643
|
|
|
635
644
|
if not isinstance(self, classproperty.cached):
|
|
636
|
-
return self.fdel(
|
|
645
|
+
return self.fdel(owner)
|
|
637
646
|
|
|
638
|
-
if self.__name__ in (cache := self._get_cache(
|
|
647
|
+
if self.__name__ in (cache := self._get_cache(owner)):
|
|
639
648
|
del cache[self.__name__]
|
|
640
649
|
|
|
641
|
-
self.fdel(
|
|
650
|
+
self.fdel(owner)
|
|
642
651
|
|
|
643
652
|
|
|
644
653
|
class classproperty(classproperty_base[_T, _R_co, _T_Any]):
|
|
@@ -788,22 +797,33 @@ class KwargsNotNone(KwargsT):
|
|
|
788
797
|
|
|
789
798
|
|
|
790
799
|
class SingletonMeta(type):
|
|
791
|
-
_instances: ClassVar[dict[
|
|
800
|
+
_instances: ClassVar[dict[SingletonMeta, Any]] = {}
|
|
792
801
|
_singleton_init: bool
|
|
793
802
|
|
|
794
803
|
def __new__[MetaSelf: SingletonMeta](
|
|
795
|
-
mcls: type[MetaSelf],
|
|
804
|
+
mcls: type[MetaSelf],
|
|
805
|
+
name: str,
|
|
806
|
+
bases: tuple[type, ...],
|
|
807
|
+
namespace: dict[str, Any],
|
|
808
|
+
*,
|
|
809
|
+
init: bool = False,
|
|
810
|
+
**kwargs: Any,
|
|
796
811
|
) -> MetaSelf:
|
|
797
|
-
|
|
798
|
-
|
|
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
|
|
799
822
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
|
|
803
|
-
elif cls._singleton_init:
|
|
804
|
-
cls._instances[cls].__init__(*args, **kwargs)
|
|
823
|
+
if cls._singleton_init:
|
|
824
|
+
cls._instances[cls].__init__(*args, **kwargs)
|
|
805
825
|
|
|
806
|
-
|
|
826
|
+
return cls._instances[cls]
|
|
807
827
|
|
|
808
828
|
|
|
809
829
|
class Singleton(metaclass=SingletonMeta):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|