From df4a826454f962a9c099280a5848fb0419f172cf Mon Sep 17 00:00:00 2001 From: Richard Lin Date: Sun, 7 May 2023 21:17:40 -0700 Subject: [PATCH] Add packaging tests, support blocks defined in __main__ (#252) Add local packaging run to workflow tests, with an abbreviated (blinky-only) unittest and top-level test. Resolves #251, where blocks defined in `__main__` cause an error when the HDL server tries to resolve those blocks, because the HDL server is a separate Python instance and thinks itself is `__main__` (instead of the original file). The fix is to detect when a library's module is `__main__` and effectively guess the correct original module name by using the filename. Might be a better way to do it, but this works, and is largely what a websearch turned out for finding the original module name for `__main__`. Bumps the package version since this is a significant bugfix. --- .github/workflows/pr-python.yml | 31 +++++++++++++++++++++++-------- developing.md | 14 +++++++++++++- edg_core/Core.py | 11 ++++++++++- edg_core/Util.py | 1 - examples/test_blinky.py | 10 ++++++++++ pyproject.toml | 2 +- 6 files changed, 57 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pr-python.yml b/.github/workflows/pr-python.yml index 4b1b56f5b..b42abb88f 100644 --- a/.github/workflows/pr-python.yml +++ b/.github/workflows/pr-python.yml @@ -43,8 +43,7 @@ jobs: pip install mypy mypy-protobuf types-protobuf types-Deprecated mypy --version - name: mypy - run: | - mypy --install-types . + run: mypy --install-types . unittest_latest_3_11: needs: pre_job @@ -57,11 +56,29 @@ jobs: python-version: '3.11' - name: install dependencies - run: | - pip install -r requirements.txt + run: pip install -r requirements.txt - name: unittest run: python -m unittest discover + packagetest_latest_3_11: + needs: pre_job + if: ${{ needs.pre_job.outputs.should_skip != 'true' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + with: + python-version: '3.11' + + - name: install dependencies + run: pip install -r requirements.txt + - name: package + run: python -m pip install . + - name: unittest + run: cd examples && python -m unittest test_blinky + - name: toptest + run: cd examples && python test_blinky.py + mypy_latest_3_9: needs: pre_job if: ${{ needs.pre_job.outputs.should_skip != 'true' }} @@ -77,8 +94,7 @@ jobs: pip install mypy mypy-protobuf types-protobuf types-Deprecated mypy --version - name: mypy - run: | - mypy --install-types . + run: mypy --install-types . unittest_latest_3_9: needs: pre_job @@ -91,7 +107,6 @@ jobs: python-version: '3.9' - name: install dependencies - run: | - pip install -r requirements.txt + run: pip install -r requirements.txt - name: unittest run: python -m unittest discover diff --git a/developing.md b/developing.md index f7d1444f4..4b2ebf0b1 100644 --- a/developing.md +++ b/developing.md @@ -50,7 +50,19 @@ If you have not modified any of the .scala files, you do not need to recompile t 1. [Download and install sbt](https://www.scala-sbt.org/download.html), a build tool or Scala. 2. In the `compiler/` folder, run `sbt assembly` to compile the compiler JAR file. The system will automatically prefer the locally built JAR file over the pre-compiled JAR and indicate its use through the console. -3. Optionally, to commit a new pre-compiled JAR, move the newly compiled JAR from `compiler/target/scala-*/edg-compiler-assembly-*-SNAPSHOT.jar` to `compiler/edg-compiler-precompiled.jar`. +3. Optionally, to commit a new pre-compiled JAR, move the newly compiled JAR from `compiler/target/scala-*/edg-compiler-assembly-*-SNAPSHOT.jar` to `edg_core/resources/edg-compiler-precompiled.jar`. + +### Packaging +Largely based on [this tutorial](https://realpython.com/pypi-publish-python-package/). + +Local: +- Install in editable mode (package refers to this source directory, instead of making a copy): `python -m pip install -e .` + +Upload: +- These dependencies are necessary: `python -m pip install build twine` +- Build the package (creates a `dist` folder with a `.whl` (zipped) file): `python -m build` +- Optionally, upload to TestPyPI: `python -m twine upload -r testpypi dist/*` +- Upload to PyPI: `python -m twine upload dist/*` ## Frontend Architecture diff --git a/edg_core/Core.py b/edg_core/Core.py index 1a9e1ab3c..e559125a4 100644 --- a/edg_core/Core.py +++ b/edg_core/Core.py @@ -227,7 +227,16 @@ def _name_from(self, base: LibraryElement) -> str: def _static_def_name(cls) -> str: """If this library element is defined by class (all instances have an equivalent library definition), returns the definition name. Otherwise, should crash.""" - return cls.__module__ + "." + cls.__name__ + if cls.__module__ == "__main__": + # when the top-level design is run as main, the module name is __main__ which is meaningless + # and breaks when the HDL server tries to resolve the __main__ reference (to itself), + # so this needs to resolve the correct name + import inspect + import os + module = os.path.splitext(os.path.basename(inspect.getfile(cls)))[0] + else: + module = cls.__module__ + return module + "." + cls.__name__ def _get_def_name(self) -> str: """Returns the definition name""" diff --git a/edg_core/Util.py b/edg_core/Util.py index 1e829d7bf..d421297e5 100644 --- a/edg_core/Util.py +++ b/edg_core/Util.py @@ -28,4 +28,3 @@ def edg_to_dict(obj: Union[BasePort, BaseBlock]) -> Dict[str, Any]: } else: raise ValueError - diff --git a/examples/test_blinky.py b/examples/test_blinky.py index 66197d9cb..dea827bf9 100644 --- a/examples/test_blinky.py +++ b/examples/test_blinky.py @@ -445,3 +445,13 @@ def test_design_array(self) -> None: def test_design_packed(self) -> None: compile_board_inplace(TestBlinkyPacked, False) + + +if __name__ == "__main__": + # this unit test can also be run as __main__ to test a non-unit-test environment + compile_board_inplace(TestBlinkyEmpty, False) + compile_board_inplace(TestBlinkyComplete, False) + compile_board_inplace(TestBlinkyWithLibrary, False) + compile_board_inplace(TestBlinkyWithLibraryExport, False) + compile_board_inplace(TestBlinkyArray, False) + compile_board_inplace(TestBlinkyPacked, False) diff --git a/pyproject.toml b/pyproject.toml index 8bba3055b..9757d26b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "edg" -version = "0.0.0" +version = "0.0.1" description = "Hardware description language for circuit boards" readme = "README.md" authors = [{ name = "Ducky", email = "richard.lin@berkeley.edu" }]