M Makefile => Makefile +41 -17
@@ 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
+
M README.md => README.md +7 -4
@@ 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
M gap/toml_parser.py => gap/toml_parser.py +29 -13
@@ 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
M pyproject.toml => pyproject.toml +2 -2
@@ 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 = [
M setup.cfg => setup.cfg +2 -2
@@ 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