Skip to content

Commit 3a3738f

Browse files
authored
Merge pull request #76 from EasyScience/develop
Version 1.1.0
2 parents f757075 + 2b810a1 commit 3a3738f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+989
-489
lines changed

.github/workflows/python-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
strategy:
3131
max-parallel: 4
3232
matrix:
33-
python-version: ['3.9', '3.10', '3.11']
33+
python-version: ['3.9', '3.10', '3.11', '3.12']
3434
os: [ubuntu-latest, macos-latest, windows-latest]
3535

3636
runs-on: ${{ matrix.os }}

Examples/fitting/plot_constraints.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This example shows the usages of the different constraints.
55
"""
66

7-
from easyscience.fitting import Constraints
7+
from easyscience import Constraints
88
from easyscience.Objects.ObjectClasses import Parameter
99

1010
p1 = Parameter('p1', 1)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ classifiers = [
2727
"Programming Language :: Python :: 3.12",
2828
"Development Status :: 3 - Alpha"
2929
]
30-
requires-python = ">=3.9,<3.12"
30+
requires-python = ">=3.9,<3.13"
3131
dependencies = [
3232
"asteval",
3333
"bumps",

src/easyscience/Objects/Groups.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from typing import Union
1919

2020
from easyscience.global_object.undo_redo import NotarizedDict
21+
from easyscience.Objects.new_variable.descriptor_base import DescriptorBase
2122
from easyscience.Objects.ObjectClasses import BasedBase
2223
from easyscience.Objects.ObjectClasses import Descriptor
2324

@@ -40,6 +41,7 @@ def __init__(
4041
name: str,
4142
*args: Union[B, V],
4243
interface: Optional[iF] = None,
44+
unique_name: Optional[str] = None,
4345
**kwargs,
4446
):
4547
"""
@@ -51,7 +53,7 @@ def __init__(
5153
:param _kwargs: Fields which this class should contain
5254
:type _kwargs: dict
5355
"""
54-
BasedBase.__init__(self, name)
56+
BasedBase.__init__(self, name, unique_name=unique_name)
5557
kwargs = {key: kwargs[key] for key in kwargs.keys() if kwargs[key] is not None}
5658
_args = []
5759
for item in args:
@@ -67,7 +69,7 @@ def __init__(
6769
_kwargs[key] = item
6870
kwargs = _kwargs
6971
for item in list(kwargs.values()) + _args:
70-
if not issubclass(type(item), (Descriptor, BasedBase)):
72+
if not issubclass(type(item), (Descriptor, DescriptorBase, BasedBase)):
7173
raise AttributeError('A collection can only be formed from easyscience objects.')
7274
args = _args
7375
_kwargs = {}
@@ -83,10 +85,11 @@ def __init__(
8385
for key in kwargs.keys():
8486
if key in self.__dict__.keys() or key in self.__slots__:
8587
raise AttributeError(f'Given kwarg: `{key}`, is an internal attribute. Please rename.')
86-
self._global_object.map.add_edge(self, kwargs[key])
87-
self._global_object.map.reset_type(kwargs[key], 'created_internal')
88-
if interface is not None:
89-
kwargs[key].interface = interface
88+
if kwargs[key]: # Might be None (empty tuple or list)
89+
self._global_object.map.add_edge(self, kwargs[key])
90+
self._global_object.map.reset_type(kwargs[key], 'created_internal')
91+
if interface is not None:
92+
kwargs[key].interface = interface
9093
# TODO wrap getter and setter in Logger
9194
if interface is not None:
9295
self.interface = interface
@@ -104,7 +107,7 @@ def insert(self, index: int, value: Union[V, B]) -> None:
104107
:rtype: None
105108
"""
106109
t_ = type(value)
107-
if issubclass(t_, (BasedBase, Descriptor)):
110+
if issubclass(t_, (BasedBase, Descriptor, DescriptorBase)):
108111
update_key = list(self._kwargs.keys())
109112
values = list(self._kwargs.values())
110113
# Update the internal dict
@@ -165,7 +168,7 @@ def __setitem__(self, key: int, value: Union[B, V]) -> None:
165168
if isinstance(value, Number): # noqa: S3827
166169
item = self.__getitem__(key)
167170
item.value = value
168-
elif issubclass(type(value), BasedBase) or issubclass(type(value), Descriptor):
171+
elif issubclass(type(value), (BasedBase, Descriptor, DescriptorBase)):
169172
update_key = list(self._kwargs.keys())
170173
values = list(self._kwargs.values())
171174
old_item = values[key]

src/easyscience/Objects/ObjectClasses.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from .Variable import Parameter
2929

3030
if TYPE_CHECKING:
31-
from easyscience.fitting.Constraints import C
31+
from easyscience.Constraints import C
3232
from easyscience.Objects.Inferface import iF
3333
from easyscience.Objects.Variable import V
3434

@@ -186,7 +186,7 @@ def _get_linkable_attributes(self) -> List[V]:
186186
for key, item in self._kwargs.items():
187187
if hasattr(item, '_get_linkable_attributes'):
188188
item_list = [*item_list, *item._get_linkable_attributes()]
189-
elif issubclass(type(item), Descriptor) or issubclass(type(item), DescriptorBase):
189+
elif issubclass(type(item), (Descriptor, DescriptorBase)):
190190
item_list.append(item)
191191
return item_list
192192

@@ -215,6 +215,12 @@ def __dir__(self) -> Iterable[str]:
215215
new_class_objs = list(k for k in dir(self.__class__) if not k.startswith('_'))
216216
return sorted(new_class_objs)
217217

218+
def __copy__(self) -> BasedBase:
219+
"""Return a copy of the object."""
220+
temp = self.as_dict(skip=['unique_name'])
221+
new_obj = self.__class__.from_dict(temp)
222+
return new_obj
223+
218224

219225
if TYPE_CHECKING:
220226
B = TypeVar('B', bound=BasedBase)
@@ -346,7 +352,9 @@ def getter(obj: BV) -> BV:
346352
@staticmethod
347353
def __setter(key: str) -> Callable[[BV], None]:
348354
def setter(obj: BV, value: float) -> None:
349-
if issubclass(obj._kwargs[key].__class__, Descriptor) and not issubclass(value.__class__, Descriptor):
355+
if issubclass(obj._kwargs[key].__class__, (Descriptor, DescriptorBase)) and not issubclass(
356+
value.__class__, (Descriptor, DescriptorBase)
357+
):
350358
obj._kwargs[key].value = value
351359
else:
352360
obj._kwargs[key] = value

src/easyscience/Objects/Variable.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
from easyscience import global_object
3131
from easyscience import pint
3232
from easyscience import ureg
33-
from easyscience.fitting.Constraints import SelfConstraint
33+
from easyscience.Constraints import SelfConstraint
3434
from easyscience.global_object.undo_redo import property_stack_deco
3535
from easyscience.Objects.core import ComponentSerializer
3636
from easyscience.Utils.classTools import addProp
3737
from easyscience.Utils.Exceptions import CoreSetException
3838

3939
if TYPE_CHECKING:
40-
from easyscience.fitting.Constraints import C
40+
from easyscience.Constraints import C
4141

4242
Q_ = ureg.Quantity
4343
M_ = ureg.Measurement
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
from .descriptor_bool import DescriptorBool # noqa: F401
2-
from .descriptor_number import DescriptorNumber # noqa: F401
3-
from .descriptor_str import DescriptorStr # noqa: F401
4-
from .parameter import Parameter # noqa: F401
1+
from .descriptor_bool import DescriptorBool
2+
from .descriptor_number import DescriptorNumber
3+
from .descriptor_str import DescriptorStr
4+
from .parameter import Parameter
5+
6+
__all__ = [
7+
DescriptorBool,
8+
DescriptorNumber,
9+
DescriptorStr,
10+
Parameter,
11+
]

src/easyscience/Objects/new_variable/descriptor_base.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class DescriptorBase(ComponentSerializer, metaclass=abc.ABCMeta):
2727
# Used by serializer
2828
_REDIRECT = {'parent': None}
2929

30-
_global_object = global_object
3130

3231
def __init__(
3332
self,
@@ -55,7 +54,7 @@ def __init__(
5554
"""
5655

5756
if unique_name is None:
58-
unique_name = self._global_object.generate_unique_name(self.__class__.__name__)
57+
unique_name = global_object.generate_unique_name(self.__class__.__name__)
5958
self._unique_name = unique_name
6059

6160
if not isinstance(name, str):
@@ -80,10 +79,10 @@ def __init__(
8079

8180
# Let the collective know we've been assimilated
8281
self._parent = parent
83-
self._global_object.map.add_vertex(self, obj_type='created')
82+
global_object.map.add_vertex(self, obj_type='created')
8483
# Make the connection between self and parent
8584
if parent is not None:
86-
self._global_object.map.add_edge(parent, self)
85+
global_object.map.add_edge(parent, self)
8786

8887
@property
8988
def name(self) -> str:
@@ -187,7 +186,7 @@ def unique_name(self, new_unique_name: str):
187186
if not isinstance(new_unique_name, str):
188187
raise TypeError('Unique name has to be a string.')
189188
self._unique_name = new_unique_name
190-
self._global_object.map.add_vertex(self)
189+
global_object.map.add_vertex(self)
191190

192191
@property
193192
@abc.abstractmethod
@@ -205,7 +204,6 @@ def __repr__(self) -> str:
205204

206205
def __copy__(self) -> DescriptorBase:
207206
"""Return a copy of the object."""
208-
temp = self.as_dict()
209-
temp['unique_name'] = None
207+
temp = self.as_dict(skip=['unique_name'])
210208
new_obj = self.__class__.from_dict(temp)
211209
return new_obj

0 commit comments

Comments
 (0)