diff --git a/.btd.yml b/.btd.yml index 270d2f8..2fb7499 100644 --- a/.btd.yml +++ b/.btd.yml @@ -4,5 +4,5 @@ requirements: requirements.txt target: gh-pages formats: [ html ] images: - base: btdi/sphinx:vhdldomain + base: btdi/sphinx:pytooling theme: https://codeload.github.com/buildthedocs/sphinx.theme/tar.gz/v1 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ac698f8..4ed2d90 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,16 +1,30 @@ # New Features - + +* tbd * tbd # Changes +* tbd * tbd # Bug Fixes +* tbd +* tbd + +# Documentation + +* tbd +* tbd + +# Unit Tests + +* tbd * tbd ---------- -# Related PRs: +# Related Issues and Pull-Requests * tbd +* tbd diff --git a/VHDLDomain/Directive.py b/VHDLDomain/Directive.py index 232a735..284a416 100644 --- a/VHDLDomain/Directive.py +++ b/VHDLDomain/Directive.py @@ -88,16 +88,201 @@ class BaseDirective(ObjectDescription): """ Mapping of option names to validator functions. - A dictionary, mapping known option names to conversion functions such as :py:class:`int` or :py:class:`float` + A dictionary, mapping known option names to conversion functions such as :class:`int` or :class:`float` (default: {}, no options). Several conversion functions are defined in the ``directives/__init__.py`` module. - Option conversion functions take a single parameter, the option argument (a string or :py:class:`None`), validate it - and/or convert it to the appropriate form. Conversion functions may raise :py:exc:`ValueError` and - :py:exc:`TypeError` exceptions. + Option conversion functions take a single parameter, the option argument (a string or :class:`None`), validate it + and/or convert it to the appropriate form. Conversion functions may raise :exc:`ValueError` and + :exc:`TypeError` exceptions. """ - # def __init__(self, *args, **kwargs): - # super().__init__(*args, **kwargs) + def ParseBooleanOption(self, optionName: str, default: bool) -> bool: + try: + option = self.options[optionName] + except KeyError: + try: + option = self.defaultValues[optionName] + except KeyError: + return default + + if option in ("yes", "true"): + return True + elif option in ("no", "false"): + return False + else: + raise ValueError(f"Value '{option}' not supported for a boolean value (yes/true, no/false).") + + def _PrepareTable(self, columns: Dict[str, int], classes: List[str]) -> Tuple[table, tgroup]: + tableGroup = nodes.tgroup(cols=(len(columns))) + table = nodes.table("", tableGroup, classes=classes) + + tableRow = nodes.row() + for columnTitle, width in columns.items(): + tableGroup += nodes.colspec(colwidth=width) + tableRow += nodes.entry("", nodes.paragraph(text=columnTitle)) + + tableGroup += nodes.thead("", tableRow) + + return table, tableGroup + + +@export +class WithParametersMixin(metaclass=ExtendedType, mixin=True): + def ParseParameterStyleOption(self, optionName: str) -> ParameterStyle: + try: + option = self.options[optionName] + except KeyError: + try: + option = self.defaultValues[optionName] + except KeyError: + return ParameterStyle.Table + + if option == "never": + return ParameterStyle.Never + elif option == "table": + return ParameterStyle.Table + elif option == "sections": + return ParameterStyle.Sections + else: + raise ValueError(f"value '{option}' is not in list of choices: never, table, sections.") + + +@export +class WithGenericsMixin(WithParametersMixin): + def _CreateGenericsAsTable(self, entity: Entity) -> table: + table, tableGroup = self._PrepareTable( + columns={ + "Generic Name": 2, + "Type": 1, + "Default Value": 2, + "Description": 4, + }, + classes=["vhdl", "vhdl-generic-table"] + ) + + tableBody = nodes.tbody() + tableGroup += tableBody + + for generic in entity.GenericItems: + cellGenericName = nodes.entry() + cellGenericType = nodes.entry() + cellDefaultValue = nodes.entry() + cellDescription = nodes.entry() + tableBody += nodes.row("", cellGenericName, cellGenericType, cellDefaultValue, cellDescription) + + if isinstance(generic, GenericConstantInterfaceItem): + cellGenericName += nodes.paragraph(text=", ".join(generic.Identifiers)) + cellGenericType += nodes.paragraph(text=generic.Documentation) + if generic.DefaultExpression is not None: + cellDefaultValue += nodes.paragraph(text="??") # str(generic.DefaultExpression)) + if generic.Documentation is not None: + cellDescription += nodes.paragraph(text=generic.Documentation) + + return table + + def _CreateGenericsAsSections(self, entity: Entity) -> List[section]: + content = [] + for generic in entity.GenericItems: + if isinstance(generic, GenericConstantInterfaceItem): + genericSection = nodes.section(ids=[f"{entity.NormalizedIdentifier}-generic-{nID}" for nID in generic.NormalizedIdentifiers]) + genericSection.append(nodes.title(text=", ".join(generic.Identifiers))) + genericSection.append(nodes.paragraph(text=generic.Documentation)) + + content.append(genericSection) + + return content + + def CreateGenericSection(self, entity: Entity, style: ParameterStyle) -> section: + content = [ + nodes.title(text="Generics") + ] + + if True: + content.append(nodes.paragraph(text="list of all generics")) + + if style is ParameterStyle.Table: + content.append(self._CreateGenericsAsTable(entity)) + elif style is ParameterStyle.Sections: + content.extend(self._CreateGenericsAsSections(entity)) + + section = nodes.section( + ids=[f"{entity.NormalizedIdentifier}-generics"], + classes=["vhdl", "vhdl-entity-generic-section"] + ) + section.extend(content) + + return section + + +@export +class WithPortsMixin(WithParametersMixin): + def _CreatePortsAsTable(self, entity: Entity) -> table: + table, tableGroup = self._PrepareTable( + columns={ + "Port Name": 2, + "Direction": 1, + "Type": 1, + "Default Value": 2, + "Description": 4, + }, + classes=["vhdl", "vhdl-port-table"] + ) + + tableBody = nodes.tbody() + tableGroup += tableBody + + for port in entity.PortItems: + cellPortName = nodes.entry() + cellPortDirection = nodes.entry() + cellPortType = nodes.entry() + cellDefaultValue = nodes.entry() + cellDescription = nodes.entry() + tableBody += nodes.row("", cellPortName, cellPortDirection, cellPortType, cellDefaultValue, cellDescription) + + if isinstance(port, PortSignalInterfaceItem): + cellPortName += nodes.paragraph(text=", ".join(port.Identifiers)) + cellPortDirection += nodes.paragraph(text=str(port.Mode)) + cellPortType += nodes.paragraph(text=port.Documentation) + if port.DefaultExpression is not None: + cellDefaultValue += nodes.paragraph(text=str(port.DefaultExpression)) + if port.Documentation is not None: + cellDescription += nodes.paragraph(text=port.Documentation) + + return table + + def _CreatePortsAsSections(self, entity: Entity) -> List[section]: + content = [] + for port in entity.PortItems: + if isinstance(port, PortSignalInterfaceItem): + portSection = nodes.section(ids=[f"{entity.NormalizedIdentifier}-port-{nID}" for nID in port.NormalizedIdentifiers]) + portSection.append(nodes.title(text=", ".join(port.Identifiers))) + portSection.append(nodes.paragraph(text=port.Documentation)) + + content.append(portSection) + + return content + + + def CreatePortSection(self, entity: Entity, style: ParameterStyle) -> section: + content = [ + nodes.title(text="Ports") + ] + + if True: + content.append(nodes.paragraph(text="list of all ports")) + + if style is ParameterStyle.Table: + content.append(self._CreatePortsAsTable(entity)) + elif style is ParameterStyle.Sections: + content.extend(self._CreatePortsAsSections(entity)) + + section = nodes.section( + ids=[f"{entity.NormalizedIdentifier}-ports"], + classes=["vhdl", "vhdl-entity-port-section"] + ) + section.extend(content) + + return section @export @@ -195,17 +380,49 @@ class DescribeContext(BaseDirective): def run(self) -> List[Node]: from VHDLDomain import Design + # FIXME: check with regexp + # FIXME: better error message(s) + if len(self.arguments) == 1: + try: + libraryName, contextName = self.arguments[0].split(".") + except ValueError: + raise ValueError(f"Parameter to 'vhdl:describecontext' has incorrect format.") + else: + raise ValueError(f"Parameter to 'vhdl:describecontext' directive has too many content lines ({len(self.arguments)}).") + + # TODO: Can this be done in an __init__ or so? + self.directiveName = self.name.split(":")[1] + self.defaultValues = self.env.config.vhdl_defaults[self.directiveName] + + # parse all directive options or use default values + optionReferencedBy = self.ParseBooleanOption("referencedby", True) + + # Get entity object from design vhdlDomain: Domain = self.env.domains["vhdl"] designs: Dict[str, Design] = vhdlDomain.data["designs"] - design = designs["StopWatch"] + design = designs["StopWatch"] # FIXME: allow specification of design name or default design + library = design.GetLibrary(libraryName.lower()) + context = library.Contexts[contextName.lower()] - paragraph = nodes.paragraph(text="Describe context") + content = [ + nodes.title(text=context.Identifier), + nodes.paragraph(text=context.Documentation) + ] - return [paragraph] + # if optionReferencedBy: + # content.append(self.CreateReferencedBySection(package)) + + contextSection = nodes.section( + ids=[context.NormalizedIdentifier], + classes=["vhdl", "vhdl-context-section"] + ) + contextSection.extend(content) + + return [contextSection] @export -class DescribeEntity(BaseDirective): +class DescribeEntity(BaseDirective, WithGenericsMixin, WithPortsMixin): """ This directive will be replaced by the description of a VHDL entity. """ @@ -221,19 +438,6 @@ class DescribeEntity(BaseDirective): "referencedby": strip, } - def _PrepareTable(self, columns: Dict[str, int], classes: List[str]) -> Tuple[table, tgroup]: - tableGroup = nodes.tgroup(cols=(len(columns))) - table = nodes.table("", tableGroup, classes=classes) - - tableRow = nodes.row() - for columnTitle, width in columns.items(): - tableGroup += nodes.colspec(colwidth=width) - tableRow += nodes.entry("", nodes.paragraph(text=columnTitle)) - - tableGroup += nodes.thead("", tableRow) - - return table, tableGroup - def CreateDefinitionSection(self, entity: Entity) -> section: title = nodes.title(text="Definition") paragraph = nodes.literal_block(text=dedent(f"""\ @@ -258,168 +462,47 @@ def CreateDefinitionSection(self, entity: Entity) -> section: return section - def CreateGenericSection(self, entity: Entity, style: ParameterStyle) -> section: - content = [ - nodes.title(text="Generics") - ] - - if True: - content.append(nodes.paragraph(text="list of all generics")) - - if style is ParameterStyle.Table: - table, tableGroup = self._PrepareTable( - columns={ - "Generic Name": 2, - "Type": 1, - "Default Value": 4, - }, - classes=["vhdl", "vhdl-generic-table"] - ) - - tableBody = nodes.tbody() - tableGroup += tableBody - - for generic in entity.GenericItems: - cellGenericName = nodes.entry() - cellGenericType = nodes.entry() - cellDefaultValue = nodes.entry() - tableBody += nodes.row("", cellGenericName, cellGenericType, cellDefaultValue) - - if isinstance(generic, GenericConstantInterfaceItem): - cellGenericName += nodes.paragraph(text=", ".join(generic.Identifiers)) - cellGenericType += nodes.paragraph(text=generic.Documentation) - if generic.DefaultExpression is not None: - cellDefaultValue += nodes.paragraph(text="??") # str(generic.DefaultExpression)) - - content.append(table) - elif style is ParameterStyle.Sections: - for generic in entity.GenericItems: - if isinstance(generic, GenericConstantInterfaceItem): - genericSection = nodes.section(ids=[f"{entity.NormalizedIdentifier}-generic-{nID}" for nID in generic.NormalizedIdentifiers]) - genericSection.append(nodes.title(text=", ".join(generic.Identifiers))) - genericSection.append(nodes.paragraph(text=generic.Documentation)) - - content.append(genericSection) - - section = nodes.section( - ids=[f"{entity.NormalizedIdentifier}-generics"], - classes=["vhdl", "vhdl-entity-generic-section"] - ) - section.extend(content) - - return section - - def CreatePortSection(self, entity: Entity, style: ParameterStyle) -> section: - content = [ - nodes.title(text="Ports") - ] - - if True: - content.append(nodes.paragraph(text="list of all ports")) - - if style is ParameterStyle.Table: - table, tableGroup = self._PrepareTable( - columns={ - "Port Name": 2, - "Direction": 1, - "Type": 1, - "Default Value": 3 - }, - classes=["vhdl", "vhdl-port-table"] - ) - - tableBody = nodes.tbody() - tableGroup += tableBody - - for port in entity.PortItems: - cellPortName = nodes.entry() - cellPortDirection = nodes.entry() - cellPortType = nodes.entry() - cellDefaultValue = nodes.entry() - tableBody += nodes.row("", cellPortName, cellPortDirection, cellPortType, cellDefaultValue) - - if isinstance(port, PortSignalInterfaceItem): - cellPortName += nodes.paragraph(text=", ".join(port.Identifiers)) - cellPortDirection += nodes.paragraph(text=str(port.Mode)) - cellPortType += nodes.paragraph(text=port.Documentation) - if port.DefaultExpression is not None: - cellDefaultValue += nodes.paragraph(text=str(port.DefaultExpression)) - - content.append(table) - elif style is ParameterStyle.Sections: - for port in entity.PortItems: - if isinstance(port, PortSignalInterfaceItem): - portSection = nodes.section(ids=[f"{entity.NormalizedIdentifier}-port-{nID}" for nID in port.NormalizedIdentifiers]) - portSection.append(nodes.title(text=", ".join(port.Identifiers))) - portSection.append(nodes.paragraph(text=port.Documentation)) - - content.append(portSection) - - section = nodes.section( - ids=[f"{entity.NormalizedIdentifier}-ports"], - classes=["vhdl", "vhdl-entity-port-section"] - ) - section.extend(content) - - return section - def CreateArchitectureSection(self, entity: Entity) -> section: - title = nodes.title(text="Architectures") - paragraph = nodes.paragraph(text=", ".join(entity.Architectures)) section = nodes.section( - "", - title, - paragraph, ids=[f"{entity.NormalizedIdentifier}-architectures"], classes=["vhdl", "vhdl-entity-architectures-section"] ) + section += nodes.title(text="Architectures") + section += nodes.paragraph(text=", ".join(entity.Architectures)) return section def CreateReferencedBySection(self, entity: Entity) -> section: - title = nodes.title(text="Referenced By") - paragraph = nodes.paragraph(text="list of usages and back links") section = nodes.section( - "", - title, - paragraph, ids=[f"{entity.NormalizedIdentifier}-referenced-by"], classes=["vhdl", "vhdl-entity-referencedby-section"] ) + predecessors = entity.HierarchyVertex.Predecessors + + section += nodes.title(text="Referenced By") + section += nodes.paragraph(text=f"Entity '{entity.Identifier}' is referenced from {len(predecessors)} code locations:") + + bulletList = nodes.bullet_list() + section += bulletList + + for referencingVertex in predecessors: + listItem = nodes.list_item() + listItem += nodes.paragraph(text=repr(referencingVertex.Value)) + bulletList += listItem + return section def CreateInnerHierarchySection(self, entity: Entity) -> section: - title = nodes.title(text="Inner Hierarchy") - paragraph = nodes.paragraph(text="diagram of inner instances") section = nodes.section( - "", - title, - paragraph, ids=[f"{entity.NormalizedIdentifier}-hierarchy"], classes=["vhdl", "vhdl-entity-innerhierarchy-section"] ) + section += nodes.title(text="Inner Hierarchy") + section += nodes.paragraph(text="diagram of inner instances") return section - def ParseParameterStyleOption(self, optionName: str) -> ParameterStyle: - try: - option = self.options[optionName] - except KeyError: - try: - option = self.defaultValues[optionName] - except KeyError: - return ParameterStyle.Table - - if option == "never": - return ParameterStyle.Never - elif option == "table": - return ParameterStyle.Table - elif option == "sections": - return ParameterStyle.Sections - else: - raise ValueError(f"value '{option}' is not in list of choices: never, table, sections.") - def ParseArchitecturesStyleOption(self, optionName: str) -> ArchitecturesStyle: try: option = self.options[optionName] @@ -438,25 +521,11 @@ def ParseArchitecturesStyleOption(self, optionName: str) -> ArchitecturesStyle: else: raise ValueError(f"value '{option}' is not in list of choices: never, multiple, always.") - def ParseBooleanOption(self, optionName: str, default: bool) -> bool: - try: - option = self.options[optionName] - except KeyError: - try: - option = self.defaultValues[optionName] - except KeyError: - return default - - if option in ("yes", "true"): - return True - elif option in ("no", "false"): - return False - else: - raise ValueError(f"Value '{option}' not supported for a boolean value (yes/true, no/false).") - def run(self) -> List[Node]: from VHDLDomain import Design + # FIXME: check with regexp + # FIXME: better error message(s) if len(self.arguments) == 1: try: libraryName, entityName = self.arguments[0].split(".") @@ -469,6 +538,7 @@ def run(self) -> List[Node]: self.directiveName = self.name.split(":")[1] self.defaultValues = self.env.config.vhdl_defaults[self.directiveName] + # parse all directive options or use default values optionDefinition = self.ParseBooleanOption("definition", True) optionGenerics = self.ParseParameterStyleOption("genericlist") optionPorts = self.ParseParameterStyleOption("portlist") @@ -476,9 +546,10 @@ def run(self) -> List[Node]: optionReferencedBy = self.ParseBooleanOption("referencedby", True) optionHierarchy = self.ParseBooleanOption("hierarchy", True) + # Get entity object from design vhdlDomain: Domain = self.env.domains["vhdl"] designs: Dict[str, Design] = vhdlDomain.data["designs"] - design = designs["StopWatch"] + design = designs["StopWatch"] # FIXME: allow specification of design name or default design library = design.GetLibrary(libraryName.lower()) entity = library.Entities[entityName.lower()] @@ -490,9 +561,9 @@ def run(self) -> List[Node]: if optionDefinition: content.append(self.CreateDefinitionSection(entity)) - if optionGenerics is not ParameterStyle.Never: + if optionGenerics is not ParameterStyle.Never and len(entity.GenericItems) > 0: content.append(self.CreateGenericSection(entity, optionGenerics)) - if optionPorts is not ParameterStyle.Never: + if optionPorts is not ParameterStyle.Never and len(entity.PortItems) > 0: content.append(self.CreatePortSection(entity, optionPorts)) if (optionArchitectures is ArchitecturesStyle.Always or @@ -537,7 +608,7 @@ def run(self) -> List[Node]: @export -class DescribePackage(BaseDirective): +class DescribePackage(BaseDirective, WithGenericsMixin): """ This directive will be replaced by the description of a VHDL package. """ @@ -554,13 +625,59 @@ class DescribePackage(BaseDirective): def run(self) -> List[Node]: from VHDLDomain import Design + # FIXME: check with regexp + # FIXME: better error message(s) + if len(self.arguments) == 1: + try: + libraryName, packageName = self.arguments[0].split(".") + except ValueError: + raise ValueError(f"Parameter to 'vhdl:describepackage' has incorrect format.") + else: + raise ValueError(f"Parameter to 'vhdl:describepackage' directive has too many content lines ({len(self.arguments)}).") + + # TODO: Can this be done in an __init__ or so? + self.directiveName = self.name.split(":")[1] + self.defaultValues = self.env.config.vhdl_defaults[self.directiveName] + + # parse all directive options or use default values + optionDefinition = self.ParseBooleanOption("definition", True) + optionGenerics = self.ParseParameterStyleOption("genericlist") + optionReferencedBy = self.ParseBooleanOption("referencedby", True) + + # Get entity object from design vhdlDomain: Domain = self.env.domains["vhdl"] designs: Dict[str, Design] = vhdlDomain.data["designs"] - design = designs["StopWatch"] + design = designs["StopWatch"] # FIXME: allow specification of design name or default design + library = design.GetLibrary(libraryName.lower()) + package = library.Packages[packageName.lower()] - paragraph = nodes.paragraph(text="Describe package") + content = [ + nodes.title(text=package.Identifier), + nodes.paragraph(text=package.Documentation) + ] - return [paragraph] + # if optionDefinition: + # content.append(self.CreateDefinitionSection(package)) + if optionGenerics is not ParameterStyle.Never and len(package.GenericItems) > 0: + content.append(self.CreateGenericSection(package, optionGenerics)) + # if optionReferencedBy: + # content.append(self.CreateReferencedBySection(package)) + + content.append(nodes.paragraph(text="Constants")) + for constant in package.Constants.values(): + content.append(nodes.paragraph(text=constant.Identifiers)) + + content.append(nodes.paragraph(text="Subprograms")) + for subprogram in package.Subprograms.values(): + content.append(nodes.paragraph(text=subprogram.Identifiers)) + + packageSection = nodes.section( + ids=[package.NormalizedIdentifier], + classes=["vhdl", "vhdl-package-section"] + ) + packageSection.extend(content) + + return [packageSection] @export @@ -602,10 +719,42 @@ class DescribeConfiguration(BaseDirective): def run(self) -> List[Node]: from VHDLDomain import Design + # FIXME: check with regexp + # FIXME: better error message(s) + if len(self.arguments) == 1: + try: + libraryName, configurationName = self.arguments[0].split(".") + except ValueError: + raise ValueError(f"Parameter to 'vhdl:describepackage' has incorrect format.") + else: + raise ValueError(f"Parameter to 'vhdl:describepackage' directive has too many content lines ({len(self.arguments)}).") + + # TODO: Can this be done in an __init__ or so? + self.directiveName = self.name.split(":")[1] + self.defaultValues = self.env.config.vhdl_defaults[self.directiveName] + + # parse all directive options or use default values + optionReferencedBy = self.ParseBooleanOption("referencedby", True) + + # Get entity object from design vhdlDomain: Domain = self.env.domains["vhdl"] designs: Dict[str, Design] = vhdlDomain.data["designs"] - design = designs["StopWatch"] + design = designs["StopWatch"] # FIXME: allow specification of design name or default design + library = design.GetLibrary(libraryName.lower()) + configuration = library.Configurations[configurationName.lower()] + + content = [ + nodes.title(text=configuration.Identifier), + nodes.paragraph(text=configuration.Documentation) + ] - paragraph = nodes.paragraph(text="Describe configuration") + # if optionReferencedBy: + # content.append(self.CreateReferencedBySection(package)) - return [paragraph] + configurationSection = nodes.section( + ids=[configuration.NormalizedIdentifier], + classes=["vhdl", "vhdl-configuration-section"] + ) + configurationSection.extend(content) + + return [configurationSection] diff --git a/VHDLDomain/__init__.py b/VHDLDomain/__init__.py index 3691c71..2aa22ee 100644 --- a/VHDLDomain/__init__.py +++ b/VHDLDomain/__init__.py @@ -42,7 +42,7 @@ __email__ = "Paebbels@gmail.com" __copyright__ = "2016-2023, Patrick Lehmann" __license__ = "Apache License, Version 2.0" -__version__ = "0.1.0" +__version__ = "0.2.0" from pathlib import Path from typing import Dict, Tuple, Any, Optional as Nullable, cast @@ -105,12 +105,12 @@ class VHDLDomain(Domain): "describedesign": DescribeDesign, # "describelibrary": DescribeLibrary, # "describedocument": DescribeDocument, - # "describecontext": DescribeContext, + "describecontext": DescribeContext, "describeentity": DescribeEntity, # "describearchitecture": DescribeArchitecture, - # "describepackage": DescribePackage, + "describepackage": DescribePackage, # "describepackagebody": DescribePackageBody, - # "describeconfiguration": DescribeConfiguration, + "describeconfiguration": DescribeConfiguration, } #: A dictionary of all directives in this domain. roles = { diff --git a/dist/requirements.txt b/dist/requirements.txt index e4718c9..f3db59e 100644 --- a/dist/requirements.txt +++ b/dist/requirements.txt @@ -1,2 +1,2 @@ -wheel>=0.38.1 -twine +wheel ~= 0.45 +twine ~= 6.0 diff --git a/doc/Dependency.rst b/doc/Dependency.rst index bbc60e4..092c497 100644 --- a/doc/Dependency.rst +++ b/doc/Dependency.rst @@ -23,9 +23,9 @@ VHDLDomain Package +--------------------------------------------------------+-------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Package** | **Version** | **License** | **Dependencies** | +========================================================+=============+==========================================================================================+=================================================================================================================================+ -| `pyTooling `__ | ≥2.12.0 | `Apache License, 2.0 `__ | *None* | +| `pyTooling `__ | ≥8.0 | `Apache License, 2.0 `__ | *None* | +--------------------------------------------------------+-------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+ -| `Sphinx `__ | ≥5.3.0 | `BSD-2-Clause `__ |br| | * ❓`sphinxcontrib-applehelp <>`__ | +| `Sphinx `__ | ≥7.4 | `BSD-2-Clause `__ |br| | * ❓`sphinxcontrib-applehelp <>`__ | | | | | * ❓`sphinxcontrib-devhelp <>`__ | | | | * ``sphinx.util.smartypants`` | * ❓`sphinxcontrib-jsmath <>`__ | | | | * ``smartypants.py`` | * ❓`sphinxcontrib-htmlhelp <>`__ | @@ -71,19 +71,21 @@ the mandatory dependencies too. .. rubric:: Dependency List -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ -| **Package** | **Version** | **License** | **Dependencies** | -+===========================================================+=============+========================================================================================+======================+ -| `pytest `__ | ≥7.2.0 | `MIT `__ | *Not yet evaluated.* | -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ -| `pytest-cov `__ | ≥4.0.0 | `MIT `__ | *Not yet evaluated.* | -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ -| `Coverage `__ | ≥7.0 | `Apache License, 2.0 `__ | *Not yet evaluated.* | -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ -| `mypy `__ | ≥0.990 | `MIT `__ | *Not yet evaluated.* | -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ -| `lxml `__ | ≥4.9 | `BSD 3-Clause `__ | *Not yet evaluated.* | -+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=====================================================================+=============+========================================================================================+======================+ +| `pytest `__ | ≥7.4.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `pytest-cov `__ | ≥6.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `Coverage `__ | ≥7.6 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `mypy `__ | ≥1.13 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `typing-extensions `__ | ≥4.7.1 | `PSF-2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `lxml `__ | ≥5.3 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ .. _dependency-documentation: @@ -110,15 +112,19 @@ the mandatory dependencies too. +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | **Package** | **Version** | **License** | **Dependencies** | +=================================================================================================+==============+==========================================================================================================+======================+ -| `Sphinx `__ | ≥5.3.0 | `BSD 3-Clause `__ | *Not yet evaluated.* | +| `pyTooling `__ | ≥8.0 | `Apache License, 2.0 `__ | *None* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ -| `sphinx_btd_theme `__ | | `MIT `__ | *Not yet evaluated.* | +| `Sphinx `__ | ≥7.4 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ +| `sphinxcontrib-mermaid `__ | ≥0.9.2 | `BSD `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ -| `autoapi `__ | | `Apache License, 2.0 `__ | *Not yet evaluated.* | +| `autoapi `__ | ≥2.0.1 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ +| `sphinx_btd_theme `__ | | `MIT `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ | ❗❗ `sphinx_fontawesome `__ | ≥0.0.6 | `GPL 2.0 `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ -| `sphinx_autodoc_typehints `__ | ≥1.19.5 | `MIT `__ | *Not yet evaluated.* | +| `sphinx_autodoc_typehints `__ | ≥2.3 | `MIT `__ | *Not yet evaluated.* | +-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+ @@ -146,9 +152,9 @@ install the mandatory dependencies too. +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Package** | **Version** | **License** | **Dependencies** | +============================================================================+==============+==========================================================================================================+======================================================================================================================================================+ -| `pyTooling `__ | ≥2.12.0 | `Apache License, 2.0 `__ | *None* | +| `pyTooling `__ | ≥8.0 | `Apache License, 2.0 `__ | *None* | +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `wheel `__ | ≥0.38.1 | `MIT `__ | *Not yet evaluated.* | +| `wheel `__ | ≥0.40.0 | `MIT `__ | *Not yet evaluated.* | +----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -177,7 +183,7 @@ install the mandatory dependencies too. +----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ | **Package** | **Version** | **License** | **Dependencies** | +==========================================================+==============+===========================================================================================+======================+ -| `wheel `__ | ≥0.38.1 | `MIT `__ | *Not yet evaluated.* | +| `wheel `__ | ≥ 0.45 | `MIT `__ | *Not yet evaluated.* | +----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ -| `Twine `__ | any | `Apache License, 2.0 `__ | *Not yet evaluated.* | +| `Twine `__ | ≥6.0 | `Apache License, 2.0 `__ | *Not yet evaluated.* | +----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ diff --git a/doc/StopWatch/index.rst b/doc/StopWatch/index.rst index a853f81..0eed9f2 100644 --- a/doc/StopWatch/index.rst +++ b/doc/StopWatch/index.rst @@ -14,19 +14,30 @@ StopWatch lib_Utilities ************* +.. vhdl:describepackage:: lib_Utilities.Utilities_pkg + +.. vhdl:describecontext:: lib_Utilities.Utilities_ctx + .. vhdl:describeentity:: lib_Utilities.Counter .. vhdl:describeentity:: lib_Utilities.Debouncer .. vhdl:describeentity:: lib_Utilities.sync_Bits + lib_StopWatch ************* +.. vhdl:describepackage:: lib_StopWatch.StopWatch_pkg + +.. vhdl:describecontext:: lib_StopWatch.StopWatch_ctx + .. vhdl:describeentity:: lib_StopWatch.seg7_Encoder .. vhdl:describeentity:: lib_StopWatch.seg7_Display +.. vhdl:describeconfiguration:: lib_StopWatch.seg7_Display_cfg + .. vhdl:describeentity:: lib_StopWatch.StopWatch .. vhdl:describeentity:: lib_StopWatch.toplevel diff --git a/doc/conf.py b/doc/conf.py index 7e1f0ba..3982ab3 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -59,10 +59,10 @@ # ============================================================================== # Restructured Text settings # ============================================================================== -prologPath = "prolog.inc" +prologPath = Path("prolog.inc") try: - with open(prologPath, "r") as prologFile: - rst_prolog = prologFile.read() + with prologPath.open("r", encoding="utf-8") as fileHandle: + rst_prolog = fileHandle.read() except Exception as ex: print(f"[ERROR:] While reading '{prologPath}'.") print(ex) @@ -225,9 +225,9 @@ # Sphinx.Ext.ExtLinks # ============================================================================== extlinks = { - "ghissue": ('https://GitHub.com/vhdl/VHDLDomain/issues/%s', 'issue #'), - "ghpull": ('https://GitHub.com/vhdl/VHDLDomain/pull/%s', 'pull request #'), - "ghsrc": ('https://GitHub.com/vhdl/VHDLDomain/blob/main/%s?ts=2', ""), + "ghissue": ('https://GitHub.com/vhdl/VHDLDomain/issues/%s', 'issue #%s'), + "ghpull": ('https://GitHub.com/vhdl/VHDLDomain/pull/%s', 'pull request #%s'), + "ghsrc": ('https://GitHub.com/vhdl/VHDLDomain/blob/main/%s?ts=2', None), } diff --git a/doc/index.rst b/doc/index.rst index 8a11e91..58de718 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -68,7 +68,7 @@ News * Connecting pyGHDL.dom, pyVHDLModel and Sphinx with this extension. -.. _contributors: +.. _CONTRIBUTORS: Contributors ************ @@ -77,6 +77,8 @@ Contributors * `and more... `__ +.. _LICENSE: + License ******* diff --git a/doc/requirements.txt b/doc/requirements.txt index 25917fd..f7fe8a0 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,20 +1,10 @@ -r ../requirements.txt -pyTooling>=2.12.0 - # Enforce latest version on ReadTheDocs -sphinx>=5.3.0, <6.0 +sphinx ~= 8.2 +docutils ~= 0.21 # Sphinx Extenstions -#sphinx.ext.coverage -#sphinxcontrib-actdiag>=0.8.5 -sphinxcontrib-mermaid>=0.7.1 -#sphinxcontrib-seqdiag>=0.8.5 -#sphinxcontrib-textstyle>=0.2.1 -#sphinxcontrib-spelling>=2.2.0 +sphinxcontrib-mermaid>=0.9.2 autoapi>=2.0.1 -sphinx_fontawesome>=0.0.6 -sphinx_autodoc_typehints>=1.19.5 -# changelog>=0.3.5 - -# BuildTheDocs Extensions (mostly patched Sphinx extensions) +sphinx_autodoc_typehints ~= 2.3 diff --git a/pyproject.toml b/pyproject.toml index df1e990..043755f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [build-system] requires = [ - "pyTooling >= 2.12.0", - "setuptools >= 62.3.3", - "wheel >= 0.38.1" + "setuptools ~= 75.5", + "wheel ~= 0.45", + "pyTooling ~= 8.0" ] build-backend = "setuptools.build_meta" @@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta" line-length = 120 [tool.mypy] -python_version = "3.11" +python_version = "3.13" namespace_packages = true pretty = true @@ -19,6 +19,7 @@ show_error_context = true html_report = "report/typing" [tool.pytest.ini_options] +addopts = "--tb=native" # Don't set 'python_classes = *' otherwise, pytest doesn't search for classes # derived from unittest.Testcase python_files = "*" diff --git a/requirements.txt b/requirements.txt index 792e4e7..ee3c440 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ -pyTooling>=2.12.0 -pyGHDL +pyTooling ~= 8.4 +#pyGHDL +https://github.com/ghdl/ghdl/archive/master.zip#pyGHDL diff --git a/setup.py b/setup.py index de4028e..d4a1577 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ packageDirectory = packageName packageInformationFile = Path(f"{packageDirectory}/__init__.py") -DescribePythonPackageHostedOnGitHub( +setup(**DescribePythonPackageHostedOnGitHub( packageName=packageName, description="A Sphinx domain providing VHDL language support.", gitHubNamespace=gitHubNamespace, @@ -46,9 +46,13 @@ sourceFileWithVersion=packageInformationFile, developmentStatus="alpha", classifiers=list(DEFAULT_CLASSIFIERS) + [ + "Framework :: Sphinx :: Domain", "Framework :: Sphinx :: Extension", "Topic :: Documentation :: Sphinx", "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", "Topic :: Software Development :: Documentation", - ] -) + ], + dataFiles={ + packageName: ["py.typed"] + } +)) diff --git a/tests/requirements.txt b/tests/requirements.txt index 7719481..a09846f 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,12 +1,13 @@ -r ../requirements.txt # Coverage collection -Coverage>=7.0 +Coverage ~= 7.6 # Test Runner -pytest>=7.2.0 -pytest-cov>=4.0.0 +pytest >= 7.4.0 +pytest-cov ~= 6.0 # Static Type Checking -mypy>=0.990 -lxml>=4.9 +mypy ~= 1.13 +typing_extensions ~= 4.12 +lxml >= 5.4 diff --git a/tests/unit/Instantiate.py b/tests/unit/Instantiate.py index 7e55504..a3e96f0 100644 --- a/tests/unit/Instantiate.py +++ b/tests/unit/Instantiate.py @@ -33,6 +33,7 @@ from unittest import TestCase from pyVHDLModel import Library +from pyVHDLModel.Name import SimpleName from pyVHDLModel.Symbol import LibraryReferenceSymbol @@ -46,7 +47,7 @@ class Symbols(TestCase): def test_LibraryReferenceSymbol(self): - symbol = LibraryReferenceSymbol("Lib") + symbol = LibraryReferenceSymbol(SimpleName("Lib")) self.assertEqual("Lib", symbol.Identifier) self.assertEqual("lib", symbol.NormalizedIdentifier)