metaflow 2.15.5__py2.py3-none-any.whl → 2.15.7__py2.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.
- metaflow/_vendor/typeguard/_checkers.py +259 -95
- metaflow/_vendor/typeguard/_config.py +4 -4
- metaflow/_vendor/typeguard/_decorators.py +8 -12
- metaflow/_vendor/typeguard/_functions.py +33 -32
- metaflow/_vendor/typeguard/_pytest_plugin.py +40 -13
- metaflow/_vendor/typeguard/_suppression.py +3 -5
- metaflow/_vendor/typeguard/_transformer.py +84 -48
- metaflow/_vendor/typeguard/_union_transformer.py +1 -0
- metaflow/_vendor/typeguard/_utils.py +13 -9
- metaflow/_vendor/typing_extensions.py +1088 -500
- metaflow/_vendor/v3_7/__init__.py +1 -0
- metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
- metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
- metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
- metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
- metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
- metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
- metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
- metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
- metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
- metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
- metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
- metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
- metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
- metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
- metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
- metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
- metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
- metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
- metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
- metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
- metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
- metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
- metaflow/_vendor/v3_7/zipp.py +329 -0
- metaflow/cmd/develop/stubs.py +1 -1
- metaflow/extension_support/__init__.py +1 -1
- metaflow/plugins/argo/argo_workflows.py +34 -11
- metaflow/plugins/argo/argo_workflows_deployer_objects.py +7 -6
- metaflow/plugins/pypi/utils.py +4 -0
- metaflow/runner/click_api.py +7 -2
- metaflow/vendor.py +1 -0
- metaflow/version.py +1 -1
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/Makefile +2 -2
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/METADATA +4 -3
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/RECORD +53 -27
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/WHEEL +1 -1
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/Tiltfile +0 -0
- {metaflow-2.15.5.data → metaflow-2.15.7.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/entry_points.txt +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info/licenses}/LICENSE +0 -0
- {metaflow-2.15.5.dist-info → metaflow-2.15.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import ast
|
4
|
+
import sys
|
5
|
+
import types
|
6
|
+
from collections.abc import Callable, Iterable
|
7
|
+
from importlib.abc import MetaPathFinder
|
8
|
+
from importlib.machinery import ModuleSpec, SourceFileLoader
|
9
|
+
from importlib.util import cache_from_source, decode_source
|
10
|
+
from inspect import isclass
|
11
|
+
from os import PathLike
|
12
|
+
from types import CodeType, ModuleType, TracebackType
|
13
|
+
from typing import Sequence, TypeVar
|
14
|
+
from unittest.mock import patch
|
15
|
+
|
16
|
+
from ._config import global_config
|
17
|
+
from ._transformer import TypeguardTransformer
|
18
|
+
|
19
|
+
if sys.version_info >= (3, 12):
|
20
|
+
from collections.abc import Buffer
|
21
|
+
else:
|
22
|
+
from metaflow._vendor.v3_7.typing_extensions import Buffer
|
23
|
+
|
24
|
+
if sys.version_info >= (3, 11):
|
25
|
+
from typing import ParamSpec
|
26
|
+
else:
|
27
|
+
from metaflow._vendor.v3_7.typing_extensions import ParamSpec
|
28
|
+
|
29
|
+
if sys.version_info >= (3, 10):
|
30
|
+
from importlib.metadata import PackageNotFoundError, version
|
31
|
+
else:
|
32
|
+
from metaflow._vendor.v3_7.importlib_metadata import PackageNotFoundError, version
|
33
|
+
|
34
|
+
try:
|
35
|
+
OPTIMIZATION = "typeguard" + "".join(version("typeguard").split(".")[:3])
|
36
|
+
except PackageNotFoundError:
|
37
|
+
OPTIMIZATION = "typeguard"
|
38
|
+
|
39
|
+
P = ParamSpec("P")
|
40
|
+
T = TypeVar("T")
|
41
|
+
|
42
|
+
|
43
|
+
# The name of this function is magical
|
44
|
+
def _call_with_frames_removed(
|
45
|
+
f: Callable[P, T], *args: P.args, **kwargs: P.kwargs
|
46
|
+
) -> T:
|
47
|
+
return f(*args, **kwargs)
|
48
|
+
|
49
|
+
|
50
|
+
def optimized_cache_from_source(path: str, debug_override: bool | None = None) -> str:
|
51
|
+
return cache_from_source(path, debug_override, optimization=OPTIMIZATION)
|
52
|
+
|
53
|
+
|
54
|
+
class TypeguardLoader(SourceFileLoader):
|
55
|
+
@staticmethod
|
56
|
+
def source_to_code(
|
57
|
+
data: Buffer | str | ast.Module | ast.Expression | ast.Interactive,
|
58
|
+
path: Buffer | str | PathLike[str] = "<string>",
|
59
|
+
) -> CodeType:
|
60
|
+
if isinstance(data, (ast.Module, ast.Expression, ast.Interactive)):
|
61
|
+
tree = data
|
62
|
+
else:
|
63
|
+
if isinstance(data, str):
|
64
|
+
source = data
|
65
|
+
else:
|
66
|
+
source = decode_source(data)
|
67
|
+
|
68
|
+
tree = _call_with_frames_removed(
|
69
|
+
ast.parse,
|
70
|
+
source,
|
71
|
+
path,
|
72
|
+
"exec",
|
73
|
+
)
|
74
|
+
|
75
|
+
tree = TypeguardTransformer().visit(tree)
|
76
|
+
ast.fix_missing_locations(tree)
|
77
|
+
|
78
|
+
if global_config.debug_instrumentation and sys.version_info >= (3, 9):
|
79
|
+
print(
|
80
|
+
f"Source code of {path!r} after instrumentation:\n"
|
81
|
+
"----------------------------------------------",
|
82
|
+
file=sys.stderr,
|
83
|
+
)
|
84
|
+
print(ast.unparse(tree), file=sys.stderr)
|
85
|
+
print("----------------------------------------------", file=sys.stderr)
|
86
|
+
|
87
|
+
return _call_with_frames_removed(
|
88
|
+
compile, tree, path, "exec", 0, dont_inherit=True
|
89
|
+
)
|
90
|
+
|
91
|
+
def exec_module(self, module: ModuleType) -> None:
|
92
|
+
# Use a custom optimization marker – the import lock should make this monkey
|
93
|
+
# patch safe
|
94
|
+
with patch(
|
95
|
+
"importlib._bootstrap_external.cache_from_source",
|
96
|
+
optimized_cache_from_source,
|
97
|
+
):
|
98
|
+
super().exec_module(module)
|
99
|
+
|
100
|
+
|
101
|
+
class TypeguardFinder(MetaPathFinder):
|
102
|
+
"""
|
103
|
+
Wraps another path finder and instruments the module with
|
104
|
+
:func:`@typechecked <typeguard.typechecked>` if :meth:`should_instrument` returns
|
105
|
+
``True``.
|
106
|
+
|
107
|
+
Should not be used directly, but rather via :func:`~.install_import_hook`.
|
108
|
+
|
109
|
+
.. versionadded:: 2.6
|
110
|
+
"""
|
111
|
+
|
112
|
+
def __init__(self, packages: list[str] | None, original_pathfinder: MetaPathFinder):
|
113
|
+
self.packages = packages
|
114
|
+
self._original_pathfinder = original_pathfinder
|
115
|
+
|
116
|
+
def find_spec(
|
117
|
+
self,
|
118
|
+
fullname: str,
|
119
|
+
path: Sequence[str] | None,
|
120
|
+
target: types.ModuleType | None = None,
|
121
|
+
) -> ModuleSpec | None:
|
122
|
+
if self.should_instrument(fullname):
|
123
|
+
spec = self._original_pathfinder.find_spec(fullname, path, target)
|
124
|
+
if spec is not None and isinstance(spec.loader, SourceFileLoader):
|
125
|
+
spec.loader = TypeguardLoader(spec.loader.name, spec.loader.path)
|
126
|
+
return spec
|
127
|
+
|
128
|
+
return None
|
129
|
+
|
130
|
+
def should_instrument(self, module_name: str) -> bool:
|
131
|
+
"""
|
132
|
+
Determine whether the module with the given name should be instrumented.
|
133
|
+
|
134
|
+
:param module_name: full name of the module that is about to be imported (e.g.
|
135
|
+
``xyz.abc``)
|
136
|
+
|
137
|
+
"""
|
138
|
+
if self.packages is None:
|
139
|
+
return True
|
140
|
+
|
141
|
+
for package in self.packages:
|
142
|
+
if module_name == package or module_name.startswith(package + "."):
|
143
|
+
return True
|
144
|
+
|
145
|
+
return False
|
146
|
+
|
147
|
+
|
148
|
+
class ImportHookManager:
|
149
|
+
"""
|
150
|
+
A handle that can be used to uninstall the Typeguard import hook.
|
151
|
+
"""
|
152
|
+
|
153
|
+
def __init__(self, hook: MetaPathFinder):
|
154
|
+
self.hook = hook
|
155
|
+
|
156
|
+
def __enter__(self) -> None:
|
157
|
+
pass
|
158
|
+
|
159
|
+
def __exit__(
|
160
|
+
self,
|
161
|
+
exc_type: type[BaseException],
|
162
|
+
exc_val: BaseException,
|
163
|
+
exc_tb: TracebackType,
|
164
|
+
) -> None:
|
165
|
+
self.uninstall()
|
166
|
+
|
167
|
+
def uninstall(self) -> None:
|
168
|
+
"""Uninstall the import hook."""
|
169
|
+
try:
|
170
|
+
sys.meta_path.remove(self.hook)
|
171
|
+
except ValueError:
|
172
|
+
pass # already removed
|
173
|
+
|
174
|
+
|
175
|
+
def install_import_hook(
|
176
|
+
packages: Iterable[str] | None = None,
|
177
|
+
*,
|
178
|
+
cls: type[TypeguardFinder] = TypeguardFinder,
|
179
|
+
) -> ImportHookManager:
|
180
|
+
"""
|
181
|
+
Install an import hook that instruments functions for automatic type checking.
|
182
|
+
|
183
|
+
This only affects modules loaded **after** this hook has been installed.
|
184
|
+
|
185
|
+
:param packages: an iterable of package names to instrument, or ``None`` to
|
186
|
+
instrument all packages
|
187
|
+
:param cls: a custom meta path finder class
|
188
|
+
:return: a context manager that uninstalls the hook on exit (or when you call
|
189
|
+
``.uninstall()``)
|
190
|
+
|
191
|
+
.. versionadded:: 2.6
|
192
|
+
|
193
|
+
"""
|
194
|
+
if packages is None:
|
195
|
+
target_packages: list[str] | None = None
|
196
|
+
elif isinstance(packages, str):
|
197
|
+
target_packages = [packages]
|
198
|
+
else:
|
199
|
+
target_packages = list(packages)
|
200
|
+
|
201
|
+
for finder in sys.meta_path:
|
202
|
+
if (
|
203
|
+
isclass(finder)
|
204
|
+
and finder.__name__ == "PathFinder"
|
205
|
+
and hasattr(finder, "find_spec")
|
206
|
+
):
|
207
|
+
break
|
208
|
+
else:
|
209
|
+
raise RuntimeError("Cannot find a PathFinder in sys.meta_path")
|
210
|
+
|
211
|
+
hook = cls(target_packages, finder)
|
212
|
+
sys.meta_path.insert(0, hook)
|
213
|
+
return ImportHookManager(hook)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from metaflow._vendor.v3_7.typeguard._config import TypeCheckConfiguration, global_config
|
6
|
+
|
7
|
+
|
8
|
+
class TypeCheckMemo:
|
9
|
+
"""
|
10
|
+
Contains information necessary for type checkers to do their work.
|
11
|
+
|
12
|
+
.. attribute:: globals
|
13
|
+
:type: dict[str, Any]
|
14
|
+
|
15
|
+
Dictionary of global variables to use for resolving forward references.
|
16
|
+
|
17
|
+
.. attribute:: locals
|
18
|
+
:type: dict[str, Any]
|
19
|
+
|
20
|
+
Dictionary of local variables to use for resolving forward references.
|
21
|
+
|
22
|
+
.. attribute:: self_type
|
23
|
+
:type: type | None
|
24
|
+
|
25
|
+
When running type checks within an instance method or class method, this is the
|
26
|
+
class object that the first argument (usually named ``self`` or ``cls``) refers
|
27
|
+
to.
|
28
|
+
|
29
|
+
.. attribute:: config
|
30
|
+
:type: TypeCheckConfiguration
|
31
|
+
|
32
|
+
Contains the configuration for a particular set of type checking operations.
|
33
|
+
"""
|
34
|
+
|
35
|
+
__slots__ = "globals", "locals", "self_type", "config"
|
36
|
+
|
37
|
+
def __init__(
|
38
|
+
self,
|
39
|
+
globals: dict[str, Any],
|
40
|
+
locals: dict[str, Any],
|
41
|
+
*,
|
42
|
+
self_type: type | None = None,
|
43
|
+
config: TypeCheckConfiguration = global_config,
|
44
|
+
):
|
45
|
+
self.globals = globals
|
46
|
+
self.locals = locals
|
47
|
+
self.self_type = self_type
|
48
|
+
self.config = config
|
@@ -0,0 +1,100 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import sys
|
4
|
+
import warnings
|
5
|
+
|
6
|
+
from pytest import Config, Parser
|
7
|
+
|
8
|
+
from metaflow._vendor.v3_7.typeguard._config import CollectionCheckStrategy, ForwardRefPolicy, global_config
|
9
|
+
from metaflow._vendor.v3_7.typeguard._exceptions import InstrumentationWarning
|
10
|
+
from metaflow._vendor.v3_7.typeguard._importhook import install_import_hook
|
11
|
+
from metaflow._vendor.v3_7.typeguard._utils import qualified_name, resolve_reference
|
12
|
+
|
13
|
+
|
14
|
+
def pytest_addoption(parser: Parser) -> None:
|
15
|
+
group = parser.getgroup("typeguard")
|
16
|
+
group.addoption(
|
17
|
+
"--typeguard-packages",
|
18
|
+
action="store",
|
19
|
+
help="comma separated name list of packages and modules to instrument for "
|
20
|
+
"type checking, or :all: to instrument all modules loaded after typeguard",
|
21
|
+
)
|
22
|
+
group.addoption(
|
23
|
+
"--typeguard-debug-instrumentation",
|
24
|
+
action="store_true",
|
25
|
+
help="print all instrumented code to stderr",
|
26
|
+
)
|
27
|
+
group.addoption(
|
28
|
+
"--typeguard-typecheck-fail-callback",
|
29
|
+
action="store",
|
30
|
+
help=(
|
31
|
+
"a module:varname (e.g. typeguard:warn_on_error) reference to a function "
|
32
|
+
"that is called (with the exception, and memo object as arguments) to "
|
33
|
+
"handle a TypeCheckError"
|
34
|
+
),
|
35
|
+
)
|
36
|
+
group.addoption(
|
37
|
+
"--typeguard-forward-ref-policy",
|
38
|
+
action="store",
|
39
|
+
choices=list(ForwardRefPolicy.__members__),
|
40
|
+
help=(
|
41
|
+
"determines how to deal with unresolveable forward references in type "
|
42
|
+
"annotations"
|
43
|
+
),
|
44
|
+
)
|
45
|
+
group.addoption(
|
46
|
+
"--typeguard-collection-check-strategy",
|
47
|
+
action="store",
|
48
|
+
choices=list(CollectionCheckStrategy.__members__),
|
49
|
+
help="determines how thoroughly to check collections (list, dict, etc)",
|
50
|
+
)
|
51
|
+
|
52
|
+
|
53
|
+
def pytest_configure(config: Config) -> None:
|
54
|
+
packages_option = config.getoption("typeguard_packages")
|
55
|
+
if packages_option:
|
56
|
+
if packages_option == ":all:":
|
57
|
+
packages: list[str] | None = None
|
58
|
+
else:
|
59
|
+
packages = [pkg.strip() for pkg in packages_option.split(",")]
|
60
|
+
already_imported_packages = sorted(
|
61
|
+
package for package in packages if package in sys.modules
|
62
|
+
)
|
63
|
+
if already_imported_packages:
|
64
|
+
warnings.warn(
|
65
|
+
f"typeguard cannot check these packages because they are already "
|
66
|
+
f"imported: {', '.join(already_imported_packages)}",
|
67
|
+
InstrumentationWarning,
|
68
|
+
stacklevel=1,
|
69
|
+
)
|
70
|
+
|
71
|
+
install_import_hook(packages=packages)
|
72
|
+
|
73
|
+
debug_option = config.getoption("typeguard_debug_instrumentation")
|
74
|
+
if debug_option:
|
75
|
+
global_config.debug_instrumentation = True
|
76
|
+
|
77
|
+
fail_callback_option = config.getoption("typeguard_typecheck_fail_callback")
|
78
|
+
if fail_callback_option:
|
79
|
+
callback = resolve_reference(fail_callback_option)
|
80
|
+
if not callable(callback):
|
81
|
+
raise TypeError(
|
82
|
+
f"{fail_callback_option} ({qualified_name(callback.__class__)}) is not "
|
83
|
+
f"a callable"
|
84
|
+
)
|
85
|
+
|
86
|
+
global_config.typecheck_fail_callback = callback
|
87
|
+
|
88
|
+
forward_ref_policy_option = config.getoption("typeguard_forward_ref_policy")
|
89
|
+
if forward_ref_policy_option:
|
90
|
+
forward_ref_policy = ForwardRefPolicy.__members__[forward_ref_policy_option]
|
91
|
+
global_config.forward_ref_policy = forward_ref_policy
|
92
|
+
|
93
|
+
collection_check_strategy_option = config.getoption(
|
94
|
+
"typeguard_collection_check_strategy"
|
95
|
+
)
|
96
|
+
if collection_check_strategy_option:
|
97
|
+
collection_check_strategy = CollectionCheckStrategy.__members__[
|
98
|
+
collection_check_strategy_option
|
99
|
+
]
|
100
|
+
global_config.collection_check_strategy = collection_check_strategy
|
@@ -0,0 +1,88 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import sys
|
4
|
+
from collections.abc import Callable, Generator
|
5
|
+
from contextlib import contextmanager
|
6
|
+
from functools import update_wrapper
|
7
|
+
from threading import Lock
|
8
|
+
from typing import ContextManager, TypeVar, overload
|
9
|
+
|
10
|
+
if sys.version_info >= (3, 10):
|
11
|
+
from typing import ParamSpec
|
12
|
+
else:
|
13
|
+
from metaflow._vendor.v3_7.typing_extensions import ParamSpec
|
14
|
+
|
15
|
+
P = ParamSpec("P")
|
16
|
+
T = TypeVar("T")
|
17
|
+
|
18
|
+
type_checks_suppressed = 0
|
19
|
+
type_checks_suppress_lock = Lock()
|
20
|
+
|
21
|
+
|
22
|
+
@overload
|
23
|
+
def suppress_type_checks(func: Callable[P, T]) -> Callable[P, T]:
|
24
|
+
...
|
25
|
+
|
26
|
+
|
27
|
+
@overload
|
28
|
+
def suppress_type_checks() -> ContextManager[None]:
|
29
|
+
...
|
30
|
+
|
31
|
+
|
32
|
+
def suppress_type_checks(
|
33
|
+
func: Callable[P, T] | None = None
|
34
|
+
) -> Callable[P, T] | ContextManager[None]:
|
35
|
+
"""
|
36
|
+
Temporarily suppress all type checking.
|
37
|
+
|
38
|
+
This function has two operating modes, based on how it's used:
|
39
|
+
|
40
|
+
#. as a context manager (``with suppress_type_checks(): ...``)
|
41
|
+
#. as a decorator (``@suppress_type_checks``)
|
42
|
+
|
43
|
+
When used as a context manager, :func:`check_type` and any automatically
|
44
|
+
instrumented functions skip the actual type checking. These context managers can be
|
45
|
+
nested.
|
46
|
+
|
47
|
+
When used as a decorator, all type checking is suppressed while the function is
|
48
|
+
running.
|
49
|
+
|
50
|
+
Type checking will resume once no more context managers are active and no decorated
|
51
|
+
functions are running.
|
52
|
+
|
53
|
+
Both operating modes are thread-safe.
|
54
|
+
|
55
|
+
"""
|
56
|
+
|
57
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
58
|
+
global type_checks_suppressed
|
59
|
+
|
60
|
+
with type_checks_suppress_lock:
|
61
|
+
type_checks_suppressed += 1
|
62
|
+
|
63
|
+
assert func is not None
|
64
|
+
try:
|
65
|
+
return func(*args, **kwargs)
|
66
|
+
finally:
|
67
|
+
with type_checks_suppress_lock:
|
68
|
+
type_checks_suppressed -= 1
|
69
|
+
|
70
|
+
def cm() -> Generator[None, None, None]:
|
71
|
+
global type_checks_suppressed
|
72
|
+
|
73
|
+
with type_checks_suppress_lock:
|
74
|
+
type_checks_suppressed += 1
|
75
|
+
|
76
|
+
try:
|
77
|
+
yield
|
78
|
+
finally:
|
79
|
+
with type_checks_suppress_lock:
|
80
|
+
type_checks_suppressed -= 1
|
81
|
+
|
82
|
+
if func is None:
|
83
|
+
# Context manager mode
|
84
|
+
return contextmanager(cm)()
|
85
|
+
else:
|
86
|
+
# Decorator mode
|
87
|
+
update_wrapper(wrapper, func)
|
88
|
+
return wrapper
|