runnable 0.39.0__tar.gz → 0.39.1__tar.gz
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.
- {runnable-0.39.0 → runnable-0.39.1}/PKG-INFO +1 -1
- {runnable-0.39.0 → runnable-0.39.1}/pyproject.toml +1 -1
- {runnable-0.39.0 → runnable-0.39.1}/runnable/parameters.py +24 -38
- {runnable-0.39.0 → runnable-0.39.1}/.gitignore +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/LICENSE +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/any_path.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/file_system.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/minio.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/catalog/s3.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/emulate.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/k8s.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/k8s_job_spec.yaml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/local.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/local_container.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/job_executor/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/conditional.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/fail.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/map.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/parallel.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/stub.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/success.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/nodes/task.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/argo.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/emulate.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/local.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/local_container.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/mocked.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/pipeline_executor/retry.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/any_path.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/chunked_fs.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/chunked_minio.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/db/implementation_FF.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/db/integration_FF.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/file_system.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/generic_chunked.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/minio.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/run_log_store/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/secrets/README.md +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/secrets/dotenv.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/extensions/secrets/pyproject.toml +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/__init__.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/catalog.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/cli.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/context.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/datastore.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/defaults.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/entrypoints.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/exceptions.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/executor.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/graph.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/names.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/nodes.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/pickler.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/sdk.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/secrets.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/tasks.py +0 -0
- {runnable-0.39.0 → runnable-0.39.1}/runnable/utils.py +0 -0
@@ -3,7 +3,7 @@ import inspect
|
|
3
3
|
import json
|
4
4
|
import logging
|
5
5
|
import os
|
6
|
-
from typing import Any, Dict, Type
|
6
|
+
from typing import Any, Dict, Type, get_origin
|
7
7
|
|
8
8
|
from pydantic import BaseModel, ConfigDict
|
9
9
|
from typing_extensions import Callable
|
@@ -97,7 +97,6 @@ def filter_arguments_for_func(
|
|
97
97
|
params[key] = JsonParameter(kind="json", value=v)
|
98
98
|
|
99
99
|
bound_args = {}
|
100
|
-
missing_required_args: list[str] = []
|
101
100
|
var_keyword_param = None
|
102
101
|
namespace_param = None
|
103
102
|
|
@@ -108,12 +107,12 @@ def filter_arguments_for_func(
|
|
108
107
|
logger.warning(f"Ignoring parameter {name} as it is VAR_POSITIONAL")
|
109
108
|
continue
|
110
109
|
|
111
|
-
# Check for **kwargs parameter
|
110
|
+
# Check for **kwargs parameter, we need to send in all the unnamed values in this as a dict
|
112
111
|
if value.kind == inspect.Parameter.VAR_KEYWORD:
|
113
112
|
var_keyword_param = name
|
114
113
|
continue
|
115
114
|
|
116
|
-
# Check for argparse.Namespace parameter
|
115
|
+
# Check for argparse.Namespace parameter, we need to send in all the unnamed values in this as a namespace
|
117
116
|
if value.annotation == argparse.Namespace:
|
118
117
|
namespace_param = name
|
119
118
|
continue
|
@@ -124,16 +123,17 @@ def filter_arguments_for_func(
|
|
124
123
|
# Default value is given in the function signature, we can use it
|
125
124
|
bound_args[name] = value.default
|
126
125
|
else:
|
127
|
-
# This is a required parameter that's missing
|
128
|
-
|
126
|
+
# This is a required parameter that's missing - error immediately
|
127
|
+
raise ValueError(
|
128
|
+
f"Function {func.__name__} has required parameter '{name}' that is not present in the parameters"
|
129
|
+
)
|
129
130
|
else:
|
130
131
|
# We have a parameter of this name, lets bind it
|
131
132
|
param_value = params[name]
|
132
133
|
|
133
|
-
if (
|
134
|
-
|
135
|
-
|
136
|
-
) and not isinstance(param_value, ObjectParameter):
|
134
|
+
if (issubclass(value.annotation, BaseModel)) and not isinstance(
|
135
|
+
param_value, ObjectParameter
|
136
|
+
):
|
137
137
|
# Even if the annotation is a pydantic model, it can be passed as an object parameter
|
138
138
|
# We try to cast it as a pydantic model if asked
|
139
139
|
named_param = params[name].get_value()
|
@@ -147,22 +147,32 @@ def filter_arguments_for_func(
|
|
147
147
|
)
|
148
148
|
bound_args[name] = bound_model
|
149
149
|
|
150
|
-
elif value.annotation
|
150
|
+
elif value.annotation is not inspect.Parameter.empty and callable(
|
151
151
|
value.annotation
|
152
152
|
):
|
153
153
|
# Cast it if its a primitive type. Ensure the type matches the annotation.
|
154
154
|
try:
|
155
|
-
|
155
|
+
# Handle typing generics like Dict[str, int], List[str] by using their origin
|
156
|
+
origin = get_origin(value.annotation)
|
157
|
+
if origin is not None:
|
158
|
+
# For generics like Dict[str, int], use dict() instead of Dict[str, int]()
|
159
|
+
bound_args[name] = origin(params[name].get_value())
|
160
|
+
else:
|
161
|
+
# Regular callable types like int, str, float, etc.
|
162
|
+
bound_args[name] = value.annotation(params[name].get_value())
|
156
163
|
except (ValueError, TypeError) as e:
|
164
|
+
annotation_name = getattr(
|
165
|
+
value.annotation, "__name__", str(value.annotation)
|
166
|
+
)
|
157
167
|
raise ValueError(
|
158
|
-
f"Cannot cast parameter '{name}' to {
|
168
|
+
f"Cannot cast parameter '{name}' to {annotation_name}: {e}"
|
159
169
|
)
|
160
170
|
else:
|
161
171
|
# We do not know type of parameter, we send the value as found
|
162
172
|
bound_args[name] = params[name].get_value()
|
163
173
|
|
164
174
|
# Find extra parameters (parameters in params but not consumed by regular function parameters)
|
165
|
-
consumed_param_names = set(bound_args.keys())
|
175
|
+
consumed_param_names = set(bound_args.keys())
|
166
176
|
extra_params = {k: v for k, v in params.items() if k not in consumed_param_names}
|
167
177
|
|
168
178
|
# Second pass: Handle **kwargs and argparse.Namespace parameters
|
@@ -176,30 +186,6 @@ def filter_arguments_for_func(
|
|
176
186
|
for param_name, param_value in extra_params.items():
|
177
187
|
setattr(args_namespace, param_name, param_value.get_value())
|
178
188
|
bound_args[namespace_param] = args_namespace
|
179
|
-
elif extra_params:
|
180
|
-
# Function doesn't accept **kwargs or namespace, but we have extra parameters
|
181
|
-
# This should only be an error if we also have missing required parameters
|
182
|
-
# or if the function truly can't handle the extra parameters
|
183
|
-
if missing_required_args:
|
184
|
-
# We have both missing required and extra parameters - this is an error
|
185
|
-
raise ValueError(
|
186
|
-
f"Function {func.__name__} has parameters {missing_required_args} that are not present in the parameters"
|
187
|
-
)
|
188
|
-
# If we only have extra parameters and no missing required ones, we just ignore the extras
|
189
|
-
# This allows for more flexible parameter passing
|
190
|
-
|
191
|
-
# Check for missing required parameters
|
192
|
-
if missing_required_args:
|
193
|
-
if var_keyword_param is None and namespace_param is None:
|
194
|
-
# No way to handle missing parameters
|
195
|
-
raise ValueError(
|
196
|
-
f"Function {func.__name__} has parameters {missing_required_args} that are not present in the parameters"
|
197
|
-
)
|
198
|
-
# If we have **kwargs or namespace, missing parameters might be handled there
|
199
|
-
# But if they're truly required (no default), we should still error
|
200
|
-
raise ValueError(
|
201
|
-
f"Function {func.__name__} has parameters {missing_required_args} that are not present in the parameters"
|
202
|
-
)
|
203
189
|
|
204
190
|
return bound_args
|
205
191
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|