prefect-client 2.19.3__py3-none-any.whl → 2.19.4__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.
- prefect/deployments/base.py +7 -1
- prefect/flows.py +8 -1
- prefect/utilities/callables.py +74 -3
- prefect/utilities/importtools.py +5 -5
- {prefect_client-2.19.3.dist-info → prefect_client-2.19.4.dist-info}/METADATA +1 -1
- {prefect_client-2.19.3.dist-info → prefect_client-2.19.4.dist-info}/RECORD +9 -9
- {prefect_client-2.19.3.dist-info → prefect_client-2.19.4.dist-info}/LICENSE +0 -0
- {prefect_client-2.19.3.dist-info → prefect_client-2.19.4.dist-info}/WHEEL +0 -0
- {prefect_client-2.19.3.dist-info → prefect_client-2.19.4.dist-info}/top_level.txt +0 -0
prefect/deployments/base.py
CHANGED
@@ -396,7 +396,13 @@ async def _find_flow_functions_in_file(filename: str) -> List[Dict]:
|
|
396
396
|
return decorated_functions
|
397
397
|
|
398
398
|
for node in ast.walk(tree):
|
399
|
-
if isinstance(
|
399
|
+
if isinstance(
|
400
|
+
node,
|
401
|
+
(
|
402
|
+
ast.FunctionDef,
|
403
|
+
ast.AsyncFunctionDef,
|
404
|
+
),
|
405
|
+
):
|
400
406
|
for decorator in node.decorator_list:
|
401
407
|
# handles @flow
|
402
408
|
is_name_match = (
|
prefect/flows.py
CHANGED
@@ -1830,7 +1830,14 @@ def load_flow_argument_from_entrypoint(
|
|
1830
1830
|
(
|
1831
1831
|
node
|
1832
1832
|
for node in ast.walk(parsed_code)
|
1833
|
-
if isinstance(
|
1833
|
+
if isinstance(
|
1834
|
+
node,
|
1835
|
+
(
|
1836
|
+
ast.FunctionDef,
|
1837
|
+
ast.AsyncFunctionDef,
|
1838
|
+
),
|
1839
|
+
)
|
1840
|
+
and node.name == func_name
|
1834
1841
|
),
|
1835
1842
|
None,
|
1836
1843
|
)
|
prefect/utilities/callables.py
CHANGED
@@ -448,7 +448,14 @@ def _generate_signature_from_source(
|
|
448
448
|
(
|
449
449
|
node
|
450
450
|
for node in ast.walk(parsed_code)
|
451
|
-
if isinstance(
|
451
|
+
if isinstance(
|
452
|
+
node,
|
453
|
+
(
|
454
|
+
ast.FunctionDef,
|
455
|
+
ast.AsyncFunctionDef,
|
456
|
+
),
|
457
|
+
)
|
458
|
+
and node.name == func_name
|
452
459
|
),
|
453
460
|
None,
|
454
461
|
)
|
@@ -456,6 +463,26 @@ def _generate_signature_from_source(
|
|
456
463
|
raise ValueError(f"Function {func_name} not found in source code")
|
457
464
|
parameters = []
|
458
465
|
|
466
|
+
# Handle annotations for positional only args e.g. def func(a, /, b, c)
|
467
|
+
for arg in func_def.args.posonlyargs:
|
468
|
+
name = arg.arg
|
469
|
+
annotation = arg.annotation
|
470
|
+
if annotation is not None:
|
471
|
+
try:
|
472
|
+
ann_code = compile(ast.Expression(annotation), "<string>", "eval")
|
473
|
+
annotation = eval(ann_code, namespace)
|
474
|
+
except Exception as e:
|
475
|
+
logger.debug("Failed to evaluate annotation for %s: %s", name, e)
|
476
|
+
annotation = inspect.Parameter.empty
|
477
|
+
else:
|
478
|
+
annotation = inspect.Parameter.empty
|
479
|
+
|
480
|
+
param = inspect.Parameter(
|
481
|
+
name, inspect.Parameter.POSITIONAL_ONLY, annotation=annotation
|
482
|
+
)
|
483
|
+
parameters.append(param)
|
484
|
+
|
485
|
+
# Determine the annotations for args e.g. def func(a: int, b: str, c: float)
|
459
486
|
for arg in func_def.args.args:
|
460
487
|
name = arg.arg
|
461
488
|
annotation = arg.annotation
|
@@ -478,6 +505,7 @@ def _generate_signature_from_source(
|
|
478
505
|
)
|
479
506
|
parameters.append(param)
|
480
507
|
|
508
|
+
# Handle default values for args e.g. def func(a=1, b="hello", c=3.14)
|
481
509
|
defaults = [None] * (
|
482
510
|
len(func_def.args.args) - len(func_def.args.defaults)
|
483
511
|
) + func_def.args.defaults
|
@@ -493,6 +521,42 @@ def _generate_signature_from_source(
|
|
493
521
|
default = None # Set to None if evaluation fails
|
494
522
|
parameters[parameters.index(param)] = param.replace(default=default)
|
495
523
|
|
524
|
+
# Handle annotations for keyword only args e.g. def func(*, a: int, b: str)
|
525
|
+
for kwarg in func_def.args.kwonlyargs:
|
526
|
+
name = kwarg.arg
|
527
|
+
annotation = kwarg.annotation
|
528
|
+
if annotation is not None:
|
529
|
+
try:
|
530
|
+
ann_code = compile(ast.Expression(annotation), "<string>", "eval")
|
531
|
+
annotation = eval(ann_code, namespace)
|
532
|
+
except Exception as e:
|
533
|
+
logger.debug("Failed to evaluate annotation for %s: %s", name, e)
|
534
|
+
annotation = inspect.Parameter.empty
|
535
|
+
else:
|
536
|
+
annotation = inspect.Parameter.empty
|
537
|
+
|
538
|
+
param = inspect.Parameter(
|
539
|
+
name, inspect.Parameter.KEYWORD_ONLY, annotation=annotation
|
540
|
+
)
|
541
|
+
parameters.append(param)
|
542
|
+
|
543
|
+
# Handle default values for keyword only args e.g. def func(*, a=1, b="hello")
|
544
|
+
defaults = [None] * (
|
545
|
+
len(func_def.args.kwonlyargs) - len(func_def.args.kw_defaults)
|
546
|
+
) + func_def.args.kw_defaults
|
547
|
+
for param, default in zip(parameters[-len(func_def.args.kwonlyargs) :], defaults):
|
548
|
+
if default is not None:
|
549
|
+
try:
|
550
|
+
def_code = compile(ast.Expression(default), "<string>", "eval")
|
551
|
+
default = eval(def_code, namespace)
|
552
|
+
except Exception as e:
|
553
|
+
logger.debug(
|
554
|
+
"Failed to evaluate default value for %s: %s", param.name, e
|
555
|
+
)
|
556
|
+
default = None
|
557
|
+
parameters[parameters.index(param)] = param.replace(default=default)
|
558
|
+
|
559
|
+
# Handle annotations for varargs and kwargs e.g. def func(*args: int, **kwargs: str)
|
496
560
|
if func_def.args.vararg:
|
497
561
|
parameters.append(
|
498
562
|
inspect.Parameter(
|
@@ -504,7 +568,7 @@ def _generate_signature_from_source(
|
|
504
568
|
inspect.Parameter(func_def.args.kwarg.arg, inspect.Parameter.VAR_KEYWORD)
|
505
569
|
)
|
506
570
|
|
507
|
-
# Handle return annotation
|
571
|
+
# Handle return annotation e.g. def func() -> int
|
508
572
|
return_annotation = func_def.returns
|
509
573
|
if return_annotation is not None:
|
510
574
|
try:
|
@@ -536,7 +600,14 @@ def _get_docstring_from_source(source_code: str, func_name: str) -> Optional[str
|
|
536
600
|
(
|
537
601
|
node
|
538
602
|
for node in ast.walk(parsed_code)
|
539
|
-
if isinstance(
|
603
|
+
if isinstance(
|
604
|
+
node,
|
605
|
+
(
|
606
|
+
ast.FunctionDef,
|
607
|
+
ast.AsyncFunctionDef,
|
608
|
+
),
|
609
|
+
)
|
610
|
+
and node.name == func_name
|
540
611
|
),
|
541
612
|
None,
|
542
613
|
)
|
prefect/utilities/importtools.py
CHANGED
@@ -379,7 +379,7 @@ def safe_load_namespace(source_code: str):
|
|
379
379
|
"""
|
380
380
|
parsed_code = ast.parse(source_code)
|
381
381
|
|
382
|
-
namespace = {}
|
382
|
+
namespace = {"__name__": "prefect_safe_namespace_loader"}
|
383
383
|
|
384
384
|
# Walk through the AST and find all import statements
|
385
385
|
for node in ast.walk(parsed_code):
|
@@ -413,11 +413,11 @@ def safe_load_namespace(source_code: str):
|
|
413
413
|
except ImportError as e:
|
414
414
|
logger.debug("Failed to import from %s: %s", node.module, e)
|
415
415
|
|
416
|
-
# Handle local
|
416
|
+
# Handle local definitions
|
417
417
|
for node in ast.walk(parsed_code):
|
418
|
-
if isinstance(node, (ast.ClassDef, ast.FunctionDef)):
|
418
|
+
if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.Assign)):
|
419
419
|
try:
|
420
|
-
# Compile and execute each class and function definition
|
420
|
+
# Compile and execute each class and function definition and assignment
|
421
421
|
code = compile(
|
422
422
|
ast.Module(body=[node], type_ignores=[]),
|
423
423
|
filename="<ast>",
|
@@ -425,5 +425,5 @@ def safe_load_namespace(source_code: str):
|
|
425
425
|
)
|
426
426
|
exec(code, namespace)
|
427
427
|
except Exception as e:
|
428
|
-
logger.debug("Failed to compile
|
428
|
+
logger.debug("Failed to compile: %s", e)
|
429
429
|
return namespace
|
@@ -9,7 +9,7 @@ prefect/engine.py,sha256=hGaxEyJB0OSb_fc2sRsoL550DGOeuwttWOY3dQR6wZw,90418
|
|
9
9
|
prefect/exceptions.py,sha256=Fyl-GXvF9OuKHtsyn5EhWg81pkU1UG3DFHsI1JzhOQE,10851
|
10
10
|
prefect/filesystems.py,sha256=XniPSdBAqywj43X7GyfuWJQIbz07QJ5Y3cVNLhIF3lQ,35260
|
11
11
|
prefect/flow_runs.py,sha256=mFHLavZk1yZ62H3UazuNDBZWAF7AqKttA4rMcHgsVSw,3119
|
12
|
-
prefect/flows.py,sha256=
|
12
|
+
prefect/flows.py,sha256=2CRt3E0THxqriT9ZwMCaPBUMxwkRHU4UNg3iYjvQaTE,75292
|
13
13
|
prefect/futures.py,sha256=RaWfYIXtH7RsWxQ5QWTTlAzwtVV8XWpXaZT_hLq35vQ,12590
|
14
14
|
prefect/manifests.py,sha256=sTM7j8Us5d49zaydYKWsKb7zJ96v1ChkLkLeR0GFYD8,683
|
15
15
|
prefect/new_flow_engine.py,sha256=A1adTWTBAwPCn6ay003Jsoc2SdYgHV4AcJo1bmpa_7Y,16039
|
@@ -180,7 +180,7 @@ prefect/concurrency/events.py,sha256=agci0Y5S0SwZhENgXIG_lbsqh4om9oeU6E_GbtZ55wM
|
|
180
180
|
prefect/concurrency/services.py,sha256=qk4y4H5UsUKz67BufZBJ3WXt2y8UEndXn6TxDkqPzeA,2549
|
181
181
|
prefect/concurrency/sync.py,sha256=gXyiiA0bul7jjpHWPm6su8pFdBiMOekhu9FHnjiPWBQ,3339
|
182
182
|
prefect/deployments/__init__.py,sha256=dM866rOEz3BbAN_xaFMHj3Hw1oOFemBTZ2yxVE6IGoY,394
|
183
|
-
prefect/deployments/base.py,sha256=
|
183
|
+
prefect/deployments/base.py,sha256=0l2D_laMc3q2Q5nvh-WANv3iDy4Ih5BqcPMNJJbHuP0,16391
|
184
184
|
prefect/deployments/deployments.py,sha256=bYNmxU0yn2jzluGIr2tUkgRi73WGQ6gGbjb0GlD4EIk,41656
|
185
185
|
prefect/deployments/runner.py,sha256=a2dxc84zCofZFXV47M2zfntqUaoAhGWvf7o0s3MjPws,44772
|
186
186
|
prefect/deployments/schedules.py,sha256=23GDCAKOP-aAEKGappwTrM4HU67ndVH7NR4Dq0neU_U,1884
|
@@ -255,7 +255,7 @@ prefect/types/__init__.py,sha256=aZvlQ2uXl949sJ_khmxSVkRH3o6edo-eJ_GBGMBN5Yg,313
|
|
255
255
|
prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
256
256
|
prefect/utilities/annotations.py,sha256=bXB43j5Zsq5gaBcJe9qnszBlnNwCTwqSTgcu2OkkRLo,2776
|
257
257
|
prefect/utilities/asyncutils.py,sha256=1xpjGFs72vQTPXfG0ww1mfNBwp0-UbRICLGVeRuiqOg,17010
|
258
|
-
prefect/utilities/callables.py,sha256
|
258
|
+
prefect/utilities/callables.py,sha256=-Ccr5JmDoafth46MPPQCRStBMSG_ickCDfBztpd_MAs,21119
|
259
259
|
prefect/utilities/collections.py,sha256=0v-NNXxYYzkUTCCNDMNB44AnDv9yj35UYouNraCqlo8,15449
|
260
260
|
prefect/utilities/compat.py,sha256=mNQZDnzyKaOqy-OV-DnmH_dc7CNF5nQgW_EsA4xMr7g,906
|
261
261
|
prefect/utilities/context.py,sha256=BThuUW94-IYgFYTeMIM9KMo8ShT3oiI7w5ajZHzU1j0,1377
|
@@ -264,7 +264,7 @@ prefect/utilities/dockerutils.py,sha256=O5lIgCej5KGRYU2TC1NzNuIK595uOIWJilhZXYEV
|
|
264
264
|
prefect/utilities/engine.py,sha256=TKiYqpfgt4zopuI8yvh2e-V9GgLcRrh3TpKRhvLuHdw,25669
|
265
265
|
prefect/utilities/filesystem.py,sha256=M_TeZ1MftjBf7hDLWk-Iphir369TpJ1binMsBKiO9YE,4449
|
266
266
|
prefect/utilities/hashing.py,sha256=EOwZLmoIZImuSTxAvVqInabxJ-4RpEfYeg9e2EDQF8o,1752
|
267
|
-
prefect/utilities/importtools.py,sha256=
|
267
|
+
prefect/utilities/importtools.py,sha256=1rPTqlUY3qWP4GeX4wYrSE9pUtKrD8-ngnDz0uqT2ZI,14600
|
268
268
|
prefect/utilities/math.py,sha256=wLwcKVidpNeWQi1TUIWWLHGjlz9UgboX9FUGhx_CQzo,2821
|
269
269
|
prefect/utilities/names.py,sha256=x-stHcF7_tebJPvB1dz-5FvdXJXNBTg2kFZXSnIBBmk,1657
|
270
270
|
prefect/utilities/processutils.py,sha256=yo_GO48pZzgn4A0IK5irTAoqyUCYvWKDSqHXCrtP8c4,14547
|
@@ -285,8 +285,8 @@ prefect/workers/block.py,sha256=5bdCuqT-4I-et_8ZLG2y1AODzYiCQwFiivhdt5NMEog,7635
|
|
285
285
|
prefect/workers/process.py,sha256=pPtCdA7fKQ4OsvoitT-cayZeh5HgLX4xBUYlb2Zad-Q,9475
|
286
286
|
prefect/workers/server.py,sha256=WVZJxR8nTMzK0ov0BD0xw5OyQpT26AxlXbsGQ1OrxeQ,1551
|
287
287
|
prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
|
288
|
-
prefect_client-2.19.
|
289
|
-
prefect_client-2.19.
|
290
|
-
prefect_client-2.19.
|
291
|
-
prefect_client-2.19.
|
292
|
-
prefect_client-2.19.
|
288
|
+
prefect_client-2.19.4.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
|
289
|
+
prefect_client-2.19.4.dist-info/METADATA,sha256=jp5x5csGV9bneDyiyGLFtL_KR0Kmbvm-K3lzNIZ5psU,7401
|
290
|
+
prefect_client-2.19.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
291
|
+
prefect_client-2.19.4.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
|
292
|
+
prefect_client-2.19.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|