From 1e9f3dd016695ccc4edd5802f3ceaf03d5912fab Mon Sep 17 00:00:00 2001 From: karlicoss Date: Wed, 4 Oct 2023 23:21:19 +0100 Subject: [PATCH] ci updates: sync with pympalte - use python 3.12 - use ruff instead of pylint - use pyproject.toml --- .ci/release | 6 ++-- .ci/run | 2 +- .github/workflows/main.yml | 12 +++---- .pylintrc | 32 ------------------ pyproject.toml | 59 ++++++++++++++++++++++++++++++++ ruff.toml | 25 ++++++++++++++ setup.py | 69 -------------------------------------- tox.ini | 32 +++++++++--------- 8 files changed, 110 insertions(+), 127 deletions(-) delete mode 100644 .pylintrc create mode 100644 pyproject.toml create mode 100644 ruff.toml delete mode 100644 setup.py diff --git a/.ci/release b/.ci/release index 0ec687f..6cff663 100755 --- a/.ci/release +++ b/.ci/release @@ -21,7 +21,7 @@ import shutil is_ci = os.environ.get('CI') is not None -def main(): +def main() -> None: import argparse p = argparse.ArgumentParser() p.add_argument('--test', action='store_true', help='use test pypi') @@ -29,7 +29,7 @@ def main(): extra = [] if args.test: - extra.extend(['--repository-url', 'https://test.pypi.org/legacy/']) + extra.extend(['--repository', 'testpypi']) root = Path(__file__).absolute().parent.parent os.chdir(root) # just in case @@ -42,7 +42,7 @@ def main(): if dist.exists(): shutil.rmtree(dist) - check_call('python3 setup.py sdist bdist_wheel', shell=True) + check_call(['python3', '-m', 'build']) TP = 'TWINE_PASSWORD' password = os.environ.get(TP) diff --git a/.ci/run b/.ci/run index b15eb1c..b2c184d 100755 --- a/.ci/run +++ b/.ci/run @@ -37,4 +37,4 @@ if ! command -v python3 &> /dev/null; then fi "$PY_BIN" -m pip install --user tox -"$PY_BIN" -m tox "$@" +"$PY_BIN" -m tox --parallel --parallel-live "$@" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9471235..1ed01af 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,9 +22,10 @@ on: jobs: build: strategy: + fail-fast: false matrix: - platform: [ubuntu-latest, macos-latest] # TODO windows-latest?? - python-version: ['3.8', '3.9', '3.10', '3.11'] + platform: [ubuntu-latest, macos-latest] # todo windows-latest] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] # vvv just an example of excluding stuff from matrix # exclude: [{platform: macos-latest, python-version: '3.6'}] @@ -33,9 +34,6 @@ jobs: steps: # ugh https://github.com/actions/toolkit/blob/main/docs/commands.md#path-manipulation - run: echo "$HOME/.local/bin" >> $GITHUB_PATH - - if: ${{ matrix.platform == 'macos-latest' && matrix.python-version == '3.11' }} - # hmm somehow only seems necessary for 3.11 on osx?? - run: echo "$HOME/Library/Python/${{ matrix.python-version }}/bin" >> $GITHUB_PATH - uses: actions/setup-python@v4 with: @@ -80,7 +78,7 @@ jobs: if: github.event_name != 'pull_request' && github.event.ref == 'refs/heads/master' env: TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD_TEST }} - run: pip3 install --user wheel twine && .ci/release --test + run: pip3 install --user --upgrade build twine && .ci/release --test - name: 'release to pypi' # always deploy tags to release pypi @@ -88,4 +86,4 @@ jobs: if: github.event_name != 'pull_request' && startsWith(github.event.ref, 'refs/tags') env: TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} - run: pip3 install --user wheel twine && .ci/release + run: pip3 install --user --upgrade build twine && .ci/release diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 968bb58..0000000 --- a/.pylintrc +++ /dev/null @@ -1,32 +0,0 @@ -[MASTER] - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -# jobs=1 - -[MESSAGES CONTROL] - -# Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# -# C: picky shit like too many lines/import-outside-toplevel etc -# R: just random picky shit -# W: unused-argument, unused-import, unused-variable might be interesting -# although most of unused-variable seem either false positive or pytest fixtures (so actually used!) -disable=C,R,W, - too-few-public-methods, - too-many-return-statements, # too picky - too-many-argument, # too picky - missing-docstring, - invalid-name, - bad-whitespace, - line-too-long, - multiple-statements, - no-else-return, - no-else-raise, - len-as-condition, - wrong-import-order, - wrong-import-position, - fixme, - not-callable # ugh, sometimes gives false positives in tests? diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..668c47f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,59 @@ +# see https://github.com/karlicoss/pymplate for up-to-date reference +[project] +dynamic = ["version"] # version is managed by setuptools_scm +name = "cachew" +dependencies = [ + "appdirs" , # default cache dir + "sqlalchemy>=1.0", # cache DB interaction + "orjson", # fast json serialization + "pytz", # used to properly marshall pytz datatimes +] +requires-python = ">=3.8" + +## these need to be set if you're planning to upload to pypi +# description = "TODO" +license = {file = "LICENSE.txt"} +authors = [ + {name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}, +] +maintainers = [ + {name = "Dima Gerasimov (@karlicoss)", email = "karlicoss@gmail.com"}, +] +# keywords = [] +# # see: http://pypi.python.org/pypi?%3Aaction=list_classifiers +# classifiers = [ +# ] + + +[project.urls] +Homepage = "https://github.com/karlicoss/cachew" +## + + +[project.optional-dependencies] +testing = [ + "pytest", + "more-itertools", + "patchy", # for injecting sleeps and testing concurrent behaviour + "enlighten", # used in logging helper, but not really required + "cattrs", # benchmarking alternative marshalling implementation + "pyinstrument", # for profiling from within tests + "codetiming", # Timer context manager + + "ruff", + + "mypy", + "lxml", # for mypy html coverage +] +optional = [ + "colorlog", +] + + +[build-system] +requires = ["setuptools", "setuptools-scm"] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +version_scheme = "python-simplified-semver" +local_scheme = "dirty-tag" diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..0be93e0 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,25 @@ +ignore = [ +### too opinionated style checks + "E501", # too long lines + "E702", # Multiple statements on one line (semicolon) + "E731", # assigning lambda instead of using def + "E741", # Ambiguous variable name: `l` + "E742", # Ambiguous class name: `O + "E401", # Multiple imports on one line + "F403", # import *` used; unable to detect undefined names +### + +### + "E722", # Do not use bare `except` ## Sometimes it's useful for defensive imports and that sort of thing.. + "F811", # Redefinition of unused # this gets in the way of pytest fixtures (e.g. in cachew) + +## might be nice .. but later and I don't wanna make it strict + "E402", # Module level import not at top of file + +### maybe consider these soon +# sometimes it's useful to give a variable a name even if we don't use it as a documentation +# on the other hand, often is a sign of error + "F841", # Local variable `count` is assigned to but never used + "F401", # imported but unused +### +] diff --git a/setup.py b/setup.py deleted file mode 100644 index 01a2fe0..0000000 --- a/setup.py +++ /dev/null @@ -1,69 +0,0 @@ -# see https://github.com/karlicoss/pymplate for up-to-date reference - - -url = 'https://github.com/karlicoss/cachew' -author = 'Dima Gerasimov' -author_email = 'karlicoss@gmail.com' -description = 'Easy sqlite-backed persistent cache for dataclasses' - -install_requires = [ - 'appdirs' , # default cache dir - 'sqlalchemy>=1.0', # cache DB interaction - 'orjson', # fast json serialization - 'pytz', # used to properly marshall pytz datatimes -] - - -from setuptools import setup, find_namespace_packages # type: ignore - - -def main() -> None: - pkgs = find_namespace_packages('src', exclude=['*.tests']) - pkg = min(pkgs) - setup( - name=pkg, - use_scm_version={ - 'version_scheme': 'python-simplified-semver', - 'local_scheme': 'dirty-tag', - }, - setup_requires=['setuptools_scm'], - - url=url, - author=author, - author_email=author_email, - description=description, - - packages=pkgs, - package_dir={'': 'src'}, - package_data={pkg: ['py.typed']}, - - python_requires='>=3.8', - - install_requires=install_requires, - extras_require={ - 'testing': [ - 'pytest', 'pytz', 'patchy', - 'pylint', - 'mypy', 'lxml', - 'bandit', - - 'more-itertools', - - 'enlighten', # used in logging helper, but not really required - - 'cattrs', # benchmarking alternative marshalling implementation - - 'pyinstrument', # for profiling from within tests - 'codetiming', # Timer context manager - ], - 'optional': [ - 'colorlog', - ], - }, - - zip_safe=False, - ) - - -if __name__ == '__main__': - main() diff --git a/tox.ini b/tox.ini index 76a6245..c9f41be 100644 --- a/tox.ini +++ b/tox.ini @@ -1,26 +1,35 @@ [tox] -minversion = 3.5 +minversion = 3.21 # relies on the correct version of Python installed -envlist = tests,pylint,mypy +envlist = ruff,tests,mypy # https://github.com/tox-dev/tox/issues/20#issuecomment-247788333 # hack to prevent .tox from crapping to the project directory -toxworkdir={env:TOXWORKDIR_BASE:}{toxinidir}/.tox +toxworkdir = {env:TOXWORKDIR_BASE:}{toxinidir}/.tox [testenv] # TODO how to get package name from setuptools? package_name = "cachew" passenv = +# useful for tests to know they are running under ci CI CI_* - CIRCLE* - # respect user's cache dirs to prevent tox from crapping into project dir - MYPY_CACHE_DIR +# respect user's cache dirs to prevent tox from crapping into project dir PYTHONPYCACHEPREFIX + MYPY_CACHE_DIR + RUFF_CACHE_DIR + + +[testenv:ruff] +commands = + {envpython} -m pip install --use-pep517 -e .[testing] + {envpython} -m ruff src/ +# note: --use-pep517 here is necessary for tox --parallel flag to work properly +# otherwise it seems that it tries to modify .eggs dir in parallel and it fails [testenv:tests] commands = - {envpython} -m pip install -e .[testing] + {envpython} -m pip install --use-pep517 -e .[testing] # posargs allow test filtering, e.g. tox ... -- -k test_name {envpython} -m pytest \ --pyargs {[testenv]package_name} \ @@ -29,7 +38,7 @@ commands = [testenv:mypy] commands = - {envpython} -m pip install -e .[testing,optional] + {envpython} -m pip install --use-pep517 -e .[testing,optional] {envpython} -m mypy --install-types --non-interactive \ -p {[testenv]package_name} \ # txt report is a bit more convenient to view on CI @@ -38,13 +47,6 @@ commands = {posargs} -# todo get rid of pylint? it has limited value... -[testenv:pylint] -commands = - {envpython} -m pip install -e .[testing] - {envpython} -m pylint src/cachew {posargs} - - # todo not sure if really need bandit at all? [testenv:bandit] commands =