ominfra 0.0.0.dev123__tar.gz → 0.0.0.dev125__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {ominfra-0.0.0.dev123/ominfra.egg-info → ominfra-0.0.0.dev125}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/_executor.py +7 -4
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/_main.py +4 -10
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/base.py +7 -8
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/pyremote/_runcommands.py +7 -4
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/scripts/journald2aws.py +7 -4
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/scripts/supervisor.py +1388 -180
- ominfra-0.0.0.dev125/ominfra/supervisor/LICENSE.txt +28 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/context.py +5 -5
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/dispatchers.py +5 -5
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/groups.py +12 -18
- ominfra-0.0.0.dev125/ominfra/supervisor/inject.py +64 -0
- ominfra-0.0.0.dev125/ominfra/supervisor/main.py +118 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/process.py +8 -8
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/supervisor.py +11 -16
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/types.py +51 -6
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125/ominfra.egg-info}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra.egg-info/SOURCES.txt +2 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra.egg-info/requires.txt +2 -2
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/pyproject.toml +4 -3
- ominfra-0.0.0.dev123/ominfra/supervisor/main.py +0 -155
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/LICENSE +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/MANIFEST.in +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/README.rst +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/.manifests.json +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/__about__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/__main__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/auth.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/cli.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/dataclasses.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/__main__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/cursor.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/driver.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/main.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/journald2aws/poster.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/logs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/aws/metadata.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/gcp/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/clouds/gcp/auth.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/cmds.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/configs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/configs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/base.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/dirs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/nginx.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/repo.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/supervisor.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/systemd.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/user.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/concerns/venv.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/executor/main.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/configs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/deploy.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/main.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/nginx.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/repo.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/runtime.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/site.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/supervisor.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/poly/venv.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/deploy/remote.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/journald/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/journald/fields.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/journald/genmessages.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/journald/messages.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/journald/tailer.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/manage/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/manage/manage.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/pyremote/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/pyremote/bootstrap.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/pyremote/runcommands.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/scripts/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/ssh.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/__main__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/configs.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/datatypes.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/events.py +3 -3
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/exceptions.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/poller.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/signals.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/states.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/supervisor/utils.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/tailscale/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/tailscale/api.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/tailscale/cli.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/threadworkers.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/tools/__init__.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra/tools/listresources.py +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra.egg-info/dependency_links.txt +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra.egg-info/entry_points.txt +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/ominfra.egg-info/top_level.txt +0 -0
- {ominfra-0.0.0.dev123 → ominfra-0.0.0.dev125}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev125
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev125
|
16
|
+
Requires-Dist: omlish==0.0.0.dev125
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -76,8 +76,7 @@ import weakref # noqa
|
|
76
76
|
|
77
77
|
|
78
78
|
if sys.version_info < (3, 8):
|
79
|
-
raise OSError(
|
80
|
-
f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
79
|
+
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
81
80
|
|
82
81
|
|
83
82
|
########################################
|
@@ -150,6 +149,11 @@ def check_not_isinstance(v: T, spec: ta.Union[type, tuple]) -> T:
|
|
150
149
|
return v
|
151
150
|
|
152
151
|
|
152
|
+
def check_none(v: T) -> None:
|
153
|
+
if v is not None:
|
154
|
+
raise ValueError(v)
|
155
|
+
|
156
|
+
|
153
157
|
def check_not_none(v: ta.Optional[T]) -> T:
|
154
158
|
if v is None:
|
155
159
|
raise ValueError
|
@@ -904,8 +908,7 @@ REQUIRED_PYTHON_VERSION = (3, 8)
|
|
904
908
|
|
905
909
|
def check_runtime_version() -> None:
|
906
910
|
if sys.version_info < REQUIRED_PYTHON_VERSION:
|
907
|
-
raise OSError(
|
908
|
-
f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
911
|
+
raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
909
912
|
|
910
913
|
|
911
914
|
########################################
|
@@ -27,8 +27,7 @@ import typing as ta
|
|
27
27
|
|
28
28
|
|
29
29
|
if sys.version_info < (3, 8):
|
30
|
-
raise OSError(
|
31
|
-
f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
30
|
+
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
32
31
|
|
33
32
|
|
34
33
|
########################################
|
@@ -40,7 +39,9 @@ T = ta.TypeVar('T')
|
|
40
39
|
# ../base.py
|
41
40
|
ConcernT = ta.TypeVar('ConcernT')
|
42
41
|
ConfigT = ta.TypeVar('ConfigT')
|
42
|
+
SiteConcernT = ta.TypeVar('SiteConcernT', bound='SiteConcern')
|
43
43
|
SiteConcernConfigT = ta.TypeVar('SiteConcernConfigT', bound='SiteConcernConfig')
|
44
|
+
DeployConcernT = ta.TypeVar('DeployConcernT', bound='DeployConcern')
|
44
45
|
DeployConcernConfigT = ta.TypeVar('DeployConcernConfigT', bound='DeployConcernConfig')
|
45
46
|
|
46
47
|
|
@@ -240,9 +241,6 @@ class ConcernsContainer(abc.ABC, ta.Generic[ConcernT, ConfigT]):
|
|
240
241
|
##
|
241
242
|
|
242
243
|
|
243
|
-
SiteConcernT = ta.TypeVar('SiteConcernT', bound='SiteConcern')
|
244
|
-
|
245
|
-
|
246
244
|
class SiteConcern(abc.ABC, ta.Generic[SiteConcernConfigT]):
|
247
245
|
def __init__(self, config: SiteConcernConfigT, site: 'Site') -> None:
|
248
246
|
super().__init__()
|
@@ -270,9 +268,6 @@ class Site(ConcernsContainer[SiteConcern, SiteConfig]):
|
|
270
268
|
##
|
271
269
|
|
272
270
|
|
273
|
-
DeployConcernT = ta.TypeVar('DeployConcernT', bound='DeployConcern')
|
274
|
-
|
275
|
-
|
276
271
|
class DeployConcern(abc.ABC, ta.Generic[DeployConcernConfigT]):
|
277
272
|
def __init__(self, config: DeployConcernConfigT, deploy: 'Deploy') -> None:
|
278
273
|
super().__init__()
|
@@ -589,8 +584,7 @@ REQUIRED_PYTHON_VERSION = (3, 8)
|
|
589
584
|
|
590
585
|
def check_runtime_version() -> None:
|
591
586
|
if sys.version_info < REQUIRED_PYTHON_VERSION:
|
592
|
-
raise OSError(
|
593
|
-
f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
587
|
+
raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
594
588
|
|
595
589
|
|
596
590
|
########################################
|
@@ -10,9 +10,16 @@ from .configs import SiteConfig
|
|
10
10
|
|
11
11
|
|
12
12
|
T = ta.TypeVar('T')
|
13
|
+
|
13
14
|
ConcernT = ta.TypeVar('ConcernT')
|
14
15
|
ConfigT = ta.TypeVar('ConfigT')
|
15
16
|
|
17
|
+
SiteConcernT = ta.TypeVar('SiteConcernT', bound='SiteConcern')
|
18
|
+
SiteConcernConfigT = ta.TypeVar('SiteConcernConfigT', bound='SiteConcernConfig')
|
19
|
+
|
20
|
+
DeployConcernT = ta.TypeVar('DeployConcernT', bound='DeployConcern')
|
21
|
+
DeployConcernConfigT = ta.TypeVar('DeployConcernConfigT', bound='DeployConcernConfig')
|
22
|
+
|
16
23
|
|
17
24
|
##
|
18
25
|
|
@@ -112,10 +119,6 @@ class ConcernsContainer(abc.ABC, ta.Generic[ConcernT, ConfigT]):
|
|
112
119
|
##
|
113
120
|
|
114
121
|
|
115
|
-
SiteConcernT = ta.TypeVar('SiteConcernT', bound='SiteConcern')
|
116
|
-
SiteConcernConfigT = ta.TypeVar('SiteConcernConfigT', bound='SiteConcernConfig')
|
117
|
-
|
118
|
-
|
119
122
|
class SiteConcern(abc.ABC, ta.Generic[SiteConcernConfigT]):
|
120
123
|
def __init__(self, config: SiteConcernConfigT, site: 'Site') -> None:
|
121
124
|
super().__init__()
|
@@ -143,10 +146,6 @@ class Site(ConcernsContainer[SiteConcern, SiteConfig]):
|
|
143
146
|
##
|
144
147
|
|
145
148
|
|
146
|
-
DeployConcernT = ta.TypeVar('DeployConcernT', bound='DeployConcern')
|
147
|
-
DeployConcernConfigT = ta.TypeVar('DeployConcernConfigT', bound='DeployConcernConfig')
|
148
|
-
|
149
|
-
|
150
149
|
class DeployConcern(abc.ABC, ta.Generic[DeployConcernConfigT]):
|
151
150
|
def __init__(self, config: DeployConcernConfigT, deploy: 'Deploy') -> None:
|
152
151
|
super().__init__()
|
@@ -35,8 +35,7 @@ import zlib
|
|
35
35
|
|
36
36
|
|
37
37
|
if sys.version_info < (3, 8):
|
38
|
-
raise OSError(
|
39
|
-
f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
38
|
+
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
40
39
|
|
41
40
|
|
42
41
|
########################################
|
@@ -233,6 +232,11 @@ def check_not_isinstance(v: T, spec: ta.Union[type, tuple]) -> T:
|
|
233
232
|
return v
|
234
233
|
|
235
234
|
|
235
|
+
def check_none(v: T) -> None:
|
236
|
+
if v is not None:
|
237
|
+
raise ValueError(v)
|
238
|
+
|
239
|
+
|
236
240
|
def check_not_none(v: ta.Optional[T]) -> T:
|
237
241
|
if v is None:
|
238
242
|
raise ValueError
|
@@ -987,8 +991,7 @@ REQUIRED_PYTHON_VERSION = (3, 8)
|
|
987
991
|
|
988
992
|
def check_runtime_version() -> None:
|
989
993
|
if sys.version_info < REQUIRED_PYTHON_VERSION:
|
990
|
-
raise OSError(
|
991
|
-
f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
994
|
+
raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
992
995
|
|
993
996
|
|
994
997
|
########################################
|
@@ -45,8 +45,7 @@ import weakref # noqa
|
|
45
45
|
|
46
46
|
|
47
47
|
if sys.version_info < (3, 8):
|
48
|
-
raise OSError(
|
49
|
-
f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
48
|
+
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
50
49
|
|
51
50
|
|
52
51
|
########################################
|
@@ -929,6 +928,11 @@ def check_not_isinstance(v: T, spec: ta.Union[type, tuple]) -> T:
|
|
929
928
|
return v
|
930
929
|
|
931
930
|
|
931
|
+
def check_none(v: T) -> None:
|
932
|
+
if v is not None:
|
933
|
+
raise ValueError(v)
|
934
|
+
|
935
|
+
|
932
936
|
def check_not_none(v: ta.Optional[T]) -> T:
|
933
937
|
if v is None:
|
934
938
|
raise ValueError
|
@@ -2354,8 +2358,7 @@ REQUIRED_PYTHON_VERSION = (3, 8)
|
|
2354
2358
|
|
2355
2359
|
def check_runtime_version() -> None:
|
2356
2360
|
if sys.version_info < REQUIRED_PYTHON_VERSION:
|
2357
|
-
raise OSError(
|
2358
|
-
f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
2361
|
+
raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
|
2359
2362
|
|
2360
2363
|
|
2361
2364
|
########################################
|