Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/easyscience/Objects/variable/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from .descriptor_any_type import DescriptorAnyType
from .descriptor_bool import DescriptorBool
from .descriptor_number import DescriptorNumber
from .descriptor_str import DescriptorStr
from .parameter import Parameter

__all__ = [
DescriptorAnyType,
DescriptorBool,
DescriptorNumber,
DescriptorStr,
Expand Down
93 changes: 93 additions & 0 deletions src/easyscience/Objects/variable/descriptor_any_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from __future__ import annotations

import numbers
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Union

import numpy as np

from easyscience.global_object.undo_redo import property_stack_deco

from .descriptor_base import DescriptorBase


class DescriptorAnyType(DescriptorBase):
"""
A `Descriptor` for any type that does not fit the other Descriptors. Should be avoided when possible.
It was created to hold the symmetry operations used in the SpaceGroup class of EasyCrystallography.
"""

def __init__(
self,
name: str,
value: Any,
unique_name: Optional[str] = None,
description: Optional[str] = None,
url: Optional[str] = None,
display_name: Optional[str] = None,
parent: Optional[Any] = None,
):
"""Constructor for the DescriptorAnyType class

param name: Name of the descriptor
param value: Value of the descriptor
param description: Description of the descriptor
param url: URL of the descriptor
param display_name: Display name of the descriptor
param parent: Parent of the descriptor
.. note:: Undo/Redo functionality is implemented for the attributes `variance`, `error`, `unit` and `value`.
"""

self._value=value

super().__init__(
name=name,
unique_name=unique_name,
description=description,
url=url,
display_name=display_name,
parent=parent,
)

@property
def value(self) -> numbers.Number:
"""
Get the value.

:return: Value of self.
"""
return self._value

@value.setter
@property_stack_deco
def value(self, value: Union[list, np.ndarray]) -> None:
"""
Set the value of self.

:param value: New value for the DescriptorAnyType.
"""
self._value = value

def __copy__(self) -> DescriptorAnyType:
return super().__copy__()

def __repr__(self) -> str:
"""
Return a string representation of the DescriptorAnyType, showing its name and value.
"""

if hasattr(self._value, '__repr__'):
value_repr = repr(self._value)
else:
value_repr = type(self._value)

return f"<{self.__class__.__name__} '{self._name}': {value_repr}>"

def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]:
raw_dict = super().as_dict(skip=skip)
raw_dict['value'] = self._value
return raw_dict

92 changes: 92 additions & 0 deletions tests/unit_tests/Objects/variable/test_descriptor_any_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import pytest
import numpy as np

from easyscience.Objects.variable.descriptor_any_type import DescriptorAnyType
from easyscience import global_object

class TestDescriptorAnyType:
@pytest.fixture
def descriptor(self):
descriptor = DescriptorAnyType(
name="name",
value="string",
description="description",
url="url",
display_name="display_name",
parent=None,
)
return descriptor

@pytest.fixture
def clear(self):
global_object.map._clear()

def test_init(self, descriptor: DescriptorAnyType):
# When Then Expect
assert descriptor._value == "string"

# From super
assert descriptor._name == "name"
assert descriptor._description == "description"
assert descriptor._url == "url"
assert descriptor._display_name == "display_name"

def test_value(self, descriptor: DescriptorAnyType):
# When Then Expect
assert descriptor.value == "string"


@pytest.mark.parametrize("value", [True, "new_string", 1.0, np.array([1, 2, 3]),{"key": "value"}])
def test_set_value(self, descriptor: DescriptorAnyType,value):
# When Then
descriptor.value = value

# Expect
if isinstance(value, np.ndarray):
assert np.array_equal(descriptor._value, value)
else:
assert descriptor._value == value

@pytest.mark.parametrize(
"value, expected",
[
(True, "True"),
("new_string", "'new_string'"),
(1.0, "1.0"),
(np.array([1, 2, 3]), "array([1, 2, 3])"),
({"key": "value"}, "{'key': 'value'}")
]
)
def test_repr(self, descriptor: DescriptorAnyType, value, expected):
# Set the descriptor value
descriptor.value = value

# When Then
repr_str = str(descriptor)

print(repr_str)

# Expect
assert repr_str == f"<DescriptorAnyType 'name': {expected}>"

def test_copy(self, descriptor: DescriptorAnyType):
# When Then
descriptor_copy = descriptor.__copy__()

# Expect
assert type(descriptor_copy) == DescriptorAnyType
assert descriptor_copy._value == descriptor._value

def test_as_data_dict(self, clear, descriptor: DescriptorAnyType):
# When Then
descriptor_dict = descriptor.as_data_dict()

# Expect
assert descriptor_dict == {
"name": "name",
"value": "string",
"description": "description",
"url": "url",
"display_name": "display_name",
"unique_name": "DescriptorAnyType_0"
}
Loading