diff --git a/.editorconfig b/.editorconfig index 9d3c4f2..5094013 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,7 +2,7 @@ # https://github.com/zopefoundation/meta/tree/master/config/c-code # # EditorConfig Configuration file, for more details see: -# http://EditorConfig.org +# https://EditorConfig.org # EditorConfig is a convention description, that could be interpreted # by multiple editors to enforce common coding conventions for specific # file types diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index eaf3a78..8f2ad3c 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 with: - python-version: 3.x + python-version: '3.13' - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1 with: extra_args: --all-files --show-diff-on-failure diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4db7453..6687f58 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,12 +93,12 @@ jobs: matrix: python-version: - "pypy-3.11" - - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" + - "3.15" os: [ubuntu-latest, macos-latest, windows-latest] exclude: - os: macos-latest @@ -150,13 +150,13 @@ jobs: restore-keys: | ${{ runner.os }}-pip- - - name: Install Build Dependencies (3.14) - if: matrix.python-version == '3.14' + - name: Install Build Dependencies (3.15) + if: matrix.python-version == '3.15' run: | pip install -U pip pip install -U "setuptools >= 78.1.1,< 81" wheel twine - name: Install Build Dependencies - if: matrix.python-version != '3.14' + if: matrix.python-version != '3.15' run: | pip install -U pip pip install -U "setuptools >= 78.1.1,< 81" wheel twine @@ -197,15 +197,15 @@ jobs: python setup.py build_ext -i python setup.py bdist_wheel - - name: Install persistent and dependencies (3.14) - if: matrix.python-version == '3.14' + - name: Install persistent and dependencies (3.15) + if: matrix.python-version == '3.15' run: | # Install to collect dependencies into the (pip) cache. # Use "--pre" here because dependencies with support for this future # Python release may only be available as pre-releases pip install --pre .[test] - name: Install persistent and dependencies - if: matrix.python-version != '3.14' + if: matrix.python-version != '3.15' run: | # Install to collect dependencies into the (pip) cache. pip install -U pip "setuptools >= 78.1.1,< 81" @@ -240,20 +240,6 @@ jobs: with: name: persistent-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/*whl - - name: Publish package to PyPI (Non-Linux) - # We cannot use pypa/gh-action-pypi-publish because that - # is a container action, and those don't run on macOS - # or Windows GHA runners. - if: > - github.event_name == 'push' - && startsWith(github.ref, 'refs/tags') - && !startsWith(runner.os, 'Linux') - && !startsWith(matrix.python-version, 'pypy') - && !startsWith(matrix.python-version, '3.14') - env: - TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} - run: | - twine upload --skip-existing dist/* test: needs: build-package @@ -263,12 +249,12 @@ jobs: matrix: python-version: - "pypy-3.11" - - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" + - "3.15" os: [ubuntu-latest, macos-latest, windows-latest] exclude: - os: macos-latest @@ -326,7 +312,7 @@ jobs: name: persistent-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/ - name: Install persistent ${{ matrix.python-version }} - if: matrix.python-version == '3.14' + if: matrix.python-version == '3.15' run: | pip install -U wheel "setuptools >= 78.1.1,< 81" # coverage might have a wheel on PyPI for a future python version which is @@ -341,7 +327,7 @@ jobs: # Python release may only be available as pre-releases pip install --pre -e .[test] - name: Install persistent - if: matrix.python-version != '3.14' + if: matrix.python-version != '3.15' run: | pip install -U wheel "setuptools >= 78.1.1,< 81" pip install -U coverage[toml] @@ -387,7 +373,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ["3.11"] + python-version: ["3.13"] os: [ubuntu-latest] steps: @@ -458,7 +444,7 @@ jobs: runs-on: "ubuntu-latest" strategy: matrix: - python-version: ["3.11"] + python-version: ["3.13"] os: [ubuntu-latest] steps: @@ -524,14 +510,21 @@ jobs: tox -e release-check manylinux: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name - # We use a regular Python matrix entry to share as much code as possible. + # We use a matrix to share as much code as possible. strategy: matrix: - python-version: ["3.11"] - image: [manylinux2014_x86_64, manylinux2014_i686, manylinux2014_aarch64] - + include: + - os: ubuntu-latest + image: manylinux2014_x86_64 + python-version: "3.13" + - os: ubuntu-latest + image: manylinux2014_i686 + python-version: "3.13" + - os: ubuntu-24.04-arm + image: manylinux2014_aarch64 + python-version: "3.13" steps: - name: checkout uses: actions/checkout@v5 @@ -580,8 +573,9 @@ jobs: - name: Update pip run: pip install -U pip - - name: Build persistent (x86_64) - if: matrix.image == 'manylinux2014_x86_64' + + - name: Build persistent + if: matrix.image != 'manylinux2014_i686' # An alternate way to do this is to run the container directly with a uses: # and then the script runs inside it. That may work better with caching. # See https://github.com/pyca/bcrypt/blob/f6b5ee2eda76d077c531362ac65e16f045cf1f29/.github/workflows/wheel-builder.yml @@ -596,31 +590,59 @@ jobs: PRE_CMD: linux32 run: | bash .manylinux.sh - - name: Build persistent (aarch64) - if: matrix.image == 'manylinux2014_aarch64' - env: - DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} - run: | - # First we must enable emulation - docker run --rm --privileged hypriot/qemu-register - bash .manylinux.sh - name: Upload persistent wheels uses: actions/upload-artifact@v4 with: path: wheelhouse/*whl name: manylinux_${{ matrix.image }}_wheels.zip + - name: Restore pip cache permissions run: sudo chown -R $(whoami) ${{ steps.pip-cache-default.outputs.dir }} + - name: Prevent publishing wheels for unreleased Python versions - run: VER=$(echo '3.14' | tr -d .) && ls -al wheelhouse && sudo rm -f wheelhouse/*-cp${VER}*.whl && ls -al wheelhouse - - name: Publish package to PyPI + run: VER=$(echo '3.15' | tr -d .) && ls -al wheelhouse && sudo rm -f wheelhouse/*-cp${VER}*.whl && ls -al wheelhouse + + publish: + name: Publish to PyPI + runs-on: ubuntu-latest + # Only publish on tag pushes + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + # Wait for both build jobs to complete + needs: [build-package, manylinux] + permissions: + contents: read + + steps: + - name: Download all wheel artifacts + uses: actions/download-artifact@v4 + with: + path: dist/ + pattern: '*' + merge-multiple: true + + - name: Display structure of downloaded files + run: | + ls -lR dist/ + echo "Total wheel files:" + find dist/ -name "*.whl" | wc -l + + - name: Remove undesired wheels (if any were downloaded) + run: | + # PyPy wheels shouldn't be uploaded, remove them if present + find dist/ -name "*pypy*" -type f -delete || true + find dist/ -name "*none-any*" -type f -delete || true + # Wheels for the no-yet-supported future Python version need to go + find dist/ -name "*3.15*" -type f -delete || true + find dist/ -name "*cp315*" -type f -delete || true + # For Linux, we only want the manylinux wheels + find dist/ -name "*linux_x86_64*" -type f -delete || true + + - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - if: > - github.event_name == 'push' - && startsWith(github.ref, 'refs/tags') with: user: __token__ password: ${{ secrets.TWINE_PASSWORD }} skip-existing: true - packages-dir: wheelhouse/ + packages-dir: dist/ + verbose: true diff --git a/.manylinux-install.sh b/.manylinux-install.sh index 2840acb..acf8744 100755 --- a/.manylinux-install.sh +++ b/.manylinux-install.sh @@ -28,12 +28,12 @@ yum -y install libffi-devel tox_env_map() { case $1 in - *"cp39"*) echo 'py39';; *"cp310"*) echo 'py310';; *"cp311"*) echo 'py311';; *"cp312"*) echo 'py312';; *"cp313"*) echo 'py313';; *"cp314"*) echo 'py314';; + *"cp315"*) echo 'py315';; *) echo 'py';; esac } @@ -41,13 +41,13 @@ tox_env_map() { # Compile wheels for PYBIN in /opt/python/*/bin; do if \ - [[ "${PYBIN}" == *"cp39/"* ]] || \ [[ "${PYBIN}" == *"cp310/"* ]] || \ [[ "${PYBIN}" == *"cp311/"* ]] || \ [[ "${PYBIN}" == *"cp312/"* ]] || \ [[ "${PYBIN}" == *"cp313/"* ]] || \ - [[ "${PYBIN}" == *"cp314/"* ]] ; then - if [[ "${PYBIN}" == *"cp314/"* ]] ; then + [[ "${PYBIN}" == *"cp314/"* ]] || \ + [[ "${PYBIN}" == *"cp315/"* ]] ; then + if [[ "${PYBIN}" == *"cp315/"* ]] ; then "${PYBIN}/pip" install --pre -e /io/ "${PYBIN}/pip" wheel /io/ --pre -w wheelhouse/ else @@ -65,6 +65,9 @@ for PYBIN in /opt/python/*/bin; do fi done +# Show what wheels we have +echo "Fixing up the following wheels:" +ls -l wheelhouse/persistent*.whl # Bundle external shared libraries into the wheels for whl in wheelhouse/persistent*.whl; do auditwheel repair "$whl" -w /io/wheelhouse/ diff --git a/.meta.toml b/.meta.toml index ee932fa..17bb28d 100644 --- a/.meta.toml +++ b/.meta.toml @@ -2,7 +2,7 @@ # https://github.com/zopefoundation/meta/tree/master/config/c-code [meta] template = "c-code" -commit-id = "bfe21cd9" +commit-id = "9fcd3d67" [python] with-windows = true @@ -13,21 +13,17 @@ with-sphinx-doctests = true with-macos = false [tox] -use-flake8 = true coverage-command = [ "coverage run -m zope.testrunner --test-path=src {posargs:-vc}", "python -c 'import os, subprocess; subprocess.check_call(\"coverage run -a -m zope.testrunner --test-path=src\", env=dict(os.environ, PURE_PYTHON=\"0\"), shell=True)'", - ] +] [coverage] fail-under = 94.9 [coverage-run] source = "persistent" -additional-config = [ - "omit =", - " _ring_build.py", - ] +additional-config = ["omit =", " _ring_build.py"] [manifest] additional-rules = [ @@ -35,9 +31,10 @@ additional-rules = [ "include *.sh", "recursive-include docs *.bat", "recursive-include src *.h", - ] +] [check-manifest] additional-ignores = [ "docs/_build/html/_sources/api/*", - ] + "docs/_build/html/_static/scripts/*", +] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d3dfcd3..2a52c5c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ minimum_pre_commit_version: '3.6' repos: - repo: https://github.com/pycqa/isort - rev: "6.0.1" + rev: "7.0.0" hooks: - id: isort - repo: https://github.com/hhatto/autopep8 @@ -12,10 +12,10 @@ repos: - id: autopep8 args: [--in-place, --aggressive, --aggressive] - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.0 hooks: - id: pyupgrade - args: [--py39-plus] + args: [--py310-plus] - repo: https://github.com/isidentical/teyit rev: 0.4.3 hooks: diff --git a/CHANGES.rst b/CHANGES.rst index 613eccb..aa398f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,13 +1,16 @@ -========================== - ``persistent`` Changelog -========================== +Change log +========== 6.4 (unreleased) -================ +---------------- + +- Add support for Python 3.14. + +- Drop support for Python 3.9. 6.3 (2025-10-07) -================ +---------------- - Fix setuptools configuration to build missing cffi extension module. The released wheels for version 6.2 will not work, they are missing @@ -16,7 +19,7 @@ 6.2 (2025-10-02) -================ +---------------- - Add preliminary support for Python 3.14b2. @@ -30,14 +33,14 @@ 6.1.1 (2025-02-26) -================== +------------------ - Use ``Py_REFCNT`` to access ``cPersistentObject`` reference counts in assertions. 6.1 (2024-09-17) -================ +---------------- - Add final support for Python 3.13. @@ -46,7 +49,7 @@ 6.0 (2024-05-30) -================ +---------------- - Drop support for Python 3.7. @@ -54,19 +57,19 @@ 5.2 (2024-02-16) -================ +---------------- - Add preliminary support for Python 3.13a3. 5.1 (2023-10-05) -================ +---------------- - Add support for Python 3.12. 5.0 (2023-01-09) -================ +---------------- - Build Linux binary wheels for Python 3.11. @@ -74,19 +77,19 @@ 4.9.3 (2022-11-16) -================== +------------------ - Add support for building arm64 wheels on macOS. 4.9.2 (2022-11-03) -================== +------------------ - Update Python 3.11 support to final release. 4.9.1 (2022-09-16) -================== +------------------ - Update Python 3.11 support to 3.11.0-rc1. @@ -95,33 +98,39 @@ 4.9.0 (2022-03-10) -================== +------------------ - Add support for Python 3.11 (as of 3.11a5). 4.8.0 (2022-03-07) -================== +------------------ - Switch package to src-layout, this is a packaging only change. (`#168 `_) + - Add support for Python 3.10. 4.7.0 (2021-04-13) -================== +------------------ - Add support for Python 3.9. + - Move from Travis CI to Github Actions. + - Supply manylinux wheels for aarch64 (ARM). + - Fix the pure-Python implementation to activate a ghost object when setting its ``__class__`` and ``__dict__``. This matches the behaviour of the C implementation. See `issue 155 `_. + - Fix the CFFI cache implementation (used on CPython when ``PURE_PYTHON=1``) to not print unraisable ``AttributeErrors`` from ``_WeakValueDictionary`` during garbage collection. See `issue 150 `_. + - Make the pure-Python implementation of the cache run a garbage collection (``gc.collect()``) on ``full_sweep``, ``incrgc`` and ``minimize`` *if* it detects that an object that was weakly @@ -130,16 +139,20 @@ ``zope.interface`` utilities/adapters registered. This partly reverts a change from release 4.2.3. + 4.6.4 (2020-03-26) -================== +------------------ - Fix an overly specific test failure using zope.interface 5. See `issue 144 `_. + - Fix two reference leaks that could theoretically occur as the result - of obscure errors. See `issue 143 `_. + of obscure errors. + See `issue 143 `_. + 4.6.3 (2020-03-18) -================== +------------------ - Fix a crash in the test suite under a 32-bit CPython on certain 32-bit platforms. See `issue 137 @@ -148,7 +161,7 @@ 4.6.2 (2020-03-12) -================== +------------------ - Fix an ``AssertionError`` clearing a non-empty ``PersistentMapping`` that has no connection. See `issue 139 @@ -156,7 +169,7 @@ 4.6.1 (2020-03-06) -================== +------------------ - Stop installing C header files on PyPy (which is what persistent before 4.6.0 used to do), fixes `issue 135 @@ -164,7 +177,7 @@ 4.6.0 (2020-03-05) -================== +------------------ - Fix slicing of ``PersistentList`` to always return instances of the same class. It was broken on Python 3 prior to 3.7.4. @@ -178,7 +191,8 @@ non-empty value prevents the extensions from being used. Also, all C extensions are required together or none of them will be used. This prevents strange errors that arise from a mismatch of Python and C - implementations. See `issue 131 `_. + implementations. + See `issue 131 `_. Note that some private implementation details such as the names of the pure-Python implementations have changed. @@ -209,8 +223,9 @@ Note that ``ctypes`` is required to use the Python implementation (except on PyPy). + 4.5.1 (2019-11-06) -================== +------------------ - Add support for Python 3.8. @@ -218,7 +233,7 @@ 4.5.0 (2019-05-09) -================== +------------------ - Fully test the C implementation of the PickleCache, and fix discrepancies between it and the Python implementation: @@ -250,7 +265,7 @@ 4.4.3 (2018-10-22) -================== +------------------ - Fix the repr of the persistent objects to include the module name when using the C extension. This matches the pure-Python behaviour @@ -264,7 +279,7 @@ 4.4.2 (2018-08-28) -================== +------------------ - Explicitly use unsigned constants for packing and unpacking C timestamps, fixing an arithmetic issue for GCC when optimizations @@ -273,14 +288,14 @@ 4.4.1 (2018-08-23) -================== +------------------ - Fix installation of source packages on PyPy. See `issue 88 `_. 4.4.0 (2018-08-22) -================== +------------------ - Use unsigned constants when doing arithmetic on C timestamps, possibly avoiding some overflow issues with some compilers or @@ -331,10 +346,11 @@ 4.3.0 (2018-07-30) -================== +------------------ - Fix the possibility of a rare crash in the C extension when - deallocating items. See https://github.com/zopefoundation/persistent/issues/66 + deallocating items. + See https://github.com/zopefoundation/persistent/issues/66 - Change cPickleCache's comparison of object sizes to determine whether an object can go in the cache to use ``PyObject_TypeCheck()``. @@ -347,19 +363,19 @@ 4.2.4.2 (2017-04-23) -==================== +-------------------- - Packaging-only release: fix Python 2.7 ``manylinux`` wheels. 4.2.4.1 (2017-04-21) -==================== +-------------------- - Packaging-only release: get ``manylinux`` wheel built automatically. 4.2.4 (2017-03-20) -================== +------------------ - Avoid raising a ``SystemError: error return without exception set`` when loading an object with slots whose jar generates an exception @@ -367,7 +383,7 @@ 4.2.3 (2017-03-08) -================== +------------------ - Fix the hashcode of Python ``TimeStamp`` objects on 64-bit Python on Windows. See https://github.com/zopefoundation/persistent/pull/55 @@ -389,7 +405,7 @@ 4.2.2 (2016-11-29) -================== +------------------ - Drop use of ``ctypes`` for determining maximum integer size, to increase pure-Python compatibility. See https://github.com/zopefoundation/persistent/pull/31 @@ -402,14 +418,14 @@ 4.2.1 (2016-05-26) -================== +------------------ - Fix the hashcode of C ``TimeStamp`` objects on 64-bit Python 3 on Windows. 4.2.0 (2016-05-05) -================== +------------------ - Fixed the Python(/PYPY) implementation ``TimeStamp.timeTime`` method to have subsecond precision. @@ -423,13 +439,13 @@ 4.1.1 (2015-06-02) -================== +------------------ - Fix manifest and re-upload to fix stray files included in 4.1.0. 4.1.0 (2015-05-19) -================== +------------------ - Make the Python implementation of ``Persistent`` and ``PickleCache`` behave more similarly to the C implementation. In particular, the @@ -439,7 +455,7 @@ 4.0.9 (2015-04-08) -================== +------------------ - Make the C and Python ``TimeStamp`` objects behave more alike. The Python version now produces the same ``repr`` and ``.raw()`` output as @@ -455,7 +471,7 @@ 4.0.8 (2014-03-20) -================== +------------------ - Add support for Python 3.4. @@ -474,7 +490,7 @@ 4.0.7 (2014-02-20) -================== +------------------ - Avoid a KeyError from ``_p_accessed()`` on newly-created objects under pure-Python: these objects may be assigned to a jar, but not yet added @@ -491,20 +507,20 @@ 4.0.6 (2013-01-03) -================== +------------------ - Updated Trove classifiers. 4.0.5 (2012-12-14) -================== +------------------ - Fixed the C-extensions under Py3k (previously they compiled but were not importable). 4.0.4 (2012-12-11) -================== +------------------ - Added support for Python 3.3. @@ -513,7 +529,7 @@ 4.0.3 (2012-11-19) -================== +------------------ - Fixed: In the C implimentation, an integer was compared with a pointer, with undefined results and a compiler warning. @@ -527,13 +543,13 @@ 4.0.2 (2012-08-27) -================== +------------------ - Correct initialization functions in renamed ``_timestamp`` extension. 4.0.1 (2012-08-26) -================== +------------------ - Worked around test failure due to overflow to long on 32-bit systems. @@ -549,7 +565,7 @@ 4.0.0 (2012-08-11) -================== +------------------ Platform Changes ---------------- diff --git a/docs/conf.py b/docs/conf.py index 5aa9944..efd5048 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'sphinx_rtd_theme' +html_theme = 'furo' # html_static_path = ['_static'] # Example configuration for intersphinx: refer to the Python standard library. diff --git a/docs/requirements.txt b/docs/requirements.txt index 62b6df6..d25c685 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ Sphinx repoze.sphinx.autointerface -sphinx_rtd_theme>1 -docutils<0.19 +furo diff --git a/pyproject.toml b/pyproject.toml index acaeb6a..a36c4a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,9 +7,64 @@ requires = [ "setuptools", "wheel", "cffi; platform_python_implementation == 'CPython'", + "pycparser", ] build-backend = "setuptools.build_meta" +[project] +name = "persistent" +version = "6.4.dev0" +description = "Translucent persistent objects" +readme = "README.rst" +requires-python = ">=3.10" +license = "ZPL-2.1" +authors = [ + { name = "Zope Foundation and contributors", email = "zope-dev@zope.dev" }, +] +maintainers = [ + { name = "Plone Foundation and contributors", email = "zope-dev@zope.dev" }, +] +classifiers = [ + "Development Status :: 6 - Mature", + "Framework :: ZODB", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Database", + "Topic :: Software Development :: Libraries :: Python Modules", +] +dependencies = [ + "zope.deferredimport", + "zope.interface", + "cffi ; platform_python_implementation == 'CPython'", +] + +[project.optional-dependencies] +docs = [ + "Sphinx", + "repoze.sphinx.autointerface", + "furo", +] +test = [ + "manuel", + "zope.testrunner >= 6.4", +] + +[project.urls] +Documentation = "https://persistent.readthedocs.io" +Issues = "https://github.com/zopefoundation/persistent/issues" +Source = "https://github.com/zopefoundation/persistent" +Changelog = "https://github.com/zopefoundation/persistent/blob/master/CHANGES.rst" + [tool.coverage.run] branch = true source = ["persistent"] diff --git a/setup.cfg b/setup.cfg index d818cbe..0463858 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,6 +14,7 @@ ignore = docs/_build/html/_sources/* docs/_build/doctest/* docs/_build/html/_sources/api/* + docs/_build/html/_static/scripts/* [isort] force_single_line = True diff --git a/setup.py b/setup.py index 095ea2e..0994cef 100644 --- a/setup.py +++ b/setup.py @@ -12,27 +12,12 @@ # ############################################################################## -import os import platform from setuptools import Extension -from setuptools import find_packages from setuptools import setup -version = '6.4.dev0' - -here = os.path.abspath(os.path.dirname(__file__)) - - -def _read_file(filename): - with open(os.path.join(here, filename)) as f: - return f.read() - - -README = (_read_file('README.rst') + '\n\n' + _read_file('CHANGES.rst')) - - define_macros = ( # We currently use macros like PyBytes_AS_STRING # and internal functions like _PyObject_GetDictPtr @@ -86,66 +71,6 @@ def _read_file(filename): 'src/persistent/ring.h', ] -setup(name='persistent', - version=version, - description='Translucent persistent objects', - long_description=README, - long_description_content_type='text/x-rst', - classifiers=[ - "Development Status :: 6 - Mature", - "License :: OSI Approved :: Zope Public License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Framework :: ZODB", - "Topic :: Database", - "Topic :: Software Development :: Libraries :: Python Modules", - "Operating System :: Microsoft :: Windows", - "Operating System :: Unix", - ], - author="Zope Foundation and Contributors", - author_email="zodb-dev@zope.org", - url="https://github.com/zopefoundation/persistent/", - project_urls={ - 'Documentation': 'https://persistent.readthedocs.io', - 'Issue Tracker': 'https://github.com/zopefoundation/' - 'persistent/issues', - 'Sources': 'https://github.com/zopefoundation/persistent', - }, - license="ZPL-2.1", - packages=find_packages('src'), - package_dir={'': 'src'}, - include_package_data=True, - zip_safe=False, - ext_modules=ext_modules, +setup(ext_modules=ext_modules, cffi_modules=['src/persistent/_ring_build.py:ffi'], - headers=headers, - setup_requires=[ - "cffi ; platform_python_implementation == 'CPython'", - "pycparser", - ], - extras_require={ - 'test': [ - 'zope.testrunner', - 'manuel', - ], - 'testing': (), - 'docs': [ - 'Sphinx', - 'repoze.sphinx.autointerface', - 'sphinx_rtd_theme', - ], - }, - python_requires='>=3.9', - install_requires=[ - 'zope.deferredimport', - 'zope.interface', - "cffi ; platform_python_implementation == 'CPython'", - ], - entry_points={}) + headers=headers) diff --git a/src/persistent/list.py b/src/persistent/list.py index 40e44e1..4102ef0 100644 --- a/src/persistent/list.py +++ b/src/persistent/list.py @@ -13,7 +13,6 @@ ############################################################################## """Python implementation of persistent list.""" -import sys from collections import UserList import persistent @@ -52,30 +51,6 @@ class PersistentList(UserList, persistent.Persistent): else lambda inst: inst.__delitem__(_SLICE_ALL) ) - if sys.version_info[:3] < (3, 7, 4): # pragma: no cover - # Prior to 3.7.4, Python 3 failed to properly - # return an instance of the same class. - # See https://bugs.python.org/issue27639 - # and https://github.com/zopefoundation/persistent/issues/112. - # We only define the special method on the necessary versions to avoid - # any speed penalty. - def __getitem__(self, item): - result = self.__super_getitem(item) - if isinstance(item, slice): - result = self.__class__(result) - return result - - if sys.version_info[:3] < (3, 7, 4): # pragma: no cover - # Likewise for __copy__. - # See - # https://github.com/python/cpython/commit/3645d29a1dc2102fdb0f5f0c0129ff2295bcd768 - def __copy__(self): - inst = self.__class__.__new__(self.__class__) - inst.__dict__.update(self.__dict__) - # Create a copy and avoid triggering descriptors - inst.__dict__["data"] = self.__dict__["data"][:] - return inst - def __setitem__(self, i, item): self.__super_setitem(i, item) self._p_changed = 1 diff --git a/src/persistent/mapping.py b/src/persistent/mapping.py index 0c1b346..cb69438 100644 --- a/src/persistent/mapping.py +++ b/src/persistent/mapping.py @@ -93,8 +93,6 @@ def clear(self): # so if there was a _container it was persisted as data. We want # to preserve that, even if we won't make any modifications otherwise. needs_changed = '_container' in self.__dict__ or bool(self) - # Python 2 implements this by directly calling self.data.clear(), - # but Python 3 does so by repeatedly calling self.popitem() self.__super_clear() if needs_changed: self._p_changed = 1 diff --git a/src/persistent/tests/test_mapping.py b/src/persistent/tests/test_mapping.py index 1962576..f34218d 100644 --- a/src/persistent/tests/test_mapping.py +++ b/src/persistent/tests/test_mapping.py @@ -251,7 +251,7 @@ def test_update_keywords(self): self.assertEqual(pm, {'b': 42}) pm = self._makeOne() - # ``other`` shows up in a Python 3 signature. + # ``other`` shows up in a Python signature. pm.update(other=42) self.assertEqual(pm, {'other': 42}) pm = self._makeOne() diff --git a/src/persistent/tests/test_persistence.py b/src/persistent/tests/test_persistence.py index fa8aa3d..c1023b6 100644 --- a/src/persistent/tests/test_persistence.py +++ b/src/persistent/tests/test_persistence.py @@ -1833,10 +1833,7 @@ class TestPersistent(self._getTargetClass()): def _normalize_repr(self, r): # addresses - r = re.sub(r'at 0x[0-9a-fA-F]*', 'at 0xdeadbeef', r) - # Python 3.7 removed the trailing , in exception reprs - r = r.replace("',)", "')") - return r + return re.sub(r'at 0x[0-9a-fA-F]*', 'at 0xdeadbeef', r) def _normalized_repr(self, o): return self._normalize_repr(repr(o)) diff --git a/src/persistent/timestamp.py b/src/persistent/timestamp.py index faa9a97..ac850d4 100644 --- a/src/persistent/timestamp.py +++ b/src/persistent/timestamp.py @@ -37,7 +37,7 @@ # Make sure to overflow and wraparound just # like the C code does. from ctypes import c_long -except ImportError: # pragma: no cover +except ModuleNotFoundError: # pragma: no cover # XXX: This is broken on 64-bit windows, where # sizeof(long) != sizeof(Py_ssize_t) # sizeof(long) == 4, sizeof(Py_ssize_t) == 8 diff --git a/tox.ini b/tox.ini index 4ae77e7..82ace46 100644 --- a/tox.ini +++ b/tox.ini @@ -5,18 +5,18 @@ minversion = 4.0 envlist = release-check lint - py39,py39-pure py310,py310-pure py311,py311-pure py312,py312-pure py313,py313-pure py314,py314-pure + py315,py315-pure pypy3 docs coverage [testenv] -pip_pre = py314: true +pip_pre = py315: true deps = setuptools >= 78.1.1,< 81 Sphinx @@ -66,7 +66,7 @@ deps = commands_pre = commands = check-manifest - check-python-versions --only setup.py,tox.ini,.github/workflows/tests.yml + check-python-versions --only pyproject.toml,setup.py,tox.ini,.github/workflows/tests.yml python -m build --sdist --no-isolation twine check dist/*