ominfra 0.0.0.dev424__py3-none-any.whl → 0.0.0.dev426__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.
Files changed (30) hide show
  1. ominfra/clouds/aws/journald2aws/cursor.py +4 -1
  2. ominfra/clouds/aws/journald2aws/driver.py +4 -1
  3. ominfra/clouds/aws/journald2aws/poster.py +4 -1
  4. ominfra/clouds/aws/models/services/ec2.py +31 -0
  5. ominfra/journald/messages.py +4 -1
  6. ominfra/journald/tailer.py +4 -1
  7. ominfra/manage/deploy/commands.py +4 -1
  8. ominfra/manage/main.py +4 -1
  9. ominfra/manage/remote/_main.py +4 -1
  10. ominfra/manage/remote/execution.py +4 -1
  11. ominfra/manage/system/commands.py +4 -1
  12. ominfra/manage/system/platforms.py +4 -1
  13. ominfra/scripts/journald2aws.py +379 -32
  14. ominfra/scripts/manage.py +384 -32
  15. ominfra/scripts/supervisor.py +385 -36
  16. ominfra/supervisor/dispatchersimpl.py +4 -1
  17. ominfra/supervisor/io.py +4 -1
  18. ominfra/supervisor/main.py +2 -2
  19. ominfra/supervisor/processimpl.py +4 -1
  20. ominfra/supervisor/setupimpl.py +4 -1
  21. ominfra/supervisor/signals.py +4 -1
  22. ominfra/supervisor/supervisor.py +4 -1
  23. ominfra/threadworkers.py +4 -1
  24. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/METADATA +3 -3
  25. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/RECORD +30 -30
  26. /ominfra/{.manifests.json → .omlish-manifests.json} +0 -0
  27. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/WHEEL +0 -0
  28. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/entry_points.txt +0 -0
  29. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/licenses/LICENSE +0 -0
  30. {ominfra-0.0.0.dev424.dist-info → ominfra-0.0.0.dev426.dist-info}/top_level.txt +0 -0
ominfra/scripts/manage.py CHANGED
@@ -90,8 +90,10 @@ TomlParseFloat = ta.Callable[[str], ta.Any] # ta.TypeAlias
90
90
  TomlKey = ta.Tuple[str, ...] # ta.TypeAlias
91
91
  TomlPos = int # ta.TypeAlias
92
92
 
93
- # ../../omlish/lite/cached.py
93
+ # ../../omlish/lite/attrops.py
94
94
  T = ta.TypeVar('T')
95
+
96
+ # ../../omlish/lite/cached.py
95
97
  CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
96
98
 
97
99
  # ../../omlish/lite/check.py
@@ -2484,6 +2486,335 @@ class Abstract:
2484
2486
  update_abstracts(cls, force=True)
2485
2487
 
2486
2488
 
