diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index c35604b..0000000 --- a/.coveragerc +++ /dev/null @@ -1,4 +0,0 @@ -[run] -relative_files = True -include = - spinach/* \ No newline at end of file diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 93e30e4..3e051df 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -18,11 +18,11 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + pip install hatch twine - name: Build and publish env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python setup.py sdist bdist_wheel + hatch build twine upload dist/* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 34b0753..067b6fb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,15 +28,15 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -e .[tests] + pip install hatch - name: Lint run: | - pycodestyle --ignore=E252,W503,W504 spinach tests + hatch run pep8 - name: Test with pytest run: | - pytest -v --cov=spinach tests/ + hatch run ci - name: Coveralls uses: AndreMiras/coveralls-python-action@develop diff --git a/.gitignore b/.gitignore index 5194427..756c307 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# _version is generated by setuptools_scm and requests not to be under a VCS +spinach/_version.py + +.hatch .pyc __pycache__ diff --git a/doc/conf.py b/doc/conf.py index 128fded..cc1209b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -22,6 +22,7 @@ sys.path.insert(0, os.path.abspath('..')) import spinach +from spinach import _version as spinach_version # -- General configuration ------------------------------------------------ @@ -66,9 +67,9 @@ # built documents. # # The short X.Y version. -version = spinach.__version__ +version = spinach_version.__version__ # The full version, including alpha/beta/rc tags. -release = spinach.__version__ +release = spinach_version.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..928f32d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,124 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "spinach" +dynamic = ["version"] +description = "Modern Redis task queue for Python 3" +readme = "README.rst" +license-files = { paths = ["LICENSE"] } +requires-python = ">=3.8.0,<4.0.0" +authors = [ + { name = "Nicolas Le Manchet", email = "nicolas@lemanchet.fr" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Topic :: Software Development :: Libraries", + "Topic :: System :: Distributed Computing", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +keywords = ["task", "queue", "jobs", "redis"] +urls.Source = "https://github.com/NicolasLM/spinach" + +dependencies = [ + "redis", + "blinker" +] + +[project.optional-dependencies] +tests = [ + "pytest", + "pytest-cov", + "pytest-threadleak", + "ruff", + "flask", + "django" +] + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.hooks.vcs] +version-file = "spinach/_version.py" + +[tool.hatch.build.targets.sdist] +ignore-vcs = true +include = ["/spinach", "/tests"] + +[tool.hatch.build.targets.wheel] +packages = ["spinach"] + +[tool.hatch.build.targets.wheel.package-data] +"spinach.brokers.redis_scripts" = [ + "deregister.lua", + "enqueue_job.lua", + "enqueue_jobs_from_dead_broker.lua", + "flush.lua", + "get_jobs_from_queue.lua", + "move_future_jobs.lua", + "register_periodic_tasks.lua", + "remove_job_from_running.lua", + "set_concurrency_keys.lua", +] + +[tool.hatch.envs.default] +path = ".hatch" +features = ["tests"] + +scripts.pep8 = ["ruff spinach tests"] + +scripts.py3 = [ + "docker-compose -f tests/docker-compose.yml up -d", + "pytest tests {args}", + "docker-compose -f tests/docker-compose.yml down", +] + +# A minimalist pytest runner for Github to use +scripts.ci = ["pytest -v --cov=spinach tests {args}"] + +[tool.ruff.lint] +select = ["B", "C9", "D", "E", "F", "S", "W"] +ignore = [ + "B018", # Useless expression (seems to have false-positive bugs) + "S101", # Use of `assert` detected (conflicts with pytest) + "D10", # Missing docstring in public function / module / etc. + "D203", # 1 blank line required before class docstring + "D205", # 1 blank line required between summary line and description + "D213", # Multi-line docstring summary should start at the second line + "D40", # First line of docstring complaints + "D415", # First line should end with a period, question mark, or exclamation point + # TODO(nic): The remaining ignores point to actual issues in the code. + # Remove them and fix the issues later. + "B024", + "B027", + "B904", + "D204", + "F401", + "F841", + "S301", + "S311", +] +mccabe.max-complexity = 13 + +[tool.ruff.lint.per-file-ignores] +# Aggregating symbols into a convenient location for import is good practice +# for libraries, we don't care if they look unused +"__init__.py" = ["F401"] + +[tool.coverage.run] +relative_files = true +include = ["spinach/*"] +omit = ["spinach/_version.py"] + +[tool.pytest.ini_options] +threadleak = true diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 4a1804a..0000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -threadleak = True \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 4b4afff..0000000 --- a/setup.py +++ /dev/null @@ -1,75 +0,0 @@ -from setuptools import setup, find_packages -from codecs import open -from os import path - -here = path.abspath(path.dirname(__file__)) - -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: - long_description = f.read() - -with open(path.join(here, 'LICENSE'), encoding='utf-8') as f: - long_description += f.read() - -with open(path.join(here, 'spinach', 'const.py'), encoding='utf-8') as fp: - version = dict() - exec(fp.read(), version) - version = version['VERSION'] - -setup( - name='spinach', - version=version, - description='Modern Redis task queue for Python 3', - long_description=long_description, - url='https://github.com/NicolasLM/spinach', - author='Nicolas Le Manchet', - author_email='nicolas@lemanchet.fr', - license='BSD 2-clause', - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Libraries', - 'Topic :: System :: Distributed Computing', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - ], - keywords='task queue jobs redis', - - packages=find_packages(include=('spinach', 'spinach.*')), - install_requires=[ - 'redis', - 'blinker' - ], - - extras_require={ - 'tests': [ - 'pytest', - 'pytest-cov', - 'pytest-threadleak', - 'pycodestyle', - 'flask', - 'django' - ], - }, - - package_data={ - 'spinach.brokers.redis_scripts': [ - 'deregister.lua', - 'enqueue_job.lua', - 'enqueue_jobs_from_dead_broker.lua', - 'flush.lua', - 'get_jobs_from_queue.lua', - 'move_future_jobs.lua', - 'register_periodic_tasks.lua', - 'remove_job_from_running.lua', - 'set_concurrency_keys.lua', - ], - }, -) diff --git a/spinach/__init__.py b/spinach/__init__.py index dc3fc3d..2cafae2 100644 --- a/spinach/__init__.py +++ b/spinach/__init__.py @@ -1,8 +1,5 @@ from .brokers.memory import MemoryBroker from .brokers.redis import RedisBroker -from .const import VERSION from .engine import Engine from .task import Tasks, Batch, RetryException, AbortException from .worker import ThreadWorkers, AsyncioWorkers - -__version__ = VERSION diff --git a/spinach/const.py b/spinach/const.py index b91a7e6..c758507 100644 --- a/spinach/const.py +++ b/spinach/const.py @@ -1,5 +1,3 @@ -VERSION = '0.0.20' - DEFAULT_QUEUE = 'spinach' DEFAULT_NAMESPACE = 'spinach' DEFAULT_MAX_RETRIES = 0 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 2a62ff8..0000000 --- a/tox.ini +++ /dev/null @@ -1,28 +0,0 @@ -[tox] -envlist = py3, pep8 - -[testenv] -basepython = python3 -envdir = - py3: {toxworkdir}/py3 - pep8: {toxworkdir}/py3 -usedevelop = True -allowlist_externals = - docker-compose -deps = - pytest - pytest-cov - pytest-threadleak - pycodestyle - flake8 - flask - django - -[testenv:pep8] -commands = - pycodestyle --ignore=E252,W503,W504 spinach tests - -[testenv:py3] -commands_pre = docker-compose -f {toxinidir}/tests/docker-compose.yml up -d -commands = pytest tests {posargs} -commands_post = docker-compose -f {toxinidir}/tests/docker-compose.yml down