diff options
author | Michael Howitz <mh@gocept.com> | 2021-08-30 10:13:24 +0200 |
---|---|---|
committer | Michael Howitz <mh@gocept.com> | 2021-08-30 10:13:24 +0200 |
commit | a30909b918595d41936b3bf3d549be2becd99f1d (patch) | |
tree | efe93f9eb24005c42cdcc2f5195e0c213011926e | |
parent | 347d187367a4d96f4b9ba70c4a5f9aa4efa6197c (diff) | |
download | zope-security-a30909b918595d41936b3bf3d549be2becd99f1d.tar.gz |
Configuring for c-code
-rw-r--r-- | .coveragerc | 26 | ||||
-rw-r--r-- | .editorconfig | 39 | ||||
-rw-r--r-- | .github/workflows/tests.yml | 450 | ||||
-rw-r--r-- | .gitignore | 40 | ||||
-rwxr-xr-x | .manylinux-install.sh | 34 | ||||
-rwxr-xr-x | .manylinux.sh | 13 | ||||
-rw-r--r-- | .meta.toml | 62 | ||||
-rw-r--r-- | .travis.yml | 121 | ||||
-rw-r--r-- | MANIFEST.in | 19 | ||||
-rw-r--r-- | appveyor.yml | 42 | ||||
-rw-r--r-- | bootstrap.py | 210 | ||||
-rw-r--r-- | setup.cfg | 30 | ||||
-rw-r--r-- | tox.ini | 76 |
13 files changed, 744 insertions, 418 deletions
diff --git a/.coveragerc b/.coveragerc index 6bd02c1..54c7a9d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,13 +1,29 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code [run] source = zope.security -omit = */flycheck_*.py +# New in 5.0; required for the GHA coveralls submission. +relative_files = True +branch = true + +[paths] +source = + src/ + .tox/*/lib/python*/site-packages/ + .tox/pypy*/site-packages/ [report] +show_missing = true precision = 2 exclude_lines = - pragma: no cover - pragma NO COVER + except ImportError: if __name__ == '__main__': - raise NotImplementedError - self.fail + pragma: no cover + pragma: nocover raise AssertionError + raise NotImplementedError + raise unittest.Skip + self.fail\( + +[html] +directory = parts/htmlcov diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9d3c4f2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,39 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code +# +# EditorConfig Configuration file, for more details see: +# http://EditorConfig.org +# EditorConfig is a convention description, that could be interpreted +# by multiple editors to enforce common coding conventions for specific +# file types + +# top-most EditorConfig file: +# Will ignore other EditorConfig files in Home directory or upper tree level. +root = true + + +[*] # For All Files +# Unix-style newlines with a newline ending every file +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +# Set default charset +charset = utf-8 +# Indent style default +indent_style = space +# Max Line Length - a hard line wrap, should be disabled +max_line_length = off + +[*.{py,cfg,ini}] +# 4 space indentation +indent_size = 4 + +[*.{yml,zpt,pt,dtml,zcml}] +# 2 space indentation +indent_size = 2 + +[{Makefile,.gitmodules}] +# Tab indentation (no size specified, but view as 4 spaces) +indent_style = tab +indent_size = unset +tab_width = unset diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..3422aa2 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,450 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code +### +# Initially copied from +# https://github.com/actions/starter-workflows/blob/main/ci/python-package.yml +# And later based on the version jamadden updated at +# gevent/gevent, and then at zodb/relstorage and zodb/perfmetrics +# +# Original comment follows. +### +### +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions +### + +### +# Important notes on GitHub actions: +# +# - We only get 2,000 free minutes a month (private repos) +# - We only get 500MB of artifact storage +# - Cache storage is limited to 7 days and 5GB. +# - macOS minutes are 10x as expensive as Linux minutes +# - windows minutes are twice as expensive. +# +# So keep those workflows light. Note: Currently, they seem to be free +# and unlimited for open source projects. But for how long... +# +# In December 2020, github only supports x86/64. If we wanted to test +# on other architectures, we can use docker emulation, but there's no +# native support. It works, but is slow. +# +# Another major downside: You can't just re-run the job for one part +# of the matrix. So if there's a transient test failure that hit, say, 3.8, +# to get a clean run every version of Python runs again. That's bad. +# https://github.community/t/ability-to-rerun-just-a-single-job-in-a-workflow/17234/65 + +name: tests + + +# Triggers the workflow on push or pull request events and periodically +on: + push: + pull_request: + schedule: + - cron: '0 12 * * 0' # run once a week on Sunday + # Allow to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + # Weirdly, this has to be a top-level key, not ``defaults.env`` + PYTHONHASHSEED: 8675309 + PYTHONUNBUFFERED: 1 + PYTHONDONTWRITEBYTECODE: 1 + PYTHONDEVMODE: 1 + PYTHONFAULTHANDLER: 1 + ZOPE_INTERFACE_STRICT_IRO: 1 + + PIP_UPGRADE_STRATEGY: eager + # Don't get warnings about Python 2 support being deprecated. We + # know. The env var works for pip 20. + PIP_NO_PYTHON_VERSION_WARNING: 1 + PIP_NO_WARN_SCRIPT_LOCATION: 1 + + CFLAGS: -Ofast -pipe + CXXFLAGS: -Ofast -pipe + # Uploading built wheels for releases. + # TWINE_PASSWORD is encrypted and stored directly in the + # github repo settings. + TWINE_USERNAME: __token__ + + ### + # caching + # This is where we'd set up ccache, but this compiles so fast its not worth it. + ### + + +jobs: + # Because sharing code/steps is so hard, and because it can be + # extremely valuable to be able to get binary wheels without + # uploading to PyPI and even if there is some failure, (e.g., for + # other people to test/debug), the strategy is to divide the process + # into several different jobs. The first builds and saves the binary + # wheels. It has dependent jobs that download and install the wheel + # to run tests, build docs, and perform linting. Building the + # manylinux wheels is an independent set of jobs. + # + # This division is time-saving for projects that take awhile to + # build, but somewhat less of a clear-cut win given how quick this + # is to compile (at least at this writing). + build-package: + # Sigh. Note that the matrix must be kept in sync + # with `test`, and `docs` must use a subset. + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: + - 2.7 + - 3.5 + - pypy-2.7 + - pypy-3.6 + - 3.6 + - 3.7 + - 3.8 + - 3.9 + os: [ubuntu-20.04, macos-latest] + exclude: + - os: macos-latest + python-version: pypy-2.7 + - os: macos-latest + python-version: pypy-3.6 + - os: macos-latest + python-version: 3.5 + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + ### + # Caching. + # This actually *restores* a cache and schedules a cleanup action + # to save the cache. So it must come before the thing we want to use + # the cache. + ### + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install Build Dependencies + run: | + pip install -U pip + pip install -U setuptools wheel twine cffi + pip install -U coveralls coverage + + - name: Build zope.security + run: | + # Next, build the wheel *in place*. This helps ccache, and also lets us cache the configure + # output (pip install uses a random temporary directory, making this difficult). + python setup.py build_ext -i + python setup.py bdist_wheel + # Also install it, so that we get dependencies in the (pip) cache. + pip install -U coverage + pip install -U 'faulthandler; python_version == "2.7" and platform_python_implementation == "CPython"' + pip install .[test] + + - name: Check zope.security build + run: | + ls -l dist + twine check dist/* + - name: Upload zope.security wheel + uses: actions/upload-artifact@v2 + with: + name: zope.security-${{ runner.os }}-${{ matrix.python-version }}.whl + path: dist/*whl + - name: Publish package to PyPI (mac) + # We cannot 'uses: pypa/gh-action-pypi-publish@v1.4.1' because + # that's apparently a container action, and those don't run on + # the Mac. + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && startsWith(runner.os, 'Mac') + env: + TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} + run: | + twine upload --skip-existing dist/* + + test: + needs: build-package + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: + - 2.7 + - 3.5 + - pypy-2.7 + - pypy-3.6 + - 3.6 + - 3.7 + - 3.8 + - 3.9 + os: [ubuntu-20.04, macos-latest] + exclude: + - os: macos-latest + python-version: pypy-2.7 + - os: macos-latest + python-version: pypy-3.6 + - os: macos-latest + python-version: 3.5 + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + ### + # Caching. + # This actually *restores* a cache and schedules a cleanup action + # to save the cache. So it must come before the thing we want to use + # the cache. + ### + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Download zope.security wheel + uses: actions/download-artifact@v2 + with: + name: zope.security-${{ runner.os }}-${{ matrix.python-version }}.whl + path: dist/ + - name: Install zope.security + run: | + pip install -U wheel + pip install -U coverage coverage-python-version + pip install -U 'faulthandler; python_version == "2.7" and platform_python_implementation == "CPython"' + # Unzip into src/ so that testrunner can find the .so files + # when we ask it to load tests from that directory. This + # might also save some build time? + unzip -n dist/zope.security-*whl -d src + pip install -U -e .[test] + - name: Run tests with C extensions + if: ${{ !startsWith(matrix.python-version, 'pypy') }} + run: | + python -m coverage run -p -m zope.testrunner --test-path=src --auto-color --auto-progress + - name: Run tests without C extensions + run: + # coverage makes PyPy run about 3x slower! + PURE_PYTHON=1 python -m coverage run -p -m zope.testrunner --test-path=src --auto-color --auto-progress + - name: Report Coverage + run: | + coverage combine + coverage report -i + - name: Submit to Coveralls + # This is a container action, which only runs on Linux. + if: ${{ startsWith(runner.os, 'Linux') }} + uses: AndreMiras/coveralls-python-action@develop + with: + parallel: true + + coveralls_finish: + needs: test + runs-on: ubuntu-20.04 + steps: + - name: Coveralls Finished + uses: AndreMiras/coveralls-python-action@develop + with: + parallel-finished: true + + docs: + needs: build-package + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [3.9] + os: [ubuntu-20.04] + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + ### + # Caching. + # This actually *restores* a cache and schedules a cleanup action + # to save the cache. So it must come before the thing we want to use + # the cache. + ### + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Download zope.security wheel + uses: actions/download-artifact@v2 + with: + name: zope.security-${{ runner.os }}-${{ matrix.python-version }}.whl + path: dist/ + - name: Install zope.security + run: | + pip install -U wheel + pip install -U coverage + pip install -U "`ls dist/zope.security-*.whl`[docs]" + # Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it: + pip install -U "Sphinx < 4" + - name: Build docs + env: + ZOPE_INTERFACE_STRICT_IRO: 1 + run: | + sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html + sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest + + lint: + needs: build-package + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [3.9] + os: [ubuntu-20.04] + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + ### + # Caching. + # This actually *restores* a cache and schedules a cleanup action + # to save the cache. So it must come before the thing we want to use + # the cache. + ### + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Download zope.security wheel + uses: actions/download-artifact@v2 + with: + name: zope.security-${{ runner.os }}-${{ matrix.python-version }}.whl + path: dist/ + - name: Install zope.security + run: | + pip install -U pip + pip install -U wheel + pip install -U `ls dist/zope.security-*`[test] + - name: Lint + # We only need to do this on one version, and it should be Python 3, because + # pylint has stopped updating for Python 2. + # TODO: Pick a linter and configuration and make this step right. + run: | + pip install -U pylint + # python -m pylint --limit-inference-results=1 --rcfile=.pylintrc zope.security -f parseable -r n + + manylinux: + runs-on: ubuntu-20.04 + # We use a regular Python matrix entry to share as much code as possible. + strategy: + matrix: + python-version: [3.9] + image: [manylinux2010_x86_64, manylinux2010_i686, manylinux2014_aarch64] + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + ### + # Caching. + # This actually *restores* a cache and schedules a cleanup action + # to save the cache. So it must come before the thing we want to use + # the cache. + ### + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip_manylinux-${{ matrix.image }}-${{ matrix.python-version }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Update pip + run: pip install -U pip + - name: Build zope.security (x86_64) + if: matrix.image == 'manylinux2010_x86_64' + # An alternate way to do this is to run the container directly with a uses: + # and then the script runs inside it. That may work better with caching. + # See https://github.com/pyca/bcrypt/blob/f6b5ee2eda76d077c531362ac65e16f045cf1f29/.github/workflows/wheel-builder.yml + # The 2010 image is the most recent spec that comes with Python 2.7, + # and only up through the tag 2021-02-06-3d322a5 + env: + DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} + run: | + bash .manylinux.sh + - name: Build zope.security (i686) + if: matrix.image == 'manylinux2010_i686' + env: + DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} + PRE_CMD: linux32 + run: | + bash .manylinux.sh + - name: Build zope.security (aarch64) + if: matrix.image == 'manylinux2014_aarch64' + env: + DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} + run: | + # First we must enable emulation + docker run --rm --privileged hypriot/qemu-register + bash .manylinux.sh + + - name: Upload zope.security wheels + uses: actions/upload-artifact@v2 + with: + path: wheelhouse/*whl + name: manylinux_${{ matrix.image }}_wheels.zip + - name: Restore pip cache permissions + run: sudo chown -R $(whoami) ${{ steps.pip-cache.outputs.dir }} + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@v1.4.1 + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + with: + user: __token__ + password: ${{ secrets.TWINE_PASSWORD }} + skip_existing: true + packages_dir: wheelhouse/ @@ -1,19 +1,31 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code +*.dll +*.egg-info/ +*.profraw *.pyc *.pyo *.so -__pycache__ -*.egg -*.egg-info -build -docs/_build -.installed.cfg -bin -develop-eggs -eggs -parts -.tox .coverage -nosetests.xml +.coverage.* +.eggs/ +.installed.cfg +.mr.developer.cfg +.tox/ +.vscode/ +__pycache__/ +bin/ +build/ coverage.xml -.eggs -htmlcov/ +develop-eggs/ +develop/ +dist/ +docs/_build +eggs/ +etc/ +lib/ +lib64 +log/ +parts/ +pyvenv.cfg +var/ diff --git a/.manylinux-install.sh b/.manylinux-install.sh index f82f0c4..6972cae 100755 --- a/.manylinux-install.sh +++ b/.manylinux-install.sh @@ -1,17 +1,47 @@ #!/usr/bin/env bash +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code set -e -x +# Running inside docker +# Set a cache directory for pip. This was +# mounted to be the same as it is outside docker so it +# can be persisted. +export XDG_CACHE_HOME="/cache" +# XXX: This works for macOS, where everything bind-mounted +# is seen as owned by root in the container. But when the host is Linux +# the actual UIDs come through to the container, triggering +# pip to disable the cache when it detects that the owner doesn't match. +# The below is an attempt to fix that, taken from bcrypt. It seems to work on +# Github Actions. +if [ -n "$GITHUB_ACTIONS" ]; then + echo Adjusting pip cache permissions + mkdir -p $XDG_CACHE_HOME/pip + chown -R $(whoami) $XDG_CACHE_HOME +fi +ls -ld /cache +ls -ld /cache/pip + +# We need some libraries because we build wheels from scratch: +yum -y install libffi-devel + # Compile wheels for PYBIN in /opt/python/*/bin; do if [[ "${PYBIN}" == *"cp27"* ]] || \ [[ "${PYBIN}" == *"cp35"* ]] || \ [[ "${PYBIN}" == *"cp36"* ]] || \ [[ "${PYBIN}" == *"cp37"* ]] || \ - [[ "${PYBIN}" == *"cp38"* ]]; then - "${PYBIN}/pip" install -U pip setuptools cffi + [[ "${PYBIN}" == *"cp38"* ]] || \ + [[ "${PYBIN}" == *"cp39"* ]]; then "${PYBIN}/pip" install -e /io/ "${PYBIN}/pip" wheel /io/ -w wheelhouse/ + if [ `uname -m` == 'aarch64' ]; then + cd /io/ + "${PYBIN}/pip" install tox + "${PYBIN}/tox" -e py + cd .. + fi rm -rf /io/build /io/*.egg-info fi done diff --git a/.manylinux.sh b/.manylinux.sh index 2fed778..ea4ef41 100755 --- a/.manylinux.sh +++ b/.manylinux.sh @@ -1,5 +1,16 @@ #!/usr/bin/env bash +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code set -e -x -docker run --rm -v "$(pwd)":/io $DOCKER_IMAGE $PRE_CMD /io/.manylinux-install.sh +# Mount the current directory as /io +# Mount the pip cache directory as /cache +# `pip cache` requires pip 20.1 +echo Setting up caching +python --version +python -mpip --version +LCACHE="$(dirname `python -mpip cache dir`)" +echo Sharing pip cache at $LCACHE $(ls -ld $LCACHE) + +docker run --rm -e GITHUB_ACTIONS -v "$(pwd)":/io -v "$LCACHE:/cache" $DOCKER_IMAGE $PRE_CMD /io/.manylinux-install.sh diff --git a/.meta.toml b/.meta.toml new file mode 100644 index 0000000..b851644 --- /dev/null +++ b/.meta.toml @@ -0,0 +1,62 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code +[meta] +template = "c-code" +commit-id = "81a3fca06e30c8fba7256352591a7a298d676a41" + +[python] +with-appveyor = true +with-windows = false +with-pypy = true +with-future-python = false +with-legacy-python = true +with-docs = true +with-sphinx-doctests = true + +[tox] +use-flake8 = true +additional-envlist = [ + "py27-watch, py37-watch", + ] +testenv-setenv = [ + "ZOPE_INTERFACE_STRICT_IRO=1", + "watch: ZOPE_WATCH_CHECKERS = 1", + ] + +[coverage] +fail-under = 99.5 + +[manifest] +additional-rules = [ + "include *.sh", + "recursive-include docs *.bat", + "recursive-include src *.zcml", + ] + +[check-manifest] +additional-ignores = [ + "docs/_build/html/_sources/api/*", + ] + +[flake8] +additional-config = [ + "# F401 imported but unused", + "per-file-ignores =", + " src/zope/security/__init__.py: F401", + ] + +[github-actions] +additional-config = [ + "- [\"2.7\", \"py27-watch\"]", + "- [\"3.7\", \"py37-watch\"]", + ] + +[appveyor] +global-env-vars = [ + "# Currently the builds use @mgedmin's Appveyor account. The PyPI token belongs", + "# to zope.wheelbuilder, which is managed by @mgedmin and @dataflake.", + "TWINE_USERNAME: __token__", + "TWINE_PASSWORD:", + " secure: aoZC/+rvJKg8B5GMGIxd1YDPcIbo2kSsckCbQ6o8fhIRqSyuhX1iLm21hgDEkq2ePuyQ7+cWnNvXGactxjzA4iUS5GCOuF/E6YTvS3nGcuoQuH607wn2hngzz1p4Z+5ClFPx27vZiRAFgBoTbIo8XODHC9qFYluZ68eiwxFOiCuXK9ONEjMn8LjoaNSPJYyJO3Wr8W5oLeYG+wGcNGuYVXEk5/LSDg5n17ujpL7qsVTdVNjTwgmtnv191n2ip1Sgh1O5Xm9eG7VDZSxr/xNMpw==", + "ZOPE_INTERFACE_STRICT_IRO: 1", + ] diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7cb9c7f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,121 +0,0 @@ -language: python - -env: - global: - TWINE_USERNAME: zope.wheelbuilder - TWINE_PASSWORD: - secure: "U6CeZtNEPDN3qKXfrLcvHFLrowqNWxmapXLWygZRxKgfR+ypowe1Y0a4kCBEBZKtysbY26MmIkrMV07tEMxny1yUWVCvRvUaQw0Ic3t5CM0R019zjVh9fQUTdWGCwri86Qj/OaeuPeMR0LCr6d9nMSun0GWSWhjOUhkTCdchfQw=" - ZOPE_INTERFACE_STRICT_IRO: 1 - -python: - - 2.7 - - 3.5 - - 3.6 - - 3.7 - - 3.8 - - pypy - - pypy3 - -matrix: - include: - - - name: "Python: 2.7, pure (no C extensions), with ZOPE_WATCH_CHECKERS enabled" - python: "2.7" - env: PURE_PYTHON=1 ZOPE_WATCH_CHECKERS=1 - - - name: "Python: 3.7, with ZOPE_WATCH_CHECKERS enabled" - python: 3.7 - env: ZOPE_WATCH_CHECKERS=1 - - - name: "Python: 3.7, pure (no C extensions)" - python: 3.7 - env: PURE_PYTHON=1 - - # manylinux wheel builds - - name: 64-bit manylinux wheels (all Pythons) - services: docker - env: DOCKER_IMAGE=quay.io/pypa/manylinux2010_x86_64 - install: docker pull $DOCKER_IMAGE - script: bash .manylinux.sh - - - name: 32-bit manylinux wheels (all Pythons) - services: docker - env: DOCKER_IMAGE=quay.io/pypa/manylinux2010_i686 PRE_CMD=linux32 - install: docker pull $DOCKER_IMAGE - script: bash .manylinux.sh - - # It's important to use 'macpython' builds to get the least - # restrictive wheel tag. It's also important to avoid - # 'homebrew 3' because it floats instead of being a specific version. - - name: Python 2.7 wheels for MacOS - os: osx - language: generic - env: TERRYFY_PYTHON='macpython 2.7.17' - - name: Python 3.5 wheels for MacOS - os: osx - language: generic - env: TERRYFY_PYTHON='macpython 3.5' - - name: Python 3.6 wheels for MacOS - os: osx - language: generic - env: TERRYFY_PYTHON='macpython 3.6.2' - - name: Python 3.7 wheels for MacOS - os: osx - language: generic - env: TERRYFY_PYTHON='macpython 3.7.0' - - name: Python 3.8 wheels for MacOS - os: osx - language: generic - env: TERRYFY_PYTHON='macpython 3.8.0' - -before_install: - - | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - git clone https://github.com/MacPython/terryfy - source terryfy/travis_tools.sh - get_python_environment $TERRYFY_PYTHON venv - fi - -install: - - python -m pip install -U pip setuptools - - python -m pip install -U coveralls coverage - # pip install zope.proxy here because because setup_requires will use - # easy_install, which fails on Python 3.5 on Mac OS - - python -m pip install -U zope.proxy - - python -m pip install -U -e .[test,docs] - -script: - - python --version - - python -m coverage run -m zope.testrunner --test-path=src - - python -m coverage run -a -m sphinx -b doctest -d docs/_build/doctrees docs docs/_build/doctest - - python setup.py bdist_wheel - -after_success: - - python -m coveralls - - | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - # macpython 3.5 doesn't support recent TLS protocols which causes twine - # upload to fail, so we use the system Python to run twine - /usr/bin/python -m ensurepip --user - /usr/bin/python -m pip install --user -U pip - /usr/bin/python -m pip install --user -U -I twine - /usr/bin/python -m twine check dist/* - if [[ $TRAVIS_TAG ]]; then - /usr/bin/python -m twine upload --skip-existing dist/* - fi - fi - - | - if [[ -n "$DOCKER_IMAGE" ]]; then - pip install twine - twine check wheelhouse/* - if [[ $TRAVIS_TAG ]]; then - twine upload --skip-existing wheelhouse/* - fi - fi - -notifications: - email: false - -cache: pip -before_cache: - - rm -f $HOME/.cache/pip/log/debug.log diff --git a/MANIFEST.in b/MANIFEST.in index 3db8c41..327514d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,17 +1,18 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code include *.rst include *.txt -include *.py -include .coveragerc -include appveyor.yml -include .travis.yml -include tox.ini include buildout.cfg -include *.sh -recursive-include docs *.bat +include tox.ini +include appveyor.yml +include .coveragerc + recursive-include docs *.py recursive-include docs *.rst +recursive-include docs *.txt recursive-include docs Makefile + recursive-include src *.py +include *.sh +recursive-include docs *.bat recursive-include src *.zcml - -prune docs/_static diff --git a/appveyor.yml b/appveyor.yml index 532f6dd..9816396 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,12 @@ -# Currently the builds use @mgedmin's Appveyor account. The PyPI token belongs -# to zope.wheelbuilder, which is managed by @mgedmin and @dataflake. - +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code environment: - global: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: - secure: aoZC/+rvJKg8B5GMGIxd1YDPcIbo2kSsckCbQ6o8fhIRqSyuhX1iLm21hgDEkq2ePuyQ7+cWnNvXGactxjzA4iUS5GCOuF/E6YTvS3nGcuoQuH607wn2hngzz1p4Z+5ClFPx27vZiRAFgBoTbIo8XODHC9qFYluZ68eiwxFOiCuXK9ONEjMn8LjoaNSPJYyJO3Wr8W5oLeYG+wGcNGuYVXEk5/LSDg5n17ujpL7qsVTdVNjTwgmtnv191n2ip1Sgh1O5Xm9eG7VDZSxr/xNMpw== + # Currently the builds use @mgedmin's Appveyor account. The PyPI token belongs + # to zope.wheelbuilder, which is managed by @mgedmin and @dataflake. + TWINE_USERNAME: __token__ + TWINE_PASSWORD: + secure: aoZC/+rvJKg8B5GMGIxd1YDPcIbo2kSsckCbQ6o8fhIRqSyuhX1iLm21hgDEkq2ePuyQ7+cWnNvXGactxjzA4iUS5GCOuF/E6YTvS3nGcuoQuH607wn2hngzz1p4Z+5ClFPx27vZiRAFgBoTbIo8XODHC9qFYluZ68eiwxFOiCuXK9ONEjMn8LjoaNSPJYyJO3Wr8W5oLeYG+wGcNGuYVXEk5/LSDg5n17ujpL7qsVTdVNjTwgmtnv191n2ip1Sgh1O5Xm9eG7VDZSxr/xNMpw== + ZOPE_INTERFACE_STRICT_IRO: 1 matrix: - python: 27 @@ -18,10 +19,11 @@ environment: - python: 37-x64 - python: 38 - python: 38-x64 - - { python: 27, PURE_PYTHON: 1 } - - { python: 37, PURE_PYTHON: 1 } + - python: 39 + - python: 39-x64 install: + - "SET PYTHONVERSION=%PYTHON%" - "SET PATH=C:\\Python%PYTHON%;c:\\Python%PYTHON%\\scripts;%PATH%" - ps: | $env:PYTHON = "C:\\Python${env:PYTHON}" @@ -31,31 +33,23 @@ install: } - ps: if (-not (Test-Path $env:PYTHON)) { throw "No $env:PYTHON" } - echo "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 > "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -# We need to install the C extensions that BTrees setup-requires -# separately because we've seen problems with the BTrees build cleanup step trying -# to delete a .pyd that was still open. - python -m pip install -U pip - - pip install -U setuptools - - pip install -U persistent - - pip install -U BTrees - - pip install -U zope.testrunner - - pip install -U .[test] + - pip install -U setuptools wheel + - pip install -U -e .[test] + +matrix: + fast_finish: true build_script: - - pip install wheel - python -W ignore setup.py -q bdist_wheel test_script: - - python -m zope.testrunner --test-path=src - -on_success: - - echo Build succesful! - + - zope-testrunner --test-path=src artifacts: - path: 'dist\*.whl' name: wheel deploy_script: - - ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE -and $env:PURE_PYTHON -ne 1) { pip install twine; twine upload --skip-existing dist/* } + - ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE) { pip install twine; twine upload --skip-existing dist\*.whl } deploy: on diff --git a/bootstrap.py b/bootstrap.py deleted file mode 100644 index a459921..0000000 --- a/bootstrap.py +++ /dev/null @@ -1,210 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 Zope Foundation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Bootstrap a buildout-based project - -Simply run this script in a directory containing a buildout.cfg. -The script accepts buildout command-line options, so you can -use the -c option to specify an alternate configuration file. -""" - -import os -import shutil -import sys -import tempfile - -from optparse import OptionParser - -__version__ = '2015-07-01' -# See zc.buildout's changelog if this version is up to date. - -tmpeggs = tempfile.mkdtemp(prefix='bootstrap-') - -usage = '''\ -[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] - -Bootstraps a buildout-based project. - -Simply run this script in a directory containing a buildout.cfg, using the -Python that you want bin/buildout to use. - -Note that by using --find-links to point to local resources, you can keep -this script from going over the network. -''' - -parser = OptionParser(usage=usage) -parser.add_option("--version", - action="store_true", default=False, - help=("Return bootstrap.py version.")) -parser.add_option("-t", "--accept-buildout-test-releases", - dest='accept_buildout_test_releases', - action="store_true", default=False, - help=("Normally, if you do not specify a --version, the " - "bootstrap script and buildout gets the newest " - "*final* versions of zc.buildout and its recipes and " - "extensions for you. If you use this flag, " - "bootstrap and buildout will get the newest releases " - "even if they are alphas or betas.")) -parser.add_option("-c", "--config-file", - help=("Specify the path to the buildout configuration " - "file to be used.")) -parser.add_option("-f", "--find-links", - help=("Specify a URL to search for buildout releases")) -parser.add_option("--allow-site-packages", - action="store_true", default=False, - help=("Let bootstrap.py use existing site packages")) -parser.add_option("--buildout-version", - help="Use a specific zc.buildout version") -parser.add_option("--setuptools-version", - help="Use a specific setuptools version") -parser.add_option("--setuptools-to-dir", - help=("Allow for re-use of existing directory of " - "setuptools versions")) - -options, args = parser.parse_args() -if options.version: - print("bootstrap.py version %s" % __version__) - sys.exit(0) - - -###################################################################### -# load/install setuptools - -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen - -ez = {} -if os.path.exists('ez_setup.py'): - exec(open('ez_setup.py').read(), ez) -else: - exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) - -if not options.allow_site_packages: - # ez_setup imports site, which adds site packages - # this will remove them from the path to ensure that incompatible versions - # of setuptools are not in the path - import site - # inside a virtualenv, there is no 'getsitepackages'. - # We can't remove these reliably - if hasattr(site, 'getsitepackages'): - for sitepackage_path in site.getsitepackages(): - # Strip all site-packages directories from sys.path that - # are not sys.prefix; this is because on Windows - # sys.prefix is a site-package directory. - if sitepackage_path != sys.prefix: - sys.path[:] = [x for x in sys.path - if sitepackage_path not in x] - -setup_args = dict(to_dir=tmpeggs, download_delay=0) - -if options.setuptools_version is not None: - setup_args['version'] = options.setuptools_version -if options.setuptools_to_dir is not None: - setup_args['to_dir'] = options.setuptools_to_dir - -ez['use_setuptools'](**setup_args) -import setuptools -import pkg_resources - -# This does not (always?) update the default working set. We will -# do it. -for path in sys.path: - if path not in pkg_resources.working_set.entries: - pkg_resources.working_set.add_entry(path) - -###################################################################### -# Install buildout - -ws = pkg_resources.working_set - -setuptools_path = ws.find( - pkg_resources.Requirement.parse('setuptools')).location - -# Fix sys.path here as easy_install.pth added before PYTHONPATH -cmd = [sys.executable, '-c', - 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path + - 'from setuptools.command.easy_install import main; main()', - '-mZqNxd', tmpeggs] - -find_links = os.environ.get( - 'bootstrap-testing-find-links', - options.find_links or - ('http://downloads.buildout.org/' - if options.accept_buildout_test_releases else None) - ) -if find_links: - cmd.extend(['-f', find_links]) - -requirement = 'zc.buildout' -version = options.buildout_version -if version is None and not options.accept_buildout_test_releases: - # Figure out the most recent final version of zc.buildout. - import setuptools.package_index - _final_parts = '*final-', '*final' - - def _final_version(parsed_version): - try: - return not parsed_version.is_prerelease - except AttributeError: - # Older setuptools - for part in parsed_version: - if (part[:1] == '*') and (part not in _final_parts): - return False - return True - - index = setuptools.package_index.PackageIndex( - search_path=[setuptools_path]) - if find_links: - index.add_find_links((find_links,)) - req = pkg_resources.Requirement.parse(requirement) - if index.obtain(req) is not None: - best = [] - bestv = None - for dist in index[req.project_name]: - distv = dist.parsed_version - if _final_version(distv): - if bestv is None or distv > bestv: - best = [dist] - bestv = distv - elif distv == bestv: - best.append(dist) - if best: - best.sort() - version = best[-1].version -if version: - requirement = '=='.join((requirement, version)) -cmd.append(requirement) - -import subprocess -if subprocess.call(cmd) != 0: - raise Exception( - "Failed to execute command:\n%s" % repr(cmd)[1:-1]) - -###################################################################### -# Import and run buildout - -ws.add_entry(tmpeggs) -ws.require(requirement) -import zc.buildout.buildout - -if not [a for a in args if '=' not in a]: - args.append('bootstrap') - -# if -c was provided, we push it back into args for buildout' main function -if options.config_file is not None: - args[0:0] = ['-c', options.config_file] - -zc.buildout.buildout.main(args) -shutil.rmtree(tmpeggs) @@ -1,11 +1,21 @@ -[nosetests] -nocapture=1 -cover-package=zope.security -cover-erase=1 -with-doctest=0 -where=src -exclude=untrustedpython +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code +[bdist_wheel] +universal = 1 -[aliases] -dev = develop easy_install zope.security[testing] -docs = easy_install zope.security[docs] +[zest.releaser] +create-wheel = no + +[flake8] +doctests = 1 +# F401 imported but unused +per-file-ignores = + src/zope/security/__init__.py: F401 + +[check-manifest] +ignore = + .editorconfig + .meta.toml + docs/_build/html/_sources/* + docs/_build/doctest/* + docs/_build/html/_sources/api/* @@ -1,39 +1,71 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/c-code [tox] +minversion = 3.18 envlist = -# Jython support pending 2.7 support, due 2012-07-15 or so. See: -# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html -# py27,pypy,jython,py33,coverage,docs - py27,py27-watch,pypy,pypy3,py35,py36,py37-watch,py37-pure,py37,py38,coverage,docs + lint + py27,py27-pure + py35,py35-pure + py36,py36-pure + py37,py37-pure + py38,py38-pure + py39,py39-pure + pypy + pypy3 + docs + coverage + py27-watch, py37-watch [testenv] +usedevelop = true +deps = + # Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it: + Sphinx < 4 +setenv = + pure: PURE_PYTHON=1 + !pure-!pypy-!pypy3: PURE_PYTHON=0 + ZOPE_INTERFACE_STRICT_IRO=1 + watch: ZOPE_WATCH_CHECKERS = 1 commands = - zope-testrunner --test-path=src [] - sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest + zope-testrunner --test-path=src {posargs:-vc} + !py27-!pypy: sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest extras = test docs -deps = -setenv = - ZOPE_INTERFACE_STRICT_IRO = 1 - watch: ZOPE_WATCH_CHECKERS = 1 - pure: PURE_PYTHON = 1 [testenv:coverage] -usedevelop = true -basepython = - python2.7 -commands = - coverage run -m zope.testrunner --test-path=src [] - coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest - coverage html - coverage report --fail-under=100 +basepython = python3 +allowlist_externals = + mkdir deps = - {[testenv]deps} coverage +setenv = + PURE_PYTHON=1 +commands = + mkdir -p {toxinidir}/parts/htmlcov + coverage run -m zope.testrunner --test-path=src {posargs:-vc} + coverage html -i + coverage report -i -m --fail-under=99.5 + +[testenv:lint] +basepython = python3 +skip_install = true +deps = + flake8 + check-manifest + check-python-versions + wheel +commands = + flake8 src setup.py + check-manifest + check-python-versions [testenv:docs] -basepython = - python3.7 +basepython = python3 +skip_install = false +# Until repoze.sphinx.autointerface supports Sphinx 4.x we cannot use it: +deps = Sphinx < 4 +commands_pre = commands = sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest |