diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d38756..e4dc28d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,11 +3,6 @@ # https://github.com/actions # https://cibuildwheel.readthedocs.io/en/stable/options/ # -# uses: https://github.com/actions/checkout @v4 -# uses: https://github.com/actions/setup-python @v4 -# uses: https://github.com/actions/download-artifact @v3 -# uses: https://github.com/actions/upload-artifact @v3 -# uses: https://github.com/pypa/cibuildwheel @v2.16 name: CI @@ -23,13 +18,13 @@ jobs: strategy: matrix: test: - - {PY: "3.10", TOXENV: "lint"} + - {PY: "3.14", TOXENV: "lint"} steps: - name: "Checkout" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Setup Python ${{matrix.test.PY}}" - uses: actions/setup-python@v4 + uses: actions/setup-python@v6 with: python-version: ${{matrix.test.PY}} @@ -46,29 +41,20 @@ jobs: strategy: matrix: test: - - {os: "ubuntu-latest", osname: "Linux", PY: "3.7", TOXENV: "py37", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "3.8", TOXENV: "py38", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "3.9", TOXENV: "py39", arch: "x64"} - {os: "ubuntu-latest", osname: "Linux", PY: "3.10", TOXENV: "py310", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "3.11", TOXENV: "py311", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "3.12", TOXENV: "py312", arch: "x64"} - - {os: "macos-latest", osname: "MacOS", PY: "3.10", TOXENV: "py310", arch: "x64"} - - {os: "macos-latest", osname: "MacOS", PY: "3.11", TOXENV: "py311", arch: "x64"} - #- {os: "macos-latest", osname: "MacOS", PY: "3.12", TOXENV: "py312", arch: "x64"} - - {os: "windows-latest", osname: "Windows", PY: "3.7", TOXENV: "py37", arch: "x86"} - - {os: "windows-latest", osname: "Windows", PY: "3.8", TOXENV: "py38", arch: "x64"} - - {os: "windows-latest", osname: "Windows", PY: "3.10", TOXENV: "py310", arch: "x86"} - - {os: "windows-latest", osname: "Windows", PY: "3.11", TOXENV: "py311", arch: "x64"} - #- {os: "windows-latest", osname: "Windows", PY: "3.12", TOXENV: "py312", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "pypy3.8", TOXENV: "pypy38", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "pypy3.9", TOXENV: "pypy39", arch: "x64"} - - {os: "ubuntu-latest", osname: "Linux", PY: "pypy3.10", TOXENV: "pypy310", arch: "x64"} + - {os: "ubuntu-latest", osname: "Linux", PY: "3.13", TOXENV: "py313", arch: "x64"} + - {os: "ubuntu-latest", osname: "Linux", PY: "3.14", TOXENV: "py314", arch: "x64"} + - {os: "macos-latest", osname: "MacOS", PY: "3.12", TOXENV: "py312", arch: "x64"} + - {os: "macos-latest", osname: "MacOS", PY: "3.14", TOXENV: "py314", arch: "arm64"} + - {os: "windows-latest", osname: "Windows", PY: "3.13", TOXENV: "py313", arch: "x64"} + - {os: "windows-latest", osname: "Windows", PY: "3.14", TOXENV: "py314", arch: "x64"} + - {os: "ubuntu-latest", osname: "Linux", PY: "pypy3.11", TOXENV: "pypy311", arch: "x64"} steps: - name: "Checkout" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Setup Python ${{matrix.test.PY}}" - uses: actions/setup-python@v4 + uses: actions/setup-python@v6 with: python-version: ${{matrix.test.PY}} architecture: ${{matrix.test.arch}} @@ -90,19 +76,16 @@ jobs: strategy: matrix: test: - - {PY: "3.7", PG: "11", TOXENV: "py37"} - - {PY: "3.8", PG: "12", TOXENV: "py38"} - - {PY: "3.9", PG: "13", TOXENV: "py39"} - - {PY: "3.10", PG: "14", TOXENV: "py310"} - - {PY: "3.11", PG: "15", TOXENV: "py311"} + - {PY: "3.10", PG: "16", TOXENV: "py310"} + - {PY: "3.14", PG: "18", TOXENV: "py314"} #- {PY: "pypy3.9", PG: "15", TOXENV: "pypy39"} #- {PY: "pypy3.10", PG: "15", TOXENV: "pypy310"} steps: - name: "Checkout" - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: "Setup Python ${{matrix.test.PY}}" - uses: actions/setup-python@v4 + uses: actions/setup-python@v6 with: python-version: ${{matrix.test.PY}} @@ -163,26 +146,24 @@ jobs: matrix: sys: - {os: "ubuntu-latest", name: "Linux", archs: "auto", qemu: false} - - {os: "ubuntu-latest", name: "Linux", archs: "aarch64", qemu: true} - - {os: "macos-latest", name: "MacOS", archs: "x86_64 arm64 universal2", qemu: false} + - {os: "ubuntu-24.04-arm", name: "Linux", archs: "aarch64", qemu: false} + - {os: "macos-15-intel", name: "MacOS", archs: "x86_64 universal2", qemu: false} + - {os: "macos-latest", name: "MacOS", archs: "auto", qemu: false} - {os: "windows-latest", name: "Windows", archs: "auto", qemu: false} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: "Set up QEMU" if: ${{matrix.sys.qemu}} - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v4 with: platforms: all - - uses: pypa/cibuildwheel@v2.16 + - uses: pypa/cibuildwheel@v3.4.1 env: CIBW_ARCHS: "${{matrix.sys.archs}}" - # cp38: cp37-macos does not support universal2/arm64 - CIBW_BUILD: "cp38-* pp*-manylinux_x86_64" - CIBW_SKIP: "pp37-*" - name: "Check" shell: bash run: | ls -l wheelhouse - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v7 with: {name: "dist", path: "wheelhouse"} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3de1bea..1075d2c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,12 @@ jobs: name: "Build source package" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: {python-version: "3.11"} - run: python3 -m pip install -r etc/requirements.build.txt --disable-pip-version-check - run: python3 setup.py sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v7 with: {name: "dist", path: "dist"} cibuildwheel: @@ -32,13 +32,13 @@ jobs: - {os: "macos-latest", name: "MacOS", archs: "x86_64 arm64 universal2", qemu: false} - {os: "windows-latest", name: "Windows", archs: "auto", qemu: false} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: "Set up QEMU" if: ${{matrix.sys.qemu}} - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v4 with: platforms: all - - uses: pypa/cibuildwheel@v2.16 + - uses: pypa/cibuildwheel@v3 env: CIBW_ARCHS: "${{matrix.sys.archs}}" # cp38: cp37-macos does not support universal2/arm64 @@ -48,7 +48,7 @@ jobs: shell: bash run: | ls -l wheelhouse - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v7 with: {name: "dist", path: "wheelhouse"} publish: @@ -56,14 +56,14 @@ jobs: runs-on: ubuntu-latest needs: [sdist, cibuildwheel] steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: {python-version: "3.11"} - run: python3 -m pip install -r etc/requirements.build.txt --disable-pip-version-check - name: "Get files" - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v8 with: {name: "dist", path: "dist"} - name: "Install pandoc" diff --git a/etc/requirements.build.txt b/etc/requirements.build.txt index ff9e40b..c2a95ec 100644 --- a/etc/requirements.build.txt +++ b/etc/requirements.build.txt @@ -1,4 +1,3 @@ -setuptools>=67 -wheel>=0.41 -twine==4.0.2 +setuptools>=82 +twine==6.2.0 tox==4.8.0 diff --git a/pyproject.toml b/pyproject.toml index 8f90a01..e6142da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,11 +6,11 @@ keywords = ["database"] dynamic = ["version"] requires-python = ">= 3.7" maintainers = [{name = "Marko Kreen", email = "markokr@gmail.com"}] +license = "ISC" classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", - "License :: OSI Approved :: ISC License (ISCL)", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", @@ -31,7 +31,7 @@ repository = "https://github.com/pgq/python-skytools" changelog = "https://github.com/pgq/python-skytools/blob/master/NEWS.rst" [build-system] -requires = ["setuptools", "wheel"] +requires = ["setuptools>=78"] build-backend = "setuptools.build_meta" [tool.setuptools] @@ -130,6 +130,10 @@ ignore_missing_imports = true module = ["skytools.basetypes"] warn_unused_ignores = false +[[tool.mypy.overrides]] +module = ["pkg_resources"] +warn_unused_ignores = false + [tool.ruff] line-length = 120 select = ["E", "F", "Q", "W", "UP", "YTT", "ANN"] @@ -249,7 +253,7 @@ py-version = "3.10" # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages. -suggestion-mode = true +#suggestion-mode = true # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. @@ -540,6 +544,8 @@ disable = [ "try-except-raise", "deprecated-module", "no-else-break", "no-else-continue", # junk "trailing-newlines", "consider-using-f-string", + "too-many-positional-arguments", + "catching-non-exception", # expected "cyclic-import", # issues diff --git a/setup.py b/setup.py index 4cb4ffc..f1fac7a 100644 --- a/setup.py +++ b/setup.py @@ -4,28 +4,38 @@ from typing import Tuple from setuptools import Extension, setup +import sysconfig + try: - from wheel.bdist_wheel import bdist_wheel + from setuptools.command.bdist_wheel import bdist_wheel + class bdist_wheel_abi3(bdist_wheel): def get_tag(self) -> Tuple[str, str, str]: python, abi, plat = super().get_tag() - if python.startswith("cp"): + if python.startswith("cp") and LIMITED_API: return CP_VER, "abi3", plat return python, abi, plat + cmdclass = {"bdist_wheel": bdist_wheel_abi3} except ImportError: cmdclass = {} -CP_VER = "cp37" -API_VER = ('Py_LIMITED_API', '0x03070000') +if sysconfig.get_config_var("Py_GIL_DISABLED"): + CP_VER = 'unused' + MACROS = [] + LIMITED_API = False +else: + CP_VER = "cp37" + MACROS = [('Py_LIMITED_API', '0x03070000')] + LIMITED_API = True setup( cmdclass = cmdclass, ext_modules = [ Extension("skytools._cquoting", ["modules/cquoting.c"], - define_macros=[API_VER], py_limited_api=True), + define_macros=MACROS, py_limited_api=LIMITED_API), Extension("skytools._chashtext", ["modules/hashtext.c"], - define_macros=[API_VER], py_limited_api=True), + define_macros=MACROS, py_limited_api=LIMITED_API), ] ) diff --git a/skytools/apipkg.py b/skytools/apipkg.py index 978bde2..9acda72 100644 --- a/skytools/apipkg.py +++ b/skytools/apipkg.py @@ -31,7 +31,7 @@ def _py_abspath(path): def distribution_version(name): """try to get the version of the named distribution, returs None on failure""" - from pkg_resources import DistributionNotFound, get_distribution + from pkg_resources import DistributionNotFound, get_distribution # type: ignore try: dist = get_distribution(name) except DistributionNotFound: @@ -96,7 +96,7 @@ def __docget(self): def __docset(self, value): self.__doc = value - __doc__ = property(__docget, __docset) # type: ignore + __doc__ = property(__docget, __docset) def __init__(self, name, importspec, implprefix=None, attr=None): super().__init__(name) @@ -165,7 +165,7 @@ def __makeattr(self, name): __getattr__ = __makeattr @property - def __dict__(self): + def __dict__(self): # type: ignore # force all the content of the module # to be loaded when __dict__ is read dictdescr = ModuleType.__dict__['__dict__'] # type: ignore diff --git a/skytools/scripting.py b/skytools/scripting.py index 54fe5bc..27b8a50 100644 --- a/skytools/scripting.py +++ b/skytools/scripting.py @@ -323,7 +323,7 @@ def parse_args(self, args: Sequence[str]) -> Tuple[Any, Sequence[str]]: args = getattr(options, "args", []) return options, args opt_parser = self.init_optparse() - options2, args2 = opt_parser.parse_args(args) + options2, args2 = opt_parser.parse_args(list(args)) return options2, args2 def print_version(self) -> None: diff --git a/skytools/tnetstrings.py b/skytools/tnetstrings.py index 126346e..a652fc1 100644 --- a/skytools/tnetstrings.py +++ b/skytools/tnetstrings.py @@ -1,5 +1,6 @@ """TNetStrings. """ +# mypy: disable-error-code="comparison-overlap" import codecs from typing import Any, List diff --git a/tox.ini b/tox.ini index e31e99d..826b747 100644 --- a/tox.ini +++ b/tox.ini @@ -5,24 +5,23 @@ envlist = lint,xlint,py3 [package] name = skytools deps = - psycopg2-binary==2.9.7; platform_python_implementation != 'PyPy' + setuptools==82.0.1 + psycopg2-binary==2.9.12; platform_python_implementation != 'PyPy' test_deps = - #coverage==7.3.0 - coverage==7.2.7 - pytest==7.4.0 - pytest-cov==4.1.0 + coverage==7.14.1 + pytest==9.0.3 + pytest-cov==7.1.0 lint_deps = - mypy==1.5.1 - pyflakes==3.1.0 - typing-extensions==4.7.1 - types-setuptools==68.1.0.0 - types-psycopg2==2.9.21.11; platform_python_implementation != 'PyPy' + mypy==2.1.0 + pyflakes==3.4.0 + typing-extensions==4.15.0 + types-setuptools==82.0.0.20260518 + types-psycopg2==2.9.21.20260518; platform_python_implementation != 'PyPy' xlint_deps = - pylint==2.17.5 - pytype==2023.8.22 + pylint==4.0.5 doc_deps = - sphinx==7.2.2 - docutils==0.20.1 + sphinx==9.1.0 + docutils==0.23 [testenv] changedir = {toxinidir} @@ -46,7 +45,7 @@ commands = [testenv:lint] #changedir = {toxinidir} -basepython = python3 +basepython = python3.14 deps = {[package]deps} {[package]lint_deps} @@ -64,7 +63,6 @@ deps = {[package]xlint_deps} commands = pylint skytools - #pytype skytools [testenv:docs] basepython = python3