From 029dc0cebe4fe61dc7190ea8613713fad69a5139 Mon Sep 17 00:00:00 2001 From: Dominic Ricottone Date: Tue, 13 Sep 2022 14:51:43 -0500 Subject: [PATCH] Updating TOML parsing for Python 3.11 Use tomllib if available, else use toml. An upcoming release will drop support for toml and therefore become supported on Python 3.11+ only. --- Makefile | 58 ++++++++++++++++++++++++++++++++-------------- README.md | 11 +++++---- gap/toml_parser.py | 42 ++++++++++++++++++++++----------- pyproject.toml | 4 ++-- setup.cfg | 4 ++-- 5 files changed, 81 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 63c6690..eee2f9e 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,14 @@ +VERSION=1.0.3 + PY_COMPILE_BIN=python -m py_compile #BUILD_BIN=python -m build BUILD_BIN=pyproject-build -#UNITTEST_BIN=python -m unittest -UNITTEST_BIN=unittest --color +#UNITTEST_FILE_BIN=python -m unittest +#UNITTEST_DIR_BIN=python -m unittest discover --top-level-directory . +UNITTEST_FILE_BIN=unittest --color +UNITTEST_DIR_BIN=unittest --color --working-directory . #MYPY_BIN=python -m mypy MYPY_BIN=MYPY_CACHE_DIR=gap/__mypycache__ mypy @@ -12,39 +16,59 @@ MYPY_BIN=MYPY_CACHE_DIR=gap/__mypycache__ mypy #PIPX_BIN=python -m pipx PIPX_BIN=pipx -.PHONY: clean bootstrap test build unittest reinstall install uninstall - +.PHONY: clean clean: rm -rf **/__pycache__ **/__mypycache__ **/*.pyc build *.egg-info -bootstrap: +gap/cli.py: gap/bootstrap.py ./gap/bootstrap.py > gap/cli.py -test: +tests/__init__.py: + touch tests/__init__.py + +tests/generated_syntax: mkdir -p tests/generated_syntax - touch tests/__init__.py tests/generated_syntax/__init__.py + +tests/generated_syntax/__init__.py: tests/generated_syntax + touch tests/__init__.py + +TEST_FILES=tests/__init__.py tests/generated_syntax tests/generated_syntax/__init__.py + +.PHONY: test +test: $(TEST_FILES) $(PY_COMPILE_BIN) gap/*.py - $(UNITTEST_BIN) --working-directory . tests + $(UNITTEST_DIR_BIN) tests $(PY_COMPILE_BIN) tests/generated_syntax/*.py - $(UNITTEST_BIN) tests/generated_syntax_tests.py + $(UNITTEST_FILE_BIN) tests/generated_syntax_tests.py $(MYPY_BIN) -p gap +.PHONY: unittest # more verbose than `make test`, skips `py_compile` and `mypy` -unittest: - mkdir -p tests/generated_syntax - touch tests/__init__.py tests/generated_syntax/__init__.py - $(UNITTEST_BIN) --working-directory . tests --verbose - $(UNITTEST_BIN) tests/generated_syntax_tests.py --verbose +unittest: $(TEST_FILES) + $(UNITTEST_DIR_BIN) tests --verbose + $(UNITTEST_FILE_BIN) tests/generated_syntax_tests.py --verbose + +PY_FILES=gap/cli.py gap/generator.py gap/__main__.py gap/toml_parser.py -build: +build/gap-$(VERSION)-py3-none-any.whl: build + +.PHONY: +build: $(PY_FILES) mkdir -p build $(BUILD_BIN) --wheel --no-isolation --outdir build/ +.PHONY: reinstall reinstall: uninstall install -install: - $(PIPX_BIN) install build/gap-1.0.2-py3-none-any.whl +.PHONY: install +install: build/gap-$(VERSION)-py3-none-any.whl + $(PIPX_BIN) install build/gap-$(VERSION)-py3-none-any.whl +.PHONY: uninstall uninstall: $(PIPX_BIN) uninstall gap +.PHONY: rc +rc: + docker run --interactive --tty --rm --name pytest --mount type=bind,src=$(pwd),dst=/code python:3.11-rc sh + diff --git a/README.md b/README.md index ad6b88d..eccff6f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,17 @@ # generated argument parser -A package that uses external configuration files to generate a static, standalone parser module. +A package that uses external configuration files to generate a static, +standalone parser module. ## To-Do -Add parsers aside from `toml`, like `json` and `configparser`. - -Allow import of third-party libraries, like `toml`, to fail-just remove that format from the valid list. +Python 3.11 introduces a `tomllib` module. **Release 1.0.2** will continue to +work perfectly for Python 3.6 or later. **Release 1.0.3** will continue to +function perfectly as well, but the test suite will fail due to `mypy` not +having type stubs for `tomllib`. **Release 1.0.4** will drop `toml` as a +dependency and therefore drop support for Python 3.10 or earlier. ## Workflow diff --git a/gap/toml_parser.py b/gap/toml_parser.py index bbe4fd2..aaeee35 100644 --- a/gap/toml_parser.py +++ b/gap/toml_parser.py @@ -1,19 +1,35 @@ #!/usr/bin/env python3 -# type: ignore from typing import MutableMapping, Any -import toml +try: + #3.11+ + import tomllib -def data_from_file(filename: str) -> MutableMapping[str, Any]: - try: - with open(filename, 'r') as f: - data = toml.load(f) - except OSError: - message = 'file "{0}" cannot be found'.format(filename) - raise FileNotFoundError(message) from None - except toml.TomlDecodeError: - message = 'file "{0}" is invalid TOML'.format(filename) - raise ValueError(message) from None - return data + def data_from_file(filename: str) -> MutableMapping[str, Any]: + try: + with open(filename, 'rb') as f: + data = tomllib.load(f) + except OSError: + message = 'file "{0}" cannot be found'.format(filename) + raise FileNotFoundError(message) from None + except tomllib.TOMLDecodeError: + message = 'file "{0}" is invalid TOML'.format(filename) + raise ValueError(message) from None + return data + +except: + import toml #type: ignore + + def data_from_file(filename: str) -> MutableMapping[str, Any]: #type: ignore + try: + with open(filename, 'r') as f: + data = toml.load(f) + except OSError: + message = 'file "{0}" cannot be found'.format(filename) + raise FileNotFoundError(message) from None + except toml.TomlDecodeError: + message = 'file "{0}" is invalid TOML'.format(filename) + raise ValueError(message) from None + return data diff --git a/pyproject.toml b/pyproject.toml index 09d6c9f..e2b54d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,9 +6,9 @@ build-backend = "setuptools.build_meta" name = "gap" description = "Generated argument parser" readme = "README.md" -version = "1.0.2" +version = "1.0.3" authors = [ { name = "Dominic Ricottone", email = "me@dominic-ricottone.com" } ] -urls = { source = "git.dominic-ricottone.com/gap" } +urls = { source = "git.dominic-ricottone.com/~dricottone/gap" } license = { file = "LICENSE.md" } requires-python = ">=3.6" dependencies = [ diff --git a/setup.cfg b/setup.cfg index 214160f..ca68df8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,12 +1,12 @@ [metadata] name = gap -version = 1.0.2 +version = 1.0.3 description = Generated argument parser long_description = file: README.md license = GPL author = Dominic Ricottone author_email = me@dominic-ricottone.com -url = git.dominic-ricottone.com/gap +url = git.dominic-ricottone.com/~dricottone/gap [options] packages = gap -- 2.45.2