Skip to content

Commit 09885a7

Browse files
authored
fix: design and type hint of custom collections (#2695)
1 parent 3323383 commit 09885a7

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

src/ansys/dpf/core/__init__.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,16 @@
109109
from ansys.dpf.core.dpf_operator import available_operator_names
110110

111111

112-
from ansys.dpf.core.collection import CollectionFactory as _CollectionFactory
113112
from ansys.dpf.core.collection import Collection as _Collection
114113
from ansys.dpf.core.label_space import LabelSpace
115114

116115

117116
# register classes for collection types:
118-
CustomTypeFieldsCollection:type = _CollectionFactory(CustomTypeField)
119-
GenericDataContainersCollection:type = _CollectionFactory(GenericDataContainer)
120-
StringFieldsCollection:type = _CollectionFactory(StringField)
121-
OperatorsCollection: type = _CollectionFactory(Operator)
122-
AnyCollection:type = _Collection
117+
CustomTypeFieldsCollection = _Collection.collection_factory(CustomTypeField)
118+
GenericDataContainersCollection = _Collection.collection_factory(GenericDataContainer)
119+
StringFieldsCollection = _Collection.collection_factory(StringField)
120+
OperatorsCollection = _Collection.collection_factory(Operator)
121+
AnyCollection = _Collection
123122

124123
# for matplotlib
125124
# solves "QApplication: invalid style override passed, ignoring it."

src/ansys/dpf/core/collection.py

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525

2626
from __future__ import annotations
2727

28+
from typing import Generic, Type, TypeVar
29+
2830
from ansys.dpf.core import errors, server as server_module
2931
from ansys.dpf.core.any import Any
30-
from ansys.dpf.core.collection_base import TYPE, CollectionBase
32+
from ansys.dpf.core.collection_base import CollectionBase
3133
from ansys.dpf.core.common import create_dpf_instance
3234

35+
TYPE = TypeVar("TYPE")
36+
3337

34-
class Collection(CollectionBase[TYPE]):
38+
# Explicit Generic[TYPE] helps some type checkers Collection as a generic.
39+
class Collection(CollectionBase[TYPE], Generic[TYPE]):
3540
"""Represents a collection of dpf objects organised by label spaces.
3641
3742
Parameters
@@ -120,16 +125,39 @@ def add_entry(self, label_space, entry):
120125
"""
121126
return super()._add_entry(label_space, Any.new_from(entry, server=self._server))
122127

128+
@classmethod
129+
def collection_factory(cls, subtype: TYPE) -> Type[Collection[TYPE]]:
130+
"""Create classes deriving from Collection at runtime for a given subtype.
123131
124-
def CollectionFactory(subtype, BaseClass=Collection):
125-
"""Create classes deriving from Collection at runtime for a given subtype."""
132+
This factory method dynamically creates a new class that inherits from Collection
133+
and is specialized for storing entries of the specified subtype.
126134
127-
def __init__(self, **kwargs):
128-
BaseClass.__init__(self, **kwargs)
135+
Parameters
136+
----------
137+
subtype : type
138+
Any recognized DPF type. For example, CustomTypeField, GenericDataContainer,
139+
StringField, Operator, etc. This type will be used as the entries_type for
140+
the new collection class.
129141
130-
new_class = type(
131-
str(subtype.__name__) + "sCollection",
132-
(BaseClass,),
133-
{"__init__": __init__, "entries_type": subtype},
134-
)
135-
return new_class
142+
Returns
143+
-------
144+
Type[Collection[TYPE]]
145+
A new class that inherits from Collection and is specialized for the given
146+
subtype. The class name will be "{subtype.__name__}sCollection".
147+
148+
Examples
149+
--------
150+
>>> from ansys.dpf.core.string_field import StringField
151+
>>> from ansys.dpf.core.collection import Collection
152+
>>> string_fields_collection = Collection.collection_factory(StringField)()
153+
>>> string_fields_collection.__class__.__name__
154+
'StringFieldsCollection'
155+
>>> string_fields_collection.entries_type.__name__
156+
'StringField'
157+
"""
158+
new_class = type(
159+
str(subtype.__name__) + "sCollection",
160+
(cls,),
161+
{"entries_type": subtype},
162+
)
163+
return new_class

0 commit comments

Comments
 (0)