ominfra 0.0.0.dev158__py3-none-any.whl → 0.0.0.dev160__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.
@@ -11,6 +11,7 @@ from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
11
11
  from omlish.lite.cached import cached_nullary
12
12
  from omlish.lite.check import check
13
13
 
14
+ from .atomics import DeployAtomicPathSwapping
14
15
  from .paths import DeployPath
15
16
  from .paths import DeployPathOwner
16
17
  from .types import DeployAppTag
@@ -22,16 +23,18 @@ class DeployVenvManager(DeployPathOwner):
22
23
  self,
23
24
  *,
24
25
  deploy_home: ta.Optional[DeployHome] = None,
26
+ atomics: DeployAtomicPathSwapping,
25
27
  ) -> None:
26
28
  super().__init__()
27
29
 
28
30
  self._deploy_home = deploy_home
31
+ self._atomics = atomics
29
32
 
30
33
  @cached_nullary
31
34
  def _dir(self) -> str:
32
35
  return os.path.join(check.non_empty_str(self._deploy_home), 'venvs')
33
36
 
34
- def get_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
37
+ def get_owned_deploy_paths(self) -> ta.AbstractSet[DeployPath]:
35
38
  return {
36
39
  DeployPath.parse('venvs/@app/@tag/'),
37
40
  }
@@ -45,6 +48,8 @@ class DeployVenvManager(DeployPathOwner):
45
48
  ) -> None:
46
49
  sys_exe = 'python3'
47
50
 
51
+ # !! NOTE: (most) venvs cannot be relocated, so an atomic swap can't be used. it's up to the path manager to
52
+ # garbage collect orphaned dirs.
48
53
  await asyncio_subprocesses.check_call(sys_exe, '-m', 'venv', venv_dir)
49
54
 
50
55
  #
@@ -1487,6 +1487,10 @@ def is_new_type(spec: ta.Any) -> bool:
1487
1487
  return isinstance(spec, types.FunctionType) and spec.__code__ is ta.NewType.__code__.co_consts[1] # type: ignore # noqa
1488
1488
 
1489
1489
 
1490
+ def get_new_type_supertype(spec: ta.Any) -> ta.Any:
1491
+ return spec.__supertype__
1492
+
1493
+
1490
1494
  def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
1491
1495
  seen = set()
1492
1496
  todo = list(reversed(cls.__subclasses__()))
@@ -2450,9 +2454,7 @@ class aclosing(contextlib.AbstractAsyncContextManager): # noqa
2450
2454
  """
2451
2455
  TODO:
2452
2456
  - pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
2453
- - namedtuple
2454
2457
  - literals
2455
- - newtypes?
2456
2458
  """
2457
2459
 
2458
2460
 
@@ -2462,7 +2464,7 @@ TODO:
2462
2464
  @dc.dataclass(frozen=True)
2463
2465
  class ObjMarshalOptions:
2464
2466
  raw_bytes: bool = False
2465
- nonstrict_dataclasses: bool = False
2467
+ non_strict_fields: bool = False
2466
2468
 
2467
2469
 
2468
2470
  class ObjMarshaler(abc.ABC):
@@ -2591,10 +2593,10 @@ class IterableObjMarshaler(ObjMarshaler):
2591
2593
 
2592
2594
 
2593
2595
  @dc.dataclass(frozen=True)
2594
- class DataclassObjMarshaler(ObjMarshaler):
2596
+ class FieldsObjMarshaler(ObjMarshaler):
2595
2597
  ty: type
2596
2598
  fs: ta.Mapping[str, ObjMarshaler]
2597
- nonstrict: bool = False
2599
+ non_strict: bool = False
2598
2600
 
2599
2601
  def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
2600
2602
  return {
@@ -2606,7 +2608,7 @@ class DataclassObjMarshaler(ObjMarshaler):
2606
2608
  return self.ty(**{
2607
2609
  k: self.fs[k].unmarshal(v, ctx)
2608
2610
  for k, v in o.items()
2609
- if not (self.nonstrict or ctx.options.nonstrict_dataclasses) or k in self.fs
2611
+ if not (self.non_strict or ctx.options.non_strict_fields) or k in self.fs
2610
2612
  })
2611
2613
 
2612
2614
 
@@ -2738,7 +2740,7 @@ class ObjMarshalerManager:
2738
2740
  ty: ta.Any,
2739
2741
  rec: ta.Callable[[ta.Any], ObjMarshaler],
2740
2742
  *,
2741
- nonstrict_dataclasses: bool = False,
2743
+ non_strict_fields: bool = False,
2742
2744
  ) -> ObjMarshaler:
