Skip to content

Commit

Permalink
refactor: Deprecate old, now-unused functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Wuestengecko committed Dec 12, 2024
1 parent b5dfb59 commit 0e671d2
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
9 changes: 9 additions & 0 deletions capellambse/loader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
from capellambse.loader import exs
from capellambse.loader.modelinfo import ModelInfo

if sys.version_info >= (3, 13):
from warnings import deprecated
else:
from typing_extensions import deprecated

E = builder.ElementMaker()
LOGGER = logging.getLogger(__name__)
PROJECT_NATURE = "org.polarsys.capella.project.nature"
Expand Down Expand Up @@ -419,6 +424,10 @@ def __replace_nsmap(self, new_nsmap: dict[str | None, str]) -> None:

self.root = new_root

@deprecated(
"iterall_xt() is deprecated,"
" use iterall() or iter_qtypes() + iter_qtype() instead"
)
def iterall_xt(
self, xtypes: cabc.Container[str]
) -> cabc.Iterator[etree._Element]:
Expand Down
14 changes: 13 additions & 1 deletion capellambse/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
import collections.abc as cabc
import enum
import functools
import sys
import typing as t
import warnings

if sys.version_info >= (3, 13):
from warnings import deprecated
else:
from typing_extensions import deprecated

VIRTUAL_NAMESPACE_PREFIX = (
"https://dsd-dbs.github.io/py-capellambse/virtual-namespace/"
)
Expand All @@ -28,18 +34,24 @@
"""Covariant TypeVar (unbound)."""


@deprecated("set_accessor is deprecated and no longer needed")
def set_accessor(
cls: type[ModelObject], attr: str, accessor: Accessor
) -> None:
setattr(cls, attr, accessor)
accessor.__set_name__(cls, attr)


@deprecated("set_self_references is deprecated, use a 'Containment' instead")
def set_self_references(*args: tuple[type[ModelObject], str]) -> None:
for cls, attr in args:
setattr(cls, attr, DirectProxyAccessor(cls, aslist=ElementList))
setattr(cls, attr, DirectProxyAccessor(cls, aslist=ElementList)) # type: ignore[deprecated]


@deprecated(
'`@attr_equal("...")` is deprecated,'
' use `class X(ModelElement, eq="...")` instead'
)
def attr_equal(attr: str) -> cabc.Callable[[type[T]], type[T]]:
def add_wrapped_eq(cls: type[T]) -> type[T]:
orig_eq = cls.__eq__
Expand Down
53 changes: 45 additions & 8 deletions capellambse/model/_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import itertools
import logging
import operator
import sys
import types
import typing as t
import warnings
Expand All @@ -59,13 +60,19 @@

from . import T, T_co, U_co

if sys.version_info >= (3, 13):
from warnings import deprecated
else:
from typing_extensions import deprecated

_NotSpecifiedType = t.NewType("_NotSpecifiedType", object)
_NOT_SPECIFIED = _NotSpecifiedType(object())
"Used to detect unspecified optional arguments"

LOGGER = logging.getLogger(__name__)


@deprecated("@xtype_handler is deprecated and no longer used")
def xtype_handler(
arch: str | None = None, /, *xtypes: str
) -> cabc.Callable[[type[T]], type[T]]:
Expand All @@ -78,6 +85,7 @@ def xtype_handler(
return lambda i: i


@deprecated("build_xtype is deprecated")
def build_xtype(class_: type[_obj.ModelObject]) -> str:
ns: _obj.Namespace | None = getattr(class_, "__capella_namespace__", None)
if ns is None:
Expand Down Expand Up @@ -587,6 +595,7 @@ def _resolve_super_attributes(
self.single_attr = super_acc.single_attr


@deprecated("WritableAccessor is deprecated, use Relation instead")
class WritableAccessor(Accessor["_obj.ElementList[T_co]"], t.Generic[T_co]):
"""An Accessor that also provides write support on lists it returns."""

Expand Down Expand Up @@ -820,6 +829,7 @@ def purge_references(self, obj, target):
)


@deprecated("PhysicalAccessor is deprecated, use Relation instead")
class PhysicalAccessor(Accessor["_obj.ElementList[T_co]"], t.Generic[T_co]):
"""Helper super class for accessors that work with real elements."""

Expand Down Expand Up @@ -853,18 +863,19 @@ def __init__(
super().__init__()
if xtypes is None:
self.xtypes = (
{build_xtype(class_)}
{build_xtype(class_)} # type: ignore[deprecated]
if class_ is not _obj.ModelElement
else set()
)
elif isinstance(xtypes, type):
assert issubclass(xtypes, _obj.ModelElement)
self.xtypes = {build_xtype(xtypes)}
self.xtypes = {build_xtype(xtypes)} # type: ignore[deprecated]
elif isinstance(xtypes, str):
self.xtypes = {xtypes}
else:
self.xtypes = {
i if isinstance(i, str) else build_xtype(i) for i in xtypes
i if isinstance(i, str) else build_xtype(i) # type: ignore[deprecated]
for i in xtypes
}

self.aslist = aslist
Expand Down Expand Up @@ -900,6 +911,7 @@ def _make_list(self, parent_obj, elements):
)


@deprecated("DirectProxyAccessor is deprecated, use Containment instead")
class DirectProxyAccessor(WritableAccessor[T_co], PhysicalAccessor[T_co]):
"""Creates proxy objects on the fly."""

Expand Down Expand Up @@ -992,10 +1004,11 @@ def __init__(
elif isinstance(rootelem, type) and issubclass(
rootelem, _obj.ModelElement
):
self.rootelem = [build_xtype(rootelem)]
self.rootelem = [build_xtype(rootelem)] # type: ignore[deprecated]
else:
self.rootelem = [
i if isinstance(i, str) else build_xtype(i) for i in rootelem
i if isinstance(i, str) else build_xtype(i) # type: ignore[deprecated]
for i in rootelem
]

def __get__(self, obj, objtype=None):
Expand Down Expand Up @@ -1164,6 +1177,9 @@ def purge_references(
yield


@deprecated(
"DeepProxyAccessor is deprecated, use @property and model.search() instead"
)
class DeepProxyAccessor(PhysicalAccessor[T_co]):
"""A DirectProxyAccessor that searches recursively through the tree."""

Expand Down Expand Up @@ -1213,9 +1229,9 @@ def __init__(
elif isinstance(rootelem, type) and issubclass(
rootelem, _obj.ModelElement
):
self.rootelem = (build_xtype(rootelem),)
self.rootelem = (build_xtype(rootelem),) # type: ignore[deprecated]
elif not isinstance(rootelem, str): # type: ignore[unreachable]
self.rootelem = tuple(build_xtype(i) for i in rootelem)
self.rootelem = tuple(build_xtype(i) for i in rootelem) # type: ignore[deprecated]
else:
raise TypeError(
"Invalid 'rootelem', expected a type or list of types: "
Expand Down Expand Up @@ -1268,6 +1284,10 @@ class Allocation(Relationship[T_co]):
backattr: str | None

@t.overload
@deprecated(
"Raw classes, xsi:type strings and 'aslist' are deprecated,"
" migrate to (Namespace, 'ClassName') tuples and drop aslist=..."
)
def __init__(
self,
tag: str | None,
Expand Down Expand Up @@ -1927,6 +1947,10 @@ def _resolve_super_attributes(
self.attr = super_acc.attr


@deprecated(
"PhysicalLinkEndsAccessor is deprecated,"
" use Association with fixed_length=2 instead"
)
class PhysicalLinkEndsAccessor(Association[T_co]):
def __init__(
self,
Expand Down Expand Up @@ -2041,6 +2065,9 @@ def __get__(self, obj, objtype=None):
return _obj.wrap_xml(obj._model, parent)


@deprecated(
"AttributeMatcherAccessor is deprecated, use FilterAccessor instead"
)
class AttributeMatcherAccessor(DirectProxyAccessor[T_co]):
__slots__ = (
"_AttributeMatcherAccessor__aslist",
Expand Down Expand Up @@ -2471,6 +2498,11 @@ def purge_references(
yield


@deprecated(
"TypecastAccessor is deprecated,"
" use Filter to perform filtering"
" or Alias to create an unfiltered Alias"
)
class TypecastAccessor(WritableAccessor[T_co], PhysicalAccessor[T_co]):
"""Changes the static type of the value of another accessor.
Expand Down Expand Up @@ -2554,7 +2586,7 @@ def create(
if typehint:
raise TypeError(f"{self._qualname} does not support type hints")
acc: WritableAccessor = getattr(self.class_, self.attr)
obj = acc.create(elmlist, build_xtype(self.class_), **kw)
obj = acc.create(elmlist, build_xtype(self.class_), **kw) # type: ignore[deprecated]
assert isinstance(obj, self.class_)
return obj

Expand Down Expand Up @@ -2593,9 +2625,14 @@ def purge_references(
class Containment(Relationship[T_co]):
__slots__ = ("classes", "role_tag")

aslist: type[_obj.ElementListCouplingMixin]
alternate: type[_obj.ModelObject] | None

@t.overload
@deprecated(
"Raw classes, xsi:type strings and 'aslist' are deprecated,"
" migrate to (Namespace, 'ClassName') tuples and drop aslist=..."
)
def __init__(
self,
role_tag: str,
Expand Down
12 changes: 12 additions & 0 deletions capellambse/model/_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import logging
import operator
import re
import sys
import textwrap
import typing as t
import warnings
Expand All @@ -55,6 +56,11 @@

from . import VIRTUAL_NAMESPACE_PREFIX, T, U, _descriptors, _pods, _styleclass

if sys.version_info >= (3, 13):
from warnings import deprecated
else:
from typing_extensions import deprecated

if t.TYPE_CHECKING:
import capellambse.metamodel as mm

Expand Down Expand Up @@ -591,6 +597,7 @@ def progress_status(self) -> str:
return wrap_xml(self._model, self._model._loader[uuid]).name

@classmethod
@deprecated("ModelElement.from_model is deprecated, use wrap_xml instead")
def from_model(
cls, model: capellambse.MelodyModel, element: etree._Element
) -> te.Self:
Expand Down Expand Up @@ -1596,6 +1603,7 @@ def _newlist(self, elements: list[etree._Element]) -> ElementList[T]:
return newlist


@deprecated("MixedElementList is deprecated, use base ElementList instead")
class MixedElementList(ElementList[ModelElement]):
"""ElementList that handles proxies using ``XTYPE_HANDLERS``."""

Expand Down Expand Up @@ -2031,6 +2039,10 @@ def wrap_xml(
return obj


@deprecated(
"find_wrapper is deprecated,"
" use resolve_class_name or MelodyModel.resolve_class instead"
)
@functools.cache
def find_wrapper(typehint: str) -> tuple[type[ModelObject], ...]:
"""Find the possible wrapper classes for the hinted type.
Expand Down

0 comments on commit 0e671d2

Please sign in to comment.