Skip to content

Commit 6b1feb5

Browse files
committed
fixed handling of reserved attributes in python, shell and workflow tasks
1 parent 1ec1933 commit 6b1feb5

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

pydra/design/base.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ def extract_fields_from_class(
334334
arg_type: type[Arg],
335335
out_type: type[Out],
336336
auto_attribs: bool,
337+
skip_fields: ty.Iterable[str] = (),
337338
) -> tuple[dict[str, Arg], dict[str, Out]]:
338339
"""Extract the input and output fields from an existing class
339340
@@ -348,6 +349,8 @@ def extract_fields_from_class(
348349
auto_attribs : bool
349350
Whether to assume that all attribute annotations should be interpreted as
350351
fields or not
352+
skip_fields : Iterable[str], optional
353+
The names of attributes to skip when extracting the fields, by default ()
351354
352355
Returns
353356
-------
@@ -364,10 +367,15 @@ def get_fields(klass, field_type, auto_attribs, helps) -> dict[str, Field]:
364367
fields_dict = {}
365368
# Get fields defined in base classes if present
366369
for field in list_fields(klass):
367-
fields_dict[field.name] = field
370+
if field.name not in skip_fields:
371+
fields_dict[field.name] = field
368372
type_hints = ty.get_type_hints(klass)
369373
for atr_name in dir(klass):
370-
if atr_name in ["Task", "Outputs"] or atr_name.startswith("__"):
374+
if (
375+
atr_name in ["Task", "Outputs"]
376+
or atr_name in skip_fields
377+
or atr_name.startswith("__")
378+
):
371379
continue
372380
try:
373381
atr = getattr(klass, atr_name)
@@ -394,7 +402,7 @@ def get_fields(klass, field_type, auto_attribs, helps) -> dict[str, Field]:
394402
)
395403
if auto_attribs:
396404
for atr_name, type_ in type_hints.items():
397-
if atr_name.startswith("_"):
405+
if atr_name.startswith("_") or atr_name in skip_fields:
398406
continue
399407
if atr_name not in list(fields_dict) + ["Task", "Outputs"]:
400408
fields_dict[atr_name] = field_type(

pydra/design/python.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,13 @@ def make(wrapped: ty.Callable | type) -> PythonDef:
136136
name = klass.__name__
137137
check_explicit_fields_are_none(klass, inputs, outputs)
138138
parsed_inputs, parsed_outputs = extract_fields_from_class(
139-
PythonDef, PythonOutputs, klass, arg, out, auto_attribs
139+
PythonDef,
140+
PythonOutputs,
141+
klass,
142+
arg,
143+
out,
144+
auto_attribs,
145+
skip_fields=["function"],
140146
)
141147
else:
142148
if not isinstance(wrapped, ty.Callable):

pydra/design/shell.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,13 @@ def make(
342342
class_name = klass.__name__
343343
check_explicit_fields_are_none(klass, inputs, outputs)
344344
parsed_inputs, parsed_outputs = extract_fields_from_class(
345-
ShellDef, ShellOutputs, klass, arg, out, auto_attribs
345+
ShellDef,
346+
ShellOutputs,
347+
klass,
348+
arg,
349+
out,
350+
auto_attribs,
351+
skip_fields=["executable"],
346352
)
347353
else:
348354
if not isinstance(wrapped, (str, list)):

pydra/design/workflow.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,13 @@ def make(wrapped: ty.Callable | type) -> TaskDef:
145145
name = klass.__name__
146146
check_explicit_fields_are_none(klass, inputs, outputs)
147147
parsed_inputs, parsed_outputs = extract_fields_from_class(
148-
WorkflowDef, WorkflowOutputs, klass, arg, out, auto_attribs
148+
WorkflowDef,
149+
WorkflowOutputs,
150+
klass,
151+
arg,
152+
out,
153+
auto_attribs,
154+
skip_fields=["constructor"],
149155
)
150156
else:
151157
if not inspect.isfunction(wrapped):

0 commit comments

Comments
 (0)