2743
2745
  if isinstance(ty, type):
2744
2746
  if abc.ABC in ty.__bases__:
@@ -2760,12 +2762,22 @@ class ObjMarshalerManager:
2760
2762
  return EnumObjMarshaler(ty)
2761
2763
 
2762
2764
  if dc.is_dataclass(ty):
2763
- return DataclassObjMarshaler(
2765
+ return FieldsObjMarshaler(
2764
2766
  ty,
2765
2767
  {f.name: rec(f.type) for f in dc.fields(ty)},
2766
- nonstrict=nonstrict_dataclasses,
2768
+ non_strict=non_strict_fields,
2769
+ )
2770
+
2771
+ if issubclass(ty, tuple) and hasattr(ty, '_fields'):
2772
+ return FieldsObjMarshaler(
2773
+ ty,
2774
+ {p.name: rec(p.annotation) for p in inspect.signature(ty).parameters.values()},
2775
+ non_strict=non_strict_fields,
2767
2776
  )
2768
2777
 
2778
+ if is_new_type(ty):
2779
+ return rec(get_new_type_supertype(ty))
2780
+
2769
2781
  if is_generic_alias(ty):
2770
2782
  try:
2771
2783
  mt = self._generic_mapping_types[ta.get_origin(ty)]
@@ -2899,12 +2911,12 @@ def is_debugger_attached() -> bool:
2899
2911
  return any(frame[1].endswith('pydevd.py') for frame in inspect.stack())
2900
2912
 
2901
2913
 
2902
- REQUIRED_PYTHON_VERSION = (3, 8)
2914
+ LITE_REQUIRED_PYTHON_VERSION = (3, 8)
2903
2915
 
2904
2916
 
2905
- def check_runtime_version() -> None:
2906
- if sys.version_info < REQUIRED_PYTHON_VERSION:
2907
- raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
2917
+ def check_lite_runtime_version() -> None:
2918
+ if sys.version_info < LITE_REQUIRED_PYTHON_VERSION:
2919
+ raise OSError(f'Requires python {LITE_REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
2908
2920
 
2909
2921
 
2910
2922
  ########################################
@@ -3482,6 +3494,7 @@ TODO:
3482
3494
  - structured
3483
3495
  - prefixed
3484
3496
  - debug
3497
+ - optional noisy? noisy will never be lite - some kinda configure_standard callback mechanism?
3485
3498
  """
3486
3499
 
3487
3500
 
@@ -3518,8 +3531,9 @@ class StandardLogFormatter(logging.Formatter):
3518
3531
  ##
3519
3532
 
3520
3533
 
3521
- class StandardLogHandler(ProxyLogHandler):
3522
- pass
3534
+ class StandardConfiguredLogHandler(ProxyLogHandler):
3535
+ def __init_subclass__(cls, **kwargs):
3536
+ raise TypeError('This class serves only as a marker and should not be subclassed.')
3523
3537
 
3524
3538
 
3525
3539
  ##
@@ -3550,7 +3564,7 @@ def configure_standard_logging(
3550
3564
  target: ta.Optional[logging.Logger] = None,
3551
3565
  force: bool = False,
3552
3566
  handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
3553
- ) -> ta.Optional[StandardLogHandler]:
3567
+ ) -> ta.Optional[StandardConfiguredLogHandler]:
3554
3568
  with _locking_logging_module_lock():
3555
3569
  if target is None:
3556
3570
  target = logging.root
@@ -3558,7 +3572,7 @@ def configure_standard_logging(
3558
3572
  #
3559
3573
 
3560
3574
  if not force:
3561
- if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
3575
+ if any(isinstance(h, StandardConfiguredLogHandler) for h in list(target.handlers)):
3562
3576
  return None
3563
3577
 
3564
3578
  #
@@ -3592,7 +3606,7 @@ def configure_standard_logging(
3592
3606
 
3593
3607
  #
3594
3608
 
3595
- return StandardLogHandler(handler)
3609
+ return StandardConfiguredLogHandler(handler)
3596
3610
 
3597
3611
 
3598
3612
  ########################################