Skip to content

Fix/circular dependencies#620

Open
wingedfox wants to merge 2 commits into
dbinfrago:masterfrom
wingedfox:fix/circular-dependencies
Open

Fix/circular dependencies#620
wingedfox wants to merge 2 commits into
dbinfrago:masterfrom
wingedfox:fix/circular-dependencies

Conversation

@wingedfox
Copy link
Copy Markdown

Circular dependencies in present code prevent effective codebase analysis, this change switches import from capellambse.model to more specific dependencies to address this issue.

Copy link
Copy Markdown
Member

@Wuestengecko Wuestengecko left a comment

Choose a reason for hiding this comment

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

Hi, and thanks for the PR!

Circular dependencies in present code prevent effective codebase analysis

The tools we normally use in this repo (most notably mypy and ruff) seem to be handling these cycles just fine. Which other tools are you using where you're seeing issues? Considering the implications about API surface (which I mentioned in a comment below), would it be an option to fix those tools and make them properly handle cycles instead?

Additionally, this PR doesn't fix all cycles - we're still importing capellambse.metamodel into capellambse.model._obj (though guarded behind if TYPE_CHECKING). I didn't fully check the codebase, so there may or may not be other cycles left.

import typing as t

import capellambse.model as m
from capellambse.model import _descriptors, _obj, _pods
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

From the perspective of capellambse.metamodel, the capellambse.model._descriptors and other "underscored" modules are private to model and should not be used directly. This is why we currently use them via the public exports at capellambse.model.

If we want to directly import _descriptors etc. we need to make them public by removing the leading underscore. However this would also increase the public API surface, which is something I'd want to avoid, unless there's a very good reason.

The output format to use.

If ``None``, the :class:`~capellambse.diagram.Diagram` is returned
If ``None``, the :class:`~capellambse._diagram.Diagram` is returned
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Bad search/replace

sourcefmt
Name of the current format. If None, the current format is a
:class:`capellambse.diagram.Diagram` object.
:class:`capellambse._diagram.Diagram` object.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Bad search/replace

Comment on lines +47 to +48
from capellambse import aird, helpers, svg
from capellambse import diagram as _diagram
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why this import rename? There doesn't seem to be any naming conflict.

Comment on lines -78 to +84
origin = m.Association["CatalogElement"]((NS, "CatalogElement"), "origin")
current_compliancy = m.Association["CompliancyDefinition"](

kind = _pods.EnumPOD("kind", CatalogElementKind)
author = _pods.StringPOD("author")
environment = _pods.StringPOD("environment")
suffix = _pods.StringPOD("suffix")
purpose = _pods.StringPOD("purpose")
is_read_only = _pods.BoolPOD("readOnly")
version = _pods.StringPOD("version")
tags = _pods.StringPOD("tags")
origin = _descriptors.Single(
_descriptors.Association["CatalogElement"](
(NS, "CatalogElement"), "origin"
)
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This change from Association to Single[Association] might be interesting (and small) enough to put on a faster track.


LOGGER = logging.getLogger(__name__)

import capellambse.metamodel as mm
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • This import should be moved to the other imports a few lines above (before the isort:skip-ed pathlib import)
  • We're also importing several metamodel submodules directly (only to use them exactly once each), we can easily move these over to mm.* as well

import enum

import capellambse.model as m
from capellambse.metamodel.behavior import AbstractBehavior, AbstractSignal
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

self,
model: m.MelodyModel,
parent: etree._Element,
xmltag: str | None,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Another bug fix, might also be worth fast-tracking (note we also need to actually pass it on to super().__init__(), which we currently don't).

"ownedConfigurationItems", (NS, "ConfigurationItem")
)
configuration_item_pkgs = m.Containment["ConfigurationItemPkg"](
configuration_item_pkgs: _descriptors.Containment[ConfigurationItemPkg] = _descriptors.Containment["ConfigurationItemPkg"](
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Explicit annotations should not be necessary as long as the Generic does get passed somewhere.

Suggested change
configuration_item_pkgs: _descriptors.Containment[ConfigurationItemPkg] = _descriptors.Containment["ConfigurationItemPkg"](
configuration_item_pkgs = _descriptors.Containment["ConfigurationItemPkg"](

import typing as t

import capellambse.model as m
from capellambse.model import _descriptors, _obj, _pods
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These files are in large parts generated automatically based on Capella's upstream metamodel using scripts/ecore2py.py. That script currently still uses classes from capellambse.model directly, and would have to be adjusted to use these new imports as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants