Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use literal type instead of enum type for _typ #905

Merged
merged 8 commits into from
Oct 10, 2024
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 docs/compatibility/change_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ChangeType(StrEnum):
FIELD_REMOVED = "field_removed"
FIELD_DEFAULT_CHANGED = "field_default_changed"
FIELD_DESCRIPTION_CHANGED = "field_description_changed"
FIELD_TITLE_CHANGED = "field_title_changed"
# field type change types
FIELD_CARDINALITY_CHANGED = "field_cardinality_changed"
FIELD_REFERENCE_CHANGED = "field_reference_changed"
Expand Down
39 changes: 28 additions & 11 deletions docs/compatibility/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import itertools
import logging
import re
from pathlib import Path
from typing import Iterable, Sequence
Expand All @@ -11,6 +12,8 @@

from . import change_schemas, loader

logger = logging.getLogger(__name__)

REGEX_IGNORE_VERSION = re.compile(r"v\d+\.\d+\.\d+(-rc\d+)?")


Expand All @@ -21,11 +24,23 @@ def _diff_type_base(
This function compares two type base schemas and yields the changes.
"""
if schema_old.title != schema_new.title:
raise RuntimeError(
logger.warning(
(
"Title should not change. Renaming is not detectable and the titles are autogenerated.\n"
f"{schema_old.title} -> {schema_new.title}"
)
"'%s' -> '%s'\n"
"%s -> %s"
),
schema_old.title,
schema_new.title,
old_trace,
new_trace,
)
yield change_schemas.Change(
type=change_schemas.ChangeType.FIELD_TITLE_CHANGED,
old=schema_old.title,
new=schema_new.title,
old_trace=old_trace,
new_trace=new_trace,
)
if REGEX_IGNORE_VERSION.sub(schema_old.description, "{__gh_version__}") != REGEX_IGNORE_VERSION.sub(
schema_new.description, "{__gh_version__}"
Expand Down Expand Up @@ -288,7 +303,9 @@ def _diff_root_schemas(
yield from _diff_schema_type(schema_old, schema_new, old_trace, new_trace)


def diff_schemas(schemas_old: Path, schemas_new: Path) -> Iterable[change_schemas.Change]:
def diff_schemas(
schemas_old: Path, schemas_new: Path, old_trace: str, new_trace: str
) -> Iterable[change_schemas.Change]:
"""
This function compares two BO4E versions and yields the changes.
Note: The paths to the old and the new schemas should correspond to the same root node of the tree structure.
Expand All @@ -302,23 +319,23 @@ def diff_schemas(schemas_old: Path, schemas_new: Path) -> Iterable[change_schema
type=change_schemas.ChangeType.CLASS_REMOVED,
old=loader.load_schema_file(schemas_old / schema_file),
new=None,
old_trace=f"{'/'.join(schema_file.with_suffix('').parts)}#",
new_trace="#",
old_trace=f"{old_trace}/{'/'.join(schema_file.with_suffix('').parts)}#",
new_trace=f"{new_trace}/#",
)
for schema_file in new_schema_files - old_schema_files:
yield change_schemas.Change(
type=change_schemas.ChangeType.CLASS_ADDED,
old=None,
new=loader.load_schema_file(schemas_new / schema_file),
old_trace="#",
new_trace=f"{'/'.join(schema_file.with_suffix('').parts)}#",
old_trace=f"{old_trace}/#",
new_trace=f"{new_trace}/{'/'.join(schema_file.with_suffix('').parts)}#",
)
for schema_file in old_schema_files & new_schema_files:
yield from _diff_root_schemas(
loader.load_schema_file(schemas_old / schema_file),
loader.load_schema_file(schemas_new / schema_file),
f"{'/'.join(schema_file.with_suffix('').parts)}#",
f"{'/'.join(schema_file.with_suffix('').parts)}#",
f"{old_trace}/{'/'.join(schema_file.with_suffix('').parts)}#",
f"{new_trace}/{'/'.join(schema_file.with_suffix('').parts)}#",
)


Expand All @@ -333,7 +350,7 @@ def compare_bo4e_versions(
dir_old_schemas = loader.pull_or_reuse_bo4e_version(version_old, gh_token)
dir_new_schemas = loader.pull_or_reuse_bo4e_version(version_new, gh_token, from_local=from_local)
print(f"Comparing {version_old} with {version_new}")
yield from diff_schemas(dir_old_schemas, dir_new_schemas)
yield from diff_schemas(dir_old_schemas, dir_new_schemas, version_old, version_new)


def compare_bo4e_versions_iteratively(
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/angebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# pylint: disable=too-few-public-methods, too-many-instance-attributes
# pylint: disable=no-name-in-module
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

import pydantic
from pydantic import Field
Expand Down Expand Up @@ -38,7 +38,7 @@ class Angebot(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.ANGEBOT
typ: Annotated[Literal[Typ.ANGEBOT], Field(alias="_typ")] = Typ.ANGEBOT
#: Eindeutige Nummer des Angebotes
angebotsnummer: Optional[str] = None
#: Erstellungsdatum des Angebots
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/ausschreibung.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# pylint: disable=too-few-public-methods, too-many-instance-attributes
# pylint: disable=no-name-in-module
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

import pydantic
from pydantic import Field
Expand Down Expand Up @@ -36,7 +36,7 @@ class Ausschreibung(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.AUSSCHREIBUNG
typ: Annotated[Literal[Typ.AUSSCHREIBUNG], Field(alias="_typ")] = Typ.AUSSCHREIBUNG
#: Vom Herausgeber der Ausschreibung vergebene eindeutige Nummer
ausschreibungsnummer: Optional[str] = None
#: Aufzählung für die Typisierung von Ausschreibungen
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/buendelvertrag.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# pylint: disable=too-few-public-methods
# pylint: disable=no-name-in-module
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

import pydantic
from pydantic import Field
Expand Down Expand Up @@ -38,7 +38,7 @@ class Buendelvertrag(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.BUENDELVERTRAG
typ: Annotated[Literal[Typ.BUENDELVERTRAG], Field(alias="_typ")] = Typ.BUENDELVERTRAG

# pylint: disable=duplicate-code
#: Eine im Verwendungskontext eindeutige Nummer für den Vertrag
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/energiemenge.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -34,7 +34,7 @@ class Energiemenge(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.ENERGIEMENGE
typ: Annotated[Literal[Typ.ENERGIEMENGE], Field(alias="_typ")] = Typ.ENERGIEMENGE
#: Eindeutige Nummer der Marktlokation bzw. der Messlokation, zu der die Energiemenge gehört
lokations_id: Optional[str] = None
# todo: add validator such that only mess- or marktlokations IDs are accepted + cross check with lokationstyp
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/fremdkosten.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Contains Fremdkosten class and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -35,7 +35,7 @@ class Fremdkosten(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.FREMDKOSTEN
typ: Annotated[Literal[Typ.FREMDKOSTEN], Field(alias="_typ")] = Typ.FREMDKOSTEN
#: Für diesen Zeitraum wurden die Kosten ermittelt
gueltigkeit: Optional["Zeitraum"] = None
#: Die Gesamtsumme über alle Kostenblöcke und -positionen
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/geraet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -33,7 +33,7 @@ class Geraet(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.GERAET
typ: Annotated[Literal[Typ.GERAET], Field(alias="_typ")] = Typ.GERAET

#: Die auf dem Gerät aufgedruckte Nummer, die vom MSB vergeben wird.
geraetenummer: Optional[str] = None
Expand Down
6 changes: 1 addition & 5 deletions src/bo4e/bo/geschaeftsobjekt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
from bo4e.version import __version__
from bo4e.zusatzattribut import ZusatzAttribut

from ..enum.typ import Typ
from ..utils import postprocess_docstring

# pylint: disable=too-few-public-methods


@postprocess_docstring
class Geschaeftsobjekt(BaseModel):
class Geschaeftsobjekt(BaseModel): # pragma: no cover
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was macht das pragma?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Es schließt die Codezeilen von der Klasse aus dem Coverage-Bericht aus. Vielleicht ist das auch gar nicht nötig, fand es aber sinnvoll, da ich den Unittest vom Geschaeftsobjekt entfernt habe.

"""
Das BO Geschäftsobjekt ist der Master für alle Geschäftsobjekte.
Alle Attribute, die hier in diesem BO enthalten sind, werden an alle BOs vererbt.
Expand All @@ -35,9 +34,6 @@ class Geschaeftsobjekt(BaseModel):
version: Annotated[Optional[str], Field(alias="_version")] = (
__version__ #: Version der BO-Struktur aka "fachliche Versionierung"
)
# src/_bo4e_python_version.py
typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.GESCHAEFTSOBJEKT #: Der Typ des Geschäftsobjektes
# bo_typ is used as discriminator f.e. for databases or deserialization

zusatz_attribute: Optional[list["ZusatzAttribut"]] = None
# zusatz_attribute is a list of ZusatzAttribut objects which are used to store additional information
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/geschaeftspartner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""

# pylint: disable=too-many-instance-attributes, too-few-public-methods, disable=duplicate-code
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -39,7 +39,7 @@ class Geschaeftspartner(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.GESCHAEFTSPARTNER
typ: Annotated[Literal[Typ.GESCHAEFTSPARTNER], Field(alias="_typ")] = Typ.GESCHAEFTSPARTNER
#: Mögliche Anrede der Person
anrede: Optional["Anrede"] = None
individuelle_anrede: Optional[str] = None
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/kosten.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Contains Kosten class and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -36,7 +36,7 @@ class Kosten(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.KOSTEN
typ: Annotated[Literal[Typ.KOSTEN], Field(alias="_typ")] = Typ.KOSTEN
#: Klasse der Kosten, beispielsweise Fremdkosten
kostenklasse: Optional["Kostenklasse"] = None
#: Für diesen Zeitraum wurden die Kosten ermittelt
Expand Down
8 changes: 4 additions & 4 deletions src/bo4e/bo/lastgang.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

# pylint: disable=too-few-public-methods
# pylint: disable=no-name-in-module
from pydantic import Field, constr
from pydantic import Field

from ..enum.typ import Typ
from ..utils import postprocess_docstring
Expand Down Expand Up @@ -40,7 +40,7 @@ class Lastgang(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.LASTGANG
typ: Annotated[Literal[Typ.LASTGANG], Field(alias="_typ")] = Typ.LASTGANG
#: Angabe, ob es sich um einen Gas- oder Stromlastgang handelt
sparte: Optional["Sparte"] = None
#: Definition der gemessenen Größe anhand ihrer Einheit
Expand All @@ -54,5 +54,5 @@ class Lastgang(Geschaeftsobjekt):
#: Versionsnummer des Lastgangs
version: Optional[str] = None
#: Die OBIS-Kennzahl für den Wert, die festlegt, welche Größe mit dem Stand gemeldet wird, z.B. '1-0:1.8.1'
obis_kennzahl: Optional[constr(strict=True)] = None # type: ignore[valid-type]
obis_kennzahl: Optional[str] = None
zeit_intervall_laenge: Optional["Menge"]
4 changes: 2 additions & 2 deletions src/bo4e/bo/lokationszuordnung.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Contains Lokationszuordnung class
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -33,7 +33,7 @@ class Lokationszuordnung(Geschaeftsobjekt):
`Lokationszuordnung JSON Schema <https://json-schema.app/view/%23?url=https://raw.githubusercontent.com/BO4E/BO4E-Schemas/{__gh_version__}/src/bo4e_schemas/bo/Lokationszuordnung.json>`_
"""

typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.LOKATIONSZUORDNUNG
typ: Annotated[Literal[Typ.LOKATIONSZUORDNUNG], Field(alias="_typ")] = Typ.LOKATIONSZUORDNUNG

#: Liste mit referenzierten Marktlokationen
marktlokationen: Optional[list["Marktlokation"]] = None
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/marktlokation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""

# pylint: disable=too-many-instance-attributes, too-few-public-methods
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -46,7 +46,7 @@ class Marktlokation(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.MARKTLOKATION
typ: Annotated[Literal[Typ.MARKTLOKATION], Field(alias="_typ")] = Typ.MARKTLOKATION

#: Identifikationsnummer einer Marktlokation, an der Energie entweder verbraucht, oder erzeugt wird.
marktlokations_id: Optional[str] = None
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/marktteilnehmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# pylint: disable=too-few-public-methods
# pylint: disable=no-name-in-module
from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -34,7 +34,7 @@ class Marktteilnehmer(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.MARKTTEILNEHMER
typ: Annotated[Literal[Typ.MARKTTEILNEHMER], Field(alias="_typ")] = Typ.MARKTTEILNEHMER
#: Gibt im Klartext die Bezeichnung der Marktrolle an
marktrolle: Optional["Marktrolle"] = None
#: Gibt die Codenummer der Marktrolle an
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/messlokation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -39,7 +39,7 @@ class Messlokation(Geschaeftsobjekt):

"""

typ: Annotated[Optional["Typ"], Field(alias="_typ")] = Typ.MESSLOKATION
typ: Annotated[Literal[Typ.MESSLOKATION], Field(alias="_typ")] = Typ.MESSLOKATION

#: Die Messlokations-Identifikation; Das ist die frühere Zählpunktbezeichnung
messlokations_id: Optional[str] = None
Expand Down
4 changes: 2 additions & 2 deletions src/bo4e/bo/netzlokation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
and corresponding marshmallow schema for de-/serialization
"""

from typing import TYPE_CHECKING, Annotated, Optional
from typing import TYPE_CHECKING, Annotated, Literal, Optional

from pydantic import Field

Expand Down Expand Up @@ -37,7 +37,7 @@ class Netzlokation(Geschaeftsobjekt):

"""

typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.NETZLOKATION
typ: Annotated[Literal[Typ.NETZLOKATION], Field(alias="_typ")] = Typ.NETZLOKATION

#: Identifikationsnummer einer Netzlokation, an der Energie entweder verbraucht, oder erzeugt wird
netzlokations_id: Optional[str] = None
Expand Down
Loading
Loading