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.
@@ -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(node, ast.FunctionDef):
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(node, ast.FunctionDef) and node.name == func_name
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
  )
@@ -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(node, ast.FunctionDef) and node.name == func_name
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(node, ast.FunctionDef) and node.name == func_name
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
  )
@@ -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 class definitions
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 locally
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 class definition: %s", e)
428
+ logger.debug("Failed to compile: %s", e)
429
429
  return namespace
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 2.19.3
3
+ Version: 2.19.4
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -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=7Lir_rlrMwgTpuMOrJ56K5xwfVhDv5dYQz_HMrkdZv0,75150
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=GST7fFAI2I6Cmp2waypNEosqaERQiau8CxTcGwIg4nk,16285
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=YKStXG3vA60akk084ve4AH35DS57v_jIQo55eBUMG9c,18292
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=cG0559s8y8N9JJEfUDS9cpRScK2_KthKBpq6-BxbrnU,14561
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.3.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
289
- prefect_client-2.19.3.dist-info/METADATA,sha256=mZrLCglFtET3Q_ovgbuRaA-E9Mpci-7GKd9OojmlAjI,7401
290
- prefect_client-2.19.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
291
- prefect_client-2.19.3.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
292
- prefect_client-2.19.3.dist-info/RECORD,,
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,,