Skip to content

Commit 63f280b

Browse files
authored
Merge branch 'main' into fix/export-facets
2 parents 6ee267e + f7e8d3f commit 63f280b

File tree

12 files changed

+394
-29
lines changed

12 files changed

+394
-29
lines changed

doc/changelog.d/2260.test.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adding test coverage for nurbs, design, and geometry commands
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prevent invalid kwargs from being passed to launcher methods

src/ansys/geometry/core/connection/launcher.py

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
)
3636
from ansys.geometry.core.connection.product_instance import prepare_and_start_backend
3737
from ansys.geometry.core.logger import LOG
38-
from ansys.geometry.core.misc.checks import check_type, deprecated_argument
38+
from ansys.geometry.core.misc.checks import (
39+
check_type,
40+
deprecated_argument,
41+
kwargs_passed_not_accepted,
42+
)
3943

4044
try:
4145
import ansys.platform.instancemanagement as pypim
@@ -233,6 +237,7 @@ def _launch_with_automatic_detection(**kwargs: dict | None) -> "Modeler":
233237
raise NotImplementedError("Geometry service cannot be initialized.")
234238

235239

240+
@kwargs_passed_not_accepted
236241
def launch_remote_modeler(
237242
platform: str = "windows",
238243
version: str | None = None,
@@ -287,6 +292,7 @@ def launch_remote_modeler(
287292
)
288293

289294

295+
@kwargs_passed_not_accepted
290296
def launch_docker_modeler(
291297
port: int = pygeom_defaults.DEFAULT_PORT,
292298
connect_to_existing_service: bool = True,
@@ -362,6 +368,7 @@ def launch_docker_modeler(
362368
)
363369

364370

371+
@kwargs_passed_not_accepted
365372
def launch_modeler_with_discovery_and_pimlight(
366373
version: str | None = None,
367374
client_log_level: int = logging.INFO,
@@ -404,6 +411,7 @@ def launch_modeler_with_discovery_and_pimlight(
404411
)
405412

406413

414+
@kwargs_passed_not_accepted
407415
def launch_modeler_with_geometry_service_and_pimlight(
408416
version: str | None = None,
409417
client_log_level: int = logging.INFO,
@@ -446,6 +454,7 @@ def launch_modeler_with_geometry_service_and_pimlight(
446454
)
447455

448456

457+
@kwargs_passed_not_accepted
449458
def launch_modeler_with_spaceclaim_and_pimlight(
450459
version: str | None = None,
451460
client_log_level: int = logging.INFO,
@@ -488,6 +497,7 @@ def launch_modeler_with_spaceclaim_and_pimlight(
488497
)
489498

490499

500+
@kwargs_passed_not_accepted
491501
@deprecated_argument("product_version", "version", version="0.10.8", remove="0.13.0")
492502
def launch_modeler_with_geometry_service(
493503
version: str | int | None = None,
@@ -587,13 +597,6 @@ def launch_modeler_with_geometry_service(
587597
timeout=300,
588598
server_log_level=0)
589599
"""
590-
# if api_version is passed, throw a warning saying that it is not used
591-
if "api_version" in kwargs:
592-
LOG.warning(
593-
"The 'api_version' parameter is not used in 'launch_modeler_with_geometry_service'. "
594-
"Please remove it from the arguments."
595-
)
596-
597600
# If we are in a Windows environment, we are going to write down the server
598601
# logs in the %PUBLIC%/Documents/Ansys/GeometryService folder.
599602
if os.name == "nt" and server_logs_folder is None:
@@ -617,6 +620,7 @@ def launch_modeler_with_geometry_service(
617620
)
618621

619622

623+
@kwargs_passed_not_accepted
620624
@deprecated_argument("product_version", "version", version="0.10.8", remove="0.13.0")
621625
def launch_modeler_with_discovery(
622626
version: str | int | None = None,
@@ -720,13 +724,6 @@ def launch_modeler_with_discovery(
720724
timeout=300,
721725
server_log_level=0)
722726
"""
723-
for unused_var in ["server_logs_folder", "logs_folder"]:
724-
if unused_var in kwargs:
725-
LOG.warning(
726-
f"The '{unused_var}' parameter is not used in 'launch_modeler_with_discovery'. "
727-
"Please remove it from the arguments."
728-
)
729-
730727
return prepare_and_start_backend(
731728
BackendType.DISCOVERY,
732729
version=version,
@@ -744,6 +741,7 @@ def launch_modeler_with_discovery(
744741
)
745742

746743

744+
@kwargs_passed_not_accepted
747745
@deprecated_argument("product_version", "version", version="0.10.8", remove="0.13.0")
748746
def launch_modeler_with_spaceclaim(
749747
version: str | int | None = None,
@@ -847,13 +845,6 @@ def launch_modeler_with_spaceclaim(
847845
timeout=300,
848846
server_log_level=0)
849847
"""
850-
for unused_var in ["server_logs_folder", "logs_folder"]:
851-
if unused_var in kwargs:
852-
LOG.warning(
853-
f"The '{unused_var}' parameter is not used in 'launch_modeler_with_spaceclaim'. "
854-
"Please remove it from the arguments."
855-
)
856-
857848
return prepare_and_start_backend(
858849
BackendType.SPACECLAIM,
859850
version=version,
@@ -871,6 +862,7 @@ def launch_modeler_with_spaceclaim(
871862
)
872863

873864

865+
@kwargs_passed_not_accepted
874866
@deprecated_argument("product_version", "version", version="0.10.8", remove="0.13.0")
875867
def launch_modeler_with_core_service(
876868
version: str | int | None = None,
@@ -970,13 +962,6 @@ def launch_modeler_with_core_service(
970962
timeout=300,
971963
server_log_level=0)
972964
"""
973-
# if api_version is passed, throw a warning saying that it is not used
974-
if "api_version" in kwargs:
975-
LOG.warning(
976-
"The 'api_version' parameter is not used in 'launch_modeler_with_core_service'. "
977-
"Please remove it from the arguments."
978-
)
979-
980965
# If we are in a Windows environment, we are going to write down the server
981966
# logs in the %PUBLIC%/Documents/Ansys/GeometryService folder.
982967
if os.name == "nt" and server_logs_folder is None:

src/ansys/geometry/core/misc/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
deprecated_argument,
4646
deprecated_method,
4747
graphics_required,
48+
kwargs_passed_not_accepted,
4849
min_backend_version,
4950
run_if_graphics_required,
5051
)

src/ansys/geometry/core/misc/checks.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,79 @@ def wrapper(*args, **kwargs):
478478
return method(*args, **kwargs)
479479

480480
return wrapper
481+
482+
483+
def kwargs_passed_not_accepted(method):
484+
"""Check that no unexpected kwargs are passed to the method.
485+
486+
This decorator will raise a TypeError if any keyword arguments are passed
487+
to the decorated method that don't correspond to the method's parameters.
488+
If the method has ``**kwargs`` in its signature, this decorator will raise an
489+
error for any kwargs passed to it (that are not explicitly accepted).
490+
491+
Parameters
492+
----------
493+
method : callable
494+
The method to decorate.
495+
496+
Returns
497+
-------
498+
callable
499+
Decorated method that raises TypeError if unexpected kwargs are passed.
500+
501+
Raises
502+
------
503+
TypeError
504+
If unexpected keyword arguments are passed to the decorated method.
505+
506+
Examples
507+
--------
508+
>>> @kwargs_passed_not_accepted
509+
... def my_method(arg1, arg2):
510+
... return arg1 + arg2
511+
>>> my_method(1, 2) # Works fine
512+
3
513+
>>> my_method(arg1=1, arg2=2) # Works fine
514+
3
515+
>>> my_method(1, 2, invalid_arg=3) # Raises TypeError
516+
TypeError: The following keyword arguments are not accepted
517+
in the method 'my_method': invalid_arg.
518+
>>> @kwargs_passed_not_accepted
519+
... def my_method_with_kwargs(arg1, arg2, **kwargs):
520+
... return arg1 + arg2
521+
>>> my_method_with_kwargs(1, 2, invalid_arg=3) # Raises TypeError
522+
TypeError: The following keyword arguments are not accepted
523+
in the method 'my_method_with_kwargs': invalid_arg.
524+
"""
525+
import inspect
526+
527+
def wrapper(*args, **kwargs):
528+
# Get the method signature
529+
sig = inspect.signature(method)
530+
531+
# Check if method has **kwargs parameter
532+
has_var_keyword = any(
533+
param.kind == inspect.Parameter.VAR_KEYWORD for param in sig.parameters.values()
534+
)
535+
536+
# If method has **kwargs and kwargs are passed...
537+
if has_var_keyword and len(kwargs) > 0:
538+
# Retrieve a list of all parameter names excluding **kwargs
539+
param_names = {
540+
name
541+
for name, param in sig.parameters.items()
542+
if param.kind != inspect.Parameter.VAR_KEYWORD
543+
}
544+
545+
# Identify unexpected kwargs
546+
unexpected_kwargs = [key for key in kwargs.keys() if key not in param_names]
547+
548+
if unexpected_kwargs:
549+
raise TypeError(
550+
"The following keyword arguments are not accepted in the"
551+
+ f" method '{method.__name__}': {', '.join(unexpected_kwargs)}."
552+
)
553+
554+
return method(*args, **kwargs)
555+
556+
return wrapper

tests/_incompatible_tests.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ backends:
5858
- tests/integration/test_spaceclaim_tutorial_examples.py::test_combine_example
5959
- tests/integration/test_spaceclaim_tutorial_examples.py::test_pull_example
6060
- tests/integration/test_spaceclaim_tutorial_examples.py::test_intersect_example
61+
- tests/integration/test_design.py::test_legacy_export_download
62+
- tests/integration/test_design.py::test_updating_design_from_tracker
63+
- tests/integration/test_design.py::test_failure_for_export
6164
# Opening large files through streaming is only available from 25.2 onwards
6265
- tests/integration/test_design.py::test_modeler_open_files
6366
# Named selections elements are only consistent from 25.2 onwards
@@ -83,6 +86,8 @@ backends:
8386
- tests/integration/test_design_import.py::test_design_import_solid_edge2025
8487
- tests/integration/test_design_import.py::test_design_import_nx2412
8588
- tests/integration/test_design_import.py::test_design_import_inventor2026
89+
- tests/integration/test_design.py::test_legacy_export_download
90+
- tests/integration/test_design.py::test_failure_for_export
8691
# Bug fix included from 25.2 onwards
8792
- tests/integration/test_issues.py::test_issue_1192_temp_body_on_empty_intersect
8893
- tests/integration/test_issues.py::test_issue_2251_double_import_crash
@@ -169,6 +174,9 @@ backends:
169174
- tests/integration/test_spaceclaim_tutorial_examples.py::test_combine_example
170175
- tests/integration/test_spaceclaim_tutorial_examples.py::test_pull_example
171176
- tests/integration/test_spaceclaim_tutorial_examples.py::test_intersect_example
177+
- tests/integration/test_design.py::test_legacy_export_download
178+
- tests/integration/test_design.py::test_updating_design_from_tracker
179+
- tests/integration/test_design.py::test_failure_for_export
172180
# Opening large files through streaming is only available from 25.2 onwards
173181
- tests/integration/test_design.py::test_modeler_open_files
174182
# Named selections elements are only consistent from 25.2 onwards
@@ -203,6 +211,8 @@ backends:
203211
- tests/integration/test_design_import.py::test_design_import_solid_edge2025
204212
- tests/integration/test_design_import.py::test_design_import_nx2412
205213
- tests/integration/test_design_import.py::test_design_import_inventor2026
214+
- tests/integration/test_design.py::test_legacy_export_download
215+
- tests/integration/test_design.py::test_failure_for_export
206216
# Insert file naming convention changed in 26.1
207217
- tests/integration/test_design_import.py::test_design_insert
208218
# Bug fix included from 25.2 onwards
@@ -230,6 +240,9 @@ backends:
230240
- tests/integration/test_spaceclaim_tutorial_examples.py::test_combine_example
231241
- tests/integration/test_spaceclaim_tutorial_examples.py::test_pull_example
232242
- tests/integration/test_spaceclaim_tutorial_examples.py::test_intersect_example
243+
- tests/integration/test_design.py::test_legacy_export_download
244+
- tests/integration/test_design.py::test_updating_design_from_tracker
245+
- tests/integration/test_design.py::test_failure_for_export
233246
# Opening large files through streaming is only available from 25.2 onwards
234247
- tests/integration/test_design.py::test_modeler_open_files
235248
# Named selections elements are only consistent from 25.2 onwards
@@ -264,6 +277,8 @@ backends:
264277
- tests/integration/test_design_import.py::test_design_import_jt
265278
- tests/integration/test_design_import.py::test_design_import_solid_edge2025
266279
- tests/integration/test_design_import.py::test_design_import_nx2412
280+
- tests/integration/test_design.py::test_legacy_export_download
281+
- tests/integration/test_design.py::test_failure_for_export
267282
# Insert file naming convention changed in 26.1
268283
- tests/integration/test_design_import.py::test_design_insert
269284
# Importing named selections from design was not available prior to 26.1
@@ -315,6 +330,8 @@ backends:
315330
- tests/integration/test_design_export.py::test_import_export_open_file_design[PARASOLID_TEXT-x_t-rci_std.x_t-2-1]
316331
- tests/integration/test_design_export.py::test_import_export_open_file_design[SCDOCX-scdocx-reactorWNS.scdocx-1-3]
317332
- tests/integration/test_design_import.py::test_design_insert_id_bug
333+
- tests/integration/test_design.py::test_legacy_export_download
334+
- tests/integration/test_design.py::test_failure_for_export
318335
# Insert file naming convention changed in 26.1
319336
- tests/integration/test_design_import.py::test_design_insert
320337
# Importing named selections from design was not available prior to 26.1
56.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)