From 58b0c8fed178e3c4e1487434711170466994cacf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Mon, 12 Aug 2024 18:46:14 +0300 Subject: [PATCH 01/20] Add a tidelift security policy. --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..da9c516 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. From 29cd77a54e89ad11d029cbe28e41ccc07fb48839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 16:42:26 +0200 Subject: [PATCH 02/20] Add support for __format__. --- src/lazy_object_proxy/cext.c | 17 +++++++++++++++++ src/lazy_object_proxy/simple.py | 7 ++++--- src/lazy_object_proxy/slots.py | 3 +++ tests/test_lazy_object_proxy.py | 9 +++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/lazy_object_proxy/cext.c b/src/lazy_object_proxy/cext.c index 17f1098..4bb755f 100644 --- a/src/lazy_object_proxy/cext.c +++ b/src/lazy_object_proxy/cext.c @@ -1182,6 +1182,22 @@ static PyObject *Proxy_aexit( /* ------------------------------------------------------------------------- */ +static PyObject *Proxy_format( + ProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *format_spec = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + if (!PyArg_ParseTuple(args, "|O:format", &format_spec)) + return NULL; + + return PyObject_Format(self->wrapped, format_spec); + +} + +/* ------------------------------------------------------------------------- */ + static PyObject *Proxy_await(ProxyObject *self) { Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); @@ -1311,6 +1327,7 @@ static PyMethodDef Proxy_methods[] = { { "__round__", (PyCFunction)Proxy_round, METH_NOARGS, 0 }, { "__aenter__", (PyCFunction)Proxy_aenter, METH_NOARGS, 0 }, { "__aexit__", (PyCFunction)Proxy_aexit, METH_VARARGS | METH_KEYWORDS, 0 }, + { "__format__", (PyCFunction)Proxy_format, METH_VARARGS, 0 }, { NULL, NULL }, }; diff --git a/src/lazy_object_proxy/simple.py b/src/lazy_object_proxy/simple.py index abf0587..8009b93 100644 --- a/src/lazy_object_proxy/simple.py +++ b/src/lazy_object_proxy/simple.py @@ -91,9 +91,7 @@ def __wrapped__(self): def __repr__(self, __getattr__=object.__getattribute__): if '__wrapped__' in self.__dict__: - return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format( - type(self).__name__, id(self), self.__wrapped__, id(self.__wrapped__), self.__factory__ - ) + return f'<{type(self).__name__} at 0x{id(self):x} wrapping {self.__wrapped__!r} at 0x{id(self.__wrapped__):x} with factory {self.__factory__!r}>' else: return f'<{type(self).__name__} at 0x{id(self):x} with factory {self.__factory__!r}>' @@ -249,6 +247,9 @@ def __reduce__(self): def __reduce_ex__(self, protocol): return identity, (self.__wrapped__,) + def __format__(self, format_spec): + return self.__wrapped__.__format__(format_spec) + if await_: from .utils import __aenter__ from .utils import __aexit__ diff --git a/src/lazy_object_proxy/slots.py b/src/lazy_object_proxy/slots.py index bf035c0..eac82cc 100644 --- a/src/lazy_object_proxy/slots.py +++ b/src/lazy_object_proxy/slots.py @@ -429,6 +429,9 @@ def __reduce__(self): def __reduce_ex__(self, protocol): return identity, (self.__wrapped__,) + def __format__(self, format_spec): + return self.__wrapped__.__format__(format_spec) + if await_: from .utils import __aenter__ from .utils import __aexit__ diff --git a/tests/test_lazy_object_proxy.py b/tests/test_lazy_object_proxy.py index 6c5e637..d95aa57 100644 --- a/tests/test_lazy_object_proxy.py +++ b/tests/test_lazy_object_proxy.py @@ -1955,3 +1955,12 @@ def test_resolved_str(lop): assert obj.__resolved__ is False str(obj) assert obj.__resolved__ is True + + +def test_format(lop): + class WithFormat: + def __format__(self, format_spec): + return f'spec({format_spec!r})' + + obj = lop.Proxy(WithFormat) + assert f'{obj:stuff}' == "spec('stuff')" From bdcc696ef07eed5d11ab72d07238c39e53562c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 16:51:33 +0200 Subject: [PATCH 03/20] Drop EOL python 3.8 and update some CI config. --- .cookiecutterrc | 12 +- .github/workflows/github-actions.yml | 248 +++--------------- .pre-commit-config.yaml | 9 +- LICENSE | 2 +- README.rst | 15 +- ci/requirements.txt | 1 - .../.github/workflows/github-actions.yml | 8 +- docs/conf.py | 19 +- docs/requirements.txt | 2 +- pyproject.toml | 28 +- setup.py | 5 +- tox.ini | 9 +- 12 files changed, 92 insertions(+), 266 deletions(-) diff --git a/.cookiecutterrc b/.cookiecutterrc index 29789c1..1d621f1 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -1,9 +1,6 @@ # Generated by cookiepatcher, a small shim around cookiecutter (pip install cookiepatcher) default_context: - allow_tests_inside_package: 'no' - c_extension_function: '-' - c_extension_module: '-' c_extension_optional: 'yes' c_extension_support: 'yes' codacy: 'no' @@ -17,17 +14,19 @@ default_context: email: contact@ionelmc.ro formatter_quote_style: single full_name: Ionel Cristian Mărieș + function_name: compute github_actions: 'yes' github_actions_osx: 'yes' github_actions_windows: 'yes' license: BSD 2-Clause License + module_name: cext package_name: lazy_object_proxy pre_commit: 'yes' project_name: lazy-object-proxy project_short_description: A fast and thorough lazy object proxy. pypi_badge: 'yes' pypi_disable_upload: 'no' - release_date: '2023-01-04' + release_date: '2023-12-15' repo_hosting: github.com repo_hosting_domain: github.com repo_main_branch: master @@ -38,10 +37,11 @@ default_context: sphinx_docs: 'yes' sphinx_docs_hosting: https://python-lazy-object-proxy.readthedocs.io/ sphinx_doctest: 'no' - sphinx_theme: sphinx-py3doc-enhanced-theme + sphinx_theme: furo test_matrix_separate_coverage: 'yes' + tests_inside_package: 'no' version: 1.10.0 version_manager: bump2version website: https://blog.ionelmc.ro year_from: '2014' - year_to: '2023' + year_to: '2024' diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index f1366a9..a507797 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,5 +1,5 @@ name: build -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: test: name: ${{ matrix.name }} @@ -19,89 +19,6 @@ jobs: toxpython: 'python3.11' tox_env: 'docs' os: 'ubuntu-latest' - - name: 'py38-cover (ubuntu/x86_64)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-cover' - cover: true - cibw_arch: 'x86_64' - cibw_build: false - os: 'ubuntu-latest' - - name: 'py38-cover (windows/AMD64)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-cover' - cover: true - cibw_arch: 'AMD64' - cibw_build: false - os: 'windows-latest' - - name: 'py38-cover (macos/x86_64)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-cover' - cover: true - cibw_arch: 'x86_64' - cibw_build: false - os: 'macos-latest' - - name: 'py38-nocov (ubuntu/x86_64/manylinux)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp38-*manylinux*' - os: 'ubuntu-latest' - - name: 'py38-nocov (ubuntu/x86_64/musllinux)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp38-*musllinux*' - os: 'ubuntu-latest' - - name: 'py38-nocov (ubuntu/aarch64/manylinux)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'aarch64' - cibw_build: 'cp38-*manylinux*' - os: 'ubuntu-latest' - - name: 'py38-nocov (ubuntu/aarch64/musllinux)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'aarch64' - cibw_build: 'cp38-*musllinux*' - os: 'ubuntu-latest' - - name: 'py38-nocov (windows/AMD64)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'AMD64' - cibw_build: 'cp38-*' - os: 'windows-latest' - - name: 'py38-nocov (windows/x86)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x86' - tox_env: 'py38-nocov' - cibw_arch: 'x86' - cibw_build: 'cp38-*' - os: 'windows-latest' - - name: 'py38-nocov (macos/x86_64)' - python: '3.8' - toxpython: 'python3.8' - python_arch: 'x64' - tox_env: 'py38-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp38-*' - os: 'macos-latest' - name: 'py39-cover (ubuntu/x86_64)' python: '3.9' toxpython: 'python3.9' @@ -120,13 +37,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'py39-cover (macos/x86_64)' + - name: 'py39-cover (macos/arm64)' python: '3.9' toxpython: 'python3.9' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'py39-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'py39-nocov (ubuntu/x86_64/manylinux)' @@ -169,20 +86,12 @@ jobs: cibw_arch: 'AMD64' cibw_build: 'cp39-*' os: 'windows-latest' - - name: 'py39-nocov (windows/x86)' + - name: 'py39-nocov (macos/arm64)' python: '3.9' toxpython: 'python3.9' - python_arch: 'x86' + python_arch: 'arm64' tox_env: 'py39-nocov' - cibw_arch: 'x86' - cibw_build: 'cp39-*' - os: 'windows-latest' - - name: 'py39-nocov (macos/x86_64)' - python: '3.9' - toxpython: 'python3.9' - python_arch: 'x64' - tox_env: 'py39-nocov' - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: 'cp39-*' os: 'macos-latest' - name: 'py310-cover (ubuntu/x86_64)' @@ -203,13 +112,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'py310-cover (macos/x86_64)' + - name: 'py310-cover (macos/arm64)' python: '3.10' toxpython: 'python3.10' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'py310-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'py310-nocov (ubuntu/x86_64/manylinux)' @@ -252,20 +161,12 @@ jobs: cibw_arch: 'AMD64' cibw_build: 'cp310-*' os: 'windows-latest' - - name: 'py310-nocov (windows/x86)' + - name: 'py310-nocov (macos/arm64)' python: '3.10' toxpython: 'python3.10' - python_arch: 'x86' + python_arch: 'arm64' tox_env: 'py310-nocov' - cibw_arch: 'x86' - cibw_build: 'cp310-*' - os: 'windows-latest' - - name: 'py310-nocov (macos/x86_64)' - python: '3.10' - toxpython: 'python3.10' - python_arch: 'x64' - tox_env: 'py310-nocov' - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: 'cp310-*' os: 'macos-latest' - name: 'py311-cover (ubuntu/x86_64)' @@ -286,13 +187,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'py311-cover (macos/x86_64)' + - name: 'py311-cover (macos/arm64)' python: '3.11' toxpython: 'python3.11' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'py311-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'py311-nocov (ubuntu/x86_64/manylinux)' @@ -335,20 +236,12 @@ jobs: cibw_arch: 'AMD64' cibw_build: 'cp311-*' os: 'windows-latest' - - name: 'py311-nocov (windows/x86)' + - name: 'py311-nocov (macos/arm64)' python: '3.11' toxpython: 'python3.11' - python_arch: 'x86' + python_arch: 'arm64' tox_env: 'py311-nocov' - cibw_arch: 'x86' - cibw_build: 'cp311-*' - os: 'windows-latest' - - name: 'py311-nocov (macos/x86_64)' - python: '3.11' - toxpython: 'python3.11' - python_arch: 'x64' - tox_env: 'py311-nocov' - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: 'cp311-*' os: 'macos-latest' - name: 'py312-cover (ubuntu/x86_64)' @@ -369,13 +262,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'py312-cover (macos/x86_64)' + - name: 'py312-cover (macos/arm64)' python: '3.12' toxpython: 'python3.12' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'py312-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'py312-nocov (ubuntu/x86_64/manylinux)' @@ -418,72 +311,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: 'cp312-*' os: 'windows-latest' - - name: 'py312-nocov (windows/x86)' + - name: 'py312-nocov (macos/arm64)' python: '3.12' toxpython: 'python3.12' - python_arch: 'x86' + python_arch: 'arm64' tox_env: 'py312-nocov' - cibw_arch: 'x86' + cibw_arch: 'arm64' cibw_build: 'cp312-*' - os: 'windows-latest' - - name: 'py312-nocov (macos/x86_64)' - python: '3.12' - toxpython: 'python3.12' - python_arch: 'x64' - tox_env: 'py312-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp312-*' - os: 'macos-latest' - - name: 'pypy38-cover (ubuntu/x86_64)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-cover' - cover: true - cibw_arch: 'x86_64' - cibw_build: false - os: 'ubuntu-latest' - - name: 'pypy38-cover (windows/AMD64)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-cover' - cover: true - cibw_arch: 'AMD64' - cibw_build: false - os: 'windows-latest' - - name: 'pypy38-cover (macos/x86_64)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-cover' - cover: true - cibw_arch: 'x86_64' - cibw_build: false - os: 'macos-latest' - - name: 'pypy38-nocov (ubuntu/x86_64/manylinux)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-nocov' - cibw_arch: 'x86_64' - cibw_build: false - os: 'ubuntu-latest' - - name: 'pypy38-nocov (windows/AMD64)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-nocov' - cibw_arch: 'AMD64' - cibw_build: false - os: 'windows-latest' - - name: 'pypy38-nocov (macos/x86_64)' - python: 'pypy-3.8' - toxpython: 'pypy3.8' - python_arch: 'x64' - tox_env: 'pypy38-nocov' - cibw_arch: 'x86_64' - cibw_build: false os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' python: 'pypy-3.9' @@ -503,13 +337,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'pypy39-cover (macos/x86_64)' + - name: 'pypy39-cover (macos/arm64)' python: 'pypy-3.9' toxpython: 'pypy3.9' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'pypy39-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'pypy39-nocov (ubuntu/x86_64/manylinux)' @@ -528,12 +362,12 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'pypy39-nocov (macos/x86_64)' + - name: 'pypy39-nocov (macos/arm64)' python: 'pypy-3.9' toxpython: 'pypy3.9' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'pypy39-nocov' - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'pypy310-cover (ubuntu/x86_64)' @@ -554,13 +388,13 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'pypy310-cover (macos/x86_64)' + - name: 'pypy310-cover (macos/arm64)' python: 'pypy-3.10' toxpython: 'pypy3.10' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'pypy310-cover' cover: true - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - name: 'pypy310-nocov (ubuntu/x86_64/manylinux)' @@ -579,12 +413,12 @@ jobs: cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'pypy310-nocov (macos/x86_64)' + - name: 'pypy310-nocov (macos/arm64)' python: 'pypy-3.10' toxpython: 'pypy3.10' - python_arch: 'x64' + python_arch: 'arm64' tox_env: 'pypy310-nocov' - cibw_arch: 'x86_64' + cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' steps: @@ -606,11 +440,6 @@ jobs: pip --version tox --version pip list --format=freeze - - name: install dependencies (gdb) - if: > - !matrix.cibw_build && matrix.os == 'ubuntu' - run: > - sudo apt-get install gdb - name: cibw build and test if: matrix.cibw_build run: cibuildwheel @@ -662,3 +491,6 @@ jobs: - uses: coverallsapp/github-action@v2 with: parallel-finished: true + - uses: codecov/codecov-action@v3 + with: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0a737a5..2124ee7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,16 +6,13 @@ exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' # Note the order is intentional to avoid multiple passes of the hooks repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.7 + rev: v0.7.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] - - repo: https://github.com/psf/black - rev: 23.12.0 - hooks: - - id: black + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/LICENSE b/LICENSE index 07630f9..b56dc6d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2014-2023, Ionel Cristian Mărieș. All rights reserved. +Copyright (c) 2014-2024, Ionel Cristian Mărieș. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.rst b/README.rst index cac8bba..e429753 100644 --- a/README.rst +++ b/README.rst @@ -10,13 +10,11 @@ Overview * - docs - |docs| * - tests - - | |github-actions| - | |coveralls| |codecov| + - |github-actions| |coveralls| |codecov| * - package - - | |version| |wheel| |supported-versions| |supported-implementations| - | |commits-since| + - |version| |wheel| |supported-versions| |supported-implementations| |commits-since| .. |docs| image:: https://readthedocs.org/projects/python-lazy-object-proxy/badge/?style=flat - :target: https://python-lazy-object-proxy.readthedocs.io/ + :target: https://readthedocs.org/projects/python-lazy-object-proxy/ :alt: Documentation Status .. |github-actions| image:: https://github.com/ionelmc/python-lazy-object-proxy/actions/workflows/github-actions.yml/badge.svg @@ -91,11 +89,18 @@ Installation pip install lazy-object-proxy +You can also install the in-development version with:: + + pip install https://github.com/ionelmc/python-lazy-object-proxy/archive/master.zip + + Documentation ============= + https://python-lazy-object-proxy.readthedocs.io/ + Development =========== diff --git a/ci/requirements.txt b/ci/requirements.txt index a1708f4..b4f1852 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -1,6 +1,5 @@ virtualenv>=16.6.0 pip>=19.1.1 setuptools>=18.0.1 -six>=1.14.0 tox twine diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index 55e98d3..fb89fec 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -1,5 +1,5 @@ name: build -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: test: name: {{ '${{ matrix.name }}' }} @@ -36,8 +36,7 @@ jobs: ['ubuntu', 'x64', 'aarch64', '*manylinux*', False], ['ubuntu', 'x64', 'aarch64', '*musllinux*', False], ['windows', 'x64', 'AMD64', '*', True], - ['windows', 'x86', 'x86', '*', False], - ['macos', 'x64', 'x86_64', '*', True], + ['macos', 'arm64', 'arm64', '*', True], ] %} {% if include_cover or ('nocov' in env and not prefix.startswith('pypy')) %} {% set wheel_suffix = 'nocov' in env and wheel_arch.strip('*') %} @@ -135,3 +134,6 @@ jobs: - uses: coverallsapp/github-action@v2 with: parallel-finished: true + - uses: codecov/codecov-action@v3 + with: + CODECOV_TOKEN: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %} diff --git a/docs/conf.py b/docs/conf.py index f6d031a..18f3f99 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,3 @@ -import traceback - -import sphinx_py3doc_enhanced_theme - extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', @@ -16,7 +12,7 @@ source_suffix = '.rst' master_doc = 'index' project = 'lazy-object-proxy' -year = '2014-2023' +year = '2014-2024' author = 'Ionel Cristian Mărieș' copyright = f'{year}, {author}' try: @@ -24,17 +20,19 @@ version = release = get_distribution('lazy_object_proxy').version except Exception: + import traceback + traceback.print_exc() version = release = '1.10.0' pygments_style = 'trac' templates_path = ['.'] extlinks = { - 'issue': ('https://github.com/ionelmc/python-lazy-object-proxy/issues/%s', '#'), - 'pr': ('https://github.com/ionelmc/python-lazy-object-proxy/pull/%s', 'PR #'), + 'issue': ('https://github.com/ionelmc/python-lazy-object-proxy/issues/%s', '#%s'), + 'pr': ('https://github.com/ionelmc/python-lazy-object-proxy/pull/%s', 'PR #%s'), } -html_theme = 'sphinx_py3doc_enhanced_theme' -html_theme_path = [sphinx_py3doc_enhanced_theme.get_html_theme_path()] + +html_theme = 'furo' html_theme_options = { 'githuburl': 'https://github.com/ionelmc/python-lazy-object-proxy/', } @@ -42,9 +40,6 @@ html_use_smartypants = True html_last_updated_fmt = '%b %d, %Y' html_split_index = False -html_sidebars = { - '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], -} html_short_title = f'{project}-{version}' napoleon_use_ivar = True diff --git a/docs/requirements.txt b/docs/requirements.txt index 62bc14e..c03e307 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,2 @@ sphinx>=1.3 -sphinx-py3doc-enhanced-theme +furo diff --git a/pyproject.toml b/pyproject.toml index f84e2f2..6632079 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,11 +7,16 @@ build-backend = "setuptools.build_meta" [tool.setuptools_scm] -[tool.ruff.per-file-ignores] -"ci/*" = ["S"] - [tool.ruff] extend-exclude = ["static", "ci/templates"] +line-length = 140 +src = ["src", "tests"] +target-version = "py39" + +[tool.ruff.lint.per-file-ignores] +"ci/*" = ["S"] + +[tool.ruff.lint] ignore = [ "RUF001", # ruff-specific rules ambiguous-unicode-character-string "S101", # flake8-bandit assert @@ -23,7 +28,6 @@ ignore = [ "B004", "S102", ] -line-length = 140 select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions @@ -38,28 +42,20 @@ select = [ "PLE", # pylint errors "PT", # flake8-pytest-style "PTH", # flake8-use-pathlib - "Q", # flake8-quotes "RSE", # flake8-raise "RUF", # ruff-specific rules "S", # flake8-bandit "UP", # pyupgrade "W", # pycodestyle warnings ] -src = ["src", "tests"] -target-version = "py38" -[tool.ruff.flake8-pytest-style] +[tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false mark-parentheses = false -[tool.ruff.isort] +[tool.ruff.lint.isort] forced-separate = ["conftest"] force-single-line = true -[tool.black] -line-length = 140 -target-version = ["py38"] -skip-string-normalization = true - -[tool.ruff.flake8-quotes] -inline-quotes = "single" +[tool.ruff.format] +quote-style = "single" diff --git a/setup.py b/setup.py index 30f84c6..d7a0044 100755 --- a/setup.py +++ b/setup.py @@ -105,7 +105,6 @@ def read(*names, **kwargs): 'Programming Language :: Python', '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', @@ -126,14 +125,14 @@ def read(*names, **kwargs): keywords=[ # eg: "keyword1", "keyword2", "keyword3", ], - python_requires='>=3.8', + python_requires='>=3.9', install_requires=[ # eg: "aspectlib==1.1.1", "six>=1.7", ], extras_require={ # eg: # "rst": ["docutils>=0.11"], - # ":python_version=="2.6"": ["argparse"], + # ":python_version=='3.8'": ["backports.zoneinfo"], }, setup_requires=[ 'setuptools_scm>=3.3.1', diff --git a/tox.ini b/tox.ini index 57f7222..37b2254 100644 --- a/tox.ini +++ b/tox.ini @@ -14,16 +14,14 @@ envlist = clean, check, docs, - {py38,py39,py310,py311,py312,pypy38,pypy39,pypy310}-{cover,nocov}, + {py39,py310,py311,py312,pypy39,pypy310}-{cover,nocov}, report ignore_basepython_conflict = true [testenv] basepython = - pypy38: {env:TOXPYTHON:pypy3.8} pypy39: {env:TOXPYTHON:pypy3.9} pypy310: {env:TOXPYTHON:pypy3.10} - py38: {env:TOXPYTHON:python3.8} py39: {env:TOXPYTHON:python3.9} py310: {env:TOXPYTHON:python3.10} py311: {env:TOXPYTHON:python3.11} @@ -84,7 +82,10 @@ commands = coverage html [testenv:clean] -commands = coverage erase +commands = + python setup.py clean + coverage erase skip_install = true deps = + setuptools coverage From d76efe129ee317b2ebd2b807a5fb6509ba86b8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 16:53:27 +0200 Subject: [PATCH 04/20] Run ruff over. --- .pre-commit-config.yaml | 2 +- tests/conftest.py | 4 +-- tests/test_async_py3.py | 42 +++++++++++++------------- tests/test_lazy_object_proxy.py | 52 ++++++++++++++++----------------- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2124ee7..0964d05 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: rev: v0.7.4 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix, --show-fixes] + args: [--fix, --exit-non-zero-on-fix, --show-fixes, --unsafe-fixes] - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 diff --git a/tests/conftest.py b/tests/conftest.py index 11d0379..1317faf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,7 +28,7 @@ class FakeModule: elif name == 'django': Proxy = pytest.importorskip('django.utils.functional').SimpleLazyObject else: - raise RuntimeError('Unsupported param: %r.' % name) + raise RuntimeError(f'Unsupported param: {name!r}.') Proxy # noqa: B018 @@ -68,7 +68,7 @@ def lop(request, lop_subclass): if request.node.get_closest_marker('xfail_subclass'): request.applymarker( pytest.mark.xfail( - reason="This test can't work because subclassing disables certain " "features like __doc__ and __module__ proxying." + reason="This test can't work because subclassing disables certain features like __doc__ and __module__ proxying." ) ) if request.node.get_closest_marker('xfail_simple'): diff --git a/tests/test_async_py3.py b/tests/test_async_py3.py index 513986f..63a4e97 100644 --- a/tests/test_async_py3.py +++ b/tests/test_async_py3.py @@ -99,7 +99,7 @@ def test_func_2(lop): async def foo(): raise StopIteration - with pytest.raises(RuntimeError, match="coroutine raised StopIteration"): + with pytest.raises(RuntimeError, match='coroutine raised StopIteration'): run_async(lop.Proxy(foo)) @@ -275,7 +275,7 @@ async def g(): await foo me = lop.Proxy(g) - with pytest.raises(ValueError, match="coroutine already executing"): + with pytest.raises(ValueError, match='coroutine already executing'): me.send(None) @@ -303,7 +303,7 @@ async def coro(): c = lop.Proxy(coro) c.send(None) - with pytest.raises(RuntimeError, match="coroutine ignored GeneratorExit"): + with pytest.raises(RuntimeError, match='coroutine ignored GeneratorExit'): c.close() @@ -498,7 +498,7 @@ def test_await_1(lop): async def foo(): await 1 - with pytest.raises(TypeError, match="object int can.t.*await"): + with pytest.raises(TypeError, match='object int can.t.*await'): run_async(lop.Proxy(foo)) @@ -506,7 +506,7 @@ def test_await_2(lop): async def foo(): await [] - with pytest.raises(TypeError, match="object list can.t.*await"): + with pytest.raises(TypeError, match='object list can.t.*await'): run_async(lop.Proxy(foo)) @@ -536,7 +536,7 @@ def __await__(self): async def foo(): return await lop.Proxy(Awaitable) - with pytest.raises(TypeError, match="__await__.*returned non-iterator of type"): + with pytest.raises(TypeError, match='__await__.*returned non-iterator of type'): run_async(lop.Proxy(foo)) @@ -644,7 +644,7 @@ def __await__(self): async def foo(): return await lop.Proxy(Awaitable) - with pytest.raises(TypeError, match=r"__await__\(\) returned a coroutine"): + with pytest.raises(TypeError, match=r'__await__\(\) returned a coroutine'): run_async(lop.Proxy(foo)) c.close() @@ -658,7 +658,7 @@ def __await__(self): async def foo(): return await lop.Proxy(Awaitable) - with pytest.raises(TypeError, match="__await__.*returned non-iterator of type"): + with pytest.raises(TypeError, match='__await__.*returned non-iterator of type'): run_async(lop.Proxy(foo)) @@ -713,7 +713,7 @@ async def waiter(coro): coro = lop.Proxy(coroutine) coro.send(None) - with pytest.raises(RuntimeError, match="coroutine is being awaited already"): + with pytest.raises(RuntimeError, match='coroutine is being awaited already'): waiter(coro).send(None) @@ -749,7 +749,7 @@ async def __aexit__(self, *args): return True async def foo(): - async with lop.Proxy(lambda: Manager("A")) as a, lop.Proxy(lambda: Manager("B")) as b: + async with lop.Proxy(lambda: Manager('A')) as a, lop.Proxy(lambda: Manager('B')) as b: await lop.Proxy(lambda: AsyncYieldFrom([('managers', a.name, b.name)])) 1 / 0 @@ -769,7 +769,7 @@ async def foo(): ] async def foo(): - async with lop.Proxy(lambda: Manager("A")) as a, lop.Proxy(lambda: Manager("C")) as c: + async with lop.Proxy(lambda: Manager('A')) as a, lop.Proxy(lambda: Manager('C')) as c: await lop.Proxy(lambda: AsyncYieldFrom([('managers', a.name, c.name)])) 1 / 0 @@ -857,7 +857,7 @@ async def foo(): async with lop.Proxy(CM): pass - with pytest.raises(TypeError, match="'async with' received an object from __aenter__ " "that does not implement __await__: int"): + with pytest.raises(TypeError, match="'async with' received an object from __aenter__ " 'that does not implement __await__: int'): # it's important that __aexit__ wasn't called run_async(lop.Proxy(foo)) @@ -879,7 +879,7 @@ async def foo(): try: run_async(lop.Proxy(foo)) except TypeError as exc: - assert re.search("'async with' received an object from __aexit__ " "that does not implement __await__: int", exc.args[0]) + assert re.search("'async with' received an object from __aexit__ " 'that does not implement __await__: int', exc.args[0]) assert exc.__context__ is not None assert isinstance(exc.__context__, ZeroDivisionError) else: @@ -903,7 +903,7 @@ async def foo(): async with lop.Proxy(CM): CNT += 1 - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " "that does not implement __await__: int"): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): run_async(lop.Proxy(foo)) assert CNT == 1 @@ -915,7 +915,7 @@ async def foo(): CNT += 1 break - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " "that does not implement __await__: int"): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): run_async(lop.Proxy(foo)) assert CNT == 2 @@ -927,7 +927,7 @@ async def foo(): CNT += 1 continue - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " "that does not implement __await__: int"): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): run_async(lop.Proxy(foo)) assert CNT == 3 @@ -938,7 +938,7 @@ async def foo(): CNT += 1 return - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " "that does not implement __await__: int"): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): run_async(lop.Proxy(foo)) assert CNT == 4 @@ -1224,7 +1224,7 @@ async def main(): I += 1000 with warnings.catch_warnings(): - warnings.simplefilter("error") + warnings.simplefilter('error') # Test that __aiter__ that returns an asynchronous iterator # directly does not throw any warnings. run_async(main()) @@ -1309,7 +1309,7 @@ async def foo(): with pytest.raises(ZeroDivisionError): with warnings.catch_warnings(): - warnings.simplefilter("error") + warnings.simplefilter('error') # Test that if __aiter__ raises an exception it propagates # without any kind of warning. run_async(lop.Proxy(foo)) @@ -1622,7 +1622,7 @@ async def func(): aw.close() -@pytest.mark.skipif("sys.version_info[1] < 8") +@pytest.mark.skipif('sys.version_info[1] < 8') def test_for_assign_raising_stop_async_iteration(lop): class BadTarget: def __setitem__(self, key, value): @@ -1662,7 +1662,7 @@ async def run_gen(): assert run_async(run_gen()) == ([], 'end') -@pytest.mark.skipif("sys.version_info[1] < 8") +@pytest.mark.skipif('sys.version_info[1] < 8') def test_for_assign_raising_stop_async_iteration_2(lop): class BadIterable: def __iter__(self): diff --git a/tests/test_lazy_object_proxy.py b/tests/test_lazy_object_proxy.py index d95aa57..3c881be 100644 --- a/tests/test_lazy_object_proxy.py +++ b/tests/test_lazy_object_proxy.py @@ -1062,13 +1062,13 @@ def test_iadd(lop): assert value == 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value += one assert value == 3 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_isub(lop): @@ -1078,13 +1078,13 @@ def test_isub(lop): value -= 1 assert value == 0 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value -= one assert value == -1 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_imul(lop): @@ -1095,13 +1095,13 @@ def test_imul(lop): assert value == 4 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value *= two assert value == 8 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_imatmul(lop): @@ -1122,7 +1122,7 @@ def __imatmul__(self, other): assert value.value == 234 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_idiv(lop): @@ -1136,13 +1136,13 @@ def test_idiv(lop): assert value == 2 / 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value /= two assert value == 2 / 2 / 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_ifloordiv(lop): @@ -1153,13 +1153,13 @@ def test_ifloordiv(lop): assert value == 2 // 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value //= two assert value == 2 // 2 // 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_imod(lop): @@ -1170,13 +1170,13 @@ def test_imod(lop): assert value == 10 % 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value %= two assert value == 10 % 2 % 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_ipow(lop): @@ -1187,13 +1187,13 @@ def test_ipow(lop): assert value == 10**2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value **= two assert value == 10**2**2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_ilshift(lop): @@ -1204,13 +1204,13 @@ def test_ilshift(lop): assert value == 256 << 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value <<= two assert value == 256 << 2 << 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_irshift(lop): @@ -1221,13 +1221,13 @@ def test_irshift(lop): assert value == 2 >> 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value >>= two assert value == 2 >> 2 >> 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_iand(lop): @@ -1238,13 +1238,13 @@ def test_iand(lop): assert value == 1 & 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value &= two assert value == 1 & 2 & 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_ixor(lop): @@ -1255,13 +1255,13 @@ def test_ixor(lop): assert value == 1 ^ 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value ^= two assert value == 1 ^ 2 ^ 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_ior(lop): @@ -1272,13 +1272,13 @@ def test_ior(lop): assert value == 1 | 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy value |= two assert value == 1 | 2 | 2 if lop.kind != 'simple': - assert type(value) == lop.Proxy + assert type(value) is lop.Proxy def test_neg(lop): @@ -1781,7 +1781,7 @@ def trouble_maker(): @pytest.mark.skipif(platform.python_implementation() != 'CPython', reason="Interpreter doesn't have reference counting") def test_garbage_collection(lop): - leaky = lambda: "foobar" # noqa + leaky = lambda: 'foobar' # noqa proxy = lop.Proxy(leaky) leaky.leak = proxy ref = weakref.ref(leaky) From 47062396a89669e112d6074227a6276c6a9564ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 16:53:47 +0200 Subject: [PATCH 05/20] Up ci conf. --- .github/workflows/github-actions.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index a507797..5d7d369 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -440,6 +440,11 @@ jobs: pip --version tox --version pip list --format=freeze + - name: install dependencies (gdb) + if: > + !matrix.cibw_build && matrix.os == 'ubuntu' + run: > + sudo apt-get install gdb - name: cibw build and test if: matrix.cibw_build run: cibuildwheel From 499a92bd269546a4b295dd62f039b6fc1e87c1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 17:06:13 +0200 Subject: [PATCH 06/20] Allow building on 3.13 freetreading python. --- src/lazy_object_proxy/cext.c | 8 ++++++-- tox.ini | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lazy_object_proxy/cext.c b/src/lazy_object_proxy/cext.c index 4bb755f..f6935e6 100644 --- a/src/lazy_object_proxy/cext.c +++ b/src/lazy_object_proxy/cext.c @@ -1435,8 +1435,12 @@ moduleinit(void) return NULL; Py_INCREF(&Proxy_Type); - PyModule_AddObject(module, "Proxy", - (PyObject *)&Proxy_Type); + PyModule_AddObject(module, "Proxy", (PyObject *)&Proxy_Type); + +#ifdef Py_GIL_DISABLED + PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED); +#endif + return module; } diff --git a/tox.ini b/tox.ini index 37b2254..3c6c6af 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ envlist = clean, check, docs, - {py39,py310,py311,py312,pypy39,pypy310}-{cover,nocov}, + {py39,py310,py311,py312,py312t,pypy39,pypy310}-{cover,nocov}, report ignore_basepython_conflict = true @@ -26,6 +26,7 @@ basepython = py310: {env:TOXPYTHON:python3.10} py311: {env:TOXPYTHON:python3.11} py312: {env:TOXPYTHON:python3.12} + py313t: {env:TOXPYTHON:python3.13t} {bootstrap,clean,check,report,docs,codecov,coveralls,extension-coveralls}: {env:TOXPYTHON:python3} setenv = PYTHONPATH={toxinidir}/tests From 54ea75569944a0521b286647e82742c9ba3dd1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 17:28:43 +0200 Subject: [PATCH 07/20] Add 3.13 to ci. --- .github/workflows/github-actions.yml | 187 ++++++++++++++++++ .../.github/workflows/github-actions.yml | 7 +- setup.py | 1 + tox.ini | 5 +- 4 files changed, 196 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 5d7d369..9a0e520 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -53,6 +53,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'x86_64' cibw_build: 'cp39-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/x86_64/musllinux)' python: '3.9' @@ -61,6 +62,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'x86_64' cibw_build: 'cp39-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/aarch64/manylinux)' python: '3.9' @@ -69,6 +71,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'aarch64' cibw_build: 'cp39-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/aarch64/musllinux)' python: '3.9' @@ -77,6 +80,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'aarch64' cibw_build: 'cp39-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (windows/AMD64)' python: '3.9' @@ -85,6 +89,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'AMD64' cibw_build: 'cp39-*' + cibw_ft: 'false' os: 'windows-latest' - name: 'py39-nocov (macos/arm64)' python: '3.9' @@ -93,6 +98,7 @@ jobs: tox_env: 'py39-nocov' cibw_arch: 'arm64' cibw_build: 'cp39-*' + cibw_ft: 'false' os: 'macos-latest' - name: 'py310-cover (ubuntu/x86_64)' python: '3.10' @@ -128,6 +134,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'x86_64' cibw_build: 'cp310-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/x86_64/musllinux)' python: '3.10' @@ -136,6 +143,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'x86_64' cibw_build: 'cp310-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/aarch64/manylinux)' python: '3.10' @@ -144,6 +152,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'aarch64' cibw_build: 'cp310-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/aarch64/musllinux)' python: '3.10' @@ -152,6 +161,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'aarch64' cibw_build: 'cp310-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (windows/AMD64)' python: '3.10' @@ -160,6 +170,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'AMD64' cibw_build: 'cp310-*' + cibw_ft: 'false' os: 'windows-latest' - name: 'py310-nocov (macos/arm64)' python: '3.10' @@ -168,6 +179,7 @@ jobs: tox_env: 'py310-nocov' cibw_arch: 'arm64' cibw_build: 'cp310-*' + cibw_ft: 'false' os: 'macos-latest' - name: 'py311-cover (ubuntu/x86_64)' python: '3.11' @@ -203,6 +215,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'x86_64' cibw_build: 'cp311-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/x86_64/musllinux)' python: '3.11' @@ -211,6 +224,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'x86_64' cibw_build: 'cp311-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/aarch64/manylinux)' python: '3.11' @@ -219,6 +233,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'aarch64' cibw_build: 'cp311-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/aarch64/musllinux)' python: '3.11' @@ -227,6 +242,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'aarch64' cibw_build: 'cp311-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (windows/AMD64)' python: '3.11' @@ -235,6 +251,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'AMD64' cibw_build: 'cp311-*' + cibw_ft: 'false' os: 'windows-latest' - name: 'py311-nocov (macos/arm64)' python: '3.11' @@ -243,6 +260,7 @@ jobs: tox_env: 'py311-nocov' cibw_arch: 'arm64' cibw_build: 'cp311-*' + cibw_ft: 'false' os: 'macos-latest' - name: 'py312-cover (ubuntu/x86_64)' python: '3.12' @@ -278,6 +296,7 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'x86_64' cibw_build: 'cp312-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/x86_64/musllinux)' python: '3.12' @@ -286,6 +305,7 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'x86_64' cibw_build: 'cp312-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/aarch64/manylinux)' python: '3.12' @@ -294,6 +314,7 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'aarch64' cibw_build: 'cp312-*manylinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/aarch64/musllinux)' python: '3.12' @@ -302,6 +323,7 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'aarch64' cibw_build: 'cp312-*musllinux*' + cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (windows/AMD64)' python: '3.12' @@ -310,6 +332,7 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'AMD64' cibw_build: 'cp312-*' + cibw_ft: 'false' os: 'windows-latest' - name: 'py312-nocov (macos/arm64)' python: '3.12' @@ -318,6 +341,169 @@ jobs: tox_env: 'py312-nocov' cibw_arch: 'arm64' cibw_build: 'cp312-*' + cibw_ft: 'false' + os: 'macos-latest' + - name: 'py313-cover (ubuntu/x86_64)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-cover' + cover: true + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py313-cover (windows/AMD64)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-cover' + cover: true + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py313-cover (macos/arm64)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'arm64' + tox_env: 'py313-cover' + cover: true + cibw_arch: 'arm64' + cibw_build: false + os: 'macos-latest' + - name: 'py313-nocov (ubuntu/x86_64/manylinux)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313-*manylinux*' + cibw_ft: 'false' + os: 'ubuntu-latest' + - name: 'py313-nocov (ubuntu/x86_64/musllinux)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313-*musllinux*' + cibw_ft: 'false' + os: 'ubuntu-latest' + - name: 'py313-nocov (ubuntu/aarch64/manylinux)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313-*manylinux*' + cibw_ft: 'false' + os: 'ubuntu-latest' + - name: 'py313-nocov (ubuntu/aarch64/musllinux)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313-*musllinux*' + cibw_ft: 'false' + os: 'ubuntu-latest' + - name: 'py313-nocov (windows/AMD64)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'x64' + tox_env: 'py313-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp313-*' + cibw_ft: 'false' + os: 'windows-latest' + - name: 'py313-nocov (macos/arm64)' + python: '3.13' + toxpython: 'python3.13' + python_arch: 'arm64' + tox_env: 'py313-nocov' + cibw_arch: 'arm64' + cibw_build: 'cp313-*' + cibw_ft: 'false' + os: 'macos-latest' + - name: 'py313ft-cover (ubuntu/x86_64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py313ft-cover (windows/AMD64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py313ft-cover (macos/arm64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'arm64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'arm64' + cibw_build: false + os: 'macos-latest' + - name: 'py313ft-nocov (ubuntu/x86_64/manylinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313ftt-*manylinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/x86_64/musllinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313ftt-*musllinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/aarch64/manylinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313ftt-*manylinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/aarch64/musllinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313ftt-*musllinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (windows/AMD64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp313ftt-*' + cibw_ft: 'true' + os: 'windows-latest' + - name: 'py313ft-nocov (macos/arm64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'arm64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'arm64' + cibw_build: 'cp313ftt-*' + cibw_ft: 'true' os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' python: 'pypy-3.9' @@ -452,6 +638,7 @@ jobs: TOXPYTHON: '${{ matrix.toxpython }}' CIBW_ARCHS: '${{ matrix.cibw_arch }}' CIBW_BUILD: '${{ matrix.cibw_build }}' + CIBW_FREE_THREADED_SUPPORT: '${{ matrix.cibw_ft }}' CIBW_BUILD_VERBOSITY: '3' CIBW_TEST_REQUIRES: > tox diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index fb89fec..2735dbd 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -21,6 +21,7 @@ jobs: os: 'ubuntu-latest' {% for env in tox_environments %} {% set prefix = env.split('-')[0] -%} +{% set nogil = 'ft' in env %} {% if prefix.startswith('pypy') %} {% set python %}pypy-{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% set cpython %}pp{{ prefix[4:5] }}{% endset %} @@ -44,14 +45,15 @@ jobs: - name: '{{ env }} ({{ os }}/{{ cibw_arch }}{{ name_suffix }})' python: '{{ python }}' toxpython: '{{ toxpython }}' - python_arch: '{{ python_arch }}' + python_arch: '{{ python_arch }}{% if nogil %}-freethreaded{% endif %}' tox_env: '{{ env }}' {% if 'cover' in env %} cover: true {% endif %} cibw_arch: '{{ cibw_arch }}' {% if 'nocov' in env and not prefix.startswith('pypy') %} - cibw_build: '{{ cpython }}-{{ wheel_arch }}' + cibw_build: '{{ cpython }}{% if nogil %}t{% endif %}-{{ wheel_arch }}' + cibw_ft: '{% if nogil %}true{% else %}false{% endif %}' {% else %} cibw_build: false {% endif %} @@ -90,6 +92,7 @@ jobs: TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' CIBW_ARCHS: '{{ '${{ matrix.cibw_arch }}' }}' CIBW_BUILD: '{{ '${{ matrix.cibw_build }}' }}' + CIBW_FREE_THREADED_SUPPORT: '{{ '${{ matrix.cibw_ft }}' }}' CIBW_BUILD_VERBOSITY: '3' CIBW_TEST_REQUIRES: > tox diff --git a/setup.py b/setup.py index d7a0044..083dc0d 100755 --- a/setup.py +++ b/setup.py @@ -109,6 +109,7 @@ def read(*names, **kwargs): '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', # uncomment if you test on these interpreters: diff --git a/tox.ini b/tox.ini index 3c6c6af..d0c9ff8 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ envlist = clean, check, docs, - {py39,py310,py311,py312,py312t,pypy39,pypy310}-{cover,nocov}, + {py39,py310,py311,py312,py313,py313ft,pypy39,pypy310}-{cover,nocov}, report ignore_basepython_conflict = true @@ -26,7 +26,8 @@ basepython = py310: {env:TOXPYTHON:python3.10} py311: {env:TOXPYTHON:python3.11} py312: {env:TOXPYTHON:python3.12} - py313t: {env:TOXPYTHON:python3.13t} + py313: {env:TOXPYTHON:python3.13} + py313ft: {env:TOXPYTHON:python3.13t} {bootstrap,clean,check,report,docs,codecov,coveralls,extension-coveralls}: {env:TOXPYTHON:python3} setenv = PYTHONPATH={toxinidir}/tests From 49c70b2208bd754997fd5f6de79721d7042d4fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 17:45:57 +0200 Subject: [PATCH 08/20] I guess I need to wait on https://github.com/actions/python-versions/pull/319 and maybe https://github.com/actions/python-versions/pull/319. --- .github/workflows/github-actions.yml | 81 ------------------- .../.github/workflows/github-actions.yml | 2 + 2 files changed, 2 insertions(+), 81 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 9a0e520..b270c12 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -424,87 +424,6 @@ jobs: cibw_build: 'cp313-*' cibw_ft: 'false' os: 'macos-latest' - - name: 'py313ft-cover (ubuntu/x86_64)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-cover' - cover: true - cibw_arch: 'x86_64' - cibw_build: false - os: 'ubuntu-latest' - - name: 'py313ft-cover (windows/AMD64)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-cover' - cover: true - cibw_arch: 'AMD64' - cibw_build: false - os: 'windows-latest' - - name: 'py313ft-cover (macos/arm64)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'arm64-freethreaded' - tox_env: 'py313ft-cover' - cover: true - cibw_arch: 'arm64' - cibw_build: false - os: 'macos-latest' - - name: 'py313ft-nocov (ubuntu/x86_64/manylinux)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp313ftt-*manylinux*' - cibw_ft: 'true' - os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/x86_64/musllinux)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'x86_64' - cibw_build: 'cp313ftt-*musllinux*' - cibw_ft: 'true' - os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/aarch64/manylinux)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'aarch64' - cibw_build: 'cp313ftt-*manylinux*' - cibw_ft: 'true' - os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/aarch64/musllinux)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'aarch64' - cibw_build: 'cp313ftt-*musllinux*' - cibw_ft: 'true' - os: 'ubuntu-latest' - - name: 'py313ft-nocov (windows/AMD64)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'AMD64' - cibw_build: 'cp313ftt-*' - cibw_ft: 'true' - os: 'windows-latest' - - name: 'py313ft-nocov (macos/arm64)' - python: '3.13ft' - toxpython: 'python3.13ft' - python_arch: 'arm64-freethreaded' - tox_env: 'py313ft-nocov' - cibw_arch: 'arm64' - cibw_build: 'cp313ftt-*' - cibw_ft: 'true' - os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' python: 'pypy-3.9' toxpython: 'pypy3.9' diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index 2735dbd..c2140ef 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -22,6 +22,7 @@ jobs: {% for env in tox_environments %} {% set prefix = env.split('-')[0] -%} {% set nogil = 'ft' in env %} +{% if not nogil %} {% if prefix.startswith('pypy') %} {% set python %}pypy-{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% set cpython %}pp{{ prefix[4:5] }}{% endset %} @@ -60,6 +61,7 @@ jobs: os: '{{ os }}-latest' {% endif %} {% endfor %} +{% endif %} {% endfor %} steps: - uses: docker/setup-qemu-action@v3 From f33913bae9b8fc5d635bec7cffc8e7485844c668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 20 Nov 2024 17:58:34 +0200 Subject: [PATCH 09/20] Add support for ndigits in __round__. --- src/lazy_object_proxy/cext.c | 18 +++++++++++------- src/lazy_object_proxy/slots.py | 4 ++-- tests/test_lazy_object_proxy.py | 5 +++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/lazy_object_proxy/cext.c b/src/lazy_object_proxy/cext.c index f6935e6..4867c7f 100644 --- a/src/lazy_object_proxy/cext.c +++ b/src/lazy_object_proxy/cext.c @@ -839,24 +839,28 @@ static PyObject *Proxy_reduce( /* ------------------------------------------------------------------------- */ -static PyObject *Proxy_round( - ProxyObject *self, PyObject *args) +static PyObject *Proxy_round(ProxyObject *self, PyObject *args, PyObject *kwds) { PyObject *module = NULL; - PyObject *dict = NULL; PyObject *round = NULL; + PyObject *ndigits = NULL; PyObject *result = NULL; + char *const kwlist[] = { "ndigits", NULL }; + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:ObjectProxy", kwlist, &ndigits)) { + return NULL; + } + module = PyImport_ImportModule("builtins"); if (!module) return NULL; - dict = PyModule_GetDict(module); - round = PyDict_GetItemString(dict, "round"); + round = PyObject_GetAttrString(module, "round"); if (!round) { Py_DECREF(module); @@ -866,7 +870,7 @@ static PyObject *Proxy_round( Py_INCREF(round); Py_DECREF(module); - result = PyObject_CallFunctionObjArgs(round, self->wrapped, NULL); + result = PyObject_CallFunctionObjArgs(round, self->wrapped, ndigits, NULL); Py_DECREF(round); @@ -1324,7 +1328,7 @@ static PyMethodDef Proxy_methods[] = { { "__reduce__", (PyCFunction)Proxy_reduce, METH_NOARGS, 0 }, { "__reduce_ex__", (PyCFunction)Proxy_reduce, METH_O, 0 }, { "__fspath__", (PyCFunction)Proxy_fspath, METH_NOARGS, 0 }, - { "__round__", (PyCFunction)Proxy_round, METH_NOARGS, 0 }, + { "__round__", (PyCFunction)Proxy_round, METH_VARARGS | METH_KEYWORDS, 0 }, { "__aenter__", (PyCFunction)Proxy_aenter, METH_NOARGS, 0 }, { "__aexit__", (PyCFunction)Proxy_aexit, METH_VARARGS | METH_KEYWORDS, 0 }, { "__format__", (PyCFunction)Proxy_format, METH_VARARGS, 0 }, diff --git a/src/lazy_object_proxy/slots.py b/src/lazy_object_proxy/slots.py index eac82cc..ccb4f1c 100644 --- a/src/lazy_object_proxy/slots.py +++ b/src/lazy_object_proxy/slots.py @@ -167,8 +167,8 @@ def __fspath__(self): def __reversed__(self): return reversed(self.__wrapped__) - def __round__(self): - return round(self.__wrapped__) + def __round__(self, ndigits=None): + return round(self.__wrapped__, ndigits) def __lt__(self, other): return self.__wrapped__ < other diff --git a/tests/test_lazy_object_proxy.py b/tests/test_lazy_object_proxy.py index 3c881be..5f88394 100644 --- a/tests/test_lazy_object_proxy.py +++ b/tests/test_lazy_object_proxy.py @@ -35,6 +35,11 @@ def test_round(lop): assert round(proxy) == 1 +def test_round_ndigits(lop): + proxy = lop.Proxy(lambda: 1.49494) + assert round(proxy, 3) == 1.495 + + def test_attributes(lop): def function1(*args, **kwargs): return args, kwargs From 38795452a42a7723cf579657d63634ee8e3f6899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 16:54:56 +0300 Subject: [PATCH 10/20] Update changelog. Closes #86. --- CHANGELOG.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 52a4911..2199958 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog ========= +1.11.0 (2025-04-16) +------------------- + +* Added Python 3.13 wheels. +* Added support for ``__format__``. +* Dropped support for Python 3.8. + 1.10.0 (2023-12-15) ------------------- From 49750d7ed988440069133b032a8b88d7dafd3329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 17:30:03 +0300 Subject: [PATCH 11/20] Bump precommit and some actions. --- .github/workflows/github-actions.yml | 6 +++--- .pre-commit-config.yaml | 2 +- ci/templates/.github/workflows/github-actions.yml | 6 +++--- src/lazy_object_proxy/slots.py | 2 +- src/lazy_object_proxy/utils.py | 3 +-- tests/test_async_py3.py | 12 ++++++------ 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index b270c12..92971d0 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -581,7 +581,7 @@ jobs: with: parallel: true flag-name: ${{ matrix.tox_env }} - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v5 if: matrix.cover with: verbose: true @@ -590,7 +590,7 @@ jobs: if: matrix.cibw_build run: twine check wheelhouse/*.whl - name: upload wheel - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: matrix.cibw_build with: path: wheelhouse/*.whl @@ -602,6 +602,6 @@ jobs: - uses: coverallsapp/github-action@v2 with: parallel-finished: true - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v5 with: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0964d05..ac13451 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' # Note the order is intentional to avoid multiple passes of the hooks repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.4 + rev: v0.11.5 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes, --unsafe-fixes] diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index c2140ef..8e84a0b 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -118,7 +118,7 @@ jobs: with: parallel: true flag-name: {{ '${{ matrix.tox_env }}' }} - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v5 if: matrix.cover with: verbose: true @@ -127,7 +127,7 @@ jobs: if: matrix.cibw_build run: twine check wheelhouse/*.whl - name: upload wheel - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: matrix.cibw_build with: path: wheelhouse/*.whl @@ -139,6 +139,6 @@ jobs: - uses: coverallsapp/github-action@v2 with: parallel-finished: true - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v5 with: CODECOV_TOKEN: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %} diff --git a/src/lazy_object_proxy/slots.py b/src/lazy_object_proxy/slots.py index ccb4f1c..73bf555 100644 --- a/src/lazy_object_proxy/slots.py +++ b/src/lazy_object_proxy/slots.py @@ -77,7 +77,7 @@ class Proxy(with_metaclass(_ProxyMetaType)): * calls ``__factory__``, saves result to ``__target__`` and returns said result. """ - __slots__ = '__target__', '__factory__' + __slots__ = '__factory__', '__target__' def __init__(self, factory): object.__setattr__(self, '__factory__', factory) diff --git a/src/lazy_object_proxy/utils.py b/src/lazy_object_proxy/utils.py index 8e69787..720d768 100644 --- a/src/lazy_object_proxy/utils.py +++ b/src/lazy_object_proxy/utils.py @@ -16,8 +16,7 @@ def await_(obj): obj_type = type(obj) if ( obj_type is CoroutineType - or obj_type is GeneratorType - and bool(obj.gi_code.co_flags & CO_ITERABLE_COROUTINE) + or (obj_type is GeneratorType and bool(obj.gi_code.co_flags & CO_ITERABLE_COROUTINE)) or isinstance(obj, Awaitable) ): return do_await(obj).__await__() diff --git a/tests/test_async_py3.py b/tests/test_async_py3.py index 63a4e97..0d9450b 100644 --- a/tests/test_async_py3.py +++ b/tests/test_async_py3.py @@ -857,7 +857,7 @@ async def foo(): async with lop.Proxy(CM): pass - with pytest.raises(TypeError, match="'async with' received an object from __aenter__ " 'that does not implement __await__: int'): + with pytest.raises(TypeError, match="'async with' received an object from __aenter__ that does not implement __await__: int"): # it's important that __aexit__ wasn't called run_async(lop.Proxy(foo)) @@ -879,7 +879,7 @@ async def foo(): try: run_async(lop.Proxy(foo)) except TypeError as exc: - assert re.search("'async with' received an object from __aexit__ " 'that does not implement __await__: int', exc.args[0]) + assert re.search("'async with' received an object from __aexit__ that does not implement __await__: int", exc.args[0]) assert exc.__context__ is not None assert isinstance(exc.__context__, ZeroDivisionError) else: @@ -903,7 +903,7 @@ async def foo(): async with lop.Proxy(CM): CNT += 1 - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ that does not implement __await__: int"): run_async(lop.Proxy(foo)) assert CNT == 1 @@ -915,7 +915,7 @@ async def foo(): CNT += 1 break - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ that does not implement __await__: int"): run_async(lop.Proxy(foo)) assert CNT == 2 @@ -927,7 +927,7 @@ async def foo(): CNT += 1 continue - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ that does not implement __await__: int"): run_async(lop.Proxy(foo)) assert CNT == 3 @@ -938,7 +938,7 @@ async def foo(): CNT += 1 return - with pytest.raises(TypeError, match="'async with' received an object from __aexit__ " 'that does not implement __await__: int'): + with pytest.raises(TypeError, match="'async with' received an object from __aexit__ that does not implement __await__: int"): run_async(lop.Proxy(foo)) assert CNT == 4 From e1b16d648e1a581cc8ce8c053fa3c6a695b5aaa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 17:38:54 +0300 Subject: [PATCH 12/20] Add the freethread envs. --- .github/workflows/github-actions.yml | 81 +++++++++++++++++++ .../.github/workflows/github-actions.yml | 2 - 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 92971d0..173b749 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -424,6 +424,87 @@ jobs: cibw_build: 'cp313-*' cibw_ft: 'false' os: 'macos-latest' + - name: 'py313ft-cover (ubuntu/x86_64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py313ft-cover (windows/AMD64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py313ft-cover (macos/arm64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'arm64-freethreaded' + tox_env: 'py313ft-cover' + cover: true + cibw_arch: 'arm64' + cibw_build: false + os: 'macos-latest' + - name: 'py313ft-nocov (ubuntu/x86_64/manylinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313ftt-*manylinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/x86_64/musllinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp313ftt-*musllinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/aarch64/manylinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313ftt-*manylinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (ubuntu/aarch64/musllinux)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp313ftt-*musllinux*' + cibw_ft: 'true' + os: 'ubuntu-latest' + - name: 'py313ft-nocov (windows/AMD64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'x64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp313ftt-*' + cibw_ft: 'true' + os: 'windows-latest' + - name: 'py313ft-nocov (macos/arm64)' + python: '3.13ft' + toxpython: 'python3.13ft' + python_arch: 'arm64-freethreaded' + tox_env: 'py313ft-nocov' + cibw_arch: 'arm64' + cibw_build: 'cp313ftt-*' + cibw_ft: 'true' + os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' python: 'pypy-3.9' toxpython: 'pypy3.9' diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index 8e84a0b..f080595 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -22,7 +22,6 @@ jobs: {% for env in tox_environments %} {% set prefix = env.split('-')[0] -%} {% set nogil = 'ft' in env %} -{% if not nogil %} {% if prefix.startswith('pypy') %} {% set python %}pypy-{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% set cpython %}pp{{ prefix[4:5] }}{% endset %} @@ -61,7 +60,6 @@ jobs: os: '{{ os }}-latest' {% endif %} {% endfor %} -{% endif %} {% endfor %} steps: - uses: docker/setup-qemu-action@v3 From 1ebcd22a9dc5112812ce6af961cbd5193326821b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 17:43:33 +0300 Subject: [PATCH 13/20] Do not set binary dist if exts are disabled. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 083dc0d..df3c0c4 100755 --- a/setup.py +++ b/setup.py @@ -151,5 +151,5 @@ def read(*names, **kwargs): ] if allow_extensions else [], - distclass=BinaryDistribution, + distclass=BinaryDistribution if allow_extensions else None, ) From 9c38dc24ce4960eba3fc01b75e0e7b24c3d5dff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 17:49:26 +0300 Subject: [PATCH 14/20] Add long_description_content_type. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index df3c0c4..fdfbd9a 100755 --- a/setup.py +++ b/setup.py @@ -86,6 +86,7 @@ def read(*names, **kwargs): re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')), ), + long_description_content_type='text/x-rst', author='Ionel Cristian Mărieș', author_email='contact@ionelmc.ro', url='https://github.com/ionelmc/python-lazy-object-proxy', From 28be66870808eeee992b4e1c897a5ecbbf9472eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 17:52:31 +0300 Subject: [PATCH 15/20] Use unique actifact name. --- .github/workflows/github-actions.yml | 70 +++++++++++++++++++ .../.github/workflows/github-actions.yml | 6 ++ 2 files changed, 76 insertions(+) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 173b749..837c44c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -20,6 +20,7 @@ jobs: tox_env: 'docs' os: 'ubuntu-latest' - name: 'py39-cover (ubuntu/x86_64)' + artifact: 'py39-ubuntu-x86_64' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -29,6 +30,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py39-cover (windows/AMD64)' + artifact: 'py39-windows-AMD64' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -38,6 +40,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py39-cover (macos/arm64)' + artifact: 'py39-macos-arm64' python: '3.9' toxpython: 'python3.9' python_arch: 'arm64' @@ -47,6 +50,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py39-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py39-ubuntu-x86_64-manylinux' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -56,6 +60,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py39-ubuntu-x86_64-musllinux' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -65,6 +70,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py39-ubuntu-aarch64-manylinux' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -74,6 +80,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py39-ubuntu-aarch64-musllinux' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -83,6 +90,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py39-nocov (windows/AMD64)' + artifact: 'py39-windows-AMD64' python: '3.9' toxpython: 'python3.9' python_arch: 'x64' @@ -92,6 +100,7 @@ jobs: cibw_ft: 'false' os: 'windows-latest' - name: 'py39-nocov (macos/arm64)' + artifact: 'py39-macos-arm64' python: '3.9' toxpython: 'python3.9' python_arch: 'arm64' @@ -101,6 +110,7 @@ jobs: cibw_ft: 'false' os: 'macos-latest' - name: 'py310-cover (ubuntu/x86_64)' + artifact: 'py310-ubuntu-x86_64' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -110,6 +120,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py310-cover (windows/AMD64)' + artifact: 'py310-windows-AMD64' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -119,6 +130,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py310-cover (macos/arm64)' + artifact: 'py310-macos-arm64' python: '3.10' toxpython: 'python3.10' python_arch: 'arm64' @@ -128,6 +140,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py310-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py310-ubuntu-x86_64-manylinux' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -137,6 +150,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py310-ubuntu-x86_64-musllinux' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -146,6 +160,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py310-ubuntu-aarch64-manylinux' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -155,6 +170,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py310-ubuntu-aarch64-musllinux' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -164,6 +180,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py310-nocov (windows/AMD64)' + artifact: 'py310-windows-AMD64' python: '3.10' toxpython: 'python3.10' python_arch: 'x64' @@ -173,6 +190,7 @@ jobs: cibw_ft: 'false' os: 'windows-latest' - name: 'py310-nocov (macos/arm64)' + artifact: 'py310-macos-arm64' python: '3.10' toxpython: 'python3.10' python_arch: 'arm64' @@ -182,6 +200,7 @@ jobs: cibw_ft: 'false' os: 'macos-latest' - name: 'py311-cover (ubuntu/x86_64)' + artifact: 'py311-ubuntu-x86_64' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -191,6 +210,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py311-cover (windows/AMD64)' + artifact: 'py311-windows-AMD64' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -200,6 +220,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py311-cover (macos/arm64)' + artifact: 'py311-macos-arm64' python: '3.11' toxpython: 'python3.11' python_arch: 'arm64' @@ -209,6 +230,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py311-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py311-ubuntu-x86_64-manylinux' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -218,6 +240,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py311-ubuntu-x86_64-musllinux' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -227,6 +250,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py311-ubuntu-aarch64-manylinux' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -236,6 +260,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py311-ubuntu-aarch64-musllinux' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -245,6 +270,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py311-nocov (windows/AMD64)' + artifact: 'py311-windows-AMD64' python: '3.11' toxpython: 'python3.11' python_arch: 'x64' @@ -254,6 +280,7 @@ jobs: cibw_ft: 'false' os: 'windows-latest' - name: 'py311-nocov (macos/arm64)' + artifact: 'py311-macos-arm64' python: '3.11' toxpython: 'python3.11' python_arch: 'arm64' @@ -263,6 +290,7 @@ jobs: cibw_ft: 'false' os: 'macos-latest' - name: 'py312-cover (ubuntu/x86_64)' + artifact: 'py312-ubuntu-x86_64' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -272,6 +300,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py312-cover (windows/AMD64)' + artifact: 'py312-windows-AMD64' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -281,6 +310,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py312-cover (macos/arm64)' + artifact: 'py312-macos-arm64' python: '3.12' toxpython: 'python3.12' python_arch: 'arm64' @@ -290,6 +320,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py312-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py312-ubuntu-x86_64-manylinux' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -299,6 +330,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py312-ubuntu-x86_64-musllinux' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -308,6 +340,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py312-ubuntu-aarch64-manylinux' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -317,6 +350,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py312-ubuntu-aarch64-musllinux' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -326,6 +360,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py312-nocov (windows/AMD64)' + artifact: 'py312-windows-AMD64' python: '3.12' toxpython: 'python3.12' python_arch: 'x64' @@ -335,6 +370,7 @@ jobs: cibw_ft: 'false' os: 'windows-latest' - name: 'py312-nocov (macos/arm64)' + artifact: 'py312-macos-arm64' python: '3.12' toxpython: 'python3.12' python_arch: 'arm64' @@ -344,6 +380,7 @@ jobs: cibw_ft: 'false' os: 'macos-latest' - name: 'py313-cover (ubuntu/x86_64)' + artifact: 'py313-ubuntu-x86_64' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -353,6 +390,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py313-cover (windows/AMD64)' + artifact: 'py313-windows-AMD64' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -362,6 +400,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py313-cover (macos/arm64)' + artifact: 'py313-macos-arm64' python: '3.13' toxpython: 'python3.13' python_arch: 'arm64' @@ -371,6 +410,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py313-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py313-ubuntu-x86_64-manylinux' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -380,6 +420,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py313-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py313-ubuntu-x86_64-musllinux' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -389,6 +430,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py313-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py313-ubuntu-aarch64-manylinux' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -398,6 +440,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py313-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py313-ubuntu-aarch64-musllinux' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -407,6 +450,7 @@ jobs: cibw_ft: 'false' os: 'ubuntu-latest' - name: 'py313-nocov (windows/AMD64)' + artifact: 'py313-windows-AMD64' python: '3.13' toxpython: 'python3.13' python_arch: 'x64' @@ -416,6 +460,7 @@ jobs: cibw_ft: 'false' os: 'windows-latest' - name: 'py313-nocov (macos/arm64)' + artifact: 'py313-macos-arm64' python: '3.13' toxpython: 'python3.13' python_arch: 'arm64' @@ -425,6 +470,7 @@ jobs: cibw_ft: 'false' os: 'macos-latest' - name: 'py313ft-cover (ubuntu/x86_64)' + artifact: 'py313ft-ubuntu-x86_64' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -434,6 +480,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'py313ft-cover (windows/AMD64)' + artifact: 'py313ft-windows-AMD64' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -443,6 +490,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'py313ft-cover (macos/arm64)' + artifact: 'py313ft-macos-arm64' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'arm64-freethreaded' @@ -452,6 +500,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'py313ft-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py313ft-ubuntu-x86_64-manylinux' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -461,6 +510,7 @@ jobs: cibw_ft: 'true' os: 'ubuntu-latest' - name: 'py313ft-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py313ft-ubuntu-x86_64-musllinux' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -470,6 +520,7 @@ jobs: cibw_ft: 'true' os: 'ubuntu-latest' - name: 'py313ft-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py313ft-ubuntu-aarch64-manylinux' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -479,6 +530,7 @@ jobs: cibw_ft: 'true' os: 'ubuntu-latest' - name: 'py313ft-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py313ft-ubuntu-aarch64-musllinux' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -488,6 +540,7 @@ jobs: cibw_ft: 'true' os: 'ubuntu-latest' - name: 'py313ft-nocov (windows/AMD64)' + artifact: 'py313ft-windows-AMD64' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'x64-freethreaded' @@ -497,6 +550,7 @@ jobs: cibw_ft: 'true' os: 'windows-latest' - name: 'py313ft-nocov (macos/arm64)' + artifact: 'py313ft-macos-arm64' python: '3.13ft' toxpython: 'python3.13ft' python_arch: 'arm64-freethreaded' @@ -506,6 +560,7 @@ jobs: cibw_ft: 'true' os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' + artifact: 'pypy39-ubuntu-x86_64' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'x64' @@ -515,6 +570,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'pypy39-cover (windows/AMD64)' + artifact: 'pypy39-windows-AMD64' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'x64' @@ -524,6 +580,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'pypy39-cover (macos/arm64)' + artifact: 'pypy39-macos-arm64' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'arm64' @@ -533,6 +590,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'pypy39-nocov (ubuntu/x86_64/manylinux)' + artifact: 'pypy39-ubuntu-x86_64-manylinux' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'x64' @@ -541,6 +599,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'pypy39-nocov (windows/AMD64)' + artifact: 'pypy39-windows-AMD64' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'x64' @@ -549,6 +608,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'pypy39-nocov (macos/arm64)' + artifact: 'pypy39-macos-arm64' python: 'pypy-3.9' toxpython: 'pypy3.9' python_arch: 'arm64' @@ -557,6 +617,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'pypy310-cover (ubuntu/x86_64)' + artifact: 'pypy310-ubuntu-x86_64' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'x64' @@ -566,6 +627,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'pypy310-cover (windows/AMD64)' + artifact: 'pypy310-windows-AMD64' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'x64' @@ -575,6 +637,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'pypy310-cover (macos/arm64)' + artifact: 'pypy310-macos-arm64' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'arm64' @@ -584,6 +647,7 @@ jobs: cibw_build: false os: 'macos-latest' - name: 'pypy310-nocov (ubuntu/x86_64/manylinux)' + artifact: 'pypy310-ubuntu-x86_64-manylinux' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'x64' @@ -592,6 +656,7 @@ jobs: cibw_build: false os: 'ubuntu-latest' - name: 'pypy310-nocov (windows/AMD64)' + artifact: 'pypy310-windows-AMD64' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'x64' @@ -600,6 +665,7 @@ jobs: cibw_build: false os: 'windows-latest' - name: 'pypy310-nocov (macos/arm64)' + artifact: 'pypy310-macos-arm64' python: 'pypy-3.10' toxpython: 'pypy3.10' python_arch: 'arm64' @@ -674,12 +740,16 @@ jobs: uses: actions/upload-artifact@v4 if: matrix.cibw_build with: + name: wheel-${{ matrix.artifact }} path: wheelhouse/*.whl finish: needs: test if: ${{ always() }} runs-on: ubuntu-latest steps: + - uses: actions/upload-artifact/merge@v4 + with: + name: wheels - uses: coverallsapp/github-action@v2 with: parallel-finished: true diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index f080595..ffa3f0b 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -43,6 +43,7 @@ jobs: {% set wheel_suffix = 'nocov' in env and wheel_arch.strip('*') %} {% set name_suffix = '/' + wheel_suffix if wheel_suffix else '' %} - name: '{{ env }} ({{ os }}/{{ cibw_arch }}{{ name_suffix }})' + artifact: '{{ env.rsplit('-', 1)[0] }}-{{ os }}-{{ cibw_arch }}{{ name_suffix.replace('/', '-') }}' python: '{{ python }}' toxpython: '{{ toxpython }}' python_arch: '{{ python_arch }}{% if nogil %}-freethreaded{% endif %}' @@ -128,15 +129,20 @@ jobs: uses: actions/upload-artifact@v4 if: matrix.cibw_build with: + name: {{ 'wheel-${{ matrix.artifact }}' }} path: wheelhouse/*.whl finish: needs: test if: {{ '${{ always() }}' }} runs-on: ubuntu-latest steps: + - uses: actions/upload-artifact/merge@v4 + with: + name: wheels - uses: coverallsapp/github-action@v2 with: parallel-finished: true - uses: codecov/codecov-action@v5 with: CODECOV_TOKEN: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %} + From 7090de850e22924ec5c31db5e2f4a870377f7219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 18:58:56 +0300 Subject: [PATCH 16/20] Fix some variables for freethread builds. --- .github/workflows/github-actions.yml | 102 +++++++++--------- .../.github/workflows/github-actions.yml | 4 +- tox.ini | 2 +- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 837c44c..4ff02db 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -469,94 +469,94 @@ jobs: cibw_build: 'cp313-*' cibw_ft: 'false' os: 'macos-latest' - - name: 'py313ft-cover (ubuntu/x86_64)' - artifact: 'py313ft-ubuntu-x86_64' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-cover (ubuntu/x86_64)' + artifact: 'py313-ft-ubuntu-x86_64' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-cover' + tox_env: 'py313-ft-cover' cover: true cibw_arch: 'x86_64' cibw_build: false os: 'ubuntu-latest' - - name: 'py313ft-cover (windows/AMD64)' - artifact: 'py313ft-windows-AMD64' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-cover (windows/AMD64)' + artifact: 'py313-ft-windows-AMD64' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-cover' + tox_env: 'py313-ft-cover' cover: true cibw_arch: 'AMD64' cibw_build: false os: 'windows-latest' - - name: 'py313ft-cover (macos/arm64)' - artifact: 'py313ft-macos-arm64' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-cover (macos/arm64)' + artifact: 'py313-ft-macos-arm64' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'arm64-freethreaded' - tox_env: 'py313ft-cover' + tox_env: 'py313-ft-cover' cover: true cibw_arch: 'arm64' cibw_build: false os: 'macos-latest' - - name: 'py313ft-nocov (ubuntu/x86_64/manylinux)' - artifact: 'py313ft-ubuntu-x86_64-manylinux' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (ubuntu/x86_64/manylinux)' + artifact: 'py313-ft-ubuntu-x86_64-manylinux' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'x86_64' - cibw_build: 'cp313ftt-*manylinux*' + cibw_build: 'cp313t-*manylinux*' cibw_ft: 'true' os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/x86_64/musllinux)' - artifact: 'py313ft-ubuntu-x86_64-musllinux' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (ubuntu/x86_64/musllinux)' + artifact: 'py313-ft-ubuntu-x86_64-musllinux' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'x86_64' - cibw_build: 'cp313ftt-*musllinux*' + cibw_build: 'cp313t-*musllinux*' cibw_ft: 'true' os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/aarch64/manylinux)' - artifact: 'py313ft-ubuntu-aarch64-manylinux' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (ubuntu/aarch64/manylinux)' + artifact: 'py313-ft-ubuntu-aarch64-manylinux' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'aarch64' - cibw_build: 'cp313ftt-*manylinux*' + cibw_build: 'cp313t-*manylinux*' cibw_ft: 'true' os: 'ubuntu-latest' - - name: 'py313ft-nocov (ubuntu/aarch64/musllinux)' - artifact: 'py313ft-ubuntu-aarch64-musllinux' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (ubuntu/aarch64/musllinux)' + artifact: 'py313-ft-ubuntu-aarch64-musllinux' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'aarch64' - cibw_build: 'cp313ftt-*musllinux*' + cibw_build: 'cp313t-*musllinux*' cibw_ft: 'true' os: 'ubuntu-latest' - - name: 'py313ft-nocov (windows/AMD64)' - artifact: 'py313ft-windows-AMD64' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (windows/AMD64)' + artifact: 'py313-ft-windows-AMD64' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'x64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'AMD64' - cibw_build: 'cp313ftt-*' + cibw_build: 'cp313t-*' cibw_ft: 'true' os: 'windows-latest' - - name: 'py313ft-nocov (macos/arm64)' - artifact: 'py313ft-macos-arm64' - python: '3.13ft' - toxpython: 'python3.13ft' + - name: 'py313-ft-nocov (macos/arm64)' + artifact: 'py313-ft-macos-arm64' + python: '3.13' + toxpython: 'python3.13t' python_arch: 'arm64-freethreaded' - tox_env: 'py313ft-nocov' + tox_env: 'py313-ft-nocov' cibw_arch: 'arm64' - cibw_build: 'cp313ftt-*' + cibw_build: 'cp313t-*' cibw_ft: 'true' os: 'macos-latest' - name: 'pypy39-cover (ubuntu/x86_64)' diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index ffa3f0b..84963c7 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -25,11 +25,11 @@ jobs: {% if prefix.startswith('pypy') %} {% set python %}pypy-{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% set cpython %}pp{{ prefix[4:5] }}{% endset %} -{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} +{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5:] }}{{ 't' if nogil else '' }}{% endset %} {% else %} {% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} {% set cpython %}cp{{ prefix[2:] }}{% endset %} -{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{{ 't' if nogil else '' }}{% endset %} {% endif %} {% for os, python_arch, cibw_arch, wheel_arch, include_cover in [ ['ubuntu', 'x64', 'x86_64', '*manylinux*', True], diff --git a/tox.ini b/tox.ini index d0c9ff8..dbe24b9 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,7 @@ envlist = clean, check, docs, - {py39,py310,py311,py312,py313,py313ft,pypy39,pypy310}-{cover,nocov}, + {py39,py310,py311,py312,py313,py313-ft,pypy39,pypy310}-{cover,nocov}, report ignore_basepython_conflict = true From b6ecdc9f92446fa1bd1ddb8b0ebb3adcc82d4294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 19:13:59 +0300 Subject: [PATCH 17/20] Twine not needed. --- ci/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/requirements.txt b/ci/requirements.txt index b4f1852..6226712 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -2,4 +2,3 @@ virtualenv>=16.6.0 pip>=19.1.1 setuptools>=18.0.1 tox -twine From a210b0c705bb01c139d6b3044319c54b84438a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 19:18:50 +0300 Subject: [PATCH 18/20] Workaround for twine being uninstalable on freethreaded (cryphtography bad) --- .github/workflows/github-actions.yml | 7 +++++-- ci/templates/.github/workflows/github-actions.yml | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 4ff02db..446b4da 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -734,8 +734,11 @@ jobs: verbose: true flags: ${{ matrix.tox_env }} - name: check wheel - if: matrix.cibw_build - run: twine check wheelhouse/*.whl + if: > + !matrix.cibw_ft && matrix.cibw_build + run: + python -mpip install --progress-bar=off twine + twine check wheelhouse/*.whl - name: upload wheel uses: actions/upload-artifact@v4 if: matrix.cibw_build diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index 84963c7..4b4c7a8 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -123,8 +123,11 @@ jobs: verbose: true flags: {{ '${{ matrix.tox_env }}' }} - name: check wheel - if: matrix.cibw_build - run: twine check wheelhouse/*.whl + if: > + !matrix.cibw_ft && matrix.cibw_build + run: + python -mpip install --progress-bar=off twine + twine check wheelhouse/*.whl - name: upload wheel uses: actions/upload-artifact@v4 if: matrix.cibw_build From 14330a1791fe37f643b133ddc781c1497bd88b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Wed, 16 Apr 2025 19:37:41 +0300 Subject: [PATCH 19/20] =?UTF-8?q?Bump=20version:=201.10.0=20=E2=86=92=201.?= =?UTF-8?q?11.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- .cookiecutterrc | 2 +- README.rst | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- src/lazy_object_proxy/__init__.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f4dedb1..2024805 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.10.0 +current_version = 1.11.0 commit = True tag = True diff --git a/.cookiecutterrc b/.cookiecutterrc index 1d621f1..94d8547 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -40,7 +40,7 @@ default_context: sphinx_theme: furo test_matrix_separate_coverage: 'yes' tests_inside_package: 'no' - version: 1.10.0 + version: 1.11.0 version_manager: bump2version website: https://blog.ionelmc.ro year_from: '2014' diff --git a/README.rst b/README.rst index e429753..43d6011 100644 --- a/README.rst +++ b/README.rst @@ -45,9 +45,9 @@ Overview :alt: Supported implementations :target: https://pypi.org/project/lazy-object-proxy -.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-lazy-object-proxy/v1.10.0.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-lazy-object-proxy/v1.11.0.svg :alt: Commits since latest release - :target: https://github.com/ionelmc/python-lazy-object-proxy/compare/v1.10.0...master + :target: https://github.com/ionelmc/python-lazy-object-proxy/compare/v1.11.0...master diff --git a/docs/conf.py b/docs/conf.py index 18f3f99..dfa64f0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,7 +23,7 @@ import traceback traceback.print_exc() - version = release = '1.10.0' + version = release = '1.11.0' pygments_style = 'trac' templates_path = ['.'] diff --git a/setup.py b/setup.py index fdfbd9a..2cd958f 100755 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ def read(*names, **kwargs): use_scm_version={ 'local_scheme': 'dirty-tag', 'write_to': 'src/lazy_object_proxy/_version.py', - 'fallback_version': '1.10.0', + 'fallback_version': '1.11.0', }, license='BSD-2-Clause', description='A fast and thorough lazy object proxy.', diff --git a/src/lazy_object_proxy/__init__.py b/src/lazy_object_proxy/__init__.py index 50b9cae..e91e6c2 100644 --- a/src/lazy_object_proxy/__init__.py +++ b/src/lazy_object_proxy/__init__.py @@ -18,6 +18,6 @@ try: from ._version import version as __version__ except ImportError: - __version__ = '1.10.0' + __version__ = '1.11.0' __all__ = ('Proxy',) From 58a13f326f9cab8be03c56c514e7347546537a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 15 Dec 2023 17:45:42 +0100 Subject: [PATCH 20/20] Support SETUPPY_FORCE_PURE in tests Support testing without the C extension if SETUPPY_FORCE_PURE is set. This makes the test suite behavior consistent with setup.py behavior. --- tests/conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1317faf..383289c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,4 @@ +import os import sys import pytest @@ -19,7 +20,7 @@ class FakeModule: try: from lazy_object_proxy.cext import Proxy except ImportError: - if PYPY: + if PYPY or os.environ.get('SETUPPY_FORCE_PURE'): pytest.skip(reason='C Extension not available.') else: raise