Summary
The two-file architecture (spdx_markdown.py + _impl.py) with a __new__-based
lazy wrapper is solving a circular-import problem that does not exist, and
introduces a real isinstance() bug.
Current behavior
SPDXMarkdown is a thin wrapper that resolves to _SPDXMarkdownImpl at
instantiation time via __new__. The real class lives in _impl.py.
_SPDXMarkdownImpl does not subclass SPDXMarkdown, so
isinstance(formatter, SPDXMarkdown) returns False — a latent bug for any
code relying on type checks.
Root cause
The split was motivated by a perceived circular import: the claim was that the
entry-point scanner would deadlock if spdx_markdown.py imported
commitizen.changelog_formats.markdown at module level. In reality:
Markdown is already in sys.modules when commitizen scans
commitizen.changelog_format entry points — commitizen needs it internally
for the built-in "markdown" format.
- Nothing in
commitizen.changelog_formats imports back into this package.
There is no cycle.
Proposed fix
Collapse the two files into one. Remove the __new__ redirection, all
TYPE_CHECKING stubs, and the _resolve() machinery. SPDXMarkdown becomes a
direct subclass of Markdown.
See Plan 10 — Collapse _impl.py for the
full implementation plan.
Additional scope
- Verify
py.typed (PEP 561 marker) lands in the built wheel.
- Run
ruff check src/ after the swap — the staggered-import pattern was the
sole cause of existing E402 violations.
Reference
- Plan:
docs/plans/10-collapse-impl.md
Summary
The two-file architecture (
spdx_markdown.py+_impl.py) with a__new__-basedlazy wrapper is solving a circular-import problem that does not exist, and
introduces a real
isinstance()bug.Current behavior
SPDXMarkdownis a thin wrapper that resolves to_SPDXMarkdownImplatinstantiation time via
__new__. The real class lives in_impl.py._SPDXMarkdownImpldoes not subclassSPDXMarkdown, soisinstance(formatter, SPDXMarkdown)returnsFalse— a latent bug for anycode relying on type checks.
Root cause
The split was motivated by a perceived circular import: the claim was that the
entry-point scanner would deadlock if
spdx_markdown.pyimportedcommitizen.changelog_formats.markdownat module level. In reality:Markdownis already insys.moduleswhen commitizen scanscommitizen.changelog_formatentry points — commitizen needs it internallyfor the built-in
"markdown"format.commitizen.changelog_formatsimports back into this package.There is no cycle.
Proposed fix
Collapse the two files into one. Remove the
__new__redirection, allTYPE_CHECKINGstubs, and the_resolve()machinery.SPDXMarkdownbecomes adirect subclass of
Markdown.See Plan 10 — Collapse
_impl.pyfor thefull implementation plan.
Additional scope
py.typed(PEP 561 marker) lands in the built wheel.ruff check src/after the swap — the staggered-import pattern was thesole cause of existing E402 violations.
Reference
docs/plans/10-collapse-impl.md