Skip to content

Commit 362a2d1

Browse files
Pin aliases (#2059)
* Expose aliases in Input, Output, and PinSpecification * Add alias to template and operator code generation * Handle retro in Specification * Expose alias in operator_specification_grpcapi.py * Try getattr in template * Handle default __getattr__ * Add a deprecation warning when using pin aliases * Fix Specification doctests * Limit changes to operators with aliases * Fix retro compatibility condition * Make operator_specification_get_pin_num_aliases retro-compatible * Remove server version check * Revert "Remove server version check" This reverts commit 143aa6e. * Add server version check * Do not remove translator.py during code_generation.py * Add default value to variable for error reporting in build.py * Add aliases as valid operator inputs in the signature * Fix indent in operator.mustache * Fix indentation in operator.mustache * Print server path for operator generation * Limit tests to mac operator * Add aliases to operator signature * Fix dict creation * Revert "Limit tests to mac operator" This reverts commit 1537c46. * update generated code (#2129) Co-authored-by: PProfizi <[email protected]> * Remove redundant code following rebase * Reactivate retro testing for test_animation.py and test_animator.py * Add deprecation warning when using an alias as operator instantiation parameter * Add test_specification.py with test_pin_alias * update generated code (#2131) Co-authored-by: PProfizi <[email protected]> * Skip test_pin_alias during retro tests --------- Co-authored-by: PyAnsys CI Bot <[email protected]>
1 parent 1579d2c commit 362a2d1

18 files changed

+400
-26
lines changed

src/ansys/dpf/core/dpf_operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ def id(self) -> int:
680680
return self._id
681681

682682
@property
683-
def inputs(self):
683+
def inputs(self) -> Inputs:
684684
"""Inputs connected to the operator.
685685
686686
Returns
@@ -702,7 +702,7 @@ def inputs(self):
702702
return self._inputs
703703

704704
@property
705-
def outputs(self):
705+
def outputs(self) -> Outputs:
706706
"""Outputs from the operator's evaluation.
707707
708708
Returns

src/ansys/dpf/core/inputs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def __init__(self, spec, pin, operator, count_ellipsis=-1):
6363
self._python_expected_types.append(map_types_to_python[cpp_type])
6464
if len(self._spec.type_names) == 0:
6565
self._python_expected_types.append("Any")
66+
self.aliases = self._spec.aliases
6667
docstr = self.__str__()
6768
self.name = self._spec.name
6869
if self._count_ellipsis != -1:
@@ -187,6 +188,8 @@ def __str__(self):
187188
docstr += "\n".join(wrap(self._spec.document.capitalize())) + "\n"
188189
if self._count_ellipsis >= 0:
189190
docstr += "is ellipsis\n"
191+
if self.aliases:
192+
docstr += f"aliases: {self.aliases}\n"
190193
return docstr
191194

192195
def __inc_if_ellipsis(self):
@@ -317,6 +320,9 @@ def _add_input(self, pin, spec, count_ellipsis=-1):
317320
def __call__(self, inpt):
318321
self.connect(inpt)
319322

323+
def __getitem__(self, item) -> Input:
324+
return self._inputs[item]
325+
320326

321327
# Dynamic class Inputs
322328
class Inputs(_Inputs):

src/ansys/dpf/core/operator_specification.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class PinSpecification:
7878
optional: bool
7979
ellipsis: bool
8080
name_derived_class = str
81+
aliases: list[str]
8182

8283
def __init__(
8384
self,
@@ -87,13 +88,15 @@ def __init__(
8788
optional=False,
8889
ellipsis=False,
8990
name_derived_class="",
91+
aliases=[],
9092
):
9193
self.name = name
9294
self.type_names = type_names
9395
self.optional = optional
9496
self.document = document
9597
self.ellipsis = ellipsis
9698
self.name_derived_class = name_derived_class
99+
self.aliases = aliases
97100

98101
@property
99102
def type_names(self) -> list[str]:
@@ -140,6 +143,7 @@ def _get_copy(other, changed_types) -> PinSpecification:
140143
other.optional,
141144
other.ellipsis,
142145
other.name_derived_class,
146+
other.aliases,
143147
)
144148

145149
def __repr__(self):
@@ -367,7 +371,7 @@ def description(self) -> str:
367371
return ""
368372

369373
@property
370-
def inputs(self) -> dict:
374+
def inputs(self) -> dict[int, PinSpecification]:
371375
"""Returns a dictionary mapping the input pin numbers to their ``PinSpecification``.
372376
373377
Returns
@@ -382,15 +386,15 @@ def inputs(self) -> dict:
382386
True
383387
>>> operator.specification.inputs[4]
384388
PinSpecification(name='data_sources', _type_names=['data_sources'], ...set', ellipsis=False,
385-
name_derived_class='')
389+
name_derived_class='', aliases=[...])
386390
"""
387391
if self._map_input_pin_spec is None:
388392
self._map_input_pin_spec = {}
389393
self._fill_pins(True, self._map_input_pin_spec)
390394
return self._map_input_pin_spec
391395

392396
@property
393-
def outputs(self) -> dict:
397+
def outputs(self) -> dict[int, PinSpecification]:
394398
"""Returns a dictionary mapping the output pin numbers to their ``PinSpecification``.
395399
396400
Returns
@@ -403,7 +407,7 @@ def outputs(self) -> dict:
403407
>>> operator = dpf.operators.mesh.mesh_provider()
404408
>>> operator.specification.outputs
405409
{0: PinSpecification(name='mesh', _type_names=['abstract_meshed_region'], ...=False,
406-
name_derived_class='')}
410+
name_derived_class='', aliases=[...])}
407411
"""
408412
if self._map_output_pin_spec is None:
409413
self._map_output_pin_spec = {}
@@ -429,7 +433,18 @@ def _fill_pins(self, binput, to_fill):
429433
self._api.operator_specification_get_pin_type_name(self, binput, i_pin, i_type)
430434
for i_type in range(n_types)
431435
]
432-
436+
pin_aliases = []
437+
if server_meet_version("10.0", self._server) and hasattr(
438+
self._api, "operator_specification_get_pin_num_aliases"
439+
):
440+
for i_alias in range(
441+
self._api.operator_specification_get_pin_num_aliases(self, binput, i_pin)
442+
):
443+
pin_aliases.append(
444+
self._api.operator_specification_get_pin_alias(
445+
self, binput, i_pin, i_alias
446+
)
447+
)
433448
pin_derived_class_type_name = ""
434449
if server_meet_version("7.0", self._server) and hasattr(
435450
self._api, "operator_specification_get_pin_derived_class_type_name"
@@ -448,6 +463,7 @@ def _fill_pins(self, binput, to_fill):
448463
pin_opt,
449464
pin_ell,
450465
pin_derived_class_type_name,
466+
pin_aliases,
451467
)
452468

453469
@property

src/ansys/dpf/core/operators/build.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ def build_pin_data(pins, output=False):
101101
"document": document,
102102
"document_pin_docstring": document_pin_docstring,
103103
"ellipsis": 0 if specification.ellipsis else -1,
104+
"has_aliases": len(specification.aliases) > 0,
105+
"aliases_list": [dict([("alias", alias)]) for alias in specification.aliases],
106+
"aliases": str(specification.aliases),
104107
}
105108

106109
if specification.ellipsis:
@@ -127,11 +130,13 @@ def build_operator(
127130
input_pins = []
128131
if specification.inputs:
129132
input_pins = build_pin_data(specification.inputs)
133+
has_input_aliases = any(len(pin["aliases_list"]) > 0 for pin in input_pins)
130134

131135
output_pins = []
132136
if specification.outputs:
133137
output_pins = build_pin_data(specification.outputs, output=True)
134138
multiple_output_types = any(pin["multiple_types"] for pin in output_pins)
139+
has_output_aliases = any(len(pin["aliases_list"]) > 0 for pin in output_pins)
135140

136141
docstring = build_docstring(specification_description)
137142

@@ -150,6 +155,8 @@ def build_operator(
150155
"multiple_output_types": multiple_output_types,
151156
"category": category,
152157
"date_and_time": date_and_time,
158+
"has_input_aliases": has_input_aliases,
159+
"has_output_aliases": has_output_aliases,
153160
}
154161

155162
this_path = os.path.dirname(os.path.abspath(__file__))
@@ -164,7 +171,7 @@ def build_operator(
164171

165172

166173
def build_operators():
167-
print(f"Generating operators for server {dpf.SERVER.version}")
174+
print(f"Generating operators for server {dpf.SERVER.version} ({dpf.SERVER.ansys_path})")
168175
time_0 = time.time()
169176

170177
this_path = os.path.dirname(os.path.abspath(__file__))
@@ -228,6 +235,7 @@ def build_operators():
228235
# Write to operator file
229236
operator_file = os.path.join(category_path, scripting_name + ".py")
230237
with open(operator_file, "wb") as f:
238+
operator_str = scripting_name
231239
try:
232240
operator_str = build_operator(
233241
specification,

src/ansys/dpf/core/operators/math/accumulate.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ class accumulate(Operator):
6161
"""
6262

6363
def __init__(
64-
self, fieldA=None, weights=None, time_scoping=None, config=None, server=None
64+
self,
65+
fieldA=None,
66+
weights=None,
67+
time_scoping=None,
68+
config=None,
69+
server=None,
70+
ponderation=None,
6571
):
6672
super().__init__(name="accumulate", config=config, server=server)
6773
self._inputs = InputsAccumulate(self)
@@ -70,6 +76,13 @@ def __init__(
7076
self.inputs.fieldA.connect(fieldA)
7177
if weights is not None:
7278
self.inputs.weights.connect(weights)
79+
elif ponderation is not None:
80+
warn(
81+
DeprecationWarning(
82+
f'Operator accumulate: Input name "ponderation" is deprecated in favor of "weights".'
83+
)
84+
)
85+
self.inputs.weights.connect(ponderation)
7386
if time_scoping is not None:
7487
self.inputs.time_scoping.connect(time_scoping)
7588

@@ -92,6 +105,7 @@ def _spec() -> Specification:
92105
type_names=["field"],
93106
optional=True,
94107
document=r"""Field containing weights, one weight per entity""",
108+
aliases=["ponderation"],
95109
),
96110
2: PinSpecification(
97111
name="time_scoping",
@@ -243,6 +257,18 @@ def time_scoping(self) -> Input:
243257
"""
244258
return self._time_scoping
245259

260+
def __getattr__(self, name):
261+
if name in ["ponderation"]:
262+
warn(
263+
DeprecationWarning(
264+
f'Operator accumulate: Input name "{name}" is deprecated in favor of "weights".'
265+
)
266+
)
267+
return self.weights
268+
raise AttributeError(
269+
f"'{self.__class__.__name__}' object has no attribute '{name}'."
270+
)
271+
246272

247273
class OutputsAccumulate(_Outputs):
248274
"""Intermediate class used to get outputs from

src/ansys/dpf/core/operators/math/accumulate_fc.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def __init__(
6767
time_scoping=None,
6868
config=None,
6969
server=None,
70+
ponderation=None,
7071
):
7172
super().__init__(name="accumulate_fc", config=config, server=server)
7273
self._inputs = InputsAccumulateFc(self)
@@ -75,6 +76,13 @@ def __init__(
7576
self.inputs.fields_container.connect(fields_container)
7677
if weights is not None:
7778
self.inputs.weights.connect(weights)
79+
elif ponderation is not None:
80+
warn(
81+
DeprecationWarning(
82+
f'Operator accumulate_fc: Input name "ponderation" is deprecated in favor of "weights".'
83+
)
84+
)
85+
self.inputs.weights.connect(ponderation)
7886
if time_scoping is not None:
7987
self.inputs.time_scoping.connect(time_scoping)
8088

@@ -97,6 +105,7 @@ def _spec() -> Specification:
97105
type_names=["field"],
98106
optional=True,
99107
document=r"""Field containing weights, one weight per entity""",
108+
aliases=["ponderation"],
100109
),
101110
2: PinSpecification(
102111
name="time_scoping",
@@ -248,6 +257,18 @@ def time_scoping(self) -> Input:
248257
"""
249258
return self._time_scoping
250259

260+
def __getattr__(self, name):
261+
if name in ["ponderation"]:
262+
warn(
263+
DeprecationWarning(
264+
f'Operator accumulate_fc: Input name "{name}" is deprecated in favor of "weights".'
265+
)
266+
)
267+
return self.weights
268+
raise AttributeError(
269+
f"'{self.__class__.__name__}' object has no attribute '{name}'."
270+
)
271+
251272

252273
class OutputsAccumulateFc(_Outputs):
253274
"""Intermediate class used to get outputs from

src/ansys/dpf/core/operators/math/add_constant.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,28 @@ class add_constant(Operator):
5353
>>> result_field = op.outputs.field()
5454
"""
5555

56-
def __init__(self, field=None, weights=None, config=None, server=None):
56+
def __init__(
57+
self,
58+
field=None,
59+
weights=None,
60+
config=None,
61+
server=None,
62+
ponderation=None,
63+
):
5764
super().__init__(name="add_constant", config=config, server=server)
5865
self._inputs = InputsAddConstant(self)
5966
self._outputs = OutputsAddConstant(self)
6067
if field is not None:
6168
self.inputs.field.connect(field)
6269
if weights is not None:
6370
self.inputs.weights.connect(weights)
71+
elif ponderation is not None:
72+
warn(
73+
DeprecationWarning(
74+
f'Operator add_constant: Input name "ponderation" is deprecated in favor of "weights".'
75+
)
76+
)
77+
self.inputs.weights.connect(ponderation)
6478

6579
@staticmethod
6680
def _spec() -> Specification:
@@ -80,6 +94,7 @@ def _spec() -> Specification:
8094
type_names=["double", "vector<double>"],
8195
optional=False,
8296
document=r"""double or vector of double""",
97+
aliases=["ponderation"],
8398
),
8499
},
85100
map_output_pin_spec={
@@ -200,6 +215,18 @@ def weights(self) -> Input:
200215
"""
201216
return self._weights
202217

218+
def __getattr__(self, name):
219+
if name in ["ponderation"]:
220+
warn(
221+
DeprecationWarning(
222+
f'Operator add_constant: Input name "{name}" is deprecated in favor of "weights".'
223+
)
224+
)
225+
return self.weights
226+
raise AttributeError(
227+
f"'{self.__class__.__name__}' object has no attribute '{name}'."
228+
)
229+
203230

204231
class OutputsAddConstant(_Outputs):
205232
"""Intermediate class used to get outputs from

0 commit comments

Comments
 (0)