diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 0702313..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,150 +0,0 @@ -version: '{branch}-{build}' -build: off -image: Visual Studio 2019 -environment: - global: - TWINE_USERNAME: ionel - COVERALLS_EXTRAS: '-v' - COVERALLS_REPO_TOKEN: 6picUzuGNWKI5w3rsEyZGNvyMZ47Cz9hZ - matrix: - - TOXENV: check - TOXPYTHON: C:\Python36\python.exe - PYTHON_HOME: C:\Python36 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '32' - - TOXENV: py27-cover,codecov,coveralls - TOXPYTHON: C:\Python27\python.exe - PYTHON_HOME: C:\Python27 - PYTHON_VERSION: '2.7' - PYTHON_ARCH: '32' - - TOXENV: py27-cover,codecov,coveralls - TOXPYTHON: C:\Python27-x64\python.exe - PYTHON_HOME: C:\Python27-x64 - PYTHON_VERSION: '2.7' - PYTHON_ARCH: '64' - - TOXENV: py27-nocov - TOXPYTHON: C:\Python27\python.exe - PYTHON_HOME: C:\Python27 - PYTHON_VERSION: '2.7' - PYTHON_ARCH: '32' - WHEEL_PATH: .tox/dist - - TOXENV: py27-nocov - TOXPYTHON: C:\Python27-x64\python.exe - PYTHON_HOME: C:\Python27-x64 - PYTHON_VERSION: '2.7' - PYTHON_ARCH: '64' - WHEEL_PATH: .tox/dist - - TOXENV: py36-cover,codecov,coveralls - TOXPYTHON: C:\Python36\python.exe - PYTHON_HOME: C:\Python36 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '32' - - TOXENV: py36-cover,codecov,coveralls - TOXPYTHON: C:\Python36-x64\python.exe - PYTHON_HOME: C:\Python36-x64 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '64' - - TOXENV: py36-nocov - TOXPYTHON: C:\Python36\python.exe - PYTHON_HOME: C:\Python36 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '32' - WHEEL_PATH: .tox/dist - - TOXENV: py36-nocov - TOXPYTHON: C:\Python36-x64\python.exe - PYTHON_HOME: C:\Python36-x64 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '64' - WHEEL_PATH: .tox/dist - - TOXENV: py37-cover,codecov,coveralls - TOXPYTHON: C:\Python37\python.exe - PYTHON_HOME: C:\Python37 - PYTHON_VERSION: '3.7' - PYTHON_ARCH: '32' - - TOXENV: py37-cover,codecov,coveralls - TOXPYTHON: C:\Python37-x64\python.exe - PYTHON_HOME: C:\Python37-x64 - PYTHON_VERSION: '3.7' - PYTHON_ARCH: '64' - - TOXENV: py37-nocov - TOXPYTHON: C:\Python37\python.exe - PYTHON_HOME: C:\Python37 - PYTHON_VERSION: '3.7' - PYTHON_ARCH: '32' - WHEEL_PATH: .tox/dist - - TOXENV: py37-nocov - TOXPYTHON: C:\Python37-x64\python.exe - PYTHON_HOME: C:\Python37-x64 - PYTHON_VERSION: '3.7' - PYTHON_ARCH: '64' - WHEEL_PATH: .tox/dist - - TOXENV: py38-cover,codecov,coveralls - TOXPYTHON: C:\Python38\python.exe - PYTHON_HOME: C:\Python38 - PYTHON_VERSION: '3.8' - PYTHON_ARCH: '32' - - TOXENV: py38-cover,codecov,coveralls - TOXPYTHON: C:\Python38-x64\python.exe - PYTHON_HOME: C:\Python38-x64 - PYTHON_VERSION: '3.8' - PYTHON_ARCH: '64' - - TOXENV: py38-nocov - TOXPYTHON: C:\Python38\python.exe - PYTHON_HOME: C:\Python38 - PYTHON_VERSION: '3.8' - PYTHON_ARCH: '32' - WHEEL_PATH: .tox/dist - - TOXENV: py38-nocov - TOXPYTHON: C:\Python38-x64\python.exe - PYTHON_HOME: C:\Python38-x64 - PYTHON_VERSION: '3.8' - PYTHON_ARCH: '64' - WHEEL_PATH: .tox/dist - - TOXENV: py39-cover,codecov,coveralls - TOXPYTHON: C:\Python39\python.exe - PYTHON_HOME: C:\Python39 - PYTHON_VERSION: '3.9' - PYTHON_ARCH: '32' - - TOXENV: py39-cover,codecov,coveralls - TOXPYTHON: C:\Python39-x64\python.exe - PYTHON_HOME: C:\Python39-x64 - PYTHON_VERSION: '3.9' - PYTHON_ARCH: '64' - - TOXENV: py39-nocov - TOXPYTHON: C:\Python39\python.exe - PYTHON_HOME: C:\Python39 - PYTHON_VERSION: '3.9' - PYTHON_ARCH: '32' - WHEEL_PATH: .tox/dist - - TOXENV: py39-nocov - TOXPYTHON: C:\Python39-x64\python.exe - PYTHON_HOME: C:\Python39-x64 - PYTHON_VERSION: '3.9' - PYTHON_ARCH: '64' - WHEEL_PATH: .tox/dist -init: - - ps: echo $env:TOXENV - - ps: ls C:\Python* -install: - - '%PYTHON_HOME%\python -mpip install --progress-bar=off -rci/requirements.txt' - - '%PYTHON_HOME%\Scripts\virtualenv --version' - - '%PYTHON_HOME%\Scripts\pip --version' - - '%PYTHON_HOME%\Scripts\tox --version' -test_script: - - ps: | - Set-PSDebug -Trace 1 - $ErrorActionPreference = "Stop" - if ($Env:WHEEL_PATH) { - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd $Env:PYTHON_HOME\Scripts\tox --wheel - iex "$Env:PYTHON_HOME\Scripts\twine check $Env:WHEEL_PATH/*.whl" - iex "$Env:PYTHON_HOME\Scripts\twine upload --repository-url https://test.pypi.org/legacy/ --skip-existing $Env:WHEEL_PATH/*.whl" - } else { - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd $Env:PYTHON_HOME\Scripts\tox - } -on_failure: - - ps: dir "env:" - - ps: get-content .tox\*\log\* - -### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): -# on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 9609bf6..f04971d 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.6.0 +current_version = 1.7.0 commit = True tag = True @@ -7,10 +7,14 @@ tag = True search = 'fallback_version': '{current_version}' replace = 'fallback_version': '{new_version}' -[bumpversion:file:README.rst] +[bumpversion:file (badge):README.rst] search = /v{current_version}.svg replace = /v{new_version}.svg +[bumpversion:file (link):README.rst] +search = /v{current_version}...master +replace = /v{new_version}...master + [bumpversion:file:docs/conf.py] search = version = release = '{current_version}' replace = version = release = '{new_version}' @@ -18,4 +22,3 @@ replace = version = release = '{new_version}' [bumpversion:file:src/lazy_object_proxy/__init__.py] search = __version__ = '{current_version}' replace = __version__ = '{new_version}' - diff --git a/.cookiecutterrc b/.cookiecutterrc index 4ceb3e2..0957031 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -2,7 +2,7 @@ default_context: allow_tests_inside_package: no - appveyor: yes + appveyor: no c_extension_function: '-' c_extension_module: '-' c_extension_optional: yes @@ -16,11 +16,11 @@ default_context: command_line_interface: no command_line_interface_bin_name: '-' coveralls: yes - coveralls_token: 6picUzuGNWKI5w3rsEyZGNvyMZ47Cz9hZ distribution_name: lazy-object-proxy email: contact@ionelmc.ro full_name: Ionel Cristian Mărieș - legacy_python: yes + github_actions: yes + legacy_python: no license: BSD 2-Clause License linter: flake8 package_name: lazy_object_proxy @@ -29,9 +29,10 @@ default_context: project_short_description: A fast and thorough lazy object proxy. pypi_badge: yes pypi_disable_upload: no - release_date: '2020-11-26' + release_date: '2021-03-22' repo_hosting: github.com repo_hosting_domain: github.com + repo_main_branch: master repo_name: python-lazy-object-proxy repo_username: ionelmc requiresio: yes @@ -45,9 +46,10 @@ default_context: test_matrix_configurator: no test_matrix_separate_coverage: yes test_runner: pytest - travis: yes - travis_osx: yes - version: 1.5.2 + travis: no + travis_osx: no + version: 1.6.0 + version_manager: bump2version website: https://blog.ionelmc.ro year_from: '2014' year_to: '2021' diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 0000000..28a4b2c --- /dev/null +++ b/.github/workflows/github-actions.yml @@ -0,0 +1,573 @@ +name: build +on: [push, pull_request] +jobs: + test: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' + - name: 'py36-cover (ubuntu/x86_64)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py36-cover (windows/AMD64)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-cover,codecov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py36-cover (macos/x86_64)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'py36-nocov (ubuntu/x86_64/manylinux)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp36-*manylinux*' + os: 'ubuntu-latest' + - name: 'py36-nocov (ubuntu/x86_64/musllinux)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp36-*musllinux*' + os: 'ubuntu-latest' + - name: 'py36-nocov (ubuntu/aarch64/manylinux)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp36-*manylinux*' + os: 'ubuntu-latest' + - name: 'py36-nocov (ubuntu/aarch64/musllinux)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp36-*musllinux*' + os: 'ubuntu-latest' + - name: 'py36-nocov (windows/AMD64)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp36-*' + os: 'windows-latest' + - name: 'py36-nocov (windows/x86)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x86' + tox_env: 'py36-nocov' + cibw_arch: 'x86' + cibw_build: 'cp36-*' + os: 'windows-latest' + - name: 'py36-nocov (macos/x86_64)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp36-*' + os: 'macos-latest' + - name: 'py37-cover (ubuntu/x86_64)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py37-cover (windows/AMD64)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-cover,codecov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py37-cover (macos/x86_64)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'py37-nocov (ubuntu/x86_64/manylinux)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp37-*manylinux*' + os: 'ubuntu-latest' + - name: 'py37-nocov (ubuntu/x86_64/musllinux)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp37-*musllinux*' + os: 'ubuntu-latest' + - name: 'py37-nocov (ubuntu/aarch64/manylinux)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp37-*manylinux*' + os: 'ubuntu-latest' + - name: 'py37-nocov (ubuntu/aarch64/musllinux)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp37-*musllinux*' + os: 'ubuntu-latest' + - name: 'py37-nocov (windows/AMD64)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp37-*' + os: 'windows-latest' + - name: 'py37-nocov (windows/x86)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x86' + tox_env: 'py37-nocov' + cibw_arch: 'x86' + cibw_build: 'cp37-*' + os: 'windows-latest' + - name: 'py37-nocov (macos/x86_64)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp37-*' + os: 'macos-latest' + - name: 'py38-cover (ubuntu/x86_64)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38-cover,codecov' + 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,codecov' + 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,codecov' + 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' + python_arch: 'x64' + tox_env: 'py39-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py39-cover (windows/AMD64)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-cover,codecov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py39-cover (macos/x86_64)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'py39-nocov (ubuntu/x86_64/manylinux)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp39-*manylinux*' + os: 'ubuntu-latest' + - name: 'py39-nocov (ubuntu/x86_64/musllinux)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp39-*musllinux*' + os: 'ubuntu-latest' + - name: 'py39-nocov (ubuntu/aarch64/manylinux)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp39-*manylinux*' + os: 'ubuntu-latest' + - name: 'py39-nocov (ubuntu/aarch64/musllinux)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp39-*musllinux*' + os: 'ubuntu-latest' + - name: 'py39-nocov (windows/AMD64)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp39-*' + os: 'windows-latest' + - name: 'py39-nocov (windows/x86)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x86' + 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_build: 'cp39-*' + os: 'macos-latest' + - name: 'py310-cover (ubuntu/x86_64)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'py310-cover (windows/AMD64)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-cover,codecov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'py310-cover (macos/x86_64)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'py310-nocov (ubuntu/x86_64/manylinux)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp310-*manylinux*' + os: 'ubuntu-latest' + - name: 'py310-nocov (ubuntu/x86_64/musllinux)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-nocov' + cibw_arch: 'x86_64' + cibw_build: 'cp310-*musllinux*' + os: 'ubuntu-latest' + - name: 'py310-nocov (ubuntu/aarch64/manylinux)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp310-*manylinux*' + os: 'ubuntu-latest' + - name: 'py310-nocov (ubuntu/aarch64/musllinux)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-nocov' + cibw_arch: 'aarch64' + cibw_build: 'cp310-*musllinux*' + os: 'ubuntu-latest' + - name: 'py310-nocov (windows/AMD64)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310-nocov' + cibw_arch: 'AMD64' + cibw_build: 'cp310-*' + os: 'windows-latest' + - name: 'py310-nocov (windows/x86)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x86' + 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_build: 'cp310-*' + os: 'macos-latest' + - name: 'pypy37-cover (ubuntu/x86_64)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'pypy37-cover (windows/AMD64)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-cover,codecov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'pypy37-cover (macos/x86_64)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-cover,codecov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'pypy37-nocov (ubuntu/x86_64/manylinux)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-nocov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'ubuntu-latest' + - name: 'pypy37-nocov (windows/AMD64)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-nocov' + cibw_arch: 'AMD64' + cibw_build: false + os: 'windows-latest' + - name: 'pypy37-nocov (macos/x86_64)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37-nocov' + cibw_arch: 'x86_64' + cibw_build: false + os: 'macos-latest' + - name: 'pypy38-cover (ubuntu/x86_64)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38-cover,codecov' + 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,codecov' + 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,codecov' + 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' + steps: + - uses: docker/setup-qemu-action@v1 + if: matrix.cibw_arch == 'aarch64' + with: + platforms: arm64 + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + architecture: ${{ matrix.python_arch }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off twine tox cibuildwheel -r ci/requirements.txt + virtualenv --version + 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 + env: + TOXPYTHON: '${{ matrix.toxpython }}' + CIBW_ARCHS: '${{ matrix.cibw_arch }}' + CIBW_BUILD: '${{ matrix.cibw_build }}' + CIBW_BUILD_VERBOSITY: '3' + CIBW_TEST_REQUIRES: > + tox + tox-direct + CIBW_TEST_COMMAND: > + cd {project} && + tox --skip-pkg-install --direct-yolo -e ${{ matrix.tox_env }} -v + CIBW_TEST_COMMAND_WINDOWS: > + cd /d {project} && + tox --skip-pkg-install --direct-yolo -e ${{ matrix.tox_env }} -v + - name: regular build and test + env: + TOXPYTHON: '${{ matrix.toxpython }}' + if: > + !matrix.cibw_build + run: > + tox -e ${{ matrix.tox_env }} -v + - name: check wheel + if: matrix.cibw_build + run: twine check wheelhouse/*.whl + - name: upload wheel + uses: actions/upload-artifact@v2 + if: matrix.cibw_build + with: + path: wheelhouse/*.whl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6e974cb..ae2be47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,16 +5,16 @@ exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: master + rev: v4.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: debug-statements - repo: https://github.com/timothycrosley/isort - rev: master + rev: 5.9.3 hooks: - id: isort - repo: https://gitlab.com/pycqa/flake8 - rev: master + rev: 3.9.2 hooks: - id: flake8 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a83cd57..0000000 --- a/.travis.yml +++ /dev/null @@ -1,165 +0,0 @@ -language: python -dist: xenial -virt: lxd -cache: false -env: - global: - - LD_PRELOAD=libSegFault.so - - SEGFAULT_SIGNALS=all - - LANG=en_US.UTF-8 - - TWINE_USERNAME=ionel -matrix: - include: - - python: '3.6' - env: - - TOXENV=check - - python: '3.6' - env: - - TOXENV=docs - - os: osx - osx_image: xcode11 - language: generic - env: - - TOXENV=py27-cover - - env: - - TOXENV=py27-cover,codecov,extension-coveralls,coveralls - python: '2.7' - arch: arm64 - - env: - - TOXENV=py27-cover,codecov,extension-coveralls,coveralls - python: '2.7' - arch: amd64 - - os: osx - osx_image: xcode11 - language: generic - env: - - TOXENV=py27-nocov - - WHEEL_PATH=.tox/dist - - env: - - TOXENV=py27-nocov - - WHEEL_MANYLINUX="1 cp27" - python: '2.7' - arch: amd64 - - env: - - TOXENV=py36-cover,codecov,extension-coveralls,coveralls - python: '3.6' - arch: arm64 - - env: - - TOXENV=py36-cover,codecov,extension-coveralls,coveralls - python: '3.6' - arch: amd64 - - env: - - TOXENV=py36-nocov - - WHEEL_MANYLINUX="2014-arm cp36" - python: '3.6' - arch: arm64 - - env: - - TOXENV=py36-nocov - - WHEEL_MANYLINUX="1 cp36" - python: '3.6' - arch: amd64 - - env: - - TOXENV=py37-cover,codecov,extension-coveralls,coveralls - python: '3.7' - arch: arm64 - - env: - - TOXENV=py37-cover,codecov,extension-coveralls,coveralls - python: '3.7' - arch: amd64 - - env: - - TOXENV=py37-nocov - - WHEEL_MANYLINUX="2014-arm cp37" - python: '3.7' - arch: arm64 - - env: - - TOXENV=py37-nocov - - WHEEL_MANYLINUX="1 cp37" - python: '3.7' - arch: amd64 - - env: - - TOXENV=py38-cover,codecov,extension-coveralls,coveralls - python: '3.8' - arch: arm64 - - env: - - TOXENV=py38-cover,codecov,extension-coveralls,coveralls - python: '3.8' - arch: amd64 - - env: - - TOXENV=py38-nocov - - WHEEL_MANYLINUX="2014-arm cp38" - python: '3.8' - arch: arm64 - - env: - - TOXENV=py38-nocov - - WHEEL_MANYLINUX="1 cp38" - python: '3.8' - arch: amd64 - - os: osx - osx_image: xcode11 - language: generic - env: - - TOXENV=py39-cover - - env: - - TOXENV=py39-cover,codecov,extension-coveralls,coveralls - python: '3.9' - arch: arm64 - - env: - - TOXENV=py39-cover,codecov,extension-coveralls,coveralls - python: '3.9' - arch: amd64 - - os: osx - osx_image: xcode11 - language: generic - env: - - TOXENV=py39-nocov - - WHEEL_PATH=.tox/dist - - env: - - TOXENV=py39-nocov - - WHEEL_MANYLINUX="2014-arm cp39" - python: '3.9' - arch: arm64 - - env: - - TOXENV=py39-nocov - - WHEEL_MANYLINUX="1 cp39" - python: '3.9' - arch: amd64 -before_install: - - python --version - - uname -a - - lsb_release -a || true - - | - if [[ $TRAVIS_OS_NAME == 'osx' ]]; then - brew update-reset - [[ $TOXENV =~ py3 ]] && brew upgrade python - [[ $TOXENV =~ py2 ]] && brew install python@2 - export PATH="/usr/local/opt/python/libexec/bin:${PATH}" - fi -install: - - python -mpip uninstall virtualenv --yes - - python -mpip uninstall virtualenv --yes - - python -mpip install --progress-bar=off --upgrade --ignore-installed -rci/requirements.txt - - virtualenv --version - - pip --version - - tox --version -script: - - | - ( - set -eux - if [[ -n ${WHEEL_MANYLINUX:-} ]]; then - docker run --rm --user $UID -v $(pwd):/code ionelmc/manylinux:manylinux$WHEEL_MANYLINUX - tox --installpkg wheelhouse/*.whl -v - export WHEEL_PATH=wheelhouse - else - tox -v - fi - if [[ -n ${WHEEL_PATH:-} ]]; then - twine upload --repository-url https://test.pypi.org/legacy/ --skip-existing $WHEEL_PATH/*.whl - fi - ) -after_failure: - - cat .tox/log/* - - cat .tox/*/log/* -notifications: - email: - on_success: never - on_failure: always diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 20ad4b2..2918eac 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,19 @@ Changelog ========= +1.7.0 (2021-12-15) +------------------ + +* Switched CI to GitHub Actions, this has a couple consequences: + + * Support for Python 2.7 is dropped. You can still install it there but it's not tested anymore and + Python 2 specific handling will be removed at some point. + * Linux wheels are now provided in `musllinux` and `manylinux2014` variants. + +* Fixed ``__index__`` to fallback to ``int`` if the wrapped object doesn't have an ``__index__`` method. + This prevents situations where code using a proxy would otherwise likely just call ``int`` had the object + not have an ``__index__`` method. + 1.6.0 (2021-03-22) ------------------ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 74587c9..99f0ea4 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -68,16 +68,12 @@ If you need some code review or feedback while you're developing the code just m For merging, you should: -1. Include passing tests (run ``tox``) [1]_. +1. Include passing tests (run ``tox``). 2. Update documentation when there's new API, functionality etc. 3. Add a note to ``CHANGELOG.rst`` about the changes. 4. Add yourself to ``AUTHORS.rst``. -.. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will - `run the tests `_ - for each change you add in the pull request. - It will be slower though ... Tips ---- diff --git a/README.rst b/README.rst index 8e70976..196e115 100644 --- a/README.rst +++ b/README.rst @@ -10,22 +10,18 @@ Overview * - docs - |docs| * - tests - - | |travis| |appveyor| |requires| + - | |github-actions| |requires| | |coveralls| |codecov| * - package - | |version| |wheel| |supported-versions| |supported-implementations| | |commits-since| .. |docs| image:: https://readthedocs.org/projects/python-lazy-object-proxy/badge/?style=flat - :target: https://readthedocs.org/projects/python-lazy-object-proxy + :target: https://python-lazy-object-proxy.readthedocs.io/ :alt: Documentation Status -.. |travis| image:: https://api.travis-ci.com/ionelmc/python-lazy-object-proxy.svg?branch=master - :alt: Travis-CI Build Status - :target: https://travis-ci.com/github/ionelmc/python-lazy-object-proxy - -.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/ionelmc/python-lazy-object-proxy?branch=master&svg=true - :alt: AppVeyor Build Status - :target: https://ci.appveyor.com/project/ionelmc/python-lazy-object-proxy +.. |github-actions| image:: https://github.com/ionelmc/python-lazy-object-proxy/actions/workflows/github-actions.yml/badge.svg + :alt: GitHub Actions Build Status + :target: https://github.com/ionelmc/python-lazy-object-proxy/actions .. |requires| image:: https://requires.io/github/ionelmc/python-lazy-object-proxy/requirements.svg?branch=master :alt: Requirements Status @@ -55,9 +51,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.6.0.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-lazy-object-proxy/v1.7.0.svg :alt: Commits since latest release - :target: https://github.com/ionelmc/python-lazy-object-proxy/compare/v1.5.2...master + :target: https://github.com/ionelmc/python-lazy-object-proxy/compare/v1.7.0...master diff --git a/ci/appveyor-download.py b/ci/appveyor-download.py deleted file mode 100755 index 440b422..0000000 --- a/ci/appveyor-download.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -""" -Use the AppVeyor API to download Windows artifacts. - -Taken from: https://bitbucket.org/ned/coveragepy/src/tip/ci/download_appveyor.py -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt -""" -from __future__ import unicode_literals - -import argparse -import os -import zipfile - -import requests - - -def make_auth_headers(): - """Make the authentication headers needed to use the Appveyor API.""" - path = os.path.expanduser("~/.appveyor.token") - if not os.path.exists(path): - raise RuntimeError( - "Please create a file named `.appveyor.token` in your home directory. " - "You can get the token from https://ci.appveyor.com/api-token" - ) - with open(path) as f: - token = f.read().strip() - - headers = { - 'Authorization': 'Bearer {}'.format(token), - } - return headers - - -def download_latest_artifacts(account_project, build_id): - """Download all the artifacts from the latest build.""" - if build_id is None: - url = "https://ci.appveyor.com/api/projects/{}".format(account_project) - else: - url = "https://ci.appveyor.com/api/projects/{}/build/{}".format(account_project, build_id) - build = requests.get(url, headers=make_auth_headers()).json() - jobs = build['build']['jobs'] - print(u"Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs))) - - for job in jobs: - name = job['name'] - print(u" {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job)) - - url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts".format(job['jobId']) - response = requests.get(url, headers=make_auth_headers()) - artifacts = response.json() - - for artifact in artifacts: - is_zip = artifact['type'] == "Zip" - filename = artifact['fileName'] - print(u" {0}, {1} bytes".format(filename, artifact['size'])) - - url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts/{}".format(job['jobId'], filename) - download_url(url, filename, make_auth_headers()) - - if is_zip: - unpack_zipfile(filename) - os.remove(filename) - - -def ensure_dirs(filename): - """Make sure the directories exist for `filename`.""" - dirname = os.path.dirname(filename) - if dirname and not os.path.exists(dirname): - os.makedirs(dirname) - - -def download_url(url, filename, headers): - """Download a file from `url` to `filename`.""" - ensure_dirs(filename) - response = requests.get(url, headers=headers, stream=True) - if response.status_code == 200: - with open(filename, 'wb') as f: - for chunk in response.iter_content(16 * 1024): - f.write(chunk) - else: - print(u" Error downloading {}: {}".format(url, response)) - - -def unpack_zipfile(filename): - """Unpack a zipfile, using the names in the zip.""" - with open(filename, 'rb') as fzip: - z = zipfile.ZipFile(fzip) - for name in z.namelist(): - print(u" extracting {}".format(name)) - ensure_dirs(name) - z.extract(name) - - -parser = argparse.ArgumentParser(description='Download artifacts from AppVeyor.') -parser.add_argument('--id', - metavar='PROJECT_ID', - default='ionelmc/python-lazy-object-proxy', - help='Project ID in AppVeyor.') -parser.add_argument('build', - nargs='?', - metavar='BUILD_ID', - help='Build ID in AppVeyor. Eg: master-123') - -if __name__ == "__main__": - # import logging - # logging.basicConfig(level="DEBUG") - args = parser.parse_args() - download_latest_artifacts(args.id, args.build) diff --git a/ci/appveyor-with-compiler.cmd b/ci/appveyor-with-compiler.cmd deleted file mode 100644 index 5093538..0000000 --- a/ci/appveyor-with-compiler.cmd +++ /dev/null @@ -1,12 +0,0 @@ -SET COMMAND_TO_RUN=%* - -IF "%PYTHON_VERSION%"=="2.7" GOTO legacy -GOTO main - -:legacy -powershell -Command "Invoke-WebRequest https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi -OutFile VCForPython27.msi" -msiexec /i VCForPython27.msi /quiet /qn /norestart - -:main -ECHO Executing: %COMMAND_TO_RUN% -CALL %COMMAND_TO_RUN% || EXIT 1 diff --git a/ci/bootstrap.py b/ci/bootstrap.py index 2eb7723..323a44c 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -11,8 +11,10 @@ from os.path import dirname from os.path import exists from os.path import join +from os.path import relpath base_path = dirname(dirname(abspath(__file__))) +templates_path = join(base_path, "ci", "templates") def check_call(args): @@ -54,7 +56,7 @@ def main(): print("Project path: {0}".format(base_path)) jinja = jinja2.Environment( - loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), + loader=jinja2.FileSystemLoader(templates_path), trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True @@ -71,10 +73,12 @@ def main(): ] tox_environments = [line for line in tox_environments if line.startswith('py')] - for name in os.listdir(join("ci", "templates")): - with open(join(base_path, name), "w") as fh: - fh.write(jinja.get_template(name).render(tox_environments=tox_environments)) - print("Wrote {}".format(name)) + for root, _, files in os.walk(templates_path): + for name in files: + relative = relpath(root, templates_path) + with open(join(base_path, relative, name), "w") as fh: + fh.write(jinja.get_template(join(relative, name)).render(tox_environments=tox_environments)) + print("Wrote {}".format(name)) print("DONE.") diff --git a/ci/requirements.txt b/ci/requirements.txt index b8aff6a..d99ac18 100644 --- a/ci/requirements.txt +++ b/ci/requirements.txt @@ -1,7 +1,4 @@ -virtualenv>=16.6.0 +virtualenv>=20.4.7 pip>=19.1.1 setuptools>=18.0.1 six>=1.14.0 -importlib-metadata>=1.0 -twine -tox-wheel diff --git a/ci/templates/.appveyor.yml b/ci/templates/.appveyor.yml deleted file mode 100644 index ff8e339..0000000 --- a/ci/templates/.appveyor.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: '{branch}-{build}' -build: off -image: Visual Studio 2019 -environment: - global: - TWINE_USERNAME: ionel - COVERALLS_EXTRAS: '-v' - COVERALLS_REPO_TOKEN: 6picUzuGNWKI5w3rsEyZGNvyMZ47Cz9hZ - matrix: - - TOXENV: check - TOXPYTHON: C:\Python36\python.exe - PYTHON_HOME: C:\Python36 - PYTHON_VERSION: '3.6' - PYTHON_ARCH: '32' -{% for env in tox_environments %} -{% if env.startswith(('py2', 'py3')) %} - - TOXENV: {{ env }}{% if env.endswith('-cover') %},codecov,coveralls{% endif %}{{ "" }} - TOXPYTHON: C:\Python{{ env[2:4] }}\python.exe - PYTHON_HOME: C:\Python{{ env[2:4] }} - PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' - PYTHON_ARCH: '32' -{% if 'nocov' in env %} - WHEEL_PATH: .tox/dist -{% endif %} - - TOXENV: {{ env }}{% if env.endswith('-cover') %},codecov,coveralls{% endif %}{{ "" }} - TOXPYTHON: C:\Python{{ env[2:4] }}-x64\python.exe - PYTHON_HOME: C:\Python{{ env[2:4] }}-x64 - PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' - PYTHON_ARCH: '64' -{% if 'nocov' in env %} - WHEEL_PATH: .tox/dist -{% endif %} -{% endif %}{% endfor %} -init: - - ps: echo $env:TOXENV - - ps: ls C:\Python* -install: - - '%PYTHON_HOME%\python -mpip install --progress-bar=off -rci/requirements.txt' - - '%PYTHON_HOME%\Scripts\virtualenv --version' - - '%PYTHON_HOME%\Scripts\pip --version' - - '%PYTHON_HOME%\Scripts\tox --version' -test_script: - - ps: | - Set-PSDebug -Trace 1 - $ErrorActionPreference = "Stop" - if ($Env:WHEEL_PATH) { - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd $Env:PYTHON_HOME\Scripts\tox --wheel - iex "$Env:PYTHON_HOME\Scripts\twine check $Env:WHEEL_PATH/*.whl" - iex "$Env:PYTHON_HOME\Scripts\twine upload --repository-url https://test.pypi.org/legacy/ --skip-existing $Env:WHEEL_PATH/*.whl" - } else { - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd $Env:PYTHON_HOME\Scripts\tox - } -on_failure: - - ps: dir "env:" - - ps: get-content .tox\*\log\* - -### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): -# on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml new file mode 100644 index 0000000..5cd4146 --- /dev/null +++ b/ci/templates/.github/workflows/github-actions.yml @@ -0,0 +1,115 @@ +name: build +on: [push, pull_request] +jobs: + test: + name: {{ '${{ matrix.name }}' }} + runs-on: {{ '${{ matrix.os }}' }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' +{% for env in tox_environments %} +{% set prefix = env.split('-')[0] -%} +{% 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 %} +{% else %} +{% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% set cpython %}cp{{ prefix[2:] }}{% endset %} +{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% endif %} +{% for os, python_arch, cibw_arch, wheel_arch, include_cover in [ + ['ubuntu', 'x64', 'x86_64', '*manylinux*', True], + ['ubuntu', 'x64', 'x86_64', '*musllinux*', False], + ['ubuntu', 'x64', 'aarch64', '*manylinux*', False], + ['ubuntu', 'x64', 'aarch64', '*musllinux*', False], + ['windows', 'x64', 'AMD64', '*', True], + ['windows', 'x86', 'x86', '*', False], + ['macos', 'x64', 'x86_64', '*', True], +] %} +{% if include_cover or ('nocov' in env and not prefix.startswith('pypy')) %} +{% 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 }})' + python: '{{ python }}' + toxpython: '{{ toxpython }}' + python_arch: '{{ python_arch }}' + tox_env: '{{ env }}{% if 'cover' in env %},codecov{% endif %}' + cibw_arch: '{{ cibw_arch }}' +{% if 'nocov' in env and not prefix.startswith('pypy') %} + cibw_build: '{{ cpython }}-{{ wheel_arch }}' +{% else %} + cibw_build: false +{% endif %} + os: '{{ os }}-latest' +{% endif %} +{% endfor %} +{% endfor %} + steps: + - uses: docker/setup-qemu-action@v1 + if: matrix.cibw_arch == 'aarch64' + with: + platforms: arm64 + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: {{ '${{ matrix.python }}' }} + architecture: {{ '${{ matrix.python_arch }}' }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off twine tox cibuildwheel -r ci/requirements.txt + virtualenv --version + 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 + env: + TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' + CIBW_ARCHS: '{{ '${{ matrix.cibw_arch }}' }}' + CIBW_BUILD: '{{ '${{ matrix.cibw_build }}' }}' + CIBW_BUILD_VERBOSITY: '3' + CIBW_TEST_REQUIRES: > + tox + tox-direct + CIBW_TEST_COMMAND: > + cd {project} && + tox --skip-pkg-install --direct-yolo -e {{ '${{ matrix.tox_env }}' }} -v + CIBW_TEST_COMMAND_WINDOWS: > + cd /d {project} && + tox --skip-pkg-install --direct-yolo -e {{ '${{ matrix.tox_env }}' }} -v + - name: regular build and test + env: + TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' + if: > + !matrix.cibw_build + run: > + tox -e {{ '${{ matrix.tox_env }}' }} -v + - name: check wheel + if: matrix.cibw_build + run: twine check wheelhouse/*.whl + - name: upload wheel + uses: actions/upload-artifact@v2 + if: matrix.cibw_build + with: + path: wheelhouse/*.whl diff --git a/ci/templates/.travis.yml b/ci/templates/.travis.yml deleted file mode 100644 index 80afcea..0000000 --- a/ci/templates/.travis.yml +++ /dev/null @@ -1,88 +0,0 @@ -language: python -dist: xenial -virt: lxd -cache: false -env: - global: - - LD_PRELOAD=libSegFault.so - - SEGFAULT_SIGNALS=all - - LANG=en_US.UTF-8 - - TWINE_USERNAME=ionel -matrix: - include: - - python: '3.6' - env: - - TOXENV=check - - python: '3.6' - env: - - TOXENV=docs -{%- for env in tox_environments %}{{ '' }} -{%- if 'py39' in env or 'py27' in env %}{{ '' }} - - os: osx - osx_image: xcode11 - language: generic - env: - - TOXENV={{ env }} -{%- if 'nocov' in env %}{{ '' }} - - WHEEL_PATH=.tox/dist -{%- endif %} -{%- endif %}{{ '' }} -{%- for arch in ['arm64', 'amd64'] %}{{ '' }} -{%- if 'pypy' not in env and (arch == 'amd64' or env.startswith('py3') or 'cover' in env) %}{{ '' }} - - env: - - TOXENV={{ env }}{% if 'cover' in env %},codecov,extension-coveralls,coveralls{% endif %} -{%- if 'pypy' not in env and 'nocov' in env %}{{ '' }} - - WHEEL_MANYLINUX="{% if arch == 'arm64' %}2014-arm{% else %}1{% endif %}{{ '' }} cp{{ env.split('-')[0][2:] }}" -{%- endif %} -{%- if env.startswith('pypy3') %}{{ '' }} - - TOXPYTHON=pypy3 - python: 'pypy3' -{%- elif env.startswith('pypy') %}{{ '' }} - python: 'pypy' -{%- else %}{{ '' }} - python: '{{ '{0[2]}.{0[3]}'.format(env) }}' -{%- endif %}{{ '' }} - arch: {{ arch }} -{%- endif %}{{ '' }} -{%- endfor %}{{ '' }} -{%- endfor %}{{ '' }} -before_install: - - python --version - - uname -a - - lsb_release -a || true - - | - if [[ $TRAVIS_OS_NAME == 'osx' ]]; then - brew update-reset - [[ $TOXENV =~ py3 ]] && brew upgrade python - [[ $TOXENV =~ py2 ]] && brew install python@2 - export PATH="/usr/local/opt/python/libexec/bin:${PATH}" - fi -install: - - python -mpip uninstall virtualenv --yes - - python -mpip uninstall virtualenv --yes - - python -mpip install --progress-bar=off --upgrade --ignore-installed -rci/requirements.txt - - virtualenv --version - - pip --version - - tox --version -script: - - | - ( - set -eux - if [[ -n ${WHEEL_MANYLINUX:-} ]]; then - docker run --rm --user $UID -v $(pwd):/code ionelmc/manylinux:manylinux$WHEEL_MANYLINUX - tox --installpkg wheelhouse/*.whl -v - export WHEEL_PATH=wheelhouse - else - tox -v - fi - if [[ -n ${WHEEL_PATH:-} ]]; then - twine upload --repository-url https://test.pypi.org/legacy/ --skip-existing $WHEEL_PATH/*.whl - fi - ) -after_failure: - - cat .tox/log/* - - cat .tox/*/log/* -notifications: - email: - on_success: never - on_failure: always diff --git a/docs/conf.py b/docs/conf.py index 0e01416..94e09ff 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,7 @@ version = release = get_distribution('lazy_object_proxy').version except Exception: traceback.print_exc() - version = release = '1.6.0' + version = release = '1.7.0' pygments_style = 'trac' templates_path = ['.'] @@ -45,7 +45,7 @@ html_last_updated_fmt = '%b %d, %Y' html_split_index = False html_sidebars = { - '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], + '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], } html_short_title = '%s-%s' % (project, version) diff --git a/pyproject.toml b/pyproject.toml index e69394c..23cf6d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,5 +2,5 @@ requires = [ "setuptools>=30.3.0", "wheel", - "setuptools_scm>=3.3.1,<6.0", + "setuptools_scm>=3.3.1", ] diff --git a/setup.cfg b/setup.cfg index bae99d7..d55819a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [options] setup_requires = - setuptools_scm>=3.3.1,<6.0 + setuptools_scm>=3.3.1 [flake8] max-line-length = 140 diff --git a/setup.py b/setup.py index 40a7fd5..9038ce2 100755 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ import os import platform import re +import sys from glob import glob from os.path import basename from os.path import dirname @@ -18,6 +19,7 @@ from setuptools import find_packages from setuptools import setup from setuptools.command.build_ext import build_ext +from setuptools.dist import Distribution # Enable code coverage for C code: we can't use CFLAGS=-coverage in tox.ini, since that may mess with compiling # dependencies (e.g. numpy). Therefore we set SETUPPY_CFLAGS=-coverage in tox.ini and copy it to CFLAGS here (after @@ -30,7 +32,7 @@ LFLAGS = '' -class optional_build_ext(build_ext): +class OptionalBuildExt(build_ext): """Allow the building of C extensions to fail.""" def run(self): try: @@ -62,12 +64,18 @@ def read(*names, **kwargs): return fh.read() +class BinaryDistribution(Distribution): + """Distribution which almost always forces a binary package with platform name""" + def has_ext_modules(self): + return super().has_ext_modules() or 'SETUP_PY_ALLOW_PURE' not in os.environ + + setup( name='lazy-object-proxy', use_scm_version={ 'local_scheme': 'dirty-tag', 'write_to': 'src/lazy_object_proxy/_version.py', - 'fallback_version': '1.6.0', + 'fallback_version': '1.7.0', }, license='BSD-2-Clause', description='A fast and thorough lazy object proxy.', @@ -92,12 +100,12 @@ def read(*names, **kwargs): 'Operating System :: POSIX', 'Operating System :: Microsoft :: Windows', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', # uncomment if you test on these interpreters: @@ -123,8 +131,8 @@ def read(*names, **kwargs): # 'rst': ['docutils>=0.11'], # ':python_version=="2.6"': ['argparse'], }, - cmdclass={'build_ext': optional_build_ext}, - ext_modules=[ + cmdclass={'build_ext': OptionalBuildExt}, + ext_modules=[] if hasattr(sys, 'pypy_version_info') else [ Extension( splitext(relpath(path, 'src').replace(os.sep, '.'))[0], sources=[path], @@ -135,4 +143,5 @@ def read(*names, **kwargs): for root, _, _ in os.walk('src') for path in glob(join(root, '*.c')) ], + distclass=BinaryDistribution, ) diff --git a/src/lazy_object_proxy/__init__.py b/src/lazy_object_proxy/__init__.py index db37c85..2de91cf 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.6.0' + __version__ = '1.7.0' __all__ = "Proxy", diff --git a/src/lazy_object_proxy/simple.py b/src/lazy_object_proxy/simple.py index ea5cf8a..724998d 100644 --- a/src/lazy_object_proxy/simple.py +++ b/src/lazy_object_proxy/simple.py @@ -233,7 +233,13 @@ def __ror__(self, other): __float__ = make_proxy_method(float) __oct__ = make_proxy_method(oct) __hex__ = make_proxy_method(hex) - __index__ = make_proxy_method(operator.index) + + def __index__(self): + if hasattr(self.__wrapped__, '__index__'): + return operator.index(self.__wrapped__) + else: + return int(self.__wrapped__) + __len__ = make_proxy_method(len) __contains__ = make_proxy_method(operator.contains) __getitem__ = make_proxy_method(operator.getitem) diff --git a/src/lazy_object_proxy/slots.py b/src/lazy_object_proxy/slots.py index 41cee25..24d2f7e 100644 --- a/src/lazy_object_proxy/slots.py +++ b/src/lazy_object_proxy/slots.py @@ -392,7 +392,10 @@ def __hex__(self): return hex(self.__wrapped__) def __index__(self): - return operator.index(self.__wrapped__) + if hasattr(self.__wrapped__, '__index__'): + return operator.index(self.__wrapped__) + else: + return int(self.__wrapped__) def __len__(self): return len(self.__wrapped__) diff --git a/tests/test_async_py3.py b/tests/test_async_py3.py index dba934f..8ca24e1 100644 --- a/tests/test_async_py3.py +++ b/tests/test_async_py3.py @@ -12,6 +12,8 @@ from lazy_object_proxy.utils import await_ +pypyxfail = pytest.mark.xfail('hasattr(sys, "pypy_version_info")') + class AsyncYieldFrom: def __init__(self, obj): @@ -256,9 +258,12 @@ async def func(): pass # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly # initialized assert '__await__' in dir(coro) - assert '__iter__' in dir(coro.__await__()) - assert 'coroutine_wrapper' in str(coro.__await__()) - coro.close() # avoid RuntimeWarning + awaitable = coro.__await__() + assert '__iter__' in dir(awaitable) + assert 'coroutine_wrapper' in str(awaitable) + # avoid RuntimeWarnings + awaitable.close() + coro.close() def test_func_12(lop): @@ -825,6 +830,7 @@ async def func(): run_async(lop.Proxy(func)) +@pypyxfail def test_with_6(lop): class CM: def __aenter__(self): @@ -843,6 +849,7 @@ async def foo(): run_async(lop.Proxy(foo)) +@pypyxfail def test_with_7(lop): class CM: async def __aenter__(self): @@ -867,6 +874,7 @@ async def foo(): pytest.fail('invalid asynchronous context manager did not fail') +@pypyxfail def test_with_8(lop): CNT = 0 @@ -1112,6 +1120,7 @@ async def test3(): ['what?', 'end'] +@pypyxfail def test_for_2(lop): tup = (1, 2, 3) refs_before = sys.getrefcount(tup) @@ -1126,6 +1135,7 @@ async def foo(): assert sys.getrefcount(tup) == refs_before +@pypyxfail def test_for_3(lop): class I: def __aiter__(self): @@ -1144,6 +1154,7 @@ async def foo(): assert sys.getrefcount(aiter) == refs_before +@pypyxfail def test_for_4(lop): class I: def __aiter__(self): @@ -1165,6 +1176,7 @@ async def foo(): assert sys.getrefcount(aiter) == refs_before +@pypyxfail def test_for_6(lop): I = 0 diff --git a/tests/test_lazy_object_proxy.py b/tests/test_lazy_object_proxy.py index 8bd3532..60555de 100644 --- a/tests/test_lazy_object_proxy.py +++ b/tests/test_lazy_object_proxy.py @@ -1,11 +1,11 @@ from __future__ import print_function import gc -import imp import os import pickle import platform import sys +import types import weakref from datetime import date from datetime import datetime @@ -31,7 +31,7 @@ def target(): pass """ -objects = imp.new_module('objects') +objects = types.ModuleType('objects') exec_(OBJECTS_CODE, objects.__dict__, objects.__dict__) diff --git a/tox.ini b/tox.ini index 35ab862..a4a33a3 100644 --- a/tox.ini +++ b/tox.ini @@ -15,19 +15,21 @@ envlist = clean, check, docs, - {py27,py36,py37,py38,py39,pypy,pypy3}-{cover,nocov}, + {py36,py37,py38,py39,py310,pypy37,pypy38}-{cover,nocov}, report ignore_basepython_conflict = true [testenv] basepython = pypy: {env:TOXPYTHON:pypy} - pypy3: {env:TOXPYTHON:pypy3} + pypy37: {env:TOXPYTHON:pypy3.7} + pypy38: {env:TOXPYTHON:pypy3.8} py27: {env:TOXPYTHON:python2.7} py36: {env:TOXPYTHON:python3.6} py37: {env:TOXPYTHON:python3.7} py38: {env:TOXPYTHON:python3.8} py39: {env:TOXPYTHON:python3.9} + py310: {env:TOXPYTHON:python3.10} {bootstrap,clean,check,report,docs,codecov,coveralls,extension-coveralls}: {env:TOXPYTHON:python3} setenv = PYTHONPATH={toxinidir}/tests @@ -44,7 +46,6 @@ wheel = deps = pytest pytest-benchmark - pytest-travis-fold Django objproxies==0.9.4 hunter