2489
+ ########################################
2490
+ # ../../../omlish/lite/attrops.py
2491
+ """
2492
+ TODO:
2493
+ - dotted paths!
2494
+ - per-attr repr transform / filter
2495
+ - __ne__ ? cases where it still matters
2496
+ - ordering ?
2497
+ """
2498
+
2499
+
2500
+ ##
2501
+
2502
+
2503
+ @ta.final
2504
+ class AttrOps(ta.Generic[T]):
2505
+ @ta.final
2506
+ class Attr:
2507
+ def __init__(
2508
+ self,
2509
+ name: str,
2510
+ *,
2511
+ display: ta.Optional[str] = None,
2512
+
2513
+ repr: bool = True, # noqa
2514
+ hash: bool = True, # noqa
2515
+ eq: bool = True,
2516
+ ) -> None:
2517
+ if '.' in name:
2518
+ raise NotImplementedError('Dotted paths not yet supported')
2519
+ if not name.isidentifier() or name.startswith('__'):
2520
+ raise AttributeError(f'Invalid attr: {name!r}')
2521
+ self._name = name
2522
+
2523
+ if display is None:
2524
+ display = name[1:] if name.startswith('_') and len(name) > 1 else name
2525
+ self._display = display
2526
+
2527
+ self._repr = repr
2528
+ self._hash = hash
2529
+ self._eq = eq
2530
+
2531
+ @classmethod
2532
+ def of(
2533
+ cls,
2534
+ o: ta.Union[
2535
+ str,
2536
+ ta.Tuple[str, str],
2537
+ 'AttrOps.Attr',
2538
+ ],
2539
+ ) -> 'AttrOps.Attr':
2540
+ if isinstance(o, AttrOps.Attr):
2541
+ return o
2542
+ elif isinstance(o, str):
2543
+ return cls(o)
2544
+ else:
2545
+ name, disp = o
2546
+ return cls(
2547
+ name,
2548
+ display=disp,
2549
+ )
2550
+
2551
+ @property
2552
+ def name(self) -> str:
2553
+ return self._name
2554
+
2555
+ @property
2556
+ def display(self) -> str:
2557
+ return self._display
2558
+
2559
+ @property
2560
+ def hash(self) -> bool:
2561
+ return self._hash
2562
+
2563
+ @property
2564
+ def eq(self) -> bool:
2565
+ return self._eq
2566
+
2567
+ @ta.overload
2568
+ def __init__(
2569
+ self,
2570
+ *attrs: ta.Sequence[ta.Union[
2571
+ str,
2572
+ ta.Tuple[str, str],
2573
+ Attr,
2574
+ ]],
2575
+ with_module: bool = False,
2576
+ use_qualname: bool = False,
2577
+ with_id: bool = False,
2578
+ repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
2579
+ recursive: bool = False,
2580
+ subtypes_eq: bool = False,
2581
+ ) -> None:
2582
+ ...
2583
+
2584
+ @ta.overload
2585
+ def __init__(
2586
+ self,
2587
+ attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
2588
+ ta.Any,
2589
+ ta.Tuple[str, ta.Any],
2590
+ Attr,
2591
+ ], ...]],
2592
+ /,
2593
+ *,
2594
+ with_module: bool = False,
2595
+ use_qualname: bool = False,
2596
+ with_id: bool = False,
2597
+ repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
2598
+ recursive: bool = False,
2599
+ subtypes_eq: bool = False,
2600
+ ) -> None:
2601
+ ...
2602
+
2603
+ def __init__(
2604
+ self,
2605
+ *args,
2606
+ with_module=False,
2607
+ use_qualname=False,
2608
+ with_id=False,
2609
+ repr_filter=None,
2610
+ recursive=False,
2611
+ subtypes_eq=False,
2612
+ ) -> None:
2613
+ if args and len(args) == 1 and callable(args[0]):
2614
+ self._attrs: ta.Sequence[AttrOps.Attr] = self._capture_attrs(args[0])
2615
+ else:
2616
+ self._attrs = list(map(AttrOps.Attr.of, args))
2617
+
2618
+ self._with_module: bool = with_module
2619
+ self._use_qualname: bool = use_qualname
2620
+ self._with_id: bool = with_id
2621
+ self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
2622
+ self._recursive: bool = recursive
2623
+ self._subtypes_eq: bool = subtypes_eq
2624
+
2625
+ @property
2626
+ def attrs(self) -> ta.Sequence[Attr]:
2627
+ return self._attrs
2628
+
2629
+ #
2630
+
2631
+ @ta.final
2632
+ class _AttrCapturer:
2633
+ def __init__(self, fn):
2634
+ self.__fn = fn
2635
+
2636
+ def __getattr__(self, attr):
2637
+ return self.__fn(self, attr)
2638
+
2639
+ @classmethod
2640
+ def _capture_attrs(cls, fn: ta.Callable) -> ta.Sequence[Attr]:
2641
+ def access(parent, attr):
2642
+ dct[(ret := cls._AttrCapturer(access))] = (parent, attr)
2643
+ return ret
2644
+
2645
+ dct: dict = {}
2646
+ raw = fn(root := cls._AttrCapturer(access))
2647
+
2648
+ def rec(cap): # noqa
2649
+ if cap is root:
2650
+ return
2651
+ parent, attr = dct[cap]
2652
+ yield from rec(parent)
2653
+ yield attr
2654
+
2655
+ attrs: ta.List[AttrOps.Attr] = []
2656
+ for o in raw:
2657
+ if isinstance(o, AttrOps.Attr):
2658
+ attrs.append(o)
2659
+ continue
2660
+
2661
+ if isinstance(o, tuple):
2662
+ disp, cap, = o
2663
+ else:
2664
+ disp, cap = None, o
2665
+
2666
+ path = tuple(rec(cap))
2667
+
2668
+ attrs.append(AttrOps.Attr(
2669
+ '.'.join(path),
2670
+ display=disp,
2671
+ ))
2672
+
2673
+ return attrs
2674
+
2675
+ #
2676
+
2677
+ _repr: ta.Callable[[T], str]
2678
+
2679
+ @property
2680
+ def repr(self) -> ta.Callable[[T], str]:
2681
+ try:
2682
+ return self._repr
2683
+ except AttributeError:
2684
+ pass
2685
+
2686
+ def _repr(o: T) -> str:
2687
+ vs = ', '.join(
2688
+ f'{a._display}={v!r}' # noqa
2689
+ for a in self._attrs
2690
+ if a._repr # noqa
2691
+ for v in [getattr(o, a._name)] # noqa
2692
+ if self._repr_filter is None or self._repr_filter(v)
2693
+ )
2694
+
2695
+ return (
2696
+ f'{o.__class__.__module__ + "." if self._with_module else ""}'
2697
+ f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
2698
+ f'{("@" + hex(id(o))[2:]) if self._with_id else ""}'
2699
+ f'({vs})'
2700
+ )
2701
+
2702
+ if self._recursive:
2703
+ _repr = self._reprlib().recursive_repr()(_repr)
2704
+
2705
+ self._repr = _repr
2706
+ return _repr
2707
+
2708
+ _reprlib_: ta.ClassVar[ta.Any]
2709
+
2710
+ @classmethod
2711
+ def _reprlib(cls) -> ta.Any:
2712
+ try:
2713
+ return cls._reprlib_
2714
+ except AttributeError:
2715
+ pass
2716
+
2717
+ import reprlib # noqa
2718
+
2719
+ cls._reprlib_ = reprlib
2720
+ return reprlib
2721
+
2722
+ #
2723
+
2724
+ _hash: ta.Callable[[T], int]
2725
+
2726
+ @property
2727
+ def hash(self) -> ta.Callable[[T], int]:
2728
+ try:
2729
+ return self._hash
2730
+ except AttributeError:
2731
+ pass
2732
+
2733
+ def _hash(o: T) -> int:
2734
+ return hash(tuple(
2735
+ getattr(o, a._name) # noqa
2736
+ for a in self._attrs
2737
+ if a._hash # noqa
2738
+ ))
2739
+
2740
+ self._hash = _hash
2741
+ return _hash
2742
+
2743
+ #
2744
+
2745
+ _eq: ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]
2746
+
2747
+ @property
2748
+ def eq(self) -> ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']]:
2749
+ try:
2750
+ return self._eq
2751
+ except AttributeError:
2752
+ pass
2753
+
2754
+ def _eq(o: T, x: ta.Any) -> 'ta.Union[bool, types.NotImplementedType]':
2755
+ if self._subtypes_eq:
2756
+ if not isinstance(x, type(o)):
2757
+ return NotImplemented
2758
+ else:
2759
+ if type(x) is not type(o):
2760
+ return NotImplemented
2761
+
2762
+ return all(
2763
+ getattr(o, a._name) == getattr(x, a._name) # noqa
2764
+ for a in self._attrs
2765
+ if a._eq # noqa
2766
+ )
2767
+
2768
+ self._eq = _eq
2769
+ return _eq
2770
+
2771
+ #
2772
+
2773
+ @property
2774
+ def hash_eq(self) -> ta.Tuple[
2775
+ ta.Callable[[T], int],
2776
+ ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
2777
+ ]:
2778
+ return (self.hash, self.eq)
2779
+
2780
+ @property
2781
+ def repr_hash_eq(self) -> ta.Tuple[
2782
+ ta.Callable[[T], str],
2783
+ ta.Callable[[T], int],
2784
+ ta.Callable[[T, ta.Any], ta.Union[bool, 'types.NotImplementedType']],
2785
+ ]:
2786
+ return (self.repr, self.hash, self.eq)
2787
+
2788
+ #
2789
+
2790
+ def install(
2791
+ self,
2792
+ locals_dct: ta.MutableMapping[str, ta.Any],
2793
+ *,
2794
+ all: bool = False, # noqa
2795
+ repr: bool = False, # noqa
2796
+ hash: bool = False, # noqa
2797
+ eq: bool = False,
2798
+ ) -> 'AttrOps[T]':
2799
+ if repr or all:
2800
+ locals_dct.update(__repr__=self.repr)
2801
+ if hash or all:
2802
+ locals_dct.update(__hash__=self.hash)
2803
+ if eq or all:
2804
+ locals_dct.update(__eq__=self.eq)
2805
+ return self
2806
+
2807
+
2808
+ attr_ops = AttrOps[ta.Any]
2809
+
2810
+
2811
+ ##
2812
+
2813
+
2814
+ def attr_repr(obj: ta.Any, *attrs: str, **kwargs: ta.Any) -> str:
2815
+ return AttrOps(*attrs, **kwargs).repr(obj)
2816
+
2817
+
2487
2818
  ########################################
