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
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* CIM classes now have to be instantiated with keyword arguments. The only accepted positional argument is mrid (or equivalent identifier)
* `__hash__` and `__eq__` are now based on object identity (parity with JVM); Name equality is based on its compound mRID.
* All internal magic `dataclassy` functionality (eg `__tuple__`) has been removed - treat all CIM classes as slotted `dataclass`
* ContactDetails are now Identifiable and no longer have default id generation. The constructor now requires a string. The `id` field is deprecated, to be replaced with mrid.

### New Features
* Added a `lint` tox environment that runs `ruff check .` to enforce code quality standards. The test environments now depend on lint passing first, so CI will fail if any new lint violations are introduced.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@
__all__ = ["ContactDetails"]

from typing import Generator, Any
from dataclasses import dataclass

from zepben.ewb.util import ngen, nlen
from typing_extensions import deprecated

from zepben.ewb import zb_dataclass
from zepben.ewb.model.cim.extensions.iec61968.common.contact_method_type import ContactMethodType
from zepben.ewb.model.cim.extensions.zbex import zbex
from zepben.ewb.model.cim.iec61968.common.electronic_address import ElectronicAddress
from zepben.ewb.model.cim.iec61968.common.street_address import StreetAddress

from zepben.ewb.model.cim.extensions.iec61968.common.contact_method_type import ContactMethodType
from zepben.ewb.model.cim.iec61968.common.telephone_number import TelephoneNumber
from zepben.ewb.dataclass_descriptors.dataclass_base import DataclassBase
from zepben.ewb.model.cim.iec61970.base.core.identifiable import Identifiable
from zepben.ewb.util import ngen, nlen


@zbex
@dataclass(slots=True)
class ContactDetails(DataclassBase):
@zb_dataclass
class ContactDetails(Identifiable):
"""[ZBEX] The details required to contact a person or company.

:var id: [ZBEX] The identifier for this contact, could be autogenerated.
:var contact_address: [ZBEX] Contact address, potentially different than 'streetAddress' (e.g., another city).
:var contact_type: [ZBEX] The type of contact, e.g. Account Owner.
Expand All @@ -35,8 +36,11 @@ class ContactDetails(DataclassBase):
:var electronic_addresses: [ZBEX] Electronic addresses.
"""

id: str
"""[ZBEX] The identifier for this contact, could be autogenerated."""
@property
@deprecated("Use obj.mrid instead")
def id(self) -> str:
"""[ZBEX] The identifier for this contact, could be autogenerated."""
return self.mrid

contact_address: StreetAddress | None = None
"""[ZBEX] Contact address, potentially different than 'streetAddress' (e.g., another city)."""
Expand All @@ -63,8 +67,13 @@ class ContactDetails(DataclassBase):

_electronic_addresses: list[ElectronicAddress] | None = None

def __init__(self, id: str, phone_numbers: list[TelephoneNumber] = None, electronic_addresses: list[ElectronicAddress] = None, **kwargs):
super(ContactDetails, self).__init__(id=id, **kwargs)
def __init__(self, id: str|None=None, *args, phone_numbers: list[TelephoneNumber] = None, electronic_addresses: list[ElectronicAddress] = None, **kwargs):
if id is not None:
if "mrid" in kwargs:
raise TypeError("ContactDetails.id is an alias for mrid. Do not pass both to the constructor!")
kwargs["mrid"] = id
super(ContactDetails, self).__init__(*args, **kwargs)

for number in phone_numbers or []:
self.add_phone_number(number)

Expand Down Expand Up @@ -175,7 +184,7 @@ def __eq__(self, other: Any) -> bool:
return False
return all((
self.is_primary == other.is_primary,
self.id == other.id,
self.mrid == other.mrid,
self.contact_address == other.contact_address,
self.contact_type == other.contact_type,
self.first_name == other.first_name,
Expand Down
7 changes: 1 addition & 6 deletions src/zepben/ewb/model/cim/iec61968/metering/usage_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,7 @@ def get_contact(self, _id: str) -> ContactDetails:

def add_contact(self, contact: ContactDetails) -> UsagePoint:
"""Add a `ContactDetails` to this `UsagePoint`"""
if self._validate_reference(
other=contact,
get_identifier=lambda it: it.id,
getter=self.get_contact,
type_description=lambda: f"A ContactDetails with ID {contact.id}",
):
if self._validate_reference(contact, self.get_contact, "A ContactDetails"):
return self

if self._contacts is None:
Expand Down
6 changes: 3 additions & 3 deletions test/cim/extensions/iec61968/common/test_contact_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


def test_contact_details_constructor_default():
c = ContactDetails(id="test")
c = ContactDetails(mrid="test")

assert c.contact_address is None
assert c.contact_type is None
Expand All @@ -26,7 +26,7 @@ def test_contact_details_constructor_default():

@given(**contact_details_kwargs())
def test_contact_details_constructor_kwargs(
id,
mrid,
contact_address,
contact_type,
first_name,
Expand All @@ -38,7 +38,7 @@ def test_contact_details_constructor_kwargs(
electronic_addresses,
):
c = ContactDetails(
id=id,
mrid=mrid,
contact_address=contact_address,
contact_type=contact_type,
first_name=first_name,
Expand Down
2 changes: 1 addition & 1 deletion test/cim/fill_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def create_contact_details():

def contact_details_kwargs():
return {
"id": text(alphabet=ALPHANUM, max_size=TEXT_MAX_SIZE, min_size=1),
"mrid": text(alphabet=ALPHANUM, max_size=TEXT_MAX_SIZE, min_size=1),
"contact_address": create_street_address(),
"contact_type": one_of(none(), text(alphabet=ALPHANUM, max_size=TEXT_MAX_SIZE)),
"first_name": one_of(none(), text(alphabet=ALPHANUM, max_size=TEXT_MAX_SIZE)),
Expand Down
5 changes: 2 additions & 3 deletions test/cim/iec61968/metering/test_usage_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,13 @@ def test_end_devices_collection():


def test_contacts_collection():
validate_unordered_other(
validate_unordered(
UsagePoint,
lambda _id: ContactDetails(id=str(_id)),
ContactDetails,
UsagePoint.contacts,
UsagePoint.num_contacts,
UsagePoint.get_contact,
UsagePoint.add_contact,
UsagePoint.remove_contact,
UsagePoint.clear_contacts,
lambda it: it.id,
)
Loading