feat: add get and create methods and **kwargs support for create#4866
feat: add get and create methods and **kwargs support for create#4866Gobot1234 wants to merge 33 commits into
Conversation
This needs settings api changes that I haven't figured out
There was a problem hiding this comment.
Pull request overview
This PR adds get and create class methods to the object-oriented API for clearer alternatives to using name and new_instance_name parameters. The implementation refactors initialization logic into a shared mixin class and enables passing additional kwargs when creating objects.
Changes:
- Refactored initialization logic into
_SettingsInitializerMixinbase class - Added
getclass method to_SingletonSettingfor retrieving singleton instances - Added
createclass method to_CreatableNamedObjectSettingfor creating new instances with optional attributes
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/ansys/fluent/core/solver/settings_builtin_bases.py | Adds mixin class for shared initialization logic and implements get/create class methods |
| src/ansys/fluent/core/solver/flobject.py | Updates _create_child_object and __getitem__ to accept and pass kwargs, enabling attribute setting during object creation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@Gobot1234 Please can we define the scope of the current work. E.g.:
If we know the scope, it makes it easier to understand the changes. Thanks. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| *, | ||
| name: str, | ||
| ) -> Self: | ||
| """Get and return the singleton instance of this object in Fluent. |
There was a problem hiding this comment.
The docstring describes this method as returning a 'singleton instance', but this is misleading for a named object that can have multiple instances. Consider changing to 'Get and return the named instance of this object in Fluent.'
|
I've had some words with both core (cpython) and ty (the typechecker) devs and I've needed to change the codegen a bit more to change the current settings generator script to output pascal cased names in the pyi file so that things don't break (currently they would if you evaluated them at runtime) and so ty is now better supported. |
this api makes no sense to me, why late initialise something like this?
There was a problem hiding this comment.
@seanpearsonuk please can I get some feedback on this, I'm not really sure why you'd choose to support late initialisation so I've remove it as it massively complicated the implementation.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (2)
src/ansys/fluent/core/solver/settings_builtin_data.py:677
DATAis missing reciprocal (singular/plural) links forPathlines/Pathline. The newget()/all()helpers rely onDATA[...][2]; leaving these asNonewill causeall()to fail for this named-object type. Add the appropriate reciprocal names so navigation works consistently.
"Pathlines": (
"Singleton",
"results.graphics.pathline",
None,
),
"Pathline": (
"NamedObject",
"results.graphics.pathline",
None,
),
src/ansys/fluent/core/solver/settings_builtin_data.py:764
Fluxesdeclares a reciprocal ("Flux") but theFluxentry leaves its reciprocal asNone. This breaks the assumption in the newget()/all()helpers that the reciprocal name exists for named-object wrappers. SetFlux’s reciprocal to"Fluxes"(and ensure the pair is symmetric).
"Fluxes": (
"Singleton",
"results.report.fluxes",
"Flux",
),
"Flux": (
"NamedObject",
"results.report.fluxes",
None,
),
| from typing_extensions import Self | ||
|
|
||
| from ansys.fluent.core.generated.solver.settings_261 import root as Settings | ||
| from ansys.fluent.core.solver.flobject import ( | ||
| InactiveObjectError, |
| "IsoSurfaces": ( | ||
| "Singleton", | ||
| "results.surfaces.iso_surface", | ||
| None, | ||
| ), | ||
| "IsoSurface": ( | ||
| "NamedObject", | ||
| "results.surfaces.iso_surface", | ||
| None, | ||
| ), |
| The following examples access the list of allowed values for a particular state of | ||
| the viscous model. All string and string list objects have an ``allowed_values()`` | ||
| method, which returns a list of allowed string values if such a constraint currently applies | ||
| for that object or returns ``None`` otherwise. |
| # Generate main .pyi file for the latest version processed | ||
| builtin_settingsgen.generate_main_pyi(version) |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (3)
src/ansys/fluent/core/solver/settings_builtin_bases.py:33
- Importing
ansys.fluent.core.generated.solver.settings_261in runtime code hard-codes a specific generated version and can raise ImportError in source checkouts / environments where generated modules are not present. Consider avoiding a runtime dependency on a specific generated version (e.g., move this import underTYPE_CHECKING, or typesettingsasSettingsBase/ a Protocol instead of a concrete generated root).
from typing import Any, Protocol, cast, runtime_checkable
from typing_extensions import Self
from ansys.fluent.core.generated.solver.settings_261 import root as Settings
from ansys.fluent.core.solver.flobject import (
InactiveObjectError,
NamedObject,
SettingsBase,
src/ansys/fluent/core/solver/settings_builtin_data.py:677
Pathlines/PathlinehaveNonefor the reciprocal field, but the new builtin.all()implementation expects the reciprocal name to exist. Consider settingPathlines->PathlineandPathline->Pathlines(or otherwise ensuring.all()doesn't depend on missing reciprocals) to prevent runtime errors.
"Pathlines": (
"Singleton",
"results.graphics.pathline",
None,
),
"Pathline": (
"NamedObject",
"results.graphics.pathline",
None,
),
src/ansys/fluent/core/solver/settings_builtin_data.py:764
Fluxis missing its reciprocal (it isNone), whileFluxespoints atFlux. With the new.all()implementation depending on reciprocals, callingFlux(...).all()will fail. Consider settingFlux->Fluxes(and verifying other NamedObject entries have reciprocals where.all()is expected to work).
"Fluxes": (
"Singleton",
"results.report.fluxes",
"Flux",
),
"Flux": (
"NamedObject",
"results.report.fluxes",
None,
),
| return cast( | ||
| list[Self], | ||
| list( | ||
| _get_settings_obj( | ||
| self.settings_source, | ||
| DATA[self._db_name][2], |
| # Only pass name if it's not None to avoid sending name=None to Fluent | ||
|
|
||
| return cast( | ||
| Self, | ||
| _get_settings_obj(self.settings_source, self._db_name).create( | ||
| name, **kwargs | ||
| ), | ||
| ) | ||
|
|
||
|
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 29 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
src/ansys/fluent/core/services/batch_ops_v1.py:1
src/ansys/fluent/core/services/batch_ops_v1.pyis deleted in this PR, butsrc/ansys/fluent/core/services/__init__.pystill hasfrom ansys.fluent.core.services.batch_ops_v1 import BatchOpsServiceat line 28. Importing the package will fail with aModuleNotFoundErrorat startup. Either restore the module or remove/replace the import (and any downstream usages ofBatchOpsService). The deletion of this file (and the related rewrites todatamodel_se_v1.py) also appear to be unrelated to the stated scope of this PR (addingget/create/alland kwargs support); consider extracting them into a separate change.
| @@ -246,6 +241,12 @@ def update_dict( | |||
| """RPC UpdateDict of DataModel service.""" | |||
| return self._stub.UpdateDict(request, metadata=self._metadata) | |||
|
|
|||
| def create_object( | |||
| self, request: DataModelProtoModule.CreateObjectRequest | |||
| ) -> DataModelProtoModule.CreateObjectResponse: | |||
| """RPC CreateObject of DataModel service.""" | |||
| return self._stub.CreateObject(request, metadata=self._metadata) | |||
|
|
|||
| def delete_object( | |||
| self, request: DataModelProtoModule.DeleteObjectRequest | |||
| ) -> DataModelProtoModule.DeleteObjectResponse: | |||
| @@ -291,17 +292,11 @@ def delete_command_arguments( | |||
| "supported from Ansys 2023R2 onward." | |||
| ) from None | |||
|
|
|||
| def get_specs( | |||
| self, request: DataModelProtoModule.GetSpecsRequest | |||
| ) -> DataModelProtoModule.GetSpecsResponse: | |||
| """RPC GetSpecs of DataModel service.""" | |||
| return self._stub.GetSpecs(request, metadata=self._metadata) | |||
|
|
|||
| def get_static_info( | |||
| self, request: DataModelProtoModule.GetStaticInfoRequest | |||
| ) -> DataModelProtoModule.GetStaticInfoResponse: | |||
| """RPC GetStaticInfo of DataModel service.""" | |||
| return self._stub.GetStaticInfo(request, metadata=self._metadata) | |||
| def get_schema( | |||
| self, request: DataModelProtoModule.GetSchemaRequest | |||
| ) -> DataModelProtoModule.GetSchemaResponse: | |||
| """RPC GetSchema of DataModel service.""" | |||
| return self._stub.GetSchema(request, metadata=self._metadata) | |||
| def __init__( | ||
| self, | ||
| settings_source: SettingsBase[object] | Solver | None = None, | ||
| /, | ||
| **kwargs: Any, | ||
| ): |
| >>> velocity_request = VectorFieldDataRequest( | ||
| >>> field_name=VariableCatalog.VELOCITY, | ||
| >>> surfaces=VelocityInlets(settings_source=solver_session), | ||
| >>> surfaces=VelocityInlets(solver_session).get("inlet"), |
| elif k in obj.argument_names: | ||
| newkwds[k] = v | ||
| else: | ||
| elif k not in obj.get_active_child_names(): | ||
| unknown_keywords.add(k) |
| db_name_to_use = DATA[self.__class__._db_name][2] | ||
| if db_name_to_use is not None: | ||
| self.__dict__["_db_name"] = db_name_to_use | ||
| settings_root = _get_settings_root(effective_source) | ||
| if self._should_materialize(): | ||
| # Create extras dict with navigation params only (exclude wrapper params) | ||
| extras = { | ||
| k: v for k, v in self.__dict__.items() if k not in {"name", "kwargs"} | ||
| } | ||
| parent = _get_settings_obj(settings_root, self._db_name, extras=extras) | ||
| obj = self._init_settings_instance(parent) | ||
| _swap(self, settings_root, obj) | ||
| if db_name_to_use is not None: | ||
| self.__dict__["_db_name"] = db_name_to_use | ||
| else: | ||
| super().__setattr__(name, value) | ||
| # Container proxy: store session for get()/all(). | ||
| self.__dict__["settings_source"] = settings_root |
| pyi_entries = [] # list of (decorator: str|None, class_def: str) | ||
| base_class_names = set() # PascalCase names to import from settings_{version} | ||
| for legacy_name, v in DATA.items(): | ||
| kind, path, recip = v # reciprical name (singleton -> parent, parent -> singleton) |
| comps = path.split(".") | ||
| for comp in comps: | ||
| cls = cls._child_classes[comp] | ||
| # Check if the class has 'create' its command names (singletons) or its child classes (deprecated plural forms) |
The API surface now looks like which is fairly ORM like
Context
Fixes #4863
And adds create and get methods as more clear methods for using name and new_instance_name to the object oriented API
Scope
This PR affects all of the object oriented API, and some of the settings API related code surrounding child creation
This is due to the following changes:
.create()and the object oriented types #4863)