2488
2819
  # ../../../omlish/lite/cached.py
2489
2820
 
@@ -2502,7 +2833,7 @@ class _AbstractCachedNullary:
2502
2833
  def __call__(self, *args, **kwargs): # noqa
2503
2834
  raise TypeError
2504
2835
 
2505
- def __get__(self, instance, owner): # noqa
2836
+ def __get__(self, instance, owner=None): # noqa
2506
2837
  bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
2507
2838
  return bound
2508
2839
 
@@ -3261,13 +3592,6 @@ json_dump_compact: ta.Callable[..., None] = functools.partial(json.dump, **JSON_
3261
3592
  json_dumps_compact: ta.Callable[..., str] = functools.partial(json.dumps, **JSON_COMPACT_KWARGS)
3262
3593
 
3263
3594
 
3264
- ########################################
3265
- # ../../../omlish/lite/logs.py
3266
-
3267
-
3268
- log = logging.getLogger(__name__)
3269
-
3270
-
3271
3595
  ########################################
3272
3596
  # ../../../omlish/lite/objects.py
3273
3597
 
@@ -3578,13 +3902,6 @@ def split_keep_delimiter(s, d):
3578
3902
  ##
3579
3903
 
3580
3904
 
3581
- def attr_repr(obj: ta.Any, *attrs: str) -> str:
3582
- return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
3583
-
3584
-
3585
- ##
3586
-
3587
-
3588
3905
  FORMAT_NUM_BYTES_SUFFIXES: ta.Sequence[str] = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']
3589
3906
 
3590
3907
 
@@ -3659,13 +3976,24 @@ def typing_annotations_attr() -> str:
3659
3976
 
3660
3977
 
3661
3978
  ########################################
3662
- # ../../../omlish/logs/filters.py
3979
+ # ../../../omlish/logs/modules.py
3980
+
3981
+
3982
+ ##
3983
+
3984
+
3985
+ def get_module_logger(mod_globals: ta.Mapping[str, ta.Any]) -> logging.Logger:
3986
+ return logging.getLogger(mod_globals.get('__name__'))
3987
+
3988
+
3989
+ ########################################
3990
+ # ../../../omlish/logs/std/filters.py
3663
3991
 
3664
3992
 
3665
3993
  ##
3666
3994
 
3667
3995
 
3668
- class TidLogFilter(logging.Filter):
3996
+ class TidLoggingFilter(logging.Filter):
3669
3997
  def filter(self, record):
3670
3998
  # FIXME: handle better - missing from wasm and cosmos
3671
3999
  if hasattr(threading, 'get_native_id'):
@@ -3676,13 +4004,13 @@ class TidLogFilter(logging.Filter):
3676
4004
 
3677
4005
 
3678
4006
  ########################################
3679
- # ../../../omlish/logs/proxy.py
4007
+ # ../../../omlish/logs/std/proxy.py
3680
4008
 
3681
4009
 
3682
4010
  ##
3683
4011
 
3684
4012
 
3685
- class ProxyLogFilterer(logging.Filterer):
4013
+ class ProxyLoggingFilterer(logging.Filterer):
3686
4014
  def __init__(self, underlying: logging.Filterer) -> None: # noqa
3687
4015
  self._underlying = underlying
3688
4016
 
@@ -3708,9 +4036,9 @@ class ProxyLogFilterer(logging.Filterer):
3708
4036
  return self._underlying.filter(record)
3709
4037
 
3710
4038
 
3711
- class ProxyLogHandler(ProxyLogFilterer, logging.Handler):
4039
+ class ProxyLoggingHandler(ProxyLoggingFilterer, logging.Handler):
3712
4040
  def __init__(self, underlying: logging.Handler) -> None: # noqa
3713
- ProxyLogFilterer.__init__(self, underlying)
4041
+ ProxyLoggingFilterer.__init__(self, underlying)
3714
4042
 
3715
4043
  _underlying: logging.Handler
3716
4044
 
@@ -5350,6 +5678,9 @@ def get_remote_payload_src(
5350
5678
  # ../system/platforms.py
5351
5679
 
5352
5680
 
5681
+ log = get_module_logger(globals()) # noqa
5682
+
5683
+
5353
5684
  ##
5354
5685
 
5355
5686
 
@@ -6995,6 +7326,7 @@ class _Maybe(Maybe[T], Abstract):
6995
7326
  return op and not sp
6996
7327
 
6997
7328
 
7329
+ @ta.final
6998
7330
  class _JustMaybe(_Maybe[T]):
6999
7331
  __slots__ = ('_v', '_hash')
7000
7332
 
@@ -7032,6 +7364,7 @@ class _JustMaybe(_Maybe[T]):
7032
7364
  )
7033
7365
 
7034
7366
 
7367
+ @ta.final
7035
7368
  class _EmptyMaybe(_Maybe[T]):
7036
7369
  __slots__ = ()
7037
7370
 
@@ -7277,7 +7610,7 @@ class PredicateTimeout(Timeout):
7277
7610
 
7278
7611
 
7279
7612
  ########################################
7280
- # ../../../omlish/logs/json.py
7613
+ # ../../../omlish/logs/std/json.py
7281
7614
  """
7282
7615
  TODO:
7283
7616
  - translate json keys
@@ -7287,7 +7620,7 @@ TODO:
7287
7620
  ##
7288
7621
 
7289
7622
 
7290
- class JsonLogFormatter(logging.Formatter):
7623
+ class JsonLoggingFormatter(logging.Formatter):
7291
7624
  KEYS: ta.Mapping[str, bool] = {
7292
7625
  'name': False,
7293
7626
  'msg': False,
@@ -9386,6 +9719,7 @@ inj = InjectionApi()
9386
9719
  # ../../../omlish/logs/standard.py
9387
9720
  """
9388
9721
  TODO:
9722
+ - !! move to std !!
9389
9723
  - structured
9390
9724
  - prefixed
9391
9725
  - debug
@@ -9407,7 +9741,7 @@ STANDARD_LOG_FORMAT_PARTS = [
9407
9741
  ]
9408
9742
 
9409
9743
 
9410
- class StandardLogFormatter(logging.Formatter):
9744
+ class StandardLoggingFormatter(logging.Formatter):
9411
9745
  @staticmethod
9412
9746
  def build_log_format(parts: ta.Iterable[ta.Tuple[str, str]]) -> str:
9413
9747
  return ' '.join(v for k, v in parts)
@@ -9426,7 +9760,7 @@ class StandardLogFormatter(logging.Formatter):
9426
9760
  ##
9427
9761
 
9428
9762
 
9429
- class StandardConfiguredLogHandler(ProxyLogHandler):
9763
+ class StandardConfiguredLoggingHandler(ProxyLoggingHandler):
9430
9764
  def __init_subclass__(cls, **kwargs):
9431
9765
  raise TypeError('This class serves only as a marker and should not be subclassed.')
9432
9766
 
@@ -9459,7 +9793,7 @@ def configure_standard_logging(
9459
9793
  target: ta.Optional[logging.Logger] = None,
9460
9794
  force: bool = False,
9461
9795
  handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
9462
- ) -> ta.Optional[StandardConfiguredLogHandler]:
9796
+ ) -> ta.Optional[StandardConfiguredLoggingHandler]:
9463
9797
  with _locking_logging_module_lock():
9464
9798
  if target is None:
9465
9799
  target = logging.root
@@ -9467,7 +9801,7 @@ def configure_standard_logging(
9467
9801
  #
9468
9802
 
9469
9803
  if not force:
9470
- if any(isinstance(h, StandardConfiguredLogHandler) for h in list(target.handlers)):
9804
+ if any(isinstance(h, StandardConfiguredLoggingHandler) for h in list(target.handlers)):
9471
9805
  return None
9472
9806
 
9473
9807
  #
@@ -9481,14 +9815,14 @@ def configure_standard_logging(
9481
9815
 
9482
9816
  formatter: logging.Formatter
9483
9817
  if json:
9484
- formatter = JsonLogFormatter()
9818
+ formatter = JsonLoggingFormatter()
9485
9819
  else:
9486
- formatter = StandardLogFormatter(StandardLogFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
9820
+ formatter = StandardLoggingFormatter(StandardLoggingFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
9487
9821
  handler.setFormatter(formatter)
9488
9822
 
9489
9823
  #
9490
9824
 
9491
- handler.addFilter(TidLogFilter())
9825
+ handler.addFilter(TidLoggingFilter())
9492
9826
 
9493
9827
  #
9494
9828
 
@@ -9501,7 +9835,7 @@ def configure_standard_logging(
9501
9835
 
9502
9836
  #
9503
9837
 
9504
- return StandardConfiguredLogHandler(handler)
9838
+ return StandardConfiguredLoggingHandler(handler)
9505
9839
 
9506
9840
 
9507
9841
  ########################################
@@ -10121,6 +10455,9 @@ TODO:
10121
10455
  """
10122
10456
 
10123
10457
 
10458
+ log = get_module_logger(globals()) # noqa
10459
+
10460
+
10124
10461
  ##
10125
10462
 
10126
10463
 
@@ -11104,6 +11441,12 @@ class SingleDirDeployPathOwner(DeployPathOwner, Abstract):
11104
11441
  # ../remote/_main.py
11105
11442
 
11106
11443
 
11444
+ log = get_module_logger(globals()) # noqa
11445
+
11446
+
11447
+ ##
11448
+
11449
+
11107
11450
  class _RemoteExecutionLogHandler(logging.Handler):
11108
11451
  def __init__(self, fn: ta.Callable[[str], None]) -> None:
11109
11452
  super().__init__()
@@ -13441,6 +13784,9 @@ class InProcessRemoteExecutionConnector:
13441
13784
  # ../system/commands.py
13442
13785
 
13443
13786
 
13787
+ log = get_module_logger(globals()) # noqa
13788
+
13789
+
13444
13790
  ##
13445
13791
 
13446
13792
 
@@ -14571,6 +14917,9 @@ class DeployDriver:
14571
14917
  # ../deploy/commands.py
14572
14918
 
14573
14919
 
14920
+ log = get_module_logger(globals()) # noqa
14921
+
14922
+
14574
14923
  ##
14575
14924
 
14576
14925
 
@@ -14787,6 +15136,9 @@ def main_bootstrap(bs: MainBootstrap) -> Injector:
14787
15136
  # main.py
14788
15137
 
14789
15138
 
15139
+ log = get_module_logger(globals()) # noqa
15140
+
15141
+
14790
15142
  ##
14791
15143
 
14792
15144