From 6e8fca2617560c199c0dba67b520f1582091a59e Mon Sep 17 00:00:00 2001 From: Claude Code Date: Mon, 3 Aug 2026 23:40:22 +0000 Subject: [PATCH 1/6] v0.38.1 Republish the documentation. v0.38.0 released successfully, but its documentation was never published: `PublishToGitHubPages` was skipped on both `main` and the `v0.38.0` tag, because `CompletePipeline.yml` up to Actions v7.14.1 evaluated that job's condition with an implicit `success()` over the whole dependency closure, and the `AppTesting` jobs skipped by `apptest: false` propagated into it. Fixed in pyTooling/Actions v7.15.0, which `r7` now carries. This release exists to run the pipeline again with that fix in place; the package code is unchanged. Co-Authored-By: Patrick Lehmann --- pyVHDLModel/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyVHDLModel/__init__.py b/pyVHDLModel/__init__.py index 5fe9eb19c..aa7743088 100644 --- a/pyVHDLModel/__init__.py +++ b/pyVHDLModel/__init__.py @@ -48,7 +48,7 @@ __email__ = "Paebbels@gmail.com" __copyright__ = "2016-2026, Patrick Lehmann" __license__ = "Apache License, Version 2.0" -__version__ = "0.38.0" +__version__ = "0.38.1" # __keywords__ = [] __project_url__ = "https://github.com/VHDL/pyVHDLModel" __documentation_url__ = "https://vhdl.github.io/pyVHDLModel" From a77f028fe05e3610d9851657a606f5db7ae3913c Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 4 Aug 2026 02:01:04 +0200 Subject: [PATCH 2/6] Fixed displayed pipeline name when triggered via API on a tagged commit. --- .github/workflows/Pipeline.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Pipeline.yml b/.github/workflows/Pipeline.yml index f879e866d..842930457 100644 --- a/.github/workflows/Pipeline.yml +++ b/.github/workflows/Pipeline.yml @@ -1,4 +1,5 @@ name: Pipeline +run-name: ${{ github.ref_type == 'tag' && github.ref_name || '' }} on: push: From 7695c6585e56a8929d391e132ba82c0a9d15a8c9 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Tue, 4 Aug 2026 20:17:09 +0000 Subject: [PATCH 3/6] Update dependencies to pyTooling 8.19 and sphinx-reports 0.11.2 Incorporates Dependabot's #169 (pyTooling `~= 8.18` -> `~= 8.19`) and #170 (sphinx-reports `~= 0.11.1` -> `~= 0.11.2`), and brings `doc/Dependency.rst` in line with the requirement files - Dependabot does not touch the documentation tables, so they had drifted: * The pyTooling minimum is stated in three tables (package, documentation, packaging); all three now read 8.19. * `sphinx_design`, `sphinx-copybutton` and `sphinx_reports` are listed in `doc/requirements.txt`, but were missing from the documentation table. * `sphinx_fontawesome` was still listed, including its GPL 2.0 marker, although it is no longer a documentation requirement. `docutils_stubs` remains unlisted, matching pyTooling's own dependency table. Co-Authored-By: Patrick Lehmann --- doc/Dependency.rst | 12 ++++++++---- doc/requirements.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/Dependency.rst b/doc/Dependency.rst index 08d306f79..ff975d5de 100644 --- a/doc/Dependency.rst +++ b/doc/Dependency.rst @@ -23,7 +23,7 @@ pyVHDLModel Package +--------------------------------------------------------+-------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Package** | **Version** | **License** | **Dependencies** | +========================================================+=============+==========================================================================================+=================================================================================================================================+ -| `pyTooling `__ | ≥8.18 | `Apache License, 2.0 `__ | *None* | +| `pyTooling `__ | ≥8.19 | `Apache License, 2.0 `__ | *None* | +--------------------------------------------------------+-------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ @@ -89,7 +89,7 @@ the mandatory dependencies too. +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | **Package** | **Version** | **License** | **Dependencies** | +=================================================================================================+==============+==========================================================================================================+======================+ -| `pyTooling `__ | ≥8.18 | `Apache License, 2.0 `__ | *None* | +| `pyTooling `__ | ≥8.19 | `Apache License, 2.0 `__ | *None* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | `Sphinx `__ | ≥9.1 | `BSD 3-Clause `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ @@ -99,10 +99,14 @@ the mandatory dependencies too. +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | `autoapi `__ | ≥2.0.1 | `Apache License, 2.0 `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ -| !! `sphinx_fontawesome `__ | ≥0.0.6 | `GPL 2.0 `__ | *Not yet evaluated.* | +| `sphinx_design `__ | ≥0.7 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ +| `sphinx-copybutton `__ | ≥0.5.2 | `MIT `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | `sphinx_autodoc_typehints `__ | ≥3.13 | `MIT `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ +| `sphinx_reports `__ | ≥0.11.2 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ .. _dependency-packaging: @@ -129,7 +133,7 @@ install the mandatory dependencies too. +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Package** | **Version** | **License** | **Dependencies** | +============================================================================+==============+==========================================================================================================+======================================================================================================================================================+ -| `pyTooling `__ | ≥8.18 | `Apache License, 2.0 `__ | *None* | +| `pyTooling `__ | ≥8.19 | `Apache License, 2.0 `__ | *None* | +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ | `wheel `__ | ≥0.47 | `MIT `__ | *Not yet evaluated.* | +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/doc/requirements.txt b/doc/requirements.txt index 2f0363e6e..40c7a1363 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -14,4 +14,4 @@ autoapi >= 2.0.1 sphinx_design ~= 0.7.0 sphinx-copybutton >= 0.5.2 sphinx_autodoc_typehints ~= 3.13 -sphinx_reports ~= 0.11.1 +sphinx_reports ~= 0.11.2 diff --git a/pyproject.toml b/pyproject.toml index 100c52400..9768ce7ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ "setuptools >= 83.0", - "pyTooling ~= 8.18" + "pyTooling ~= 8.19" ] build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt index 17e26eadb..367d1c30b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -pyTooling ~= 8.18 +pyTooling ~= 8.19 From 56d329917f505c05093538f8a25b3a0b612fa038 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Tue, 4 Aug 2026 20:26:22 +0000 Subject: [PATCH 4/6] Require a range constraint in `ConstrainedScalarSubtypeSymbol` VHDL's `range_constraint` rule is `**range** range`, so a subtype indication is either a bare type mark - modelled as `SimpleSubtypeSymbol` - or a type mark followed by the `range` keyword *and* a range. A form like `integer range` doesn't exist, which leaves `ConstrainedScalarSubtypeSymbol` without a state where its constraint is absent. The `constraint` parameter therefore loses its `None` default and is typed `Range` instead of `Nullable[Range]`, in `ScalarConstraint` as well as in `ConstrainedScalarSubtypeSymbol`. The `Constraint` property is non-optional accordingly. A range constraint written as a range attribute (`natural range vector'range`) is a range too: `RangeFromName` referring to a `RangeAttributeSymbol`. It is now shown as a second example on the class and covered by a testcase, because that form was the reason the parameter was optional. Co-Authored-By: Patrick Lehmann --- pyVHDLModel/Symbol.py | 31 +++++++++++++++++++++--------- tests/unit/Instantiation/Model.py | 6 +++--- tests/unit/Instantiation/Symbol.py | 24 ++++++++++++++--------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/pyVHDLModel/Symbol.py b/pyVHDLModel/Symbol.py index d39e9e4e1..a1de8902a 100644 --- a/pyVHDLModel/Symbol.py +++ b/pyVHDLModel/Symbol.py @@ -873,28 +873,31 @@ class ScalarConstraint(Constraint, mixin=True): """ A mixin-class for a scalar constraint: a range. - The range is available as :data:`Constraint`. + The range is available as :data:`Constraint`. It is mandatory, because VHDL's ``range_constraint`` + rule is ``range range``: a type mark is either written without a constraint at all, which is a + :class:`~pyVHDLModel.Symbol.SimpleSubtypeSymbol`, or with a range following the ``range`` keyword. + A form like ``integer range`` doesn't exist. .. seealso:: * :class:`Constrained scalar subtype symbol ` """ - _constraint: Nullable[Range] #: The range constraining the scalar subtype, or ``None`` if unconstrained. + _constraint: Range #: The range constraining the scalar subtype. - def __init__(self, constraint: Nullable[Range]) -> None: + def __init__(self, constraint: Range) -> None: """ Initializes a scalar constraint. - :param constraint: The range constraining the scalar subtype, or ``None`` if unconstrained. + :param constraint: The range constraining the scalar subtype. """ self._constraint = constraint @readonly - def Constraint(self) -> Nullable[Range]: + def Constraint(self) -> Range: """ Read-only property to access the scalar type's range constraint (:attr:`_constraint`). - :returns: The constraint, or ``None`` if not set. + :returns: The constraint. """ return self._constraint @@ -904,7 +907,8 @@ class ConstrainedScalarSubtypeSymbol(SubtypeSymbol, ScalarConstraint): """ Represents a reference to a scalar subtype narrowed by a range. - The referenced language entity is available as :data:`Reference` once resolved. + The referenced language entity is available as :data:`Reference` once resolved. The range is + mandatory: a type mark without a range constraint is a :class:`~pyVHDLModel.Symbol.SimpleSubtypeSymbol`. .. admonition:: Example @@ -913,14 +917,23 @@ class ConstrainedScalarSubtypeSymbol(SubtypeSymbol, ScalarConstraint): for i in integer range 0 to 3 loop -- ^^^^^^^ <- Name -- ^^^^^^ <- Constraint + + A range constraint written as a range attribute is a :class:`~pyVHDLModel.Base.RangeFromName` + referring to a :class:`~pyVHDLModel.Symbol.RangeAttributeSymbol`: + + .. code-block:: VHDL + + subtype index is natural range vector'range; + -- ^^^^^^^ <- Name + -- ^^^^^^^^^^^^ <- Constraint """ - def __init__(self, name: Name, constraint: Nullable[Range] = None) -> None: + def __init__(self, name: Name, constraint: Range) -> None: """ Initializes a reference to a scalar subtype narrowed by a range. :param name: The name to reference the language entity. - :param constraint: The range constraining the scalar subtype, or ``None`` if unconstrained. + :param constraint: The range constraining the scalar subtype. """ super().__init__(name) ScalarConstraint.__init__(self, constraint) diff --git a/tests/unit/Instantiation/Model.py b/tests/unit/Instantiation/Model.py index fd4d0efca..127104d19 100644 --- a/tests/unit/Instantiation/Model.py +++ b/tests/unit/Instantiation/Model.py @@ -365,9 +365,9 @@ def test_ConstrainedScalarSubtypeSymbol(self) -> None: self.assertIs(rng, symbol.Constraint) def test_ConstrainedScalarSubtypeSymbol_withoutConstraint(self) -> None: - symbol = ConstrainedScalarSubtypeSymbol(SimpleName("integer")) - - self.assertIsNone(symbol.Constraint) + """The range constraint is mandatory - ``integer range`` isn't a VHDL construct.""" + with self.assertRaises(TypeError): + ConstrainedScalarSubtypeSymbol(SimpleName("integer")) class PSLEntities(TestCase): diff --git a/tests/unit/Instantiation/Symbol.py b/tests/unit/Instantiation/Symbol.py index eacd55e68..8aa3279d1 100644 --- a/tests/unit/Instantiation/Symbol.py +++ b/tests/unit/Instantiation/Symbol.py @@ -39,8 +39,8 @@ """ from unittest import TestCase -from pyVHDLModel.Base import Direction, SimpleRange -from pyVHDLModel.Name import SimpleName, AllName +from pyVHDLModel.Base import Direction, SimpleRange, RangeFromName +from pyVHDLModel.Name import SimpleName, AllName, AttributeName from pyVHDLModel.Expression import IntegerLiteral from pyVHDLModel.Symbol import ( PossibleReference, Symbol, @@ -49,7 +49,7 @@ PackageMemberReferenceSymbol, AllPackageMembersReferenceSymbol, EntityInstantiationSymbol, ComponentInstantiationSymbol, ConfigurationInstantiationSymbol, EntitySymbol, ArchitectureSymbol, PackageSymbol, - RecordElementSymbol, SubtypeSymbol, SimpleSubtypeSymbol, + RangeAttributeSymbol, RecordElementSymbol, SubtypeSymbol, SimpleSubtypeSymbol, ConstrainedScalarSubtypeSymbol, ConstrainedArraySubtypeSymbol, ConstrainedRecordSubtypeSymbol, SimpleObjectOrFunctionCallSymbol, IndexedObjectOrFunctionCallSymbol, ) @@ -203,13 +203,19 @@ def test_ScalarConstraint_WithRange(self) -> None: self.assertIs(constraint, symbol.Constraint) - def test_ScalarConstraint_WithoutRange(self) -> None: - """``None`` only means the range constraint was written as an attribute name - (``subtype s is t'range;``), which isn't implemented yet - not that the source omitted a - constraint (it never does for a constrained scalar subtype). See ``Constraint``'s docstring.""" - symbol = ConstrainedScalarSubtypeSymbol(SimpleName("integer")) + def test_ScalarConstraint_RangeIsMandatory(self) -> None: + """``integer range`` isn't a VHDL construct - a type mark without a range constraint is a + ``SimpleSubtypeSymbol``, so the range can't be omitted here.""" + with self.assertRaises(TypeError): + ConstrainedScalarSubtypeSymbol(SimpleName("integer")) - self.assertIsNone(symbol.Constraint) + def test_ScalarConstraint_WithRangeAttribute(self) -> None: + """``subtype index is natural range vector'range;`` - the range constraint is a range attribute, + which is a range denoted by a name.""" + constraint = RangeFromName(RangeAttributeSymbol(AttributeName("range", SimpleName("vector")))) + symbol = ConstrainedScalarSubtypeSymbol(SimpleName("natural"), constraint) + + self.assertIs(constraint, symbol.Constraint) def test_ArrayConstraint(self) -> None: constraint = SimpleRange(IntegerLiteral(7), IntegerLiteral(0), Direction.DownTo) From d7c8157d92b15fc7b5349b4ffd2ebc72f4767f06 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 4 Aug 2026 22:37:32 +0200 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Patrick Lehmann --- pyVHDLModel/Symbol.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pyVHDLModel/Symbol.py b/pyVHDLModel/Symbol.py index a1de8902a..0e2c3cc96 100644 --- a/pyVHDLModel/Symbol.py +++ b/pyVHDLModel/Symbol.py @@ -873,10 +873,7 @@ class ScalarConstraint(Constraint, mixin=True): """ A mixin-class for a scalar constraint: a range. - The range is available as :data:`Constraint`. It is mandatory, because VHDL's ``range_constraint`` - rule is ``range range``: a type mark is either written without a constraint at all, which is a - :class:`~pyVHDLModel.Symbol.SimpleSubtypeSymbol`, or with a range following the ``range`` keyword. - A form like ``integer range`` doesn't exist. + The range is available as :data:`Constraint`. .. seealso:: @@ -897,7 +894,7 @@ def Constraint(self) -> Range: """ Read-only property to access the scalar type's range constraint (:attr:`_constraint`). - :returns: The constraint. + :returns: The constraint of the scalar subtype. """ return self._constraint From 98ac5cd4d0db5688b4262ce81d3d01981ce21cd5 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Tue, 4 Aug 2026 20:45:17 +0000 Subject: [PATCH 6/6] Bumped version to v0.39.0. A minor release, not a patch: #172 makes the range constraint of `ConstrainedScalarSubtypeSymbol` mandatory, which is a breaking API change. `run.ps1` was still on 0.38.0 - it was missed in the v0.38.1 bump. Co-Authored-By: Patrick Lehmann --- pyVHDLModel/__init__.py | 2 +- run.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyVHDLModel/__init__.py b/pyVHDLModel/__init__.py index aa7743088..671db7295 100644 --- a/pyVHDLModel/__init__.py +++ b/pyVHDLModel/__init__.py @@ -48,7 +48,7 @@ __email__ = "Paebbels@gmail.com" __copyright__ = "2016-2026, Patrick Lehmann" __license__ = "Apache License, Version 2.0" -__version__ = "0.38.1" +__version__ = "0.39.0" # __keywords__ = [] __project_url__ = "https://github.com/VHDL/pyVHDLModel" __documentation_url__ = "https://vhdl.github.io/pyVHDLModel" diff --git a/run.ps1 b/run.ps1 index e23f2fdd1..a26cc701b 100644 --- a/run.ps1 +++ b/run.ps1 @@ -33,7 +33,7 @@ Param( ) $PackageName = "pyVHDLModel" -$PackageVersion = "0.38.0" +$PackageVersion = "0.39.0" # set default values $EnableDebug = [bool]$PSCmdlet.MyInvocation.BoundParameters["Debug"]