Skip to content

[Dependabot]: Update twine requirement from ~=6.2 to ~=7.0 - #158

Open
dependabot[bot] wants to merge 104 commits into
mainfrom
dependabot/pip/dev/twine-approx-eq-7.0
Open

[Dependabot]: Update twine requirement from ~=6.2 to ~=7.0#158
dependabot[bot] wants to merge 104 commits into
mainfrom
dependabot/pip/dev/twine-approx-eq-7.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 28, 2026

Copy link
Copy Markdown
Contributor

Updates the requirements on twine to permit the latest version.

Changelog

Sourced from twine's changelog.

twine 7.0.0 (2026-07-27)

Bugfixes ^^^^^^^^

  • Specify UTF-8 encoding when reading .pypirc files. ([#1268](https://github.com/pypa/twine/issues/1268) <https://github.com/pypa/twine/issues/1268>_)
  • Add missing subdependencies to --version output. ([#1275](https://github.com/pypa/twine/issues/1275) <https://github.com/pypa/twine/issues/1275>_)
  • The dependency on rich has been bumped to avoid a hang in some environments. ([#1308](https://github.com/pypa/twine/issues/1308) <https://github.com/pypa/twine/issues/1308>_)
  • Indices that respond with non-standard HTTP codes are now handled more gracefully. ([#1309](https://github.com/pypa/twine/issues/1309) <https://github.com/pypa/twine/issues/1309>_)

Deprecations and Removals ^^^^^^^^^^^^^^^^^^^^^^^^^

  • Fix uploading packages with metadata version 2.5. The fix no longer allows metadata version 2.0, which was never officially standardised. ([#1317](https://github.com/pypa/twine/issues/1317) <https://github.com/pypa/twine/issues/1317>_)

Misc ^^^^

  • [#1298](https://github.com/pypa/twine/issues/1298) <https://github.com/pypa/twine/issues/1298>_

twine 6.2.0 (2025-09-04)

Features ^^^^^^^^

  • Automatically refresh short-lived PyPI token in long running Trusted Publishing uploads.

    In the event that a trusted publishing upload job is taking longer than the validity period of a trusted publishing token (15 minutes at the time of this writing), and we are already 10 minutes into that validity period, we will begin to attempt to replace the token on each subsequent request. ([#1246](https://github.com/pypa/twine/issues/1246) <https://github.com/pypa/twine/issues/1246>_)

Bugfixes ^^^^^^^^

  • Fix compatibility kludge for invalid License-File metadata entries emitted by build backends to work also with packaging version 24.0. ([#1217](https://github.com/pypa/twine/issues/1217) <https://github.com/pypa/twine/issues/1217>_)
  • Fix a couple of incorrectly rendered error messages. ([#1224](https://github.com/pypa/twine/issues/1224) <https://github.com/pypa/twine/issues/1224>_)
  • twine now enforces keyring >= 21.2.0, which was previously implicitly required by API usage. ([#1229](https://github.com/pypa/twine/issues/1229) <https://github.com/pypa/twine/issues/1229>_)
  • twine now catches configparser.Error to prevent accidental leaks of secret tokens or passwords to the user's console. ([#1240](https://github.com/pypa/twine/issues/1240) <https://github.com/pypa/twine/issues/1240>_)

... (truncated)

Commits
  • fdb86cb Update changelog for 7.0.0 (#1344)
  • bfa7f7f changelog: backfill entries from PRs (#1330)
  • 4f20c0d Remove monkeypatch allowing Metadata 2.0 (#1317)
  • 1df249e build(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#1318)
  • bea9607 fix: bump minimum rich dependency to 14.3.3 to prevent verbose hang (#1308)
  • ac17a17 build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#1311)
  • 039cedf build(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#1313)
  • d465cb0 Handle non-standard HTTP status codes (#1309)
  • cab618f Bump packaging >= 26.1 (#1310)
  • 2d06e11 build(deps): bump pypa/gh-action-pypi-publish from 1.13.0 to 1.14.0 (#1307)
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Paebbels and others added 30 commits July 13, 2026 19:55
…nd PackageInstantiation context items

- ModelEntity.GetAncestor(): raise VHDLModelException instead of an unguarded
  AttributeError when no ancestor of the requested type exists on the parent
  chain (i.e. the root of the model was reached).

- AllowBlackboxMixin.AllowBlackbox: raise VHDLModelException instead of an
  unguarded AttributeError when neither a local value is set nor a parent is
  available to inherit from.

- Design.TopLevel: check HierarchyGraph.VertexCount instead of EdgeCount to
  detect an uncomputed hierarchy graph. VertexCount is populated
  unconditionally by the first step of CreateHierarchyGraph(), while
  EdgeCount can legitimately be 0 for a valid design (e.g. a single entity
  with no yet-analyzed architecture), which was incorrectly reported as
  'Hierarchy is not yet computed'.

- PackageInstantiation: accept and forward a contextItems parameter to
  Package.__init__, matching every other primary design unit. Previously,
  library/use/context clauses preceding a package instantiation design unit
  had no way to be represented at all.

- Regions.IndexDeclaredItems: replace a stray print() with
  WarningCollector.Raise(NotImplementedWarning(...)), matching the existing
  warning idiom already used 9x elsewhere in this codebase (pyTooling.Warning
  based), and consistent with pyGHDL.dom's WarningCollector usage.

Added tests/unit/Regression.py covering all fixes.
- GetAncestor: shorten docstring summary to one line, rewrite using a
  while/else loop instead of a post-loop None check. Keep the deferred
  'from pyVHDLModel.Exception import VHDLModelException' import: moving it
  to the top of Base.py creates a genuine circular import
  (Base -> Exception -> Symbol -> Base), reproduced and documented in a code
  comment.

- AllowBlackbox: drop the docstring example and the defensive
  getattr(self, '_parent', None) - AllowBlackboxMixin is always combined with
  ModelEntity (verified: every one of its 9 use sites inherits ModelEntity
  directly or transitively), so self._parent is guaranteed to exist; only its
  value can legitimately be None.

- PackageInstantiation.__init__: apply suggested parameter alignment/
  formatting and pass contextItems positionally to super().__init__(), as
  requested.

- Regions.IndexDeclaredItems: format the variable identifier list as
  single-quoted, comma-separated values via the public Identifiers property
  (was using the private _identifiers tuple's repr).

- Test suite restructuring, per review: removed tests/unit/Regression.py and
  distributed its tests by subject instead of by 'bug fixed':
    * PackageInstantiation contextItems tests -> tests/unit/Instantiate.py
      (SimpleInstance), matching the existing test_Package/test_PackageBody
      pattern.
    * GetAncestor / AllowBlackbox tests -> new tests/unit/Hierarchy.py, since
      they traverse the parent chain across multiple classes/levels of the
      model rather than testing a single construct in isolation.
    * TopLevel / IndexDeclaredItems(Variable-warning) tests ->
      tests/unit/Analyze.py, alongside the existing CreateHierarchyGraph/
      IndexArchitectures tests they exercise.

Full suite: 73 passed (was 70), no regressions.
Co-authored-by: Patrick Lehmann <Paebbels@gmail.com>
Adds a genericAssociations parameter to PackageInstantiation.__init__,
matching the same pattern already used by ComponentInstantiation and
EntityInstantiation in Concurrent.py (self._genericAssociations = [],
appended if not None - no separate mixin storage yet, hence the pre-existing
'TODO: extract to mixin' comment, left as-is).

This is needed by a companion pyGHDL.dom change that reads the generic map
aspect ('generic map (WIDTH => 16)') of a package instantiation and forwards
it here; previously PackageInstantiation always had an empty, hardcoded
GenericAssociations with no way to populate it at all.

Extended tests/unit/Instantiate.py::SimpleInstance::test_PackageInstantiation
to cover genericAssociations alongside the existing contextItems coverage.

Full suite: 73 passed, no regressions.
- Apply suggested parameter/import alignment formatting.
- Removed a redundant duplicate 'from pyVHDLModel.Expression import
  IntegerLiteral' import introduced by mistake (IntegerLiteral was already
  imported earlier in the same file alongside FloatingPointLiteral).
- test_PackageInstantiation: use keyword arguments
  (GenericAssociationItem(actual=..., formal=...)) instead of positional,
  and reordered the Formal/Actual assertions to read Formal before Actual
  (matching 'WIDTH => 16' reading order), per review.

  Investigated whether AssociationItem.__init__'s (actual, formal=None)
  parameter order itself should be swapped instead: it's the exact order
  already used at every production call site of GenericAssociationItem /
  PortAssociationItem / ParameterAssociationItem in pyGHDL.dom's
  GetMapAspect() (pyGHDL/dom/_Translate.py), which is exercised for every
  entity/component instantiation's generic and port maps. Swapping the base
  class parameter order would ripple through all of those call sites for no
  functional benefit, so kept it as-is and used keyword arguments at the
  test call site instead, which fully resolves the readability concern
  without touching that shared, already-exercised API. Left a comment
  explaining this in the test.

Full suite: 73 passed, no regressions.
Per review feedback: a keyword-argument workaround at the test call site
wasn't the right fix - the constructor's parameter order itself was
misleading and should read the same way VHDL does ('formal => actual').

AssociationItem.__init__ now takes (formal, actual), both required positional
(formal's previous default of None is dropped: every real call site already
passed both arguments explicitly, so nothing relied on the default).

Companion pyGHDL.dom change updates the 3 call sites this touches:
  - pyGHDL/dom/Concurrent.py: GenericAssociationItem/PortAssociationItem/
    ParameterAssociationItem constructors, now (node, formal, actual).
  - pyGHDL/dom/_Translate.py: GetMapAspect(), now yields cls(item, formal,
    actual) instead of cls(item, actual, formal).

Verified: full pyVHDLModel suite (73 passed) and, against real GHDL analysis
(nightly libghdl build), the full testsuite/pyunit/dom suite (18 passed,
5 skipped due to missing fixtures in this sparse checkout) - including
StopWatch's real component instantiations with generic/port maps, which
exercise this exact code path and confirm the swap didn't break anything.
…ociationItems

Per discussion: the class held is GenericAssociationItem/PortAssociationItem/
ParameterAssociationItem in every case, so the parameter/property name should
be the plural of the class name, matching genericItems (plural of the
declared-generics class) and mirroring PackageInstantiation's already-fixed
genericAssociationItems.

  genericAssociations   -> genericAssociationItems   (Concurrent.py: Instantiation,
                                                        ComponentInstantiation,
                                                        EntityInstantiation,
                                                        ConfigurationInstantiation;
                                                        Instantiation.py: PackageInstantiation)
  portAssociations       -> portAssociationItems       (same four Concurrent.py classes)
  parameterMappings      -> parameterAssociationItems  (Common.py: ProcedureCallMixin;
                                                        Concurrent.py: ConcurrentProcedureCall;
                                                        Sequential.py: ProcedureCallStatement)

parameterMappings (not '...Associations') was the odd one out - checked
whether it might be intentionally different (VHDL's LRM never calls a
procedure call's actual parameter part a 'map', unlike generic/port map
aspects) but was asked to rename it too for full consistency, so done.

Updated tests/unit/Instantiate.py accordingly. Full suite: 73 passed, no
regressions.
- Applied alignment suggestions (Common.py, Concurrent.py x4) - types and default values aligned
  at consistent columns.
- Fixed PackageInstantiation.__init__ not setting .Parent on genericAssociationItems entries.
  Concurrent.py's Instantiation base class already does this correctly for the same kind of items
  (genericAssociationItems/portAssociationItems) - PackageInstantiation was the odd one out.

Full suite: 73 passed, no regressions.
…enericItems/parameterItems/IsPure

Function.__init__ never set self._returnType (declared as a type annotation only) despite
Function.ReturnType reading it unconditionally - every Function instance crashed on
.ReturnType access:

    >>> Function('f').ReturnType
    AttributeError: 'Function' object has no attribute '_returnType'

Subprogram.__init__ (the shared base of Function/Procedure) didn't accept genericItems/
parameterItems/declaredItems/statements as constructor parameters at all - it unconditionally
initialized all four to []. pyGHDL.dom's Function/Procedure had to reach directly into
self._genericItems/self._parameterItems/self._returnType after calling super().__init__(),
bypassing the constructor entirely (marked '# TODO: move to model' in pyGHDL.dom, i.e. the
maintainer of that layer already knew this was a workaround for a gap here).

Subprogram.__init__ now accepts genericItems/parameterItems/declaredItems/statements and wires
Parent correctly on each (matching the pattern already used by WithGenericsMixin/WithPortsMixin
elsewhere - note: Subprogram could plausibly be refactored to compose those mixins instead of
reimplementing generics/parameters storage itself; left as-is for this fix since that's a larger
architectural change, flagging it as worth considering separately).

Function.__init__ now accepts and stores returnType (required - every function has one) and
Procedure/ProcedureMethod/FunctionMethod all forward the new parameters through.

Also fixed ReturnType's type hint: it was declared as pyVHDLModel.Type.Subtype, but every real
caller (pyGHDL.dom) actually passes a Symbol (SimpleSubtypeSymbol) - a reference to the return
type, not an owned type definition. Retyped as SubtypeSymbol to match actual usage.

Companion pyGHDL.dom change updates Function/Procedure to use the fixed constructor properly
instead of the private-field workaround, and additionally reads IsPure from Get_Pure_Flag (was
never read before - every function silently defaulted to IsPure=True regardless of 'impure').

Full suite: 73 passed, no regressions.
ReturnStatement misused ConditionalMixin (which sets self._condition) while ReturnValue reads
self._returnValue - the field was never actually assigned:

    >>> ReturnStatement(IntegerLiteral(5)).ReturnValue
    AttributeError: 'ReturnStatement' object has no attribute '_returnValue'

Also, ReturnStatement.__init__ didn't accept a label parameter at all, and passed its own parent
argument into Statement.__init__'s label slot (super().__init__(parent), where
Statement.__init__(label=None, parent=None) - so parent ended up in the label position).

Now stores returnValue directly (no mixin misuse), accepts label properly, and forwards both to
Statement.__init__ correctly.

Full suite: 73 passed, no regressions.
VHDLVersion overrides __eq__/__lt__/__le__/__gt__/__ge__/__ne__ without defining __hash__, which
Python implicitly sets to None whenever __eq__ is overridden - making every VHDLVersion member
unhashable and unusable as a dict key or set member:

    >>> hash(VHDLVersion.VHDL2008)
    TypeError: unhashable type: 'VHDLVersion'

Found while adding VHDL version selection to pyGHDL.dom's Design class (wanted a
{VHDLVersion: '--std option'} mapping).

Hashes by self.value. Documented one caveat: Any compares equal to every other member (see
__eq__), which no hash value can satisfy simultaneously for every member without collapsing all
members to the same hash - this implementation is internally consistent for all comparisons except
those involving Any (avoid using Any as a dict key/set member).

Full suite: 73 passed, no regressions.
- Rebased onto current dev (post #128 merge) - picked up the .Parent wiring fix for
  PackageInstantiation.genericAssociationItems automatically (already fixed there via #128).
- Re-aligned PackageInstantiation's field declarations and __init__ parameters: the
  genericAssociations -> genericAssociationItems rename made that name/type the longest, breaking
  the existing column alignment for the whole block.
- Aligned all 5 new multi-line constructors in Subprogram.py (Subprogram, Procedure, Function,
  ProcedureMethod, FunctionMethod) - these were never aligned at all when originally written.
- Aligned ReturnStatement.__init__ in Sequential.py, same reason.

Full suite: 73 passed, no regressions.
Co-authored-by: Patrick Lehmann <Paebbels@gmail.com>
…face items

Design discussed and agreed in chat first, then implemented:

- ModeViewSymbol (Symbol.py): reference to a mode view declaration, mirroring
  PackageReferenceSymbol exactly. Uses PossibleReference.View, which - along
  with .ViewAttribute - was already present in the enum, apparently
  anticipating this.

- ModeViewDeclaration, ModeViewElement, SimpleModeViewElement,
  CompositeModeViewElement (Interface.py, per 'mode views are used closely to
  interfaces'):
    - ModeViewElement uses MultipleNamedEntityMixin (mode view elements
      support comma-separated identifiers sharing one mode, e.g. 'a, b : out;',
      same pattern as Constant/Signal/Variable).
    - CompositeModeViewElement merges what GHDL's IIR splits into
      Array_Mode_View_Element/Record_Mode_View_Element - verified both are
      structurally identical (just a reference to another named view); the
      distinction requires resolving the target field's type, which needs
      semantic analysis this project doesn't perform.
    - ModeViewDeclaration.Subtype is a plain SubtypeSymbol, so 'of
      MyArrayType(0 to 7)' (LRM19 constrained array-of-views) is already
      supported for free via the existing ConstrainedArraySubtypeSymbol -
      no new work needed there.

- Split PortSignalInterfaceItem and ParameterSignalInterfaceItem into
  abstract bases with two concrete forms each (Simple/View), since VHDL-2019
  mode views apply to signal-class ports and signal-class subprogram
  parameters, but not to generics (generics are restricted to
  constants/types/subprograms/packages - confirmed against the VHDL grammar
  and by the model owner directly). GenericSignalInterfaceItem does not exist
  and is out of scope here.

- Obj.__init__ (Object.py) now tolerates subtype=None: a view-typed port has
  no separate subtype indication of its own at the parse-only level this
  project operates at (verified against real GHDL: Get_Subtype_Indication on
  Interface_View_Declaration is Null_Iir before semantic analysis) - the type
  is only implied by the referenced mode view. This is additive
  (Nullable[Symbol]), not breaking for any existing caller.

Design cross-checked against the VHDL-2017/2019 draft grammar (sigasi.com's
browsable EBNF) before implementation - interface_object_declaration is one
production shared across generic/port/parameter lists; the generics-can't-
be-signals restriction is semantic (LRM prose), not encoded in the grammar
itself, which is why GHDL's parser (grammar-level only, no full semantic
pass) accepts view-typed generics/parameters syntactically without them
being legal VHDL.

Added tests/unit/Interface.py. Full suite: 82 passed (was 73), no
regressions.
- Object.py: reverted the Nullable[Symbol] workaround entirely - you were right, an object's subtype
  can never be None, there's no VHDL syntax that omits it. Found the actual root cause instead:
  Obj._subtype is typed as the general Symbol base class, not SubtypeSymbol specifically, and
  ModeViewSymbol is also a Symbol. VHDL's own grammar treats a mode view indication as occupying the
  same structural position as an ordinary subtype indication
  (mode_indication ::= simple_mode_indication | mode_view_indication). So PortViewSignalInterfaceItem/
  ParameterViewSignalInterfaceItem now pass the ModeViewSymbol itself as the real, non-None subtype
  value - Subtype is never None, and ModeViewIndication is just an aliased, more specific name for
  the same underlying value, not a separate (possibly-None) field. Also removed dead leftover code
  from the previous version of these two constructors.

- Interface.py: fixed 4 docstrings missing a blank line before '.. admonition:: Example' (found by
  checking all occurrences in the file, not just the one flagged).

- doc/LanguageModel/InterfaceItems.rst: this document was indeed stale - checked the whole repo for
  other PortSignalInterfaceItem/ParameterSignalInterfaceItem construction sites (none found; the
  split is otherwise fully contained in the class hierarchy itself) but this doc's 'condensed
  definition' blocks and inheritance-diagram still described the old, now-abstract classes as if
  concrete. Updated the diagram and added proper sections for
  Port/ParameterSimpleSignalInterfaceItem and Port/ParameterViewSignalInterfaceItem, matching this
  file's existing (if still work-in-progress, per its own '.. todo:: Write documentation.' markers)
  conventions. Did not attempt to fix this file's other pre-existing staleness (e.g. the
  'SyntaxModel' module path references) - out of scope here.

Updated tests/unit/Interface.py: two assertions were testing the now-corrected (previously broken)
behavior - Subtype is the ModeViewSymbol itself, not None.

Full suite: 82 passed, no regressions.
alias b is s; previously lost the fact that 'b' aliases 's' entirely - Alias only ever stored its own
identifier and documentation, nothing else.

Alias.Name (a plain Name, not a *ReferenceSymbol - an alias can refer to almost anything nameable:
objects, types, subprograms, literals, so none of the narrower ReferenceSymbol classes fit) and
Alias.Subtype (Nullable[SubtypeSymbol] - genuinely optional per the grammar:
'alias_designator [ : subtype_indication ] IS name [ signature ]', unlike Obj.Subtype which is never
optional).

Added tests/unit/Declaration.py. Full suite: 84 passed (was 82), no regressions.
FunctionInstantiation/ProcedureInstantiation were bare 'pass' stub classes, and
SubprogramInstantiationMixin's __init__ took no parameters at all - _subprogramReference was always
set to None unconditionally, with no way to populate it (flagged in the code itself:
'# FIXME: is this a subprogram symbol?').

- New SubprogramReferenceSymbol (Symbol.py), mirroring PackageReferenceSymbol, using the existing
  PossibleReference.SubProgram flag. Fixes the exact mismatch flagged in that FIXME:
  _subprogramReference was typed as the resolved Subprogram entity directly rather than a Symbol
  wrapper - same class of bug PackageInstantiation had before its own fix.
- SubprogramInstantiationMixin now properly accepts and stores subprogramReference and
  genericAssociationItems (mirroring PackageInstantiation's pattern).
- ProcedureInstantiation gets a real constructor.
- FunctionInstantiation gets a real constructor too, but deliberately does NOT call
  Function.__init__ (which would require a mandatory, non-None returnType) - it calls
  Subprogram.__init__ directly instead and sets _returnType = None.

  This is NOT a repeat of the Obj.Subtype workaround: verified against real GHDL that
  Get_Return_Type on a Function_Instantiation_Declaration is Null_Iir - and unlike a plain
  function, the LRM grammar never lets a subprogram instantiation write its own return type at
  all; it can only ever be known by resolving the referenced uninstantiated subprogram, which
  needs semantic analysis this project doesn't perform. None here reflects a not-yet-resolved
  reference, the same status as any other unresolved Symbol.Reference, not an omission the source
  syntax would never allow (which is what made the Obj.Subtype case wrong).

Added tests to tests/unit/Instantiate.py. Full suite: 86 passed (was 84), no regressions.
…re Name

Good catch - Alias.Name should participate in the same resolve-later mechanism
(Symbol.Reference/IsResolved) as every other cross-reference in this model, rather than being a
bare Name with no resolution slot at all.

Also confirmed: with an explicit subtype indication, the LRM restricts an alias to referencing an
object (constant/variable/signal/file) specifically - PossibleReference.Object already exists for
exactly this. Without a subtype, the target can be almost anything nameable, so the caller should
choose a broader PossibleReference value in that case (e.g. PackageMember | EnumLiteral).

Updated tests/unit/Declaration.py accordingly. Full suite: 86 passed, no regressions.
…DL.dom but had nowhere to go

'signal s : integer range 0 to 15;' parses fine, but ConstrainedScalarSubtypeSymbol was a bare stub
(class ConstrainedScalarSubtypeSymbol(SubtypeSymbol): pass) - no fields, no constructor parameter
for a range at all. pyGHDL.dom's ConstrainedScalarSubtypeSymbol.__init__ took an rng: Range
parameter but never forwarded it (super().__init__(subtypeName)  # , rng)  # XXX: hacked), and its
.parse() classmethod was a bare 'pass'.

Added ScalarConstraint (mirroring ArrayConstraint/RecordConstraint's established pattern for
consistency, even though - like those two - it's not reused elsewhere) and gave
ConstrainedScalarSubtypeSymbol a real constructor, storing the range via ScalarConstraint.Constraint.

Constraint is Nullable - not because the source syntax ever omits a range constraint for a
constrained scalar subtype (it never does), but because pyGHDL.dom doesn't yet extract a range from
an AttributeName-based constraint (e.g. 'subtype s is t'range;') - a pre-existing, separately-
tracked TODO in that function, not something addressed here.

Added tests to tests/unit/Instantiate.py. Full suite: 88 passed (was 86), no regressions.
…he ExtendedType metaclass

Constraint (and ArrayConstraint/RecordConstraint, pre-existing, plus the new ScalarConstraint) had
no metaclass specified at all - inconsistent with every other mixin in this codebase, which all use
class XMixin(metaclass=ExtendedType, mixin=True). Fixed all four to follow that exact convention
(child mixins just add mixin=True, inheriting the metaclass from Constraint).

This was silently 'working' before only because Python resolves the metaclass conflict
automatically when one base (SubtypeSymbol, via ExtendedType) is more derived than the other's
default type metaclass - not because the declaration was actually correct.

Full suite: 88 passed, no regressions. Manually re-verified all three constrained-subtype symbol
classes (scalar/array/record) still construct and expose their constraints correctly.
Paebbels and others added 24 commits July 27, 2026 00:57
All 21 classes now carry a doc-string: 15 had none, and the six that did are
reworded to the same shape.

Following the agreed conventions:

- The doc-string describes the *class*, not the initializer - constructor
  parameters stay documented on __init__.
- Classes abstracting a VHDL construct show it in a `.. admonition:: Example` with
  a `.. code-block:: VHDL`, underlining the relevant part with `^^^` and naming the
  property it maps to.
- Abstract bases and mixins (BaseType, Type, AnonymousType, FullType, ScalarType,
  RangedScalarType, CompositeType, NumericTypeMixin, DiscreteTypeMixin) get prose
  describing their role instead - they abstract no single construct. FullType's
  doc-string states the distinction the declaration regions actually index on: full
  types go into `Types`, subtypes into `Subtypes`.

13 of the 21 carry a VHDL example; the other 8 are those bases and mixins.

Verified: caret underlines all align with real code characters and cover exactly the
intended text, and every doc-string parses as RST once the Sphinx roles are
registered.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Applies the three review points to every class in the module:

1. Summary is now "Represents a ...", followed by a separate paragraph describing
   the class in terms of its properties, cross-referenced with :data: - e.g. a
   subtype references a type (:data:`Type`), may be narrowed by a constraint
   (:data:`Range`) and may have a resolution function (:data:`ResolutionFunction`).
   Constructor parameters remain documented on __init__, not here.

2. The `<-` annotations are aligned per code-block. Subtype had one at column 47
   while its siblings sat at 48, left over from shortening a caret run without
   re-padding.

3. Classes whose construct has genuinely different shapes now show example
   variants: Subtype without a constraint / with a constraint / with a resolution
   function, and ArrayType with one dimension / with two unconstrained dimensions.

Also fixes an underline that overran: PhysicalType's Range covered "0 to 1000000 u",
reaching into the `units` keyword.

Every VHDL snippet in this module was analyzed with GHDL before being documented, so
the examples are valid VHDL rather than plausible-looking.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
All 91 classes now carry a doc-string: 77 had none, and the 14 that did are
reworded to the agreed shape - "Represents a ..." summary, a paragraph describing
the class through its properties (cross-referenced with :data:), then a VHDL
example underlining the part each property maps to.

75 carry an example. The 16 without are abstract bases (BaseExpression, Literal,
NumericLiteral, UnaryExpression, BinaryExpression, the Adding/Multiplying/Logical/
Relational/Shift groups, ...) and the BitStringBase enumeration, which abstract no
single construct.

Every VHDL snippet was analyzed with GHDL before being written into a doc-string.
That caught three invalid ones in the draft: an access type cannot be a signal
(so `p` became a variable), and o"240" is nine bits, not eight.

The `^^^` underlines and `<-` arrows are computed from the code line rather than
written by hand, so a caret can no longer be off by one or overhang. Long detail
paragraphs are wrapped to the project's 120-character limit.

interrogate: 56.1% -> 62.5%, above the configured fail-under of 59 for the first
time.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
All 37 classes in Sequential.py now carry a doc-string in the agreed shape.

Per review, VHDL revisions before 2019 are no longer named: VHDL-2008 is the
minimum supported revision, and 87/93/2000/2002 are history. 17 mentions removed
across Expression.py (14 - reduction and matching operators, conditional
expression), Type.py (2 - protected type and body) and Common.py (1). VHDL-2019
mentions are kept, since that revision is worth calling out.

The example generator gained two fixes, both found by the caret checker rather
than by reading:

- A target starting in the first columns of a code line collided with the `--`
  marker and produced negative padding, silently shifting the carets. The marker
  now hangs into the left margin only in that case, keeping the usual alignment
  everywhere else.
- Targets on any line of a multi-line snippet are located and underlined, not just
  those on the first line.

Every VHDL snippet was analyzed with GHDL first, which rejected one draft: a wait
statement is not allowed in a process with a sensitivity list.

interrogate: 62.5% -> 64.5%.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…mples

Every class in pyVHDLModel now carries a doc-string with descriptive prose: 429 of
429, of which 205 show the VHDL construct they abstract.

This commit covers Concurrent, Interface, Symbol, Name, Subprogram, Configuration,
Common, Base, Regions, Namespace, Instantiation, Exception and PSLModel, plus the
classes that previously had an example but no prose - which is what rule 1 asks
for.

The caret checker found three misaligned underlines in *pre-existing*
hand-written examples in Common.py, in ConditionalWaveform, ConditionalExpression
and SelectedWaveform:

    s <= '1' when cond else '0';
    --   ^^^^^^^^^^^^         <- ...

The first run stopped one character short, covering "'1' when con", and the second
pointed at " el" - whitespace between tokens - instead of the final "'0'". They are
regenerated, so all underlines in the package now sit on real code.

Every VHDL snippet was analyzed with GHDL first, which rejected four drafts: a wait
statement in a sensitized process, a shared variable of a non-protected type, a
`library work` clause inside a context declaration, and a file type used before its
declaration.

interrogate: 64.5% -> 70.1%.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
180 classes now carry a `.. seealso::` block, holding 488 verified class links.

Two kinds of link, per review:

- Derived classes, generated from the class hierarchy for the 121 classes with
  between one and ten direct subclasses. Sphinx lists base-classes automatically but
  not subclasses, so this is the direction worth writing down. Classes with more than
  ten subclasses (ModelEntity, Symbol, SequentialStatement, ...) are skipped, as a
  list that long is noise.

- Curated cross-links for relationships the hierarchy does not express (54 classes):
  the three generate statements to each other, the loop statements to each other,
  every concurrent statement to its sequential counterpart and back, WaveformElement
  to the three places a waveform is held, entity to architecture / component /
  configuration and back, package to package body, protected type to its body, mode
  view declaration to the ports and parameters using it, and each declaration region
  to the other and to Namespace.

Base-classes and mixins are deliberately not listed, since Sphinx already shows them.

Every link is verified to resolve against a real class, and de-duplicated by target
rather than by text - four classes already linked their subclasses with the
`:class:`~pkg.Cls`` short form, which a text comparison would have duplicated.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Applied the reviewer's suggestions from PR #151:
* Moved the `--` example markers inside the code-blocks so the snippets stay
  syntactically valid VHDL.
* Fixed caret runs that pointed at the wrong occurrence of an identifier
  (keyword/name and parameter-type/return-type overlaps).
* Added the missing declarative and statement parts to the `Procedure`,
  `Function` and `ConcurrentBlockStatement` examples.
* Corrected the `ConcurrentBlockStatement` prose: a block always forms a
  hierarchy level, independently of whether it has a port clause.
* Replaced the bare integer choice in the selected-assignment examples by a
  bit literal.
* Normalized all `seealso` bullets to the labelled `:class:`Label <target>``
  format and to declaration order.
* Reworded the `VHDLModelCriticalWarning` summary.
* Marked the PSL primary unit link as unsupported.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Applied the reviewer's second batch of comments from PR #151:
* Dropped the `b`/`v`/`s` type prefixes from the expression examples (`bres`,
  `vlhs`, `boperand`, ... -> `res`, `lhs`, `operand`), because operators can be
  overloaded and the examples should stay generic. Replaced the literal right
  operands of `**` and the shift operators by `rhs`, and `realval` by `val`.
* Fixed six examples whose `^` sat two columns right of its target: a
  single-character target in column 0 was not shifted out from under the `--`
  marker, so the caret landed on the following operator.
* Replaced "first"/"final" branch and alternative wording by the actual list
  fields (`ConditionalWaveforms[0]`, `SelectedExpressions[1]`, `Methods[0]`,
  `Elements[1]`, `SecondaryUnits[0]`), since the model has no per-alternative
  fields.
* Showed the whole if statement in the `IfBranch`/`ElsifBranch`/`ElseBranch`
  examples and bracketed the part each class represents, so the statements are
  visible. The bracket column sits inside a VHDL comment.
* Marked the declared elements of protected types, protected type bodies,
  record types and physical types instead of naming them in a trailing comment.
* Marked optional parts as `<- X (optional)`.
* Showed the optional label on `SequentialProcedureCall` and
  `ConcurrentProcedureCall`.
* Renamed `clk` to `clock` and replaced the remaining bare `0` conditions by
  `sel = '0'`.
* Completed the incomplete-type example, which was not analyzable on its own.
* Noted that the block statement's port map aspect and a protected type body's
  non-subprogram declarations are not represented by the model (both tracked in
  the findings file).

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Follow-up to the review answers:
* Every statement example now shows the label. That is 34 classes: the 31 that
  had no label plus the three that already had one. Where the label is
  mandatory (block, generate and instantiation statements) it is marked
  `<- Label`, otherwise `<- optional Label`. Verified against the analyzer
  which of the two applies rather than assuming.
* Switched the optional-part wording from `X (optional)` to `optional X`.
* Fixed the if-generate and case-generate examples, whose condition and
  selector were signals: a generate condition and a generate selector must be
  static expressions.
* Carried the list-element convention into the concurrent statements, which
  still said "first alternative"/"final branch" (`ConditionalWaveforms[0]`,
  `SelectedWaveforms[1]`, `Cases[0]`, `ElsifBranches[0]`).

All 34 labelled statements were analyzed with `ghdl -a --std=08`.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Class fields are not counted by interrogate, so this work is invisible to the
coverage number, but the fields are what a reader of the API documentation sees
next to each attribute.

Documented all 204 undocumented fields, taking the package from 78/282 (27.7%)
to 282/282 (100%). `Regions.py` and `__init__.py` were already complete and
served as the style model: a `#:` comment on the same line, aligned per class.

Where a field already carried a `# TODO:` or `# FIXME:` comment, that comment
was moved to its own line above the field rather than dropped, so the note
survives and the field still gets documentation:

* `TernaryExpression._FORMAT`
* `ConcurrentStatementsMixin._instantiations`
* `ProcessStatement._sensitivityList`
* `ProcedureCallMixin._procedure`
* `Name._root`

This change is comment-only: for every module the token stream with comments
removed is identical to the one on `dev`.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Interrogate coverage 70.1% -> 91.1%.

* `ignore-nested-functions = true`: the eight remaining nested helpers
  (`Design.CreateTypeAndObjectGraph._LinkItems`, `Design.LinkComponents.
  linkStatements`, `Design.ComputeCompileOrder.predicate`, ...) are
  implementation-internal and never rendered by Sphinx.
* Documented the 246 undocumented `__init__` methods. Per the coding
  conventions the class doc-string describes the class and `__init__`
  documents the construction parameters.

The `:param:` descriptions are derived from the `#:` field documentation added
in #152 - 642 of 678 parameters initialize a documented field, so the two
descriptions stay consistent by construction instead of by discipline. The
remaining 36 are parameters whose name differs from the field they feed
(`rng` -> `_range`, `entitySymbol` -> `_entity`, ...) or that have no field.

Three pre-existing doc-strings were wrong and are fixed:

* `InterfaceGroup.__init__` was titled "Initialize a PortGroup ..." (wrong
  class) and documented none of its three parameters.
* `BaseType.__init__` was missing `:param documentation:`.
* `Design.__init__` listed its two parameters in the wrong order.

Also fixed a pre-existing typo, "langauge" -> "language", in `Symbol.py`. It
sat in a field comment that the generator copies, so it had spread to 24 of the
new doc-strings before being corrected (25 occurrences in total).

Raised `fail-under` from 59 to 90 so the gain cannot silently regress.

Verified doc-string-only: for every module the AST with doc-strings stripped is
identical to the one on `dev`.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Addresses the review of PR #153. The reported summaries were all symptoms of
one cause: deriving the summary by splitting the class name into words. The
class name is the wrong source, so the fix is to stop using it.

* Predefined libraries and packages now take their name from the class
  doc-string, which states the VHDL identifier: "Initializes the ``ieee``
  library", "Initializes the ``math_complex`` package". That is 30 summaries
  in `IEEE.py` and `STD.py`, not the three reported. Casing is taken from the
  doc-string, so the VITAL packages keep their `VITAL_Timing` spelling.
* Everywhere else the summary is derived from the class doc-string's
  "Represents a ..." line when it has one, so the initializer and the class
  agree and the language matches what the class calls itself. That corrected
  98 summaries, including hyphenation ("if generate" -> "if-generate") and
  word order ("concurrent simple signal assignment" -> "simple concurrent
  signal assignment").
* Mixins named after a plural no longer read "Initializes a choices"; the nine
  affected now read "Initializes choices", "Initializes concurrent statements",
  and so on.
* `Obj` -> "Initializes an object", `Document` -> "Initializes a VHDL
  document", `WithDefaultExpressionMixin` -> "Initializes an object with a
  default expression", `AllowBlackboxMixin` per the suggested wording.
* `UnaryExpression` said "an unary expression"; "unary" starts with a
  consonant sound, so the vowel-based article rule was wrong there.
* `Document._path` and its parameter started lower-case and said "virtual
  document"; both now read "Path to the document. ``None`` if in-memory
  document."

Found while applying the above: `Component`'s **class** doc-string said
"Represents a configuration declaration" - copy-pasted from `Configuration` in
PR #151 and already merged to `dev`. Corrected to "a component declaration".

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Interrogate coverage 91.1% -> 97.3%. Only the 32 regular methods remain, held
back deliberately until the algorithms and their tests settle.

Documented 60 `__str__`, 8 `__repr__`, 3 `__len__`, 3 `__iter__` and 1
`__bool__`, following the style the already-documented dunders use: a summary,
a `**Format:**` line showing the rendered output, and `:returns:`.

The `**Format:**` examples are taken from *running* the methods on constructed
model objects, not from reading the code. That mattered: three of the guessed
formats were wrong, e.g. the interface groups actually render
`GenericGroup myGroup (2) - generics: WIDTH, DEPTH)` rather than the shorter
form the code suggested at a glance.

It also surfaced four defects. One is fixed here because documenting it
otherwise meant describing a method that raises:

* `Component.__repr__` returned `None` - and so raised
  `TypeError: __repr__ returned non-string` - whenever the parent was neither a
  `Package` nor an `Architecture`, e.g. for a freshly constructed component.
  Both branches of the `isinstance` chain were identical, so the fix is to drop
  the chain and always return `f"{self._parent!r}:{self._identifier}"`.

The other three are rendering/modelling decisions and are recorded in the
findings file instead:

* `Context`/`PackageBody` render `mylib?.myContext` - the `?` is appended when
  the parent *is* present, inverted relative to the `%` convention the other
  design units use for an absent parent.
* The three interface groups emit an unbalanced closing parenthesis.
* `BitStringLiteral.__str__` raises `AttributeError` on the base class, because
  `_base` is a `ClassVar` on the four subclasses only. Its `NoBase` branch is
  unreachable today.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Follow-up to the review of PR #154.

The `?` in `Context: mylib?.myContext` was an operator-precedence mistake, not
the unresolved-symbol marker: `self._parent._identifier + "?" if ... else ""`
appends the marker when the parent *is* present, and drops it when the parent
is missing - the inverse of the intent.

All six design units now use one convention: an unknown part renders as `?`.

* `Context` and `PackageBody`: `mylib.myContext` when the library is set,
  `?.myContext` when it is not (3 sites, `__str__` and `__repr__`).
* `Package`, `Entity`, `Architecture`, `Configuration`: the `%` placeholder is
  now `?` (12 sites), including the architecture list of an entity and the
  entity of an architecture.

The convention is stated once on the `DesignUnit` base-class, and the
`**Format:**` examples were updated to the new output.

`tests/unit/Instantiation/Model.py::Symbols::test_EntityInstantiationSymbol`
asserted the old `Entity: 'liB.enT(%)'` and is updated to `(?)`. It now reads
consistently with the assertion just above it, which already expected the
symbol's own unresolved marker `Lib.Ent?`.

Also repaired 16 dangling Sphinx references found while checking the new
doc-strings; all were pre-existing on `dev`:

* `pyVHDLModel.DesignUnits.*` -> `pyVHDLModel.DesignUnit.*` (8, stale module name)
* `Std_logic_arith`/`_misc`/`_signed`/`_textio`/`_unsigned` -> `Std_Logic_*` (6, casing)
* `Type.SubType` -> `Type.Subtype` (1)
* `:class:`~pyVHDLModel.Symbol`` -> `:mod:`pyVHDLModel.Symbol`` (1, it names a module)

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Addresses the review of PR #154. The four reported summaries were generic
because I had written them per *file group* rather than per class, so whole
groups shared one noun: every name in `Name.py` said "Formats the name", every
type in `Type.py` said "Formats the type definition".

Made all 36 specific, not just the four reported:

* `Name.py` (5): parenthesis, indexed, selected, attribute and open name.
* `Type.py` (10): enumerated / integer / floating-point / physical / array /
  record / access / file type definition, the record element declaration and
  the subtype declaration.
* `Expression.py` (10): unary, binary and ternary expression, both allocations
  and the five aggregate elements.
* `Concurrent.py` (4) and `Sequential.py` (4): the indexed and ranged choices
  and the two alternatives.
* `Base.py` (3): the simple range and the range denoted by a name.

The 36 matching `:returns:` lines carried the same generic nouns and are synced
to their summary.

Also fixed while checking that group: `Mode.__str__` said "Formats the
direction" and returned "Formatted direction" - copy-pasted from
`Direction.__str__` and pre-existing on `dev`.

`PossibleReference` references the `Symbol` **class** again, as intended - it is
the enumeration that class uses to filter references. My earlier change to
`:mod:` was the wrong reading.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…ass names

Findings items 3, 5 and 6 (item 7 turned out to be already fixed - see below).

**Item 3 - two `__str__` defects**

* The three interface groups emitted an unbalanced closing parenthesis
  (`GenericGroup myGroup (2) - generics: WIDTH, DEPTH)`). They also disagreed on
  the colon; all three now render `<Group>: <name> (<n>) - <kind>: <names>`.
* `BitStringLiteral.__str__` raised `AttributeError` on the base class because
  `_base` was a `ClassVar` on the four subclasses only. Declared it on the base
  with `BitStringBase.NoBase`, which also makes the method's existing `NoBase`
  branch reachable. A commented-out `# _base:  ClassVar[BitStringBase]` sat
  above the class doc-string, confirming the intent; it is removed.

**Item 5 - boolean naming**

* `BitStringLiteral._signed`/`Signed` -> `_isSigned`/`IsSigned`, including the
  `__init__` parameter. `BitStringBase.Signed` is an enum member and untouched.
* `Component._isBlackBox` -> `_isBlackbox`: it was the only `BlackBox` spelling
  in the package and disagreed with its own property `IsBlackbox`.

**Item 6 - duplicate class names in `IEEE.py`**

`Std_Logic_Arith` and `Std_Logic_TextIO` were each defined twice, so the first
of each pair was unreachable by name and `@export` registered only one.

The naive rename is wrong: `PredefinedPackage`/`PredefinedPackageBody` derive
the *VHDL* identifier from the Python class name (the body via
`__class__.__name__[:-5]`). Renaming alone produced VHDL packages called
`std_logic_arith_synopsys` and a truncated `std_logic_arith_body_mentorgra`.

So the identifier is decoupled first: both base classes take an optional
explicit identifier, defaulting to the previous class-name derivation. The four
classes are then renamed with `_MentorGraphics`/`_Synopsys` suffixes and pass
their VHDL name explicitly. `Std_Logic_Arith_Body_MentorGraphics` gained the
`__init__` it needed.

Verified behaviour-neutral: the registered VHDL identifiers for every flavor are
byte-identical to `dev`.

**Item 7 - already fixed.** The three `@readonly` getters that define a setter
were changed to `@property` in 79ce362 (PR #149); the findings entry was stale.
A check across the package reports 0 remaining.

Tests updated for the intended renames and the corrected group format.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…one`

Review of PR #155.

The group `__str__` methods repeated the item kind, which the class name
already carries:

    GenericGroup: myGroup (2) - generics: WIDTH, DEPTH
    GenericGroup: myGroup (2): WIDTH, DEPTH

All three now use the shorter form; six test expectations follow.

`PredefinedPackage`/`PredefinedPackageBody` passed `parent=None` explicitly,
which is already the default in `Package.__init__`/`PackageBody.__init__`.
Dropped in both - the suggestion named only the package, but the body had the
same redundancy.

The registered VHDL identifiers are still byte-identical to `dev` for all four
IEEE flavors.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Updates the requirements on [twine](https://github.com/pypa/twine) to permit the latest version.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](pypa/twine@6.2.0...7.0.0)

---
updated-dependencies:
- dependency-name: twine
  dependency-version: 7.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot requested a review from Paebbels as a code owner July 28, 2026 15:22
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Base automatically changed from dev to main July 31, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants