jetpytools 1.7.2__py3-none-any.whl → 1.7.4__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__ = "1.7.2"
3
+ __version__ = "1.7.4"
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__
@@ -6,7 +6,7 @@ from typing import Any, Callable, Literal, TypeAlias, Union
6
6
  from .builtins import F, SingleOrArr, SingleOrArrOpt
7
7
  from .supports import SupportsString
8
8
 
9
- __all__ = ["MISSING", "DataType", "FuncExcept", "MissingT", "PassthroughC", "StrArr", "StrArrOpt"]
9
+ __all__ = ["MISSING", "DataType", "FuncExcept", "FuncExceptT", "MissingT", "PassthroughC", "StrArr", "StrArrOpt"]
10
10
 
11
11
 
12
12
  class _MissingType(Enum):
jetpytools/types/utils.py CHANGED
@@ -23,9 +23,9 @@ from typing import (
23
23
  overload,
24
24
  )
25
25
 
26
- from typing_extensions import Self, deprecated
26
+ from typing_extensions import Self, TypeVar, deprecated
27
27
 
28
- from .builtins import F0, F1, P0, P1, R0, R1, T0, KwargsT, P, R, R0_co, R1_co, R_co, T, T0_co, T1_co, T_co
28
+ from .builtins import F0, F1, P0, P1, R0, T0, KwargsT, P, R, R0_co, R1_co, R_co, T, T0_co, T1_co, T_co
29
29
 
30
30
  __all__ = [
31
31
  "KwargsNotNone",
@@ -43,9 +43,9 @@ __all__ = [
43
43
  # ruff: noqa: N801
44
44
 
45
45
 
46
- class copy_signature(Generic[F0]):
46
+ def copy_signature(target: F0, /) -> Callable[[Callable[..., Any]], F0]:
47
47
  """
48
- Type util to copy the signature of one function to another function.
48
+ Utility function to copy the signature of one function to another one.
49
49
 
50
50
  Especially useful for passthrough functions.
51
51
 
@@ -71,12 +71,11 @@ class copy_signature(Generic[F0]):
71
71
  # another thing
72
72
  """
73
73
 
74
- def __init__(self, target: F0) -> None:
75
- """Copy the signature of ``target``."""
76
-
77
- def __call__(self, wrapped: Callable[..., Any]) -> F0:
74
+ def decorator(wrapped: Callable[..., Any]) -> F0:
78
75
  return cast(F0, wrapped)
79
76
 
77
+ return decorator
78
+
80
79
 
81
80
  class injected_self_func(Protocol[T_co, P, R_co]):
82
81
  @overload
@@ -402,35 +401,37 @@ def get_subclasses(family: type[T], exclude: Sequence[type[T]] = []) -> list[typ
402
401
  return list(set(_subclasses(family)))
403
402
 
404
403
 
405
- class classproperty_base(Generic[T, R_co]):
404
+ _T_Any = TypeVar("_T_Any", default=Any)
405
+ _T0_Any = TypeVar("_T0_Any", default=Any)
406
+
407
+
408
+ class classproperty_base(Generic[T, R_co, _T_Any]):
406
409
  __isabstractmethod__: bool = False
407
410
 
411
+ fget: Callable[[type[T]], R_co]
412
+ fset: Callable[Concatenate[type[T], _T_Any, ...], None] | None
413
+ fdel: Callable[[type[T]], None] | None
414
+
408
415
  def __init__(
409
416
  self,
410
417
  fget: Callable[[type[T]], R_co] | classmethod[T, ..., R_co],
411
- fset: Callable[Concatenate[type[T], Any, ...], None]
412
- | classmethod[T, Concatenate[Any, ...], None]
418
+ fset: Callable[Concatenate[type[T], _T_Any, ...], None]
419
+ | classmethod[T, Concatenate[_T_Any, ...], None]
413
420
  | None = None,
414
421
  fdel: Callable[[type[T]], None] | classmethod[T, ..., None] | None = None,
415
422
  doc: str | None = None,
416
423
  ) -> None:
417
- self.fget = self._wrap(fget)
418
- self.fset = self._wrap(fset) if fset is not None else fset
419
- self.fdel = self._wrap(fdel) if fdel is not None else fdel
424
+ self.fget = fget.__func__ if isinstance(fget, classmethod) else fget
425
+ self.fset = fset.__func__ if isinstance(fset, classmethod) else fset
426
+ self.fdel = fdel.__func__ if isinstance(fdel, classmethod) else fdel
420
427
 
421
428
  self.__doc__ = doc
422
429
  self.__name__ = self.fget.__name__
423
430
 
424
- def _wrap(self, func: Callable[..., R1] | classmethod[T, P1, R1]) -> classmethod[T, P1, R1]:
425
- if not isinstance(func, classmethod):
426
- func = classmethod(func)
427
-
428
- return func
429
-
430
431
  def __set_name__(self, owner: object, name: str) -> None:
431
432
  self.__name__ = name
432
433
 
433
- def _get_cache(self, type_: type) -> dict[str, Any]:
434
+ def _get_cache(self, type_: type[T]) -> dict[str, Any]:
434
435
  cache_key = getattr(self, "cache_key")
435
436
 
436
437
  if not hasattr(type_, cache_key):
@@ -438,21 +439,23 @@ class classproperty_base(Generic[T, R_co]):
438
439
 
439
440
  return getattr(type_, cache_key)
440
441
 
441
- def __get__(self, obj: T | None, type_: type | None = None) -> R_co:
442
- if type_ is None:
442
+ def __get__(self, obj: T | None, type_: type[T] | None = None) -> R_co:
443
+ if type_ is None and obj is not None:
443
444
  type_ = type(obj)
445
+ elif type_ is None:
446
+ raise NotImplementedError("Both obj and type_ are None")
444
447
 
445
448
  if not isinstance(self, classproperty.cached):
446
- return self.fget.__get__(obj, type_)()
449
+ return self.fget(type_)
447
450
 
448
451
  if self.__name__ in (cache := self._get_cache(type_)):
449
452
  return cache[self.__name__]
450
453
 
451
- value = self.fget.__get__(obj, type_)()
454
+ value = self.fget(type_)
452
455
  cache[self.__name__] = value
453
456
  return value
454
457
 
455
- def __set__(self, obj: T, value: Any) -> None:
458
+ def __set__(self, obj: T, value: _T_Any) -> None:
456
459
  if not self.fset:
457
460
  raise AttributeError(
458
461
  f'classproperty with getter "{self.__name__}" of "{obj.__class__.__name__}" object has no setter.'
@@ -460,10 +463,13 @@ class classproperty_base(Generic[T, R_co]):
460
463
 
461
464
  type_ = type(obj)
462
465
 
466
+ if not isinstance(self, classproperty.cached):
467
+ return self.fset(type_, value)
468
+
463
469
  if self.__name__ in (cache := self._get_cache(type_)):
464
470
  del cache[self.__name__]
465
471
 
466
- self.fset.__get__(None, type_)(value)
472
+ self.fset(type_, value)
467
473
 
468
474
  def __delete__(self, obj: T) -> None:
469
475
  if not self.fdel:
@@ -473,18 +479,21 @@ class classproperty_base(Generic[T, R_co]):
473
479
 
474
480
  type_ = type(obj)
475
481
 
482
+ if not isinstance(self, classproperty.cached):
483
+ return self.fdel(type_)
484
+
476
485
  if self.__name__ in (cache := self._get_cache(type_)):
477
486
  del cache[self.__name__]
478
487
 
479
- self.fdel.__get__(None, type_)()
488
+ self.fdel(type_)
480
489
 
481
490
 
482
- class classproperty(classproperty_base[T, R_co]):
491
+ class classproperty(classproperty_base[T, R_co, _T_Any]):
483
492
  """
484
493
  A combination of `classmethod` and `property`.
485
494
  """
486
495
 
487
- class cached(classproperty_base[T0, R0_co]):
496
+ class cached(classproperty_base[T0, R0_co, _T0_Any]):
488
497
  """
489
498
  A combination of `classmethod` and `property`.
490
499
 
@@ -517,7 +526,7 @@ class classproperty(classproperty_base[T, R_co]):
517
526
  del cache[name]
518
527
 
519
528
 
520
- class cachedproperty(property, Generic[R_co]):
529
+ class cachedproperty(property, Generic[R_co, _T_Any]):
521
530
  """
522
531
  Wrapper for a one-time get property, that will be cached.
523
532
 
@@ -539,16 +548,16 @@ class cachedproperty(property, Generic[R_co]):
539
548
  def __init__(
540
549
  self,
541
550
  fget: Callable[[Any], R_co],
542
- fset: Callable[[Any, Any], None] | None = None,
551
+ fset: Callable[[Any, _T_Any], None] | None = None,
543
552
  fdel: Callable[[Any], None] | None = None,
544
553
  doc: str | None = None,
545
554
  ) -> None: ...
546
555
 
547
- def getter(self, fget: Callable[..., R_co]) -> cachedproperty[R_co]: ...
556
+ def getter(self, fget: Callable[..., R_co]) -> cachedproperty[R_co, _T_Any]: ...
548
557
 
549
- def setter(self, fset: Callable[[Any, Any], None]) -> cachedproperty[R_co]: ...
558
+ def setter(self, fset: Callable[[Any, _T_Any], None]) -> cachedproperty[R_co, _T_Any]: ...
550
559
 
551
- def deleter(self, fdel: Callable[..., None]) -> cachedproperty[R_co]: ...
560
+ def deleter(self, fdel: Callable[..., None]) -> cachedproperty[R_co, _T_Any]: ...
552
561
 
553
562
  if sys.version_info < (3, 13):
554
563
 
@@ -573,7 +582,7 @@ class cachedproperty(property, Generic[R_co]):
573
582
  cache[self.__name__] = value
574
583
  return value
575
584
 
576
- def __set__(self, instance: Any, value: Any) -> None:
585
+ def __set__(self, instance: Any, value: _T_Any) -> None:
577
586
  if self.__name__ in (cache := instance.__dict__.setdefault(self.cache_key, {})):
578
587
  del cache[self.__name__]
579
588
 
@@ -605,6 +614,17 @@ class cachedproperty(property, Generic[R_co]):
605
614
  with suppress(KeyError):
606
615
  del cache[name]
607
616
 
617
+ @classmethod
618
+ def update_cache(cls, obj: object, name: str, value: Any) -> None:
619
+ """
620
+ Update cached property of an object instance.
621
+
622
+ :param obj: The object whose cache should be updated.
623
+ :param names: Property name to update.
624
+ :param value: The value to assign.
625
+ """
626
+ obj.__dict__.setdefault(cls.cache_key, {})[name] = value
627
+
608
628
 
609
629
  class KwargsNotNone(KwargsT):
610
630
  """Remove all None objects from this kwargs dict."""
jetpytools/utils/file.py CHANGED
@@ -48,7 +48,8 @@ def get_script_path() -> SPath:
48
48
  import __main__
49
49
 
50
50
  try:
51
- return SPath(__main__.__file__)
51
+ path = SPath(__main__.__file__)
52
+ return path if path.exists() else SPath.cwd()
52
53
  except AttributeError:
53
54
  return SPath.cwd()
54
55
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jetpytools
3
- Version: 1.7.2
3
+ Version: 1.7.4
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,5 +1,5 @@
1
1
  jetpytools/__init__.py,sha256=ha_pCOMqfeIbipDRrtqKOqH3NQEpX4KwN2SskpsCGb4,114
2
- jetpytools/_metadata.py,sha256=1gq8Xhbmpvzz3wxNKv9JFIJ9qn3tzlccU0sOEbmUkUU,414
2
+ jetpytools/_metadata.py,sha256=Ctf45XxZkSp6UiAUvlc0xW27P8V4tEMiFFSZtpGLKxA,414
3
3
  jetpytools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  jetpytools/enums/__init__.py,sha256=TvEt3TWmnzf2TWS_Gd6llyyXAGDKxdhdJsDgSvT7xys,41
5
5
  jetpytools/enums/base.py,sha256=s5A9iQS22JdaZMM6jEXI31m0ZjtBx7GLQ-E0xBr90Zc,2032
@@ -19,15 +19,15 @@ jetpytools/types/builtins.py,sha256=4uAutpHlkcKM3K_6BbWomqR2QgWNt6294FHE3Ck_ZIA,
19
19
  jetpytools/types/check.py,sha256=ktQOykmryUkDa2j-zcL6uEWF8QlxJ4GW8YKdbqMHGcc,959
20
20
  jetpytools/types/file.py,sha256=LbOwMAwDALWxAZZ2i7ZNexoN3GHWD-uUoIhVvUy95Vo,6539
21
21
  jetpytools/types/funcs.py,sha256=U5tBmTtLS5CLp3ZtOiA5101PQiCWQOBsmf0bj1pRwgY,2778
22
- jetpytools/types/generic.py,sha256=yCavU0bBXGh15-PxIlQE78xj05kpxMVTAGI7xAoon2Y,1121
22
+ jetpytools/types/generic.py,sha256=RRg2U7wxaM4Uzwc6QvsO99euCF3sqr8Kh34XKtVbgT8,1136
23
23
  jetpytools/types/supports.py,sha256=woMTv62HpcRiC5TG18U8NU5v2Q6iqcrHzQgXl7QYEws,3516
24
- jetpytools/types/utils.py,sha256=tIN6OdjrwHxb8XyQeptWh4YbOKdABPOZkKpONZ7eAv8,22877
24
+ jetpytools/types/utils.py,sha256=2E7eNZjwlkQIL-9KC7xj7nMULTHoivrUI22rdzPRw88,23651
25
25
  jetpytools/utils/__init__.py,sha256=_rJ-mY5PsGjBfy8Fihx_FYJfAIGSrYAYzI6Td9oFh9A,83
26
- jetpytools/utils/file.py,sha256=uJV8_S-ctu9Ya9ZR8Kp4QFZ6R62_PnaxAzsiAj2xFIE,10568
26
+ jetpytools/utils/file.py,sha256=3fJxAHjIN5zdyzO0guc3jDspcs5HPG4t4cwB_ZrAhh4,10622
27
27
  jetpytools/utils/funcs.py,sha256=2qhFyLD0OLvenjzOu2wu1ZWoZGzQ8aPmvbkAI1i9Gvk,914
28
28
  jetpytools/utils/math.py,sha256=I56OeHDDJl3X8EFXMWVEiXGAD16AKcn8KVnFuP5fFes,3445
29
29
  jetpytools/utils/ranges.py,sha256=glxypgmuzauV6KCSNujNHOdWkNEUNylOUAPS618jnIg,2559
30
- jetpytools-1.7.2.dist-info/METADATA,sha256=LN7XIprsH4za_VaporgeHwpwCPeBvmOOzjZeaHz9kl0,1198
31
- jetpytools-1.7.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- jetpytools-1.7.2.dist-info/licenses/LICENSE,sha256=l0PN-qDtXcgOB5aXP_nSUsvCK5V3o9pQCGsTzyZhKL0,1071
33
- jetpytools-1.7.2.dist-info/RECORD,,
30
+ jetpytools-1.7.4.dist-info/METADATA,sha256=DP5E8ygPnwnPuriFpgxkrCLDQUqjzU93xiU-m1XnmD0,1198
31
+ jetpytools-1.7.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ jetpytools-1.7.4.dist-info/licenses/LICENSE,sha256=l0PN-qDtXcgOB5aXP_nSUsvCK5V3o9pQCGsTzyZhKL0,1071
33
+ jetpytools-1.7.4.dist-info/RECORD,,