New Upstream Release - pytest-helpers-namespace
Ready changes
Summary
Merged new upstream version: 2021.12.29 (was: 2021.4.29).
Resulting package
Built on 2023-01-11T14:17 (took 5m7s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases python3-pytest-helpers-namespace
Lintian Result
Diff
diff --git a/.coveragerc b/.coveragerc
index 307c21a..6cb08cb 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -8,6 +8,7 @@ relative_files = True
omit =
.nox/*
setup.py
+ noxfile.py
[report]
# Regexes for lines to exclude from consideration
@@ -20,24 +21,26 @@ exclude_lines =
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
+ raise NotImplemented
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if False:
if __name__ == .__main__.:
+ if TYPE_CHECKING:
omit =
.nox/*
setup.py
- src/pytest_helpers_namespace/version.py
- tests/support/coverage/sitecustomize.py
+ noxfile.py
ignore_errors = True
[paths]
source =
- src/pytest_helpers_namespace
+ src/pytest_helpers_namespace/
+ **/site-packages/pytest_helpers_namespace/
testsuite =
tests/
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..a0cebdf
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,14 @@
+# See GitHub's Docs About Code Owners
+# for more info about the CODEOWNERS file
+
+
+# This is a comment.
+# Each line is a file pattern followed by one or more owners.
+
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence,
+# @and will be requested for
+# review when someone opens a pull request.
+
+# Team Core
+* @saltstack/team-core
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 9182cce..9cfe300 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -4,41 +4,45 @@ on: [push, pull_request]
jobs:
Pre-Commit:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
- - id: changed-files
- name: Get Changed Files
- uses: dorny/paths-filter@v2
- with:
- token: ${{ github.token }}
- list-files: shell
- filters: |
- repo:
- - added|modified:
- - '**'
- name: Set Cache Key
run: echo "PY=$(python --version --version | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- - uses: actions/cache@v2
+ - name: Install System Deps
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libxml2 libxml2-dev libxslt-dev
+ - uses: actions/cache@v1
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
- - name: Check ALL Files On Branch
- uses: pre-commit/action@v2.0.0
- if: github.event_name != 'pull_request'
- - name: Check Changed Files On PR
- uses: pre-commit/action@v2.0.0
- if: github.event_name == 'pull_request'
- with:
- extra_args: --files ${{ steps.changed-files.outputs.repo_files }}
+ - uses: pre-commit/action@v1.0.1
+ Twine-Check:
+ runs-on: ubuntu-latest
+ needs: Pre-Commit
- Docs:
- runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
+ - name: Install Nox
+ run: |
+ python -m pip install --upgrade pip
+ pip install nox
+ - name: Twine check
+ run: |
+ nox -e twine-check
+
+ PyLint:
+ runs-on: ubuntu-latest
needs: Pre-Commit
timeout-minutes: 10
@@ -56,10 +60,34 @@ jobs:
python -m pip install --upgrade pip
pip install nox
- - name: Set up Python ${{ matrix.python-version }}
+ - name: Install Lint Requirements
+ run: |
+ nox --force-color -e lint --install-only
+
+ - name: Build Docs
+ env:
+ SKIP_REQUIREMENTS_INSTALL: YES
+ run: |
+ nox --force-color -e lint
+
+ Docs:
+ runs-on: ubuntu-latest
+ needs: Pre-Commit
+
+ timeout-minutes: 10
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python 3.7 For Nox
uses: actions/setup-python@v2
with:
- python-version: ${{ matrix.python-version }}
+ python-version: 3.7
+
+ - name: Install Nox
+ run: |
+ python -m pip install --upgrade pip
+ pip install nox
- name: Install Doc Requirements
run: |
@@ -72,25 +100,32 @@ jobs:
nox --force-color -e docs
Linux:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: Pre-Commit
- timeout-minutes: 20
+ timeout-minutes: 15
strategy:
fail-fast: false
- max-parallel: 5
+ max-parallel: 4
matrix:
python-version:
- - 3.5
- - 3.6
- - 3.7
- - 3.8
- - 3.9
+ - "3.5"
+ - "3.6"
+ - "3.7"
+ - "3.8"
+ - "3.9"
+ - "3.10"
pytest-version:
- "~=6.0.0"
- "~=6.1.0"
- - ""
+ - "~=6.2.0"
+ - ">=7.0.0rc1"
+ exclude:
+ - {"python-version": "3.5", "pytest-version": "~=6.2.0"}
+ - {"python-version": "3.5", "pytest-version": ">=7.0.0rc1"}
+ - {"python-version": "3.10", "pytest-version": "~=6.0.0"}
+ - {"python-version": "3.10", "pytest-version": "~=6.1.0"}
steps:
- uses: actions/checkout@v2
@@ -103,84 +138,133 @@ jobs:
- name: Install Nox
run: |
python -m pip install --upgrade pip
- pip install nox
+ pip install nox 'pytest${{ matrix.pytest-version }}'
- name: Install Test Requirements
env:
PYTEST_VERSION_REQUIREMENT: pytest${{ matrix.pytest-version }}
run: |
- nox --force-color -e tests-${{ matrix.python-version }} --install-only
+ nox --force-color -e tests-3 --install-only
- name: Test
- id: run-tests
env:
SKIP_REQUIREMENTS_INSTALL: YES
run: |
- nox --force-color -e tests-${{ matrix.python-version }} -- -vv tests/
+ nox --force-color -e tests-3 -- -vv tests/
+
+ - name: Gather CodeCov Info
+ if: always()
+ id: codecov-info
+ run: |
+ echo ::set-output name=flag-python-version::$(python -c "import sys; print('Py{}{}'.format(*sys.version_info))")
+ echo ::set-output name=flag-pytest-version::$(python -c "import pytest; print('PyTest{}{}'.format(*pytest.__version__.split('.')))")
+ echo ::set-output name=flag-runner-os::$(python -c "print('${{ runner.os }}'.replace('-latest', ''))")
+ echo ::set-output name=uploader-url::$(python -c "print('https://uploader.codecov.io/latest/codecov-linux')")
+ echo ::set-output name=uploader-name::$(python -c "print('codecov-linux')")
- name: Create CodeCov Flags
if: always()
- id: codecov-flags
+ id: codecov
run: |
- echo ::set-output name=flags::$(python -c "import sys; print('{},{},pytest${{ matrix.pytest-version || 'latest' }}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info)))")
+ echo ::set-output name=flags::$(python -c "print(','.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
+ echo ::set-output name=report-name::$(python -c "print('-'.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
- - name: Upload Helpers Namespace Code Coverage
+ - name: Download Code Coverage Tool
if: always()
shell: bash
- env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
- REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-helpers
- REPORT_PATH: artifacts/coverage-project.xml
run: |
- if [ ! -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
+ if [ "$(which curl)x" == "x" ]; then
+ echo "Failed to find the 'curl' binary"
+ exit 0
+ fi
+
+ if [ "$(which gpg)x" == "x" ]; then
+ echo "Failed to find the 'gpg' binary"
+ exit 0
+ fi
+
+ if [ "$(which shasum)x" == "x" ]; then
+ echo "Failed to find the 'shasum' binary"
+ exit 0
+ fi
+
+ if [ ! -x codecov-linux ]; then
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }} --output ${{ steps.codecov-info.outputs.uploader-name }}; then
+ break
+ fi
n=$((n+1))
sleep 15
- done
- fi
- if [ -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM --output ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM; then
break
fi
n=$((n+1))
sleep 15
- done
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM.sig --output ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig; then
+ break
+ fi
+ n=$((n+1))
+ sleep 15
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import; then
+ break
+ fi
+ n=$((n+1))
+ sleep 15
+ done
+ gpg --verify ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM && \
+ shasum -a 256 -c ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM && \
+ chmod +x ${{ steps.codecov-info.outputs.uploader-name }} || exit 0
fi
- - name: Upload Helpers Namespace Tests Code Coverage
+ - name: Upload Project Code Coverage
if: always()
shell: bash
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
- REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-tests
- REPORT_PATH: artifacts/coverage-tests.xml
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},src
+ REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-src
+ REPORT_PATH: artifacts/coverage-project.xml
run: |
- if [ ! -f codecov.sh ]; then
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ break
+ fi
n=$((n+1))
sleep 15
done
fi
- if [ -f codecov.sh ]; then
+
+ - name: Upload Tests Code Coverage
+ if: always()
+ shell: bash
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests
+ REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-tests
+ REPORT_PATH: artifacts/coverage-tests.xml
+ run: |
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
break
fi
n=$((n+1))
@@ -192,7 +276,7 @@ jobs:
if: always()
uses: actions/upload-artifact@main
with:
- name: runtests-${{ runner.os }}-py${{ matrix.python-version }}.log
+ name: runtests-${{ steps.codecov.outputs.report-name }}.log
path: artifacts/runtests-*.log
Windows:
@@ -206,15 +290,17 @@ jobs:
max-parallel: 5
matrix:
python-version:
- - 3.5
- - 3.6
- - 3.7
- - 3.8
- - 3.9
+ - "3.6"
+ - "3.7"
+ - "3.8"
+ - "3.9"
+ - "3.10"
pytest-version:
- - "~=6.0.0"
- - "~=6.1.0"
- - ""
+ - "~=6.2.0"
+ - ">=7.0.0rc1"
+ exclude:
+ - {"python-version": "3.10", "pytest-version": "~=6.0.0"}
+ - {"python-version": "3.10", "pytest-version": "~=6.1.0"}
steps:
- uses: actions/checkout@v2
@@ -227,56 +313,81 @@ jobs:
- name: Install Nox
run: |
python -m pip install --upgrade pip
- pip install nox
+ pip install nox 'pytest${{ matrix.pytest-version }}'
- name: Install Test Requirements
+ shell: bash
env:
PYTEST_VERSION_REQUIREMENT: pytest${{ matrix.pytest-version }}
- shell: bash
run: |
export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH"
- nox --force-color -e tests-${{ matrix.python-version }} --install-only
+ nox --force-color -e tests-3 --install-only
- name: Test
- id: run-tests
shell: bash
env:
SKIP_REQUIREMENTS_INSTALL: YES
run: |
export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH"
- nox --force-color -e tests-${{ matrix.python-version }} -- -vv tests/
+ nox --force-color -e tests-3 -- -vv tests/
+
+ - name: Gather CodeCov Info
+ if: always()
+ id: codecov-info
+ shell: bash
+ run: |
+ echo ::set-output name=flag-python-version::$(python -c "import sys; print('Py{}{}'.format(*sys.version_info))")
+ echo ::set-output name=flag-pytest-version::$(python -c "import pytest; print('PyTest{}{}'.format(*pytest.__version__.split('.')))")
+ echo ::set-output name=flag-runner-os::$(python -c "print('${{ runner.os }}'.replace('-latest', ''))")
+ echo ::set-output name=uploader-url::$(python -c "print('https://uploader.codecov.io/latest/windows/codecov.exe')")
+ echo ::set-output name=uploader-name::$(python -c "print('codecov.exe')")
- name: Create CodeCov Flags
if: always()
- id: codecov-flags
+ id: codecov
run: |
- echo ::set-output name=flags::$(python -c "import sys; print('{},{},pytest${{ matrix.pytest-version || 'latest' }}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info)))")
+ echo ::set-output name=flags::$(python -c "print(','.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
+ echo ::set-output name=report-name::$(python -c "print('-'.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
+
- - name: Upload Helpers Namespace Code Coverage
+ - name: Download Code Coverage Tool
+ if: always()
+ shell: powershell
+ run: |
+ If (-not(Test-Path -Path ./${{ steps.codecov-info.outputs.uploader-name }})) {
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Ssl3
+ [Net.ServicePointManager]::SecurityProtocol = "Tls, Tls11, Tls12, Ssl3"
+
+ $ProgressPreference = 'SilentlyContinue'
+ Invoke-WebRequest -Uri https://keybase.io/codecovsecurity/pgp_keys.asc -OutFile codecov.asc
+ gpg.exe --import codecov.asc
+
+ Invoke-WebRequest -Uri ${{ steps.codecov-info.outputs.uploader-url }} -Outfile ${{ steps.codecov-info.outputs.uploader-name }}
+ Invoke-WebRequest -Uri ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM -Outfile ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM
+ Invoke-WebRequest -Uri ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM.sig -Outfile ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig
+
+ gpg.exe --verify ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM
+ If ($(Compare-Object -ReferenceObject $(($(certUtil -hashfile ${{ steps.codecov-info.outputs.uploader-name }} SHA256)[1], "${{ steps.codecov-info.outputs.uploader-name }}") -join " ") -DifferenceObject $(Get-Content ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM)).length -eq 0) {
+ echo "SHASUM verified"
+ } Else {
+ exit 0
+ }
+ }
+
+ - name: Upload Project Code Coverage
if: always()
shell: bash
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
- REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-helpers
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},src
+ REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-src
REPORT_PATH: artifacts/coverage-project.xml
run: |
- if [ ! -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
- n=$((n+1))
- sleep 15
- done
- fi
- if [ -f codecov.sh ]; then
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
break
fi
n=$((n+1))
@@ -284,31 +395,20 @@ jobs:
done
fi
- - name: Upload Helpers Namespace Tests Code Coverage
+ - name: Upload Tests Code Coverage
if: always()
shell: bash
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests
REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-tests
REPORT_PATH: artifacts/coverage-tests.xml
run: |
- if [ ! -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
- n=$((n+1))
- sleep 15
- done
- fi
- if [ -f codecov.sh ]; then
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
break
fi
n=$((n+1))
@@ -320,29 +420,31 @@ jobs:
if: always()
uses: actions/upload-artifact@main
with:
- name: runtests-${{ runner.os }}-py${{ matrix.python-version }}.log
+ name: runtests-${{ steps.codecov.outputs.report-name }}.log
path: artifacts/runtests-*.log
macOS:
runs-on: macOS-latest
needs: Pre-Commit
- timeout-minutes: 60
+ timeout-minutes: 40
strategy:
fail-fast: false
max-parallel: 5
matrix:
python-version:
- - 3.5
- - 3.6
- - 3.7
- - 3.8
- - 3.9
+ - "3.6"
+ - "3.7"
+ - "3.8"
+ - "3.9"
+ - "3.10"
pytest-version:
- - "~=6.0.0"
- - "~=6.1.0"
- - ""
+ - "~=6.2.0"
+ - ">=7.0.0rc1"
+ exclude:
+ - {"python-version": "3.10", "pytest-version": "~=6.0.0"}
+ - {"python-version": "3.10", "pytest-version": "~=6.1.0"}
steps:
- uses: actions/checkout@v2
@@ -355,84 +457,133 @@ jobs:
- name: Install Nox
run: |
python -m pip install --upgrade pip
- pip install nox
+ pip install nox 'pytest${{ matrix.pytest-version }}'
- name: Install Test Requirements
env:
PYTEST_VERSION_REQUIREMENT: pytest${{ matrix.pytest-version }}
run: |
- nox --force-color -e tests-${{ matrix.python-version }} --install-only
+ nox --force-color -e tests-3 --install-only
- name: Test
- id: run-tests
env:
SKIP_REQUIREMENTS_INSTALL: YES
run: |
- nox --force-color -e tests-${{ matrix.python-version }} -- -vv tests/
+ nox --force-color -e tests-3 -- -vv tests/
+
+ - name: Gather CodeCov Info
+ if: always()
+ id: codecov-info
+ run: |
+ echo ::set-output name=flag-python-version::$(python -c "import sys; print('Py{}{}'.format(*sys.version_info))")
+ echo ::set-output name=flag-pytest-version::$(python -c "import pytest; print('PyTest{}{}'.format(*pytest.__version__.split('.')))")
+ echo ::set-output name=flag-runner-os::$(python -c "print('${{ runner.os }}'.replace('-latest', ''))")
+ echo ::set-output name=uploader-url::$(python -c "print('https://uploader.codecov.io/latest/codecov-macos')")
+ echo ::set-output name=uploader-name::$(python -c "print('codecov-macos')")
- name: Create CodeCov Flags
if: always()
- id: codecov-flags
+ id: codecov
run: |
- echo ::set-output name=flags::$(python -c "import sys; print('{},{},pytest${{ matrix.pytest-version || 'latest' }}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info)))")
+ echo ::set-output name=flags::$(python -c "print(','.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
+ echo ::set-output name=report-name::$(python -c "print('-'.join(['${{ steps.codecov-info.outputs.flag-runner-os }}', '${{ steps.codecov-info.outputs.flag-python-version }}', '${{ steps.codecov-info.outputs.flag-pytest-version }}']))")
- - name: Upload Helpers Namespace Code Coverage
+ - name: Download Code Coverage Tool
if: always()
shell: bash
- env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
- REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-helpers
- REPORT_PATH: artifacts/coverage-project.xml
run: |
- if [ ! -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
+ if [ "$(which curl)x" == "x" ]; then
+ echo "Failed to find the 'curl' binary"
+ exit 0
+ fi
+
+ if [ "$(which gpg)x" == "x" ]; then
+ echo "Failed to find the 'gpg' binary"
+ exit 0
+ fi
+
+ if [ "$(which shasum)x" == "x" ]; then
+ echo "Failed to find the 'shasum' binary"
+ exit 0
+ fi
+
+ if [ ! -x codecov-linux ]; then
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }} --output ${{ steps.codecov-info.outputs.uploader-name }}; then
+ break
+ fi
n=$((n+1))
sleep 15
- done
- fi
- if [ -f codecov.sh ]; then
- n=0
- until [ "$n" -ge 5 ]
- do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM --output ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM; then
break
fi
n=$((n+1))
sleep 15
- done
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L ${{ steps.codecov-info.outputs.uploader-url }}.SHA256SUM.sig --output ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig; then
+ break
+ fi
+ n=$((n+1))
+ sleep 15
+ done
+ n=0
+ until [ "$n" -ge 5 ]
+ do
+ if curl --max-time 30 -L https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import; then
+ break
+ fi
+ n=$((n+1))
+ sleep 15
+ done
+ gpg --verify ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM.sig ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM && \
+ shasum -a 256 -c ${{ steps.codecov-info.outputs.uploader-name }}.SHA256SUM && \
+ chmod +x ${{ steps.codecov-info.outputs.uploader-name }} || exit 0
fi
- - name: Upload Helpers Namespace Tests Code Coverage
+ - name: Upload Project Code Coverage
if: always()
shell: bash
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},helpers
- REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-tests
- REPORT_PATH: artifacts/coverage-tests.xml
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},src
+ REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-src
+ REPORT_PATH: artifacts/coverage-project.xml
run: |
- if [ ! -f codecov.sh ]; then
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then
- break
- fi
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ break
+ fi
n=$((n+1))
sleep 15
done
fi
- if [ -f codecov.sh ]; then
+
+ - name: Upload Tests Code Coverage
+ if: always()
+ shell: bash
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests
+ REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-tests
+ REPORT_PATH: artifacts/coverage-tests.xml
+ run: |
+ if [ -x ${{ steps.codecov-info.outputs.uploader-name }} ]; then
n=0
until [ "$n" -ge 5 ]
do
- if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
+ if ./${{ steps.codecov-info.outputs.uploader-name }} -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then
break
fi
n=$((n+1))
@@ -444,5 +595,5 @@ jobs:
if: always()
uses: actions/upload-artifact@main
with:
- name: runtests-${{ runner.os }}-py${{ matrix.python-version }}.log
+ name: runtests-${{ steps.codecov.outputs.report-name }}.log
path: artifacts/runtests-*.log
diff --git a/.gitignore b/.gitignore
index 03212b5..1547f3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,3 +70,7 @@ target/
.lvimrc
artifacts/
+
+.vim/
+
+src/pytest_helpers_namespace/version.py
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 10a5db3..3cf0832 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,18 +1,22 @@
---
-minimum_pre_commit_version: 1.15.2
+minimum_pre_commit_version: 2.9.2
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v2.1.0
+ rev: v4.0.1
hooks:
- id: check-merge-conflict # Check for files that contain merge conflict strings.
- - id: trailing-whitespace # Trims trailing whitespace.
+ - id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: mixed-line-ending # Replaces or checks mixed line ending.
args: [--fix=lf]
- - id: end-of-file-fixer # Makes sure files end in a newline and only a newline.
- - id: check-merge-conflict # Check for files that contain merge conflict strings.
- - id: check-ast # Simply check whether files parse as valid python.
+ - id: end-of-file-fixer
+ - id: fix-encoding-pragma
+ args: [--remove]
+ - id: check-yaml
+ - id: debug-statements
+ language_version: python3
+ # ----- Local Hooks ----------------------------------------------------------------------------------------------->
- repo: local
hooks:
- id: sort-pylint-spelling-words
@@ -21,55 +25,109 @@ repos:
language: system
files: ^\.pylint-spelling-words$
+ - id: check-changelog-entries
+ name: Check Changelog Entries
+ entry: python .pre-commit-hooks/check-changelog-entries.py
+ language: system
+
+ - repo: local
+ hooks:
+ - id: check-copyright-headers
+ name: Check python modules for appropriate copyright headers
+ files: ^.*\.py$
+ entry: python .pre-commit-hooks/copyright-headers.py
+ language: system
+ # <---- Local Hooks ------------------------------------------------------------------------------------------------
+
+ # ----- Formatting ------------------------------------------------------------------------------------------------>
- repo: https://github.com/asottile/pyupgrade
- rev: v2.10.0
+ rev: v2.29.0
hooks:
- id: pyupgrade
name: Rewrite Code to be Py3.5+
- args: [--py3-plus]
-
- - repo: https://github.com/hakancelik96/unimport
- rev: "31cc123640880e385159c719d2f12b5cf8586495"
- hooks:
- - id: unimport
- name: Remove unused imports
- args: [--remove]
- #exclude: ^(docs/.*\.py|src/pytest_helpers_namespace/factories/(cli|daemons)/__init__\.py)$
- exclude: ^docs/.*\.py$
-
+ args: [
+ --py3-plus
+ ]
+ files: ^((setup|noxfile)|(src|tests)/.*)\.py$
+ exclude: src/pytest_helpers_namespace/version.py
- repo: https://github.com/asottile/reorder_python_imports
- rev: v2.4.0
+ rev: v2.6.0
hooks:
- id: reorder-python-imports
- args: [
- --py3-plus,
- ]
+ args:
+ - --py3-plus
+ - --application-directories=.:src
exclude: src/pytest_helpers_namespace/version.py
- repo: https://github.com/psf/black
- rev: 21.4b2
+ rev: 21.10b0
hooks:
- id: black
args: [-l 100]
exclude: src/pytest_helpers_namespace/version.py
- repo: https://github.com/asottile/blacken-docs
- rev: v1.7.0
+ rev: v1.11.0
hooks:
- id: blacken-docs
- args: [--skip-errors]
- files: ^docs/.*\.rst
- additional_dependencies: [black==21.4b2]
+# args: [--skip-errors]
+ files: ^((docs/.*|README)\.rst|src/pytest_helpers_namespace/.*\.py)$
+ additional_dependencies: [black==21.10b0]
+ # <---- Formatting -------------------------------------------------------------------------------------------------
- - repo: https://github.com/pre-commit/mirrors-pylint
- rev: v2.4.4
+ # ----- Security -------------------------------------------------------------------------------------------------->
+ - repo: https://github.com/PyCQA/bandit
+ rev: "1.7.0"
hooks:
- - id: pylint
- name: PyLint
- args: [--output-format=parseable, --rcfile=.pylintrc]
+ - id: bandit
+ alias: bandit-salt
+ name: Run bandit against the code base
+ args: [--silent, -lll, --skip, B701]
+ files: ^(?!tests/).*\.py$
exclude: src/pytest_helpers_namespace/version.py
+ - repo: https://github.com/PyCQA/bandit
+ rev: "1.7.0"
+ hooks:
+ - id: bandit
+ alias: bandit-tests
+ name: Run bandit against the test suite
+ args: [--silent, -lll, --skip, B701]
+ files: ^tests/.*
+ # <---- Security ---------------------------------------------------------------------------------------------------
+
+ # ----- Code Analysis --------------------------------------------------------------------------------------------->
+ - repo: https://github.com/pycqa/flake8
+ rev: '4.0.1'
+ hooks:
+ - id: flake8
+ exclude: ^(src/pytest_helpers_namespace/version\.py|\.pre-commit-hooks/.*\.py)$
+ additional_dependencies:
+ - flake8-mypy-fork
+ - flake8-docstrings
+ - flake8-typing-imports
+
+ - repo: https://github.com/pre-commit/mirrors-mypy
+ rev: v0.930
+ hooks:
+ - id: mypy
+ name: Run mypy against source
+ files: ^src/.*\.py$
+ args: [--strict]
+ additional_dependencies:
+ - types-attrs
+ - types-setuptools
+ - pydantic
+
+ - repo: https://github.com/pre-commit/mirrors-mypy
+ rev: v0.930
+ hooks:
+ - id: mypy
+ name: Run mypy against tests
+ files: ^tests/.*\.py$
+ args: []
additional_dependencies:
- - saltpylint
- - pyenchant
- - salt>=3001
+ - types-attrs
+ - types-setuptools
+ - pydantic
+ # <---- Code Analysis ----------------------------------------------------------------------------------------------
diff --git a/.pre-commit-hooks/check-changelog-entries.py b/.pre-commit-hooks/check-changelog-entries.py
new file mode 100755
index 0000000..876c813
--- /dev/null
+++ b/.pre-commit-hooks/check-changelog-entries.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python3
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
+# pylint: disable=invalid-name,missing-module-docstring,missing-function-docstring
+import argparse
+import pathlib
+import re
+import sys
+
+CODE_ROOT = pathlib.Path(__file__).resolve().parent.parent
+CHANGELOG_ENTRIES_PATH = CODE_ROOT / "changelog"
+CHANGELOG_LIKE_RE = re.compile(r"([\d]+)\.([a-z]+)(\.rst)?$")
+CHANGELOG_EXTENSIONS = (
+ "breaking",
+ "deprecation",
+ "feature",
+ "improvement",
+ "bugfix",
+ "doc",
+ "trivial",
+)
+CHANGELOG_ENTRY_REREX = r"^[\d]+\.({})\.rst$".format("|".join(CHANGELOG_EXTENSIONS))
+CHANGELOG_ENTRY_RE = re.compile(CHANGELOG_ENTRY_REREX)
+
+
+def check_changelog_entries(files):
+
+ exitcode = 0
+ for entry in files:
+ path = pathlib.Path(entry).resolve()
+ # Is it under changelog/
+ try:
+ path.relative_to(CHANGELOG_ENTRIES_PATH)
+ if path.name in (".gitignore", "_template.rst", __name__):
+ # These files should be ignored
+ continue
+ # Is it named properly
+ if not CHANGELOG_ENTRY_RE.match(path.name):
+ # Does it end in .rst
+ if path.suffix != ".rst":
+ exitcode = 1
+ print(
+ "The changelog entry '{}' should have '.rst' as it's file extension".format(
+ path.relative_to(CODE_ROOT),
+ ),
+ file=sys.stderr,
+ flush=True,
+ )
+ continue
+ print(
+ "The changelog entry '{}' should have one of the following extensions: {}.".format(
+ path.relative_to(CODE_ROOT),
+ ", ".join(repr(ext) for ext in CHANGELOG_EXTENSIONS),
+ ),
+ file=sys.stderr,
+ flush=True,
+ )
+ exitcode = 1
+ continue
+ check_changelog_entry_contents(path)
+ except ValueError:
+ # Not under changelog/, carry on checking
+ # Is it a changelog entry
+ if CHANGELOG_ENTRY_RE.match(path.name):
+ # So, this IS a changelog entry, but it's misplaced....
+ exitcode = 1
+ print(
+ "The changelog entry '{}' should be placed under '{}/', not '{}'".format(
+ path.relative_to(CODE_ROOT),
+ CHANGELOG_ENTRIES_PATH.relative_to(CODE_ROOT),
+ path.relative_to(CODE_ROOT).parent,
+ ),
+ file=sys.stderr,
+ flush=True,
+ )
+ continue
+ elif CHANGELOG_LIKE_RE.match(path.name) and not CHANGELOG_ENTRY_RE.match(path.name):
+ # Does it look like a changelog entry
+ print(
+ "The changelog entry '{}' should have one of the following extensions: {}.".format(
+ path.relative_to(CODE_ROOT),
+ ", ".join(repr(ext) for ext in CHANGELOG_EXTENSIONS),
+ ),
+ file=sys.stderr,
+ flush=True,
+ )
+ exitcode = 1
+ continue
+
+ elif not CHANGELOG_LIKE_RE.match(path.name) and not CHANGELOG_ENTRY_RE.match(path.name):
+ # Does not look like, and it's not a changelog entry
+ continue
+ # Does it end in .rst
+ if path.suffix != ".rst":
+ exitcode = 1
+ print(
+ "The changelog entry '{}' should have '.rst' as it's file extension".format(
+ path.relative_to(CODE_ROOT),
+ ),
+ file=sys.stderr,
+ flush=True,
+ )
+ return exitcode
+
+
+def check_changelog_entry_contents(entry):
+ contents = entry.read_text().splitlines()
+ if len(contents) > 1:
+ # More than one line.
+ # If the second line starts with '*' it's a bullet list and we need to add an
+ # empty line before it.
+ if contents[1].strip().startswith("*"):
+ contents.insert(1, "")
+ entry.write_text("{}\n".format("\n".join(contents)))
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(prog=__name__)
+ parser.add_argument("files", nargs="+")
+
+ options = parser.parse_args(argv)
+ return check_changelog_entries(options.files)
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff --git a/.pre-commit-hooks/copyright-headers.py b/.pre-commit-hooks/copyright-headers.py
new file mode 100644
index 0000000..5e853f3
--- /dev/null
+++ b/.pre-commit-hooks/copyright-headers.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
+# pylint: disable=invalid-name,missing-module-docstring,missing-function-docstring
+import argparse
+import pathlib
+import re
+import sys
+from datetime import datetime
+
+CODE_ROOT = pathlib.Path(__file__).resolve().parent.parent
+SPDX_HEADER = "# SPDX-License-Identifier: Apache-2.0"
+COPYRIGHT_HEADER = "# Copyright {year} VMware, Inc."
+COPYRIGHT_REGEX = re.compile(
+ r"# Copyright (?:(?P<start_year>[0-9]{4})(?:-(?P<cur_year>[0-9]{4}))?) VMware, Inc\."
+)
+SPDX_REGEX = re.compile(r"# SPDX-License-Identifier:.*")
+
+
+def check_copyright(files):
+ for file in files:
+ contents = file.read_text()
+ if not contents.strip():
+ # Don't add headers to empty files
+ continue
+ original_contents = contents
+ try:
+ if not COPYRIGHT_REGEX.search(contents):
+ contents = inject_copyright_header(contents)
+ if contents != original_contents:
+ print(f"Added the copyright header to {file}")
+ else:
+ contents = update_copyright_header(contents)
+ if contents != original_contents:
+ print(f"Updated the copyright header on {file}")
+ if not SPDX_REGEX.search(contents):
+ contents = inject_spdx_header(contents)
+ if contents != original_contents:
+ print(f"Added the SPDX header to {file}")
+ finally:
+ if original_contents != contents:
+ file.write_text(contents)
+
+
+def inject_copyright_header(contents):
+ lines = contents.splitlines()
+ shebang_found = False
+ for idx, line in enumerate(lines[:]):
+ if idx == 0 and line.startswith("#!"):
+ shebang_found = True
+ continue
+ if shebang_found and line.strip():
+ shebang_found = False
+ lines.insert(idx, "")
+ idx += 1
+ lines.insert(idx, COPYRIGHT_HEADER.format(year=datetime.today().year))
+ break
+ return "\n".join(lines)
+
+
+def update_copyright_header(contents):
+ lines = contents.splitlines()
+ for idx, line in enumerate(lines[:]):
+ match = COPYRIGHT_REGEX.match(line)
+ if match:
+ this_year = str(datetime.today().year)
+ initial_year = match.group("start_year").strip()
+ if initial_year == this_year:
+ return contents
+ lines[idx] = COPYRIGHT_HEADER.format(year=f"{initial_year}-{this_year}")
+ break
+ return "\n".join(lines)
+
+
+def inject_spdx_header(contents):
+ lines = contents.splitlines()
+ for idx, line in enumerate(lines[:]):
+ if COPYRIGHT_REGEX.match(line):
+ lines.insert(idx + 1, SPDX_HEADER)
+ next_line = lines[idx + 2].strip()
+ if next_line and not next_line.startswith('"""'):
+ # If the next line is not empty, insert an empty comment
+ lines.insert(idx + 2, "#")
+ break
+ return "\n".join(lines)
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(prog=__name__)
+ parser.add_argument("files", nargs="+", type=pathlib.Path)
+
+ options = parser.parse_args(argv)
+ return check_copyright(options.files)
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff --git a/.pre-commit-hooks/sort-pylint-spelling-words.py b/.pre-commit-hooks/sort-pylint-spelling-words.py
index fce892c..6a9c902 100755
--- a/.pre-commit-hooks/sort-pylint-spelling-words.py
+++ b/.pre-commit-hooks/sort-pylint-spelling-words.py
@@ -1,4 +1,6 @@
#!/usr/bin/env python
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
# pylint: skip-file
import pathlib
@@ -9,7 +11,7 @@ PYLINT_SPELLING_WORDS = REPO_ROOT / ".pylint-spelling-words"
def sort():
in_contents = PYLINT_SPELLING_WORDS.read_text()
out_contents = ""
- out_contents += "\n".join(sorted([line.lower() for line in in_contents.splitlines()]))
+ out_contents += "\n".join(sorted({line.lower() for line in in_contents.splitlines()}))
out_contents += "\n"
if in_contents != out_contents:
PYLINT_SPELLING_WORDS.write_text(out_contents)
diff --git a/.pylint-spelling-words b/.pylint-spelling-words
index 7168513..c991c73 100644
--- a/.pylint-spelling-words
+++ b/.pylint-spelling-words
@@ -1,13 +1,16 @@
abspath
autodoc
+changelog
config
confvals
css
favicon
favicons
+funcwrapper
ico
intersphinx
intl
+linkcheck
minify
namespace
namespaces
@@ -21,6 +24,8 @@ repo
rst
sitecustomize
sitevars
+str
sys
toc
virtualenvs
+vmware
diff --git a/.pylintrc b/.pylintrc
index 38f331a..fc4410e 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -19,10 +19,7 @@ persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
-load-plugins=saltpylint.pep8,
- saltpylint.strings,
- saltpylint.fileperms,
- saltpylint.smartup,
+load-plugins=
# Use multiple processes to speed up Pylint.
jobs=1
@@ -116,7 +113,8 @@ disable=R,
import-outside-toplevel,
wrong-import-position,
wrong-import-order,
- missing-whitespace-after-comma
+ missing-whitespace-after-comma,
+ consider-using-f-string
# Disabled:
# R* [refactoring suggestions & reports]
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..9931e8b
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,94 @@
+.. _changelog:
+
+=========
+Changelog
+=========
+
+Versions follow `Calendar Versioning <https://calver.org/>`_
+(`<year>.<month>.<day>`).
+
+.. towncrier-draft-entries::
+
+.. towncrier release notes start
+
+
+2021.12.29
+==========
+
+Improvements
+------------
+
+- `#11 <https://github.com/saltstack/pytest-helpers-namespace/issues/11>`_: Plugin is now fully typed.
+
+
+v2021.3.24
+==========
+
+* Switched project to a ``src`` layout.
+* Switched project to a declarative setuptools approach
+* Added support to check if a helper has been registered
+* Pytest >= 6.1.1 is now required
+
+v2019.1.8
+=========
+
+* Patch PyTest before any ``conftest.py`` file is processed.
+
+v2019.1.7
+=========
+
+* Support PyTest >= 4.1
+
+v2019.1.6.post1
+===============
+
+* No changes were made besides locking to PyTest < 4.0
+
+v2019.1.6
+=========
+
+* No changes were made besides locking to PyTest < 4.1
+
+v2017.11.11
+===========
+
+* Allow passing a string to the register function which will be the helper name
+
+v2016.7.10
+==========
+
+* `#4`_: Allow a registered function to contibue to behave as a regular function.
+
+v2016.4.15
+==========
+
+* `#3`_: Hide the ``FuncWrapper`` traceback in pytest failures. Thanks Logan Glickfield(`@lsglick`_)
+
+v2016.4.5
+=========
+
+* Use a wrapper class instead of adding an attribute to a function.
+
+v2016.4.3
+=========
+
+* `#1`_: Provide proper errors when helper functions or namespaces are being
+ overridden.
+
+v2016.3.2
+==========
+
+* First working release
+
+.. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
+.. _`file an issue`: https://github.com/saltstack/pytest-helpers-namespace/issues
+.. _`pytest`: https://github.com/pytest-dev/pytest
+.. _`nox`: https://nox.thea.codes/en/stable/
+.. _`pip`: https://pypi.python.org/pypi/pip/
+.. _`PyPI`: https://pypi.python.org/pypi
+
+.. _`#1`: https://github.com/saltstack/pytest-helpers-namespace/issues/1
+.. _`#3`: https://github.com/saltstack/pytest-helpers-namespace/pull/3
+.. _`#4`: https://github.com/saltstack/pytest-helpers-namespace/issues/4
+
+.. _`@lsglick`: https://github.com/lsglick
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..0a0233f
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,127 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in
+pytest-system-statistics project and our community a harassment-free experience
+for everyone, regardless of age, body size, visible or invisible disability,
+ethnicity, sex characteristics, gender identity and expression, level of
+experience, education, socio-economic status, nationality, personal appearance,
+race, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at oss-coc@@vmware.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..008a15c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,76 @@
+# Contributing to pytest-helpers-namespace
+
+The pytest-helpers-namespace project team welcomes contributions from the community. If you wish to contribute
+code and you have not signed our [Contributor License Agreement](https://cla.vmware.com/cla/1/preview), our
+bot will update the issue when you open a Pull Request.
+For any questions about the CLA process, please refer to our [FAQ](https://cla.vmware.com/faq).
+
+## Contribution Flow
+
+This is a rough outline of what a contributor's workflow looks like:
+
+- Create a topic branch from where you want to base your work
+- Make commits of logical units
+- Make sure your commit messages are in the proper format (see below)
+- Push your changes to a topic branch in your fork of the repository
+- Submit a pull request
+
+Example:
+
+``` shell
+git remote add upstream https://github.com/saltstack/pytest-helpers-namespace.git
+git checkout -b my-new-feature master
+git commit -a
+git push origin my-new-feature
+```
+
+### Staying In Sync With Upstream
+
+When your branch gets out of sync with the pytest-helpers-namespace/master branch, use the following to update:
+
+``` shell
+git checkout my-new-feature
+git fetch -a
+git pull --rebase upstream master
+git push --force-with-lease origin my-new-feature
+```
+
+### Updating pull requests
+
+If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into
+existing commits.
+
+If your pull request contains a single commit or your changes are related to the most recent commit, you can simply
+amend the commit.
+
+``` shell
+git add .
+git commit --amend
+git push --force-with-lease origin my-new-feature
+```
+
+If you need to squash changes into an earlier commit, you can use:
+
+``` shell
+git add .
+git commit --fixup <commit>
+git rebase -i --autosquash master
+git push --force-with-lease origin my-new-feature
+```
+
+Be sure to add a comment to the PR indicating your new changes are ready to review, as GitHub does not generate a
+notification when you git push.
+
+### Code Style
+
+### Formatting Commit Messages
+
+We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/).
+
+Be sure to include any related GitHub issue references in the commit message. See
+[GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) for referencing issues
+and commits.
+
+## Reporting Bugs and Creating Issues
+
+When opening a new issue, try to roughly follow the commit message format conventions above.
diff --git a/PKG-INFO b/PKG-INFO
index 7c38c57..5900135 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-helpers-namespace
-Version: 2021.4.29
+Version: 2021.12.29
Summary: Pytest Helpers Namespace Plugin
Home-page: https://github.com/saltstack/pytest-helpers-namespace
Author: Pedro Algarvio
@@ -37,6 +37,9 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
:alt: Supported implementations
:target: https://pypi.python.org/pypi/pytest-helpers-namespace
+ ..
+ include-starts-here
+
Pytest Helpers Namespace
========================
@@ -78,11 +81,12 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
import pytest
+
@pytest.helpers.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -101,15 +105,16 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
.. code-block:: python
- pytest_plugins = ['helpers_namespace']
+ pytest_plugins = ["helpers_namespace"]
import pytest
+
@pytest.helpers.can.haz.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -124,86 +129,6 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
You can even pass a name to the register function and that will be the helper function name.
- Contributing
- ------------
- Contributions are very welcome. Tests can be run with `nox`_, please ensure
- the coverage at least stays the same before you submit a pull request.
-
- License
- -------
-
- Distributed under the terms of the `Apache Software License 2.0`_ license,
- "pytest-helpers-namespace" is free and open source software.
-
-
- Issues
- ------
-
- If you encounter any problems, please `file an issue`_ along with a detailed
- description.
-
- Changelog
- ---------
-
- v2021.3.24
- ~~~~~~~~~~
-
- * Switched project to a ``src`` layout.
- * Switched project to a declarative setuptools approach
- * Added support to check if a helper has been registered
- * Pytest >= 6.1.1 is now required
-
- v2019.1.8
- ~~~~~~~~~
-
- * Patch PyTest before any ``conftest.py`` file is processed.
-
- v2019.1.7
- ~~~~~~~~~
-
- * Support PyTest >= 4.1
-
- v2019.1.6.post1
- ~~~~~~~~~~~~~~~
-
- * No changes were made besides locking to PyTest < 4.0
-
- v2019.1.6
- ~~~~~~~~~
-
- * No changes were made besides locking to PyTest < 4.1
-
- v2017.11.11
- ~~~~~~~~~~~
-
- * Allow passing a string to the register function which will be the helper name
-
- v2016.7.10
- ~~~~~~~~~~
-
- * Allow a registered function to contibue to behave as a regular function. `#4`_.
-
- v2016.4.15
- ~~~~~~~~~~
-
- * Hide the ``FuncWrapper`` traceback in pytest failures. `#3`_. Thanks Logan Glickfield(`@lsglick`_)
-
- v2016.4.5
- ~~~~~~~~~
-
- * Use a wrapper class instead of adding an attribute to a function.
-
- v2016.4.3
- ~~~~~~~~~
-
- * Provide proper errors when helper functions or namespaces are being
- overridden. `#1`_
-
- v2016.3.2
- ~~~~~~~~~~
-
- * First working release
-
----
This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
@@ -211,19 +136,18 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
.. _`Cookiecutter`: https://github.com/audreyr/cookiecutter
.. _`@hackebrot`: https://github.com/hackebrot
- .. _`Apache Software License 2.0`: http://www.apache.org/licenses/LICENSE-2.0
.. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
- .. _`file an issue`: https://github.com/saltstack/pytest-helpers-namespace/issues
.. _`pytest`: https://github.com/pytest-dev/pytest
- .. _`nox`: https://nox.thea.codes/en/stable/
.. _`pip`: https://pypi.python.org/pypi/pip/
.. _`PyPI`: https://pypi.python.org/pypi
- .. _`#1`: https://github.com/saltstack/pytest-helpers-namespace/issues/1
- .. _`#3`: https://github.com/saltstack/pytest-helpers-namespace/pull/3
- .. _`#4`: https://github.com/saltstack/pytest-helpers-namespace/issues/4
+ ..
+ include-ends-here
+
+ Documentation
+ =============
- .. _`@lsglick`: https://github.com/lsglick
+ The full documentation can be seen `here <https://pytest-helpers-namespace.readthedocs.io>`_.
Platform: unix
Platform: linux
@@ -239,10 +163,13 @@ Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
-Requires-Python: >=3.5
+Requires-Python: >=3.5.6
+Description-Content-Type: text/x-rst
Provides-Extra: docs
Provides-Extra: lint
Provides-Extra: tests
+Provides-Extra: changelog
diff --git a/README.rst b/README.rst
index 79c6bc4..93557dc 100644
--- a/README.rst
+++ b/README.rst
@@ -26,6 +26,9 @@
:alt: Supported implementations
:target: https://pypi.python.org/pypi/pytest-helpers-namespace
+..
+ include-starts-here
+
Pytest Helpers Namespace
========================
@@ -67,11 +70,12 @@ Consider the following ``conftest.py`` file:
import pytest
+
@pytest.helpers.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -90,15 +94,16 @@ You can even nest namespaces. Consider the following ``conftest.py`` file:
.. code-block:: python
- pytest_plugins = ['helpers_namespace']
+ pytest_plugins = ["helpers_namespace"]
import pytest
+
@pytest.helpers.can.haz.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -113,86 +118,6 @@ And now consider the following test case:
You can even pass a name to the register function and that will be the helper function name.
-Contributing
-------------
-Contributions are very welcome. Tests can be run with `nox`_, please ensure
-the coverage at least stays the same before you submit a pull request.
-
-License
--------
-
-Distributed under the terms of the `Apache Software License 2.0`_ license,
-"pytest-helpers-namespace" is free and open source software.
-
-
-Issues
-------
-
-If you encounter any problems, please `file an issue`_ along with a detailed
-description.
-
-Changelog
----------
-
-v2021.3.24
-~~~~~~~~~~
-
-* Switched project to a ``src`` layout.
-* Switched project to a declarative setuptools approach
-* Added support to check if a helper has been registered
-* Pytest >= 6.1.1 is now required
-
-v2019.1.8
-~~~~~~~~~
-
-* Patch PyTest before any ``conftest.py`` file is processed.
-
-v2019.1.7
-~~~~~~~~~
-
-* Support PyTest >= 4.1
-
-v2019.1.6.post1
-~~~~~~~~~~~~~~~
-
-* No changes were made besides locking to PyTest < 4.0
-
-v2019.1.6
-~~~~~~~~~
-
-* No changes were made besides locking to PyTest < 4.1
-
-v2017.11.11
-~~~~~~~~~~~
-
-* Allow passing a string to the register function which will be the helper name
-
-v2016.7.10
-~~~~~~~~~~
-
-* Allow a registered function to contibue to behave as a regular function. `#4`_.
-
-v2016.4.15
-~~~~~~~~~~
-
-* Hide the ``FuncWrapper`` traceback in pytest failures. `#3`_. Thanks Logan Glickfield(`@lsglick`_)
-
-v2016.4.5
-~~~~~~~~~
-
-* Use a wrapper class instead of adding an attribute to a function.
-
-v2016.4.3
-~~~~~~~~~
-
-* Provide proper errors when helper functions or namespaces are being
- overridden. `#1`_
-
-v2016.3.2
-~~~~~~~~~~
-
-* First working release
-
----
This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
@@ -200,16 +125,15 @@ This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
.. _`Cookiecutter`: https://github.com/audreyr/cookiecutter
.. _`@hackebrot`: https://github.com/hackebrot
-.. _`Apache Software License 2.0`: http://www.apache.org/licenses/LICENSE-2.0
.. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
-.. _`file an issue`: https://github.com/saltstack/pytest-helpers-namespace/issues
.. _`pytest`: https://github.com/pytest-dev/pytest
-.. _`nox`: https://nox.thea.codes/en/stable/
.. _`pip`: https://pypi.python.org/pypi/pip/
.. _`PyPI`: https://pypi.python.org/pypi
-.. _`#1`: https://github.com/saltstack/pytest-helpers-namespace/issues/1
-.. _`#3`: https://github.com/saltstack/pytest-helpers-namespace/pull/3
-.. _`#4`: https://github.com/saltstack/pytest-helpers-namespace/issues/4
+..
+ include-ends-here
+
+Documentation
+=============
-.. _`@lsglick`: https://github.com/lsglick
+The full documentation can be seen `here <https://pytest-helpers-namespace.readthedocs.io>`_.
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 1d3ea23..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-# What Python version is installed where:
-# http://www.appveyor.com/docs/installed-software#python
-
-environment:
- matrix:
- - PYTHON: "C:\\Python27"
- TOX_ENV: "py27"
-
- - PYTHON: "C:\\Python35"
- TOX_ENV: "py35"
-
- - PYTHON: "C:\\Python36"
- TOX_ENV: "py36"
-
- - PYTHON: "C:\\Python35"
- TOX_ENV: "py35"
-
-
-init:
- - "%PYTHON%/python -V"
- - "%PYTHON%/python -c \"import struct;print( 8 * struct.calcsize(\'P\'))\""
-
-install:
- - "%PYTHON%/Scripts/easy_install -U pip"
- - "%PYTHON%/Scripts/pip install tox"
- - "%PYTHON%/Scripts/pip install wheel"
- - "%PYTHON%/Scripts/pip install coverage codecov pytest-cov"
-
-build: false # Not a C# project, build stuff at the test step instead.
-
-test_script:
- - "%PYTHON%/Scripts/tox -e %TOX_ENV%"
-
-after_test:
- - "%PYTHON%/python setup.py bdist_wheel"
- - ps: "ls dist"
-
-artifacts:
- - path: dist\*
-
-on_success:
- - "%PYTHON%/Scripts/coverage report"
diff --git a/changelog/_template.rst b/changelog/_template.rst
new file mode 100644
index 0000000..f8733a0
--- /dev/null
+++ b/changelog/_template.rst
@@ -0,0 +1,48 @@
+{% macro issue_link(value) -%}
+`{{ value }} <https://github.com/saltstack/pytest-helpers-namespace/issues/{{ value[1:] }}>`_
+{%- endmacro %}
+
+{% if top_line %}
+{{ top_line }}
+{{ top_underline * ((top_line)|length)}}
+{% elif versiondata.name %}
+{{ versiondata.name }} {{ versiondata.version }} ({{ versiondata.date }})
+{{ top_underline * ((versiondata.name + versiondata.version + versiondata.date)|length + 4)}}
+{% else %}
+{{ versiondata.version }} ({{ versiondata.date }})
+{{ top_underline * ((versiondata.version + versiondata.date)|length + 3)}}
+{% endif %}
+{% for section, _ in sections.items() %}
+{% set underline = underlines[0] %}{% if section %}{{section}}
+{{ underline * section|length }}{% set underline = underlines[1] %}
+
+{% endif %}
+
+{% if sections[section] %}
+{% for category, val in definitions.items() if category in sections[section]%}
+{{ definitions[category]['name'] }}
+{{ underline * definitions[category]['name']|length }}
+
+{% if definitions[category]['showcontent'] %}
+{% for text, values in sections[section][category].items() %}
+{% set issue_joiner = joiner(', ') -%}
+- {% for value in values|sort %}{{ issue_joiner() }}{{ issue_link(value) }}{% endfor %}: {{ text }}
+{% endfor %}
+
+{% else %}
+- {{ sections[section][category]['']|join(', ') }}
+
+{% endif %}
+{% if sections[section][category]|length == 0 %}
+No significant changes.
+
+{% else %}
+{% endif %}
+
+{% endfor %}
+{% else %}
+No significant changes.
+
+
+{% endif %}
+{% endfor %}
diff --git a/debian/changelog b/debian/changelog
index ae15d9b..19f1119 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,9 @@
-pytest-helpers-namespace (2021.4.29-2) UNRELEASED; urgency=medium
+pytest-helpers-namespace (2021.12.29-1) UNRELEASED; urgency=medium
* Update standards version to 4.6.2, no changes needed.
+ * New upstream release.
- -- Debian Janitor <janitor@jelmer.uk> Wed, 11 Jan 2023 10:23:52 -0000
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 11 Jan 2023 14:13:03 -0000
pytest-helpers-namespace (2021.4.29-1) unstable; urgency=medium
diff --git a/debian/patches/Drop-setuptools-declarative-requirements.patch b/debian/patches/Drop-setuptools-declarative-requirements.patch
index d0aed49..5ebc85f 100644
--- a/debian/patches/Drop-setuptools-declarative-requirements.patch
+++ b/debian/patches/Drop-setuptools-declarative-requirements.patch
@@ -15,11 +15,11 @@ Signed-off-by: Benjamin Drung <benjamin.drung@ionos.com>
setup.cfg | 1 -
1 file changed, 1 deletion(-)
-diff --git a/setup.cfg b/setup.cfg
-index a5c667d..f4a9875 100644
---- a/setup.cfg
-+++ b/setup.cfg
-@@ -35,7 +35,6 @@ python_requires = >= 3.5
+Index: pytest-helpers-namespace.git/setup.cfg
+===================================================================
+--- pytest-helpers-namespace.git.orig/setup.cfg
++++ pytest-helpers-namespace.git/setup.cfg
+@@ -37,7 +37,6 @@ python_requires = >= 3.5.6
setup_requires =
setuptools>=50.3.2
setuptools_scm[toml]>=3.4
@@ -27,6 +27,3 @@ index a5c667d..f4a9875 100644
[options.packages.find]
where = src
---
-2.27.0
-
diff --git a/docs/Makefile b/docs/Makefile
index 2d87ff4..d4bb2cb 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,192 +1,20 @@
-# Makefile for Sphinx documentation
+# Minimal makefile for Sphinx documentation
#
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
BUILDDIR = _build
-# User-friendly check for sphinx-build
-ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
-endif
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
-
+# Put it first so that "make" without argument is like "make help".
help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " applehelp to make an Apple Help Book"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
- @echo " coverage to run coverage check of the documentation (if enabled)"
-
-clean:
- rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pytest-cookiecutterplugin_name.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pytest-cookiecutterplugin_name.qhc"
-
-applehelp:
- $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
- @echo
- @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
- @echo "N.B. You won't be able to view it unless you put it in" \
- "~/Library/Documentation/Help or install it in your application" \
- "bundle."
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/pytest-cookiecutterplugin_name"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pytest-cookiecutterplugin_name"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-latexpdfja:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-coverage:
- $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
- @echo "Testing of coverage in the sources finished, look at the " \
- "results in $(BUILDDIR)/coverage/python.txt."
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+.PHONY: help Makefile
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/css/inline-include.css b/docs/_static/css/inline-include.css
new file mode 100644
index 0000000..8a7d434
--- /dev/null
+++ b/docs/_static/css/inline-include.css
@@ -0,0 +1,15 @@
+.literal-block-wrapper, article div[class^="highlight-default"] {
+ margin-top: 0.4em;
+}
+
+.literal-block-wrapper .code-block-caption {
+ text-align: left;
+}
+
+.literal-block-wrapper .code-block-caption .caption-text {
+ padding: 0.5em 0.7em;
+ border: .1em solid var(--color-code-background);
+ border-radius: 0.6rem 0.6rem 0 0;
+ background-color: var(--color-code-background);
+ font-family: var(--font-stack--monospace);
+}
diff --git a/docs/_static/img/SaltProject_Logomark_teal.png b/docs/_static/img/SaltProject_Logomark_teal.png
new file mode 100644
index 0000000..70a0d9a
Binary files /dev/null and b/docs/_static/img/SaltProject_Logomark_teal.png differ
diff --git a/docs/_static/img/SaltProject_altlogo_teal.png b/docs/_static/img/SaltProject_altlogo_teal.png
new file mode 100644
index 0000000..53f3998
Binary files /dev/null and b/docs/_static/img/SaltProject_altlogo_teal.png differ
diff --git a/docs/all.rst b/docs/all.rst
new file mode 100644
index 0000000..681fed1
--- /dev/null
+++ b/docs/all.rst
@@ -0,0 +1,10 @@
+.. _all the states/modules:
+
+Complete List of pytest-helpers-namespace
+=========================================
+
+
+.. toctree::
+ :maxdepth: 2
+
+ ref/modules.rst
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..565b052
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1 @@
+.. include:: ../CHANGELOG.rst
diff --git a/docs/conf.py b/docs/conf.py
index b98d46d..08cc1a1 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,3 +1,6 @@
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
@@ -13,16 +16,30 @@ import os
import pathlib
import sys
-import sphinx_material_saltstack
+try:
+ from importlib_metadata import distribution
+except ImportError:
+ from importlib.metadata import distribution
+
-docs_basepath = pathlib.Path(__file__).resolve()
+try:
+ DOCS_BASEPATH = pathlib.Path(__file__).resolve().parent
+except NameError:
+ # sphinx-intl and six execute some code which will raise this NameError
+ # assume we're in the doc/ directory
+ DOCS_BASEPATH = pathlib.Path(".").resolve().parent
-additional_paths = (docs_basepath / "_ext", docs_basepath.parent.parent / "src")
+REPO_ROOT = DOCS_BASEPATH.parent
+
+addtl_paths = (
+ os.path.join(os.pardir, "src"), # pytest-helpers-namespace itself (for autodoc)
+ "_ext", # custom Sphinx extensions
+)
-for path in additional_paths:
- sys.path.insert(0, str(path))
+for addtl_path in addtl_paths:
+ sys.path.insert(0, os.path.abspath(os.path.join(DOCS_BASEPATH, addtl_path)))
-import pytest_helpers_namespace
+dist = distribution("pytest-helpers-namespace")
# -- Project information -----------------------------------------------------
@@ -31,16 +48,16 @@ if this_year == 2020:
copyright_year = 2020
else:
copyright_year = f"2020 - {this_year}"
-project = "PyTest Helpers Namespace"
-copyright = f"{copyright_year}, SaltStack, Inc."
-author = "SaltStack, Inc."
+project = dist.metadata["Summary"]
+author = dist.metadata["Author"]
+copyright = f"{copyright_year}, {author}" # pylint: disable=redefined-builtin
# The full version, including alpha/beta/rc tags
-release = pytest_helpers_namespace.__version__
+release = dist.version
# Variables to pass into the docs from sitevars.rst for rst substitution
-with open("sitevars.rst") as site_vars_file:
+with open("sitevars.rst", encoding="utf-8") as site_vars_file:
site_vars = site_vars_file.read().splitlines()
rst_prolog = """
@@ -55,7 +72,6 @@ rst_prolog = """
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
- "sphinx_material_saltstack",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.napoleon",
@@ -63,7 +79,9 @@ extensions = [
"sphinx.ext.viewcode",
"sphinx.ext.todo",
"sphinx.ext.coverage",
+ "sphinx_copybutton",
"sphinxcontrib.spelling",
+ "sphinxcontrib.towncrier",
]
# Add any paths that contain templates here, relative to this directory.
@@ -85,37 +103,16 @@ exclude_patterns = [
]
autosummary_generate = True
+modindex_common_prefix = ["pytest_helpers_namespace."]
+master_doc = "contents"
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = "sphinx_material_saltstack"
-html_theme_path = sphinx_material_saltstack.html_theme_path()
-html_context = sphinx_material_saltstack.get_html_context()
-html_sidebars = {"**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]}
-html_theme_options = {
- # Set the name of the project to appear in the navigation.
- "nav_title": "PyTest Helpers Namespace",
- # Set you GA account ID to enable tracking
- # "google_analytics_account": "",
- # Set the repo location to get a badge with stats (only if public repo)
- "repo_url": "https://github.com/saltstack/pytest-helpers-namespace",
- "repo_name": "pytest-helpers-namespace",
- "repo_type": "github",
- # Visible levels of the global TOC; -1 means unlimited
- "globaltoc_depth": 1,
- # If False, expand all TOC entries
- "globaltoc_collapse": False,
- # If True, show hidden TOC entries
- "globaltoc_includehidden": True,
- # hide tabs?
- "master_doc": False,
- # Minify for smaller HTML/CSS assets
- "html_minify": True,
- "css_minify": True,
-}
+html_theme = "furo"
+html_title = project
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@@ -124,25 +121,13 @@ html_static_path = ["_static"]
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-html_logo = os.path.join(
- html_theme_path[0],
- "sphinx_material_saltstack",
- "static",
- "images",
- "saltstack-logo.png",
-)
+html_logo = ""
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large. Favicons can be up to at least 228x228. PNG
# format is supported as well, not just .ico'
-html_favicon = os.path.join(
- html_theme_path[0],
- "sphinx_material_saltstack",
- "static",
- "images",
- "favicon.png",
-)
+html_favicon = ""
# Sphinx Napoleon Config
napoleon_google_docstring = True
@@ -160,7 +145,7 @@ napoleon_use_rtype = True
# ----- Intersphinx Config ---------------------------------------------------------------------------------------->
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
- "pytest": ("https://pytest.readthedocs.io/en/stable", None),
+ "pytest": ("https://docs.pytest.org/en/stable", None),
}
# <---- Intersphinx Config -----------------------------------------------------------------------------------------
@@ -169,6 +154,15 @@ autodoc_default_options = {"member-order": "bysource"}
autodoc_mock_imports = []
# <---- Autodoc Config -----------------------------------------------------------------------------------------------
+# ----- Towncrier Draft Release ------------------------------------------------------------------------------------->
+# Options: draft/sphinx-version/sphinx-release
+towncrier_draft_autoversion_mode = "draft"
+towncrier_draft_include_empty = True
+towncrier_draft_working_directory = REPO_ROOT
+# Not yet supported:
+# towncrier_draft_config_path = 'pyproject.toml' # relative to cwd
+# <---- Towncrier Draft Release --------------------------------------------------------------------------------------
+
def setup(app):
app.add_crossref_type(
@@ -176,7 +170,7 @@ def setup(app):
rolename="fixture",
indextemplate="pair: %s; fixture",
)
- # Allow linking to pytest confvals.
+ # Allow linking to pytest's confvals.
app.add_object_type(
"confval",
"pytest-confval",
diff --git a/docs/contents.rst b/docs/contents.rst
new file mode 100644
index 0000000..8506bc5
--- /dev/null
+++ b/docs/contents.rst
@@ -0,0 +1,13 @@
+.. _table-of-contents:
+
+=================
+Table Of Contents
+=================
+
+
+.. toctree::
+ :maxdepth: 3
+
+ ref/pytest_helpers_namespace
+ changelog
+ GitHub Repository <https://github.com/saltstack/pytest-helpers-namespace>
diff --git a/docs/index.rst b/docs/index.rst
index e3fedb7..4d30e3e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,16 +1,35 @@
-Pytest Helpers Namespace
-========================
+:orphan:
-.. include:: ../README.rst
- :start-after: ========================
+.. _about:
+.. include:: ../README.rst
+ :start-after: include-starts-here
+ :end-before: include-ends-here
-Contents:
+Documentation
+=============
-.. toctree::
- :maxdepth: 2
+Please see :ref:`Contents <table-of-contents>` for full documentation, including installation and tutorials.
+
+Bugs/Requests
+=============
+
+Please use the `GitHub issue tracker`_ to submit bugs or request features.
+
+
+Changelog
+=========
+Consult the :ref:`Changelog <changelog>` page for fixes and enhancements of each version.
+
+
+.. _GitHub issue tracker: https://github.com/saltstack/pytest-helpers-namespace/issues
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+ all.rst
Indices and tables
==================
diff --git a/docs/make.bat b/docs/make.bat
index 28beda1..922152e 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -1,62 +1,18 @@
@ECHO OFF
+pushd %~dp0
+
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
+set SOURCEDIR=.
set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
if "%1" == "" goto help
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. xml to make Docutils-native XML files
- echo. pseudoxml to make pseudoxml-XML files for display purposes
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- echo. coverage to run coverage check of the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-REM Check if sphinx-build is available and fallback to Python version if any
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 goto sphinx_python
-goto sphinx_ok
-
-:sphinx_python
-
-set SPHINXBUILD=python -m sphinx.__init__
-%SPHINXBUILD% 2> nul
+%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
@@ -69,195 +25,11 @@ if errorlevel 9009 (
exit /b 1
)
-:sphinx_ok
-
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pytest-cookiecutterplugin_name.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pytest-cookiecutterplugin_name.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdf" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf
- cd %~dp0
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdfja" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf-ja
- cd %~dp0
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-if "%1" == "coverage" (
- %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of coverage in the sources finished, look at the ^
-results in %BUILDDIR%/coverage/python.txt.
- goto end
-)
-
-if "%1" == "xml" (
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
- goto end
-)
-
-if "%1" == "pseudoxml" (
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
- goto end
-)
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
+popd
diff --git a/docs/ref/modules.rst b/docs/ref/modules.rst
new file mode 100644
index 0000000..219de5a
--- /dev/null
+++ b/docs/ref/modules.rst
@@ -0,0 +1,7 @@
+pytest_helpers_namespace
+========================
+
+.. toctree::
+ :maxdepth: 4
+
+ pytest_helpers_namespace
diff --git a/docs/ref/pytest_helpers_namespace.rst b/docs/ref/pytest_helpers_namespace.rst
new file mode 100644
index 0000000..e9fb430
--- /dev/null
+++ b/docs/ref/pytest_helpers_namespace.rst
@@ -0,0 +1,26 @@
+pytest\_helpers\_namespace package
+==================================
+
+.. automodule:: pytest_helpers_namespace
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Submodules
+----------
+
+pytest\_helpers\_namespace.plugin module
+----------------------------------------
+
+.. automodule:: pytest_helpers_namespace.plugin
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+pytest\_helpers\_namespace.version module
+-----------------------------------------
+
+.. automodule:: pytest_helpers_namespace.version
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/noxfile.py b/noxfile.py
index fb8dc14..43e4ca6 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -1,3 +1,7 @@
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
+# pylint: disable=import-error,protected-access,line-too-long
import datetime
import json
import os
@@ -11,23 +15,19 @@ from nox.command import CommandFailed
COVERAGE_VERSION_REQUIREMENT = "coverage==5.5"
+PYTEST_VERSION_REQUIREMENT = os.environ.get("PYTEST_VERSION_REQUIREMENT") or None
IS_WINDOWS = sys.platform.lower().startswith("win")
IS_DARWIN = sys.platform.lower().startswith("darwin")
if IS_WINDOWS:
- COVERAGE_FAIL_UNDER_PERCENT = 70
+ COVERAGE_FAIL_UNDER_PERCENT = 96
elif IS_DARWIN:
- COVERAGE_FAIL_UNDER_PERCENT = 75
+ COVERAGE_FAIL_UNDER_PERCENT = 96
else:
- COVERAGE_FAIL_UNDER_PERCENT = 80
+ COVERAGE_FAIL_UNDER_PERCENT = 96
# Be verbose when running under a CI context
-PIP_INSTALL_SILENT = (
- os.environ.get("JENKINS_URL")
- or os.environ.get("CI")
- or os.environ.get("DRONE")
- or os.environ.get("GITHUB_ACTIONS")
-) is None
+PIP_INSTALL_SILENT = (os.environ.get("CI") or os.environ.get("GITHUB_ACTIONS")) is None
CI_RUN = PIP_INSTALL_SILENT is False
SKIP_REQUIREMENTS_INSTALL = "SKIP_REQUIREMENTS_INSTALL" in os.environ
EXTRA_REQUIREMENTS_INSTALL = os.environ.get("EXTRA_REQUIREMENTS_INSTALL")
@@ -37,7 +37,6 @@ REPO_ROOT = pathlib.Path(__file__).resolve().parent
# Change current directory to REPO_ROOT
os.chdir(str(REPO_ROOT))
-SITECUSTOMIZE_DIR = str(REPO_ROOT / "tests" / "support" / "coverage")
ARTIFACTS_DIR = REPO_ROOT / "artifacts"
# Make sure the artifacts directory exists
ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True)
@@ -56,6 +55,24 @@ nox.options.reuse_existing_virtualenvs = True
nox.options.error_on_missing_interpreters = False
+def pytest_version(session):
+ try:
+ return session._runner._pytest_version_info
+ except AttributeError:
+ session_pytest_version = session_run_always(
+ session,
+ "python",
+ "-c",
+ 'import sys, pkg_resources; sys.stdout.write("{}".format(pkg_resources.get_distribution("pytest").version))',
+ silent=True,
+ log=False,
+ )
+ session._runner._pytest_version_info = tuple(
+ int(part) for part in session_pytest_version.split(".") if part.isdigit()
+ )
+ return session._runner._pytest_version_info
+
+
def session_run_always(session, *command, **kwargs):
try:
# Guess we weren't the only ones wanting this
@@ -73,23 +90,26 @@ def session_run_always(session, *command, **kwargs):
session._runner.global_config.install_only = old_install_only_value
-@nox.session(python=("3", "3.5", "3.6", "3.7", "3.8", "3.9"))
+@nox.session(python=("3", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"))
def tests(session):
"""
- Run tests
+ Run tests.
"""
env = {}
if SKIP_REQUIREMENTS_INSTALL is False:
# Always have the wheel package installed
- session.install("wheel", silent=PIP_INSTALL_SILENT)
- session.install(COVERAGE_VERSION_REQUIREMENT, silent=PIP_INSTALL_SILENT)
- pytest_version_requirement = os.environ.get("PYTEST_VERSION_REQUIREMENT") or None
+ session.install("--progress-bar=off", "wheel", silent=PIP_INSTALL_SILENT)
+ session.install(
+ "--progress-bar=off", COVERAGE_VERSION_REQUIREMENT, silent=PIP_INSTALL_SILENT
+ )
+ pytest_version_requirement = PYTEST_VERSION_REQUIREMENT
if pytest_version_requirement:
if not pytest_version_requirement.startswith("pytest"):
pytest_version_requirement = "pytest{}".format(pytest_version_requirement)
- session.install(pytest_version_requirement, silent=PIP_INSTALL_SILENT)
- session.install("-e", ".", silent=PIP_INSTALL_SILENT)
- session.install("-r", os.path.join("requirements", "tests.txt"), silent=PIP_INSTALL_SILENT)
+ session.install(
+ "--progress-bar=off", pytest_version_requirement, silent=PIP_INSTALL_SILENT
+ )
+ session.install("--progress-bar=off", "-e", ".[tests]", silent=PIP_INSTALL_SILENT)
if EXTRA_REQUIREMENTS_INSTALL:
session.log(
@@ -103,25 +123,15 @@ def tests(session):
session.run("coverage", "erase")
- python_path_env_var = os.environ.get("PYTHONPATH") or None
- if python_path_env_var is None:
- python_path_env_var = SITECUSTOMIZE_DIR
- else:
- python_path_entries = python_path_env_var.split(os.pathsep)
- if SITECUSTOMIZE_DIR in python_path_entries:
- python_path_entries.remove(SITECUSTOMIZE_DIR)
- python_path_entries.insert(0, SITECUSTOMIZE_DIR)
- python_path_env_var = os.pathsep.join(python_path_entries)
-
- env = {
- # The updated python path so that sitecustomize is importable
- "PYTHONPATH": python_path_env_var,
- # The full path to the .coverage data file. Makes sure we always write
- # them to the same directory
- "COVERAGE_FILE": str(COVERAGE_REPORT_DB),
- # Instruct sub processes to also run under coverage
- "COVERAGE_PROCESS_START": str(REPO_ROOT / ".coveragerc"),
- }
+ env.update(
+ {
+ # The full path to the .coverage data file. Makes sure we always write
+ # them to the same directory
+ "COVERAGE_FILE": str(COVERAGE_REPORT_DB),
+ # Instruct sub processes to also run under coverage
+ "COVERAGE_PROCESS_START": str(REPO_ROOT / ".coveragerc"),
+ }
+ )
args = [
"--rootdir",
@@ -131,9 +141,12 @@ def tests(session):
"--show-capture=no",
"--junitxml={}".format(JUNIT_REPORT),
"--showlocals",
+ "--strict-markers",
"-ra",
"-s",
]
+ if pytest_version(session) > (6, 2):
+ args.append("--lsof")
if session._runner.global_config.forcecolor:
args.append("--color=yes")
if not session.posargs:
@@ -144,54 +157,51 @@ def tests(session):
args.remove("--color=yes")
args.append(arg)
- session.run("coverage", "run", "-m", "pytest", *args, env=env)
-
- # Always combine and generate the XML coverage report
- try:
- session.run("coverage", "combine")
- except CommandFailed:
- # Sometimes some of the coverage files are corrupt which would
- # trigger a CommandFailed exception
- pass
- # Generate report for project code coverage
- session.run(
- "coverage",
- "xml",
- "-o",
- str(COVERAGE_REPORT_PROJECT),
- "--omit=tests/*",
- "--include=src/pytest_helpers_namespace/*",
- )
- # Generate report for tests code coverage
- session.run(
- "coverage",
- "xml",
- "-o",
- str(COVERAGE_REPORT_TESTS),
- "--omit=src/pytest_helpers_namespace/*",
- "--include=tests/*",
- )
try:
- cmdline = [
- "coverage",
- "report",
- "--show-missing",
- "--include=src/pytest_helpers_namespace/*,tests/*",
- "--fail-under={}".format(COVERAGE_FAIL_UNDER_PERCENT),
- ]
- session.run(*cmdline)
+ session.run("coverage", "run", "-m", "pytest", *args, env=env)
finally:
- if COVERAGE_REPORT_DB.exists():
- shutil.copyfile(str(COVERAGE_REPORT_DB), str(ARTIFACTS_DIR / ".coverage"))
+ # Always combine and generate the XML coverage report
+ try:
+ session.run("coverage", "combine")
+ except CommandFailed:
+ # Sometimes some of the coverage files are corrupt which would
+ # trigger a CommandFailed exception
+ pass
+ # Generate report for project code coverage
+ session.run(
+ "coverage",
+ "xml",
+ "-o",
+ str(COVERAGE_REPORT_PROJECT),
+ "--omit=tests/*",
+ "--include=src/pytest_helpers_namespace/*",
+ )
+ # Generate report for tests code coverage
+ session.run(
+ "coverage",
+ "xml",
+ "-o",
+ str(COVERAGE_REPORT_TESTS),
+ "--omit=src/pytest_helpers_namespace/*",
+ "--include=tests/*",
+ )
+ try:
+ cmdline = [
+ "coverage",
+ "report",
+ "--show-missing",
+ "--include=src/pytest_helpers_namespace/*,tests/*",
+ ]
+ session.run(*cmdline)
+ if pytest_version(session) >= (6, 2):
+ cmdline.append("--fail-under={}".format(COVERAGE_FAIL_UNDER_PERCENT))
+ finally:
+ if COVERAGE_REPORT_DB.exists():
+ shutil.copyfile(str(COVERAGE_REPORT_DB), str(ARTIFACTS_DIR / ".coverage"))
def _lint(session, rcfile, flags, paths):
- session.install(
- "--progress-bar=off",
- "-r",
- os.path.join("requirements", "lint.txt"),
- silent=PIP_INSTALL_SILENT,
- )
+ session.install("--progress-bar=off", "-e", ".[lint]", silent=PIP_INSTALL_SILENT)
session.run("pylint", "--version")
pylint_report_path = os.environ.get("PYLINT_REPORT")
@@ -209,7 +219,7 @@ def _lint(session, rcfile, flags, paths):
sys.stdout.flush()
if pylint_report_path:
# Write report
- with open(pylint_report_path, "w") as wfh:
+ with open(pylint_report_path, "w", encoding="utf-8") as wfh:
wfh.write(contents)
session.log("Report file written to %r", pylint_report_path)
stdout.close()
@@ -253,21 +263,16 @@ def lint_tests(session):
@nox.session(python="3")
def docs(session):
"""
- Build Docs
+ Build Docs.
"""
- session.install(
- "--progress-bar=off",
- "-r",
- os.path.join("requirements", "docs.txt"),
- silent=PIP_INSTALL_SILENT,
- )
+ session.install("--progress-bar=off", "-e", ".[docs]", silent=PIP_INSTALL_SILENT)
os.chdir("docs/")
session.run("make", "clean", external=True)
- session.run("make", "linkcheck", "SPHINXOPTS=-W", external=True)
+ # session.run("make", "linkcheck", "SPHINXOPTS=-W", external=True)
session.run("make", "coverage", "SPHINXOPTS=-W", external=True)
docs_coverage_file = os.path.join("_build", "html", "python.txt")
if os.path.exists(docs_coverage_file):
- with open(docs_coverage_file) as rfh:
+ with open(docs_coverage_file, encoding="utf-8") as rfh:
contents = rfh.readlines()[2:]
if contents:
session.error("\n" + "".join(contents))
@@ -275,17 +280,23 @@ def docs(session):
os.chdir("..")
+@nox.session(name="docs-dev", python="3")
+def docs_dev(session):
+ """
+ Build Docs.
+ """
+ session.install("--progress-bar=off", "-e", ".[docs]", silent=PIP_INSTALL_SILENT)
+ os.chdir("docs/")
+ session.run("make", "html", "SPHINXOPTS=-W", external=True, env={"LOCAL_DEV_BUILD": "1"})
+ os.chdir("..")
+
+
@nox.session(name="docs-crosslink-info", python="3")
def docs_crosslink_info(session):
"""
- Report intersphinx cross links information
+ Report intersphinx cross links information.
"""
- session.install(
- "--progress-bar=off",
- "-r",
- os.path.join("requirements", "docs.txt"),
- silent=PIP_INSTALL_SILENT,
- )
+ session.install("--progress-bar=off", "-e", ".[docs]", silent=PIP_INSTALL_SILENT)
os.chdir("docs/")
intersphinx_mapping = json.loads(
session.run(
@@ -319,15 +330,92 @@ def docs_crosslink_info(session):
@nox.session(name="gen-api-docs", python="3")
def gen_api_docs(session):
"""
- Generate API Docs
+ Generate API Docs.
"""
- session.install(
- "--progress-bar=off",
- "-r",
- os.path.join("requirements", "docs.txt"),
- silent=PIP_INSTALL_SILENT,
- )
- shutil.rmtree("docs/ref")
+ session.install("--progress-bar=off", "-e", ".[docs]", silent=PIP_INSTALL_SILENT)
+ shutil.rmtree("docs/ref", ignore_errors=True)
session.run(
"sphinx-apidoc", "--module-first", "-o", "docs/ref/", "src/pytest_helpers_namespace/"
)
+
+
+@nox.session(name="twine-check", python="3")
+def twine_check(session):
+ """
+ Run ``twine-check`` against the source distribution package.
+ """
+ session.install("--progress-bar=off", "twine", silent=PIP_INSTALL_SILENT)
+ session.run(
+ "python",
+ "setup.py",
+ "sdist",
+ silent=True,
+ log=False,
+ )
+ session.run("twine", "check", "dist/*")
+
+
+@nox.session(name="changelog", python="3")
+@nox.parametrize("draft", [False, True])
+def changelog(session, draft):
+ """
+ Generate changelog.
+ """
+ session.install("--progress-bar=off", "-e", ".[changelog]", silent=PIP_INSTALL_SILENT)
+ version = session.run(
+ "python",
+ "setup.py",
+ "--version",
+ silent=True,
+ log=False,
+ stderr=None,
+ )
+
+ town_cmd = ["towncrier", "build", "--version={}".format(version.strip())]
+ if draft:
+ town_cmd.append("--draft")
+ session.run(*town_cmd)
+
+
+@nox.session(name="release")
+def release(session):
+ """
+ Create a release tag.
+ """
+ if not session.posargs:
+ session.error(
+ "Forgot to pass the version to release? For example `nox -e release -- 1.1.0`"
+ )
+ if len(session.posargs) > 1:
+ session.error(
+ "Only one argument is supported by the `release` nox session. "
+ "For example `nox -e release -- 1.1.0`"
+ )
+ version = session.posargs[0]
+ try:
+ session.log("Generating temporary %s tag", version)
+ session.run("git", "tag", "-as", version, "-m", "Release {}".format(version), external=True)
+ changelog(session, draft=False)
+ except CommandFailed:
+ session.error("Failed to generate the temporary tag")
+ # session.notify("changelog(draft=False)")
+ try:
+ session.log("Generating the release changelog")
+ session.run(
+ "git",
+ "commit",
+ "-a",
+ "-m",
+ "Generate Changelog for version {}".format(version),
+ external=True,
+ )
+ except CommandFailed:
+ session.error("Failed to generate the release changelog")
+ try:
+ session.log("Overwriting temporary %s tag", version)
+ session.run(
+ "git", "tag", "-fas", version, "-m", "Release {}".format(version), external=True
+ )
+ except CommandFailed:
+ session.error("Failed to overwrite the temporary tag")
+ session.warn("Don't forget to push the newly created tag")
diff --git a/pyproject.toml b/pyproject.toml
index be0791f..ee96ddb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,4 +4,46 @@ build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
write_to = "src/pytest_helpers_namespace/version.py"
-write_to_template = "__version__ = \"{version}\""
+write_to_template = "# pylint: skip-file\n\n__version__ = \"{version}\"\n"
+
+[tool.towncrier]
+package = "pytest_helpers_namespace"
+filename = "CHANGELOG.rst"
+directory = "changelog/"
+title_format = "{version}"
+template = "changelog/_template.rst"
+
+ [[tool.towncrier.type]]
+ directory = "breaking"
+ name = "Breaking Changes"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "deprecation"
+ name = "Deprecations"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "feature"
+ name = "Features"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "improvement"
+ name = "Improvements"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "bugfix"
+ name = "Bug Fixes"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "doc"
+ name = "Improved Documentation"
+ showcontent = true
+
+ [[tool.towncrier.type]]
+ directory = "trivial"
+ name = "Trivial/Internal Changes"
+ showcontent = true
diff --git a/requirements/changelog.txt b/requirements/changelog.txt
new file mode 100644
index 0000000..fe1c872
--- /dev/null
+++ b/requirements/changelog.txt
@@ -0,0 +1 @@
+towncrier==21.9.0rc1
diff --git a/requirements/docs.txt b/requirements/docs.txt
index e2c4f44..5d3aa3d 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -1,6 +1,9 @@
-r base.txt
-r tests.txt
+furo
sphinx
-sphinx-material-saltstack
+sphinx-copybutton
sphinx-prompt
sphinxcontrib-spelling
+towncrier==21.3.0
+sphinxcontrib-towncrier >= 0.2.0a0
diff --git a/requirements/lint.txt b/requirements/lint.txt
index 41a062b..8b68639 100644
--- a/requirements/lint.txt
+++ b/requirements/lint.txt
@@ -1,7 +1,6 @@
-r base.txt
-r tests.txt
-pylint==2.4.4
-saltpylint==2019.6.7
+pylint==2.12.2
pyenchant
black; python_version >= '3.7'
reorder-python-imports; python_version >= '3.7'
diff --git a/setup.cfg b/setup.cfg
index 2985a7e..0b04f97 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,6 +2,7 @@
name = pytest-helpers-namespace
description = Pytest Helpers Namespace Plugin
long_description = file: README.rst
+long_description_content_type = text/x-rst
author = Pedro Algarvio
author_email = pedro@algarvio.me
url = https://github.com/saltstack/pytest-helpers-namespace
@@ -20,6 +21,7 @@ classifiers =
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
+ Programming Language :: Python :: 3.10
Development Status :: 5 - Production/Stable
Intended Audience :: Developers
License :: OSI Approved :: Apache Software License
@@ -31,7 +33,7 @@ include_package_data = True
package_dir =
=src
packages = find:
-python_requires = >= 3.5
+python_requires = >= 3.5.6
setup_requires =
setuptools>=50.3.2
setuptools_scm[toml]>=3.4
@@ -48,6 +50,7 @@ extras_require =
docs = requirements/docs.txt
lint = requirements/lint.txt
tests = requirements/tests.txt
+ changelog = requirements/changelog.txt
[options.entry_points]
pytest11 =
@@ -56,6 +59,53 @@ pytest11 =
[bdist_wheel]
universal = false
+[sdist]
+owner = root
+group = root
+
+[flake8]
+max-line-length = 120
+exclude =
+ .git,
+ .nox,
+ __pycache__,
+ src/pytest_helpers_namespace/version.py,
+ build,
+ dist,
+ docs/conf.py,
+ setup.py,
+ .pre-commit-hooks
+per-file-ignores =
+ __init__.py: F401
+ noxfile.py: D100,D102,D103,D107,D212,E501
+ src/pytestsysstats/plugin.py: W503
+ tests/*.py: D100,D103
+ignore =
+ D104,
+ D107,
+ D212,
+ D200,
+builtins =
+ __salt__
+ __opts__
+ __salt_system_encoding__
+docstring-convention = google
+
+[mypy]
+python_version = 3.7
+mypy_path = src
+ignore_missing_imports = True
+no_implicit_optional = True
+show_error_codes = True
+strict_equality = True
+warn_redundant_casts = True
+warn_return_any = True
+warn_unused_configs = True
+warn_unused_ignores = True
+disallow_any_generics = True
+check_untyped_defs = True
+no_implicit_reexport = True
+
[egg_info]
tag_build =
tag_date = 0
diff --git a/setup.py b/setup.py
index 8d30120..cbc50f7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
import setuptools
if __name__ == "__main__":
diff --git a/src/pytest_helpers_namespace.egg-info/PKG-INFO b/src/pytest_helpers_namespace.egg-info/PKG-INFO
index 7c38c57..5900135 100644
--- a/src/pytest_helpers_namespace.egg-info/PKG-INFO
+++ b/src/pytest_helpers_namespace.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-helpers-namespace
-Version: 2021.4.29
+Version: 2021.12.29
Summary: Pytest Helpers Namespace Plugin
Home-page: https://github.com/saltstack/pytest-helpers-namespace
Author: Pedro Algarvio
@@ -37,6 +37,9 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
:alt: Supported implementations
:target: https://pypi.python.org/pypi/pytest-helpers-namespace
+ ..
+ include-starts-here
+
Pytest Helpers Namespace
========================
@@ -78,11 +81,12 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
import pytest
+
@pytest.helpers.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -101,15 +105,16 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
.. code-block:: python
- pytest_plugins = ['helpers_namespace']
+ pytest_plugins = ["helpers_namespace"]
import pytest
+
@pytest.helpers.can.haz.register
def foo(bar):
- '''
+ """
this dumb helper function will just return what you pass to it
- '''
+ """
return bar
@@ -124,86 +129,6 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
You can even pass a name to the register function and that will be the helper function name.
- Contributing
- ------------
- Contributions are very welcome. Tests can be run with `nox`_, please ensure
- the coverage at least stays the same before you submit a pull request.
-
- License
- -------
-
- Distributed under the terms of the `Apache Software License 2.0`_ license,
- "pytest-helpers-namespace" is free and open source software.
-
-
- Issues
- ------
-
- If you encounter any problems, please `file an issue`_ along with a detailed
- description.
-
- Changelog
- ---------
-
- v2021.3.24
- ~~~~~~~~~~
-
- * Switched project to a ``src`` layout.
- * Switched project to a declarative setuptools approach
- * Added support to check if a helper has been registered
- * Pytest >= 6.1.1 is now required
-
- v2019.1.8
- ~~~~~~~~~
-
- * Patch PyTest before any ``conftest.py`` file is processed.
-
- v2019.1.7
- ~~~~~~~~~
-
- * Support PyTest >= 4.1
-
- v2019.1.6.post1
- ~~~~~~~~~~~~~~~
-
- * No changes were made besides locking to PyTest < 4.0
-
- v2019.1.6
- ~~~~~~~~~
-
- * No changes were made besides locking to PyTest < 4.1
-
- v2017.11.11
- ~~~~~~~~~~~
-
- * Allow passing a string to the register function which will be the helper name
-
- v2016.7.10
- ~~~~~~~~~~
-
- * Allow a registered function to contibue to behave as a regular function. `#4`_.
-
- v2016.4.15
- ~~~~~~~~~~
-
- * Hide the ``FuncWrapper`` traceback in pytest failures. `#3`_. Thanks Logan Glickfield(`@lsglick`_)
-
- v2016.4.5
- ~~~~~~~~~
-
- * Use a wrapper class instead of adding an attribute to a function.
-
- v2016.4.3
- ~~~~~~~~~
-
- * Provide proper errors when helper functions or namespaces are being
- overridden. `#1`_
-
- v2016.3.2
- ~~~~~~~~~~
-
- * First working release
-
----
This `Pytest`_ plugin was generated with `Cookiecutter`_ along with
@@ -211,19 +136,18 @@ Description: .. image:: https://github.com/saltstack/pytest-helpers-namespace/ac
.. _`Cookiecutter`: https://github.com/audreyr/cookiecutter
.. _`@hackebrot`: https://github.com/hackebrot
- .. _`Apache Software License 2.0`: http://www.apache.org/licenses/LICENSE-2.0
.. _`cookiecutter-pytest-plugin`: https://github.com/pytest-dev/cookiecutter-pytest-plugin
- .. _`file an issue`: https://github.com/saltstack/pytest-helpers-namespace/issues
.. _`pytest`: https://github.com/pytest-dev/pytest
- .. _`nox`: https://nox.thea.codes/en/stable/
.. _`pip`: https://pypi.python.org/pypi/pip/
.. _`PyPI`: https://pypi.python.org/pypi
- .. _`#1`: https://github.com/saltstack/pytest-helpers-namespace/issues/1
- .. _`#3`: https://github.com/saltstack/pytest-helpers-namespace/pull/3
- .. _`#4`: https://github.com/saltstack/pytest-helpers-namespace/issues/4
+ ..
+ include-ends-here
+
+ Documentation
+ =============
- .. _`@lsglick`: https://github.com/lsglick
+ The full documentation can be seen `here <https://pytest-helpers-namespace.readthedocs.io>`_.
Platform: unix
Platform: linux
@@ -239,10 +163,13 @@ Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
-Requires-Python: >=3.5
+Requires-Python: >=3.5.6
+Description-Content-Type: text/x-rst
Provides-Extra: docs
Provides-Extra: lint
Provides-Extra: tests
+Provides-Extra: changelog
diff --git a/src/pytest_helpers_namespace.egg-info/SOURCES.txt b/src/pytest_helpers_namespace.egg-info/SOURCES.txt
index bfd5697..001c95c 100644
--- a/src/pytest_helpers_namespace.egg-info/SOURCES.txt
+++ b/src/pytest_helpers_namespace.egg-info/SOURCES.txt
@@ -4,27 +4,43 @@
.pylint-spelling-words
.pylintrc
AUTHORS.rst
+CHANGELOG.rst
+CODE_OF_CONDUCT.md
+CONTRIBUTING.md
LICENSE
README.rst
-appveyor.yml
noxfile.py
pyproject.toml
setup.cfg
setup.py
+.github/CODEOWNERS
.github/workflows/testing.yml
+.pre-commit-hooks/check-changelog-entries.py
+.pre-commit-hooks/copyright-headers.py
.pre-commit-hooks/sort-pylint-spelling-words.py
+changelog/_template.rst
docs/Makefile
+docs/all.rst
+docs/changelog.rst
docs/conf.py
+docs/contents.rst
docs/index.rst
docs/make.bat
docs/sitevars.rst
docs/_static/.gitkeep
+docs/_static/css/inline-include.css
+docs/_static/img/SaltProject_Logomark_teal.png
+docs/_static/img/SaltProject_altlogo_teal.png
+docs/ref/modules.rst
+docs/ref/pytest_helpers_namespace.rst
requirements/base.txt
+requirements/changelog.txt
requirements/docs.txt
requirements/lint.txt
requirements/tests.txt
src/pytest_helpers_namespace/__init__.py
src/pytest_helpers_namespace/plugin.py
+src/pytest_helpers_namespace/py.typed
src/pytest_helpers_namespace/version.py
src/pytest_helpers_namespace.egg-info/PKG-INFO
src/pytest_helpers_namespace.egg-info/SOURCES.txt
diff --git a/src/pytest_helpers_namespace.egg-info/requires.txt b/src/pytest_helpers_namespace.egg-info/requires.txt
index a178fc0..73e12c0 100644
--- a/src/pytest_helpers_namespace.egg-info/requires.txt
+++ b/src/pytest_helpers_namespace.egg-info/requires.txt
@@ -1,14 +1,19 @@
pytest>=6.0.0
+[changelog]
+towncrier==21.9.0rc1
+
[docs]
+furo
sphinx
-sphinx-material-saltstack
+sphinx-copybutton
sphinx-prompt
sphinxcontrib-spelling
+towncrier==21.3.0
+sphinxcontrib-towncrier>=0.2.0a0
[lint]
-pylint==2.4.4
-saltpylint==2019.6.7
+pylint==2.12.2
pyenchant
[lint:python_version >= "3.7"]
diff --git a/src/pytest_helpers_namespace/__init__.py b/src/pytest_helpers_namespace/__init__.py
index a3a83f6..14607bf 100644
--- a/src/pytest_helpers_namespace/__init__.py
+++ b/src/pytest_helpers_namespace/__init__.py
@@ -1,3 +1,6 @@
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
# pylint: disable=missing-module-docstring
import pathlib
diff --git a/src/pytest_helpers_namespace/plugin.py b/src/pytest_helpers_namespace/plugin.py
index 90f2bfe..375a5d9 100644
--- a/src/pytest_helpers_namespace/plugin.py
+++ b/src/pytest_helpers_namespace/plugin.py
@@ -1,14 +1,28 @@
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
"""
-pytest_helpers_namespace.plugin
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pytest Helpers Namespace Plugin
+Pytest Helpers Namespace Plugin.
"""
from functools import partial
from functools import wraps
+from typing import Any
+from typing import Callable
+from typing import cast
+from typing import Optional
+from typing import TYPE_CHECKING
+from typing import TypeVar
+from typing import Union
import pytest
+if TYPE_CHECKING:
+ from typing import Dict
+
+ # pylint: disable=import-error,unused-import,no-name-in-module
+ from _pytest.main import Session
+
+ # pylint: enable=import-error,unused-import,no-name-in-module
+
try: # pragma: no cover
import importlib.metadata
@@ -24,13 +38,22 @@ except ImportError: # pragma: no cover
PYTEST_61 = pkg_resources.get_distribution("pytest").version >= "6.1.0"
+F = TypeVar("F", bound=Callable[..., Any])
+
+
class FuncWrapper:
- def __init__(self, func):
+ """
+ Wrapper class for helper functions and namespaces.
+ """
+
+ def __init__(self, func: F):
self.func = func
@staticmethod
- def register(func):
+ def register(func: F) -> F:
"""
+ Register a helper function.
+
This function will just raise a RuntimeError in case a function
registration, which also sets a nested namespace, tries to override
a known helper function with that nested namespace.
@@ -40,12 +63,13 @@ class FuncWrapper:
we will raise the exception below.
"""
raise RuntimeError(
- "A namespace is already registered under the name: {}".format(func.__name__)
+ "Helper functions cannot be used to register new helper functions. "
+ "Register and use a namespace for that."
)
- def __call__(self, *args, **kwargs):
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
"""
- This wrapper will just call the actual helper function
+ This wrapper will just call the actual helper function.
"""
__tracebackhide__ = True
return self.func(*args, **kwargs)
@@ -53,20 +77,20 @@ class FuncWrapper:
class HelpersRegistry:
"""
- Helper functions registrar which supports namespaces
+ Helper functions registrar which supports namespaces.
"""
__slots__ = ("_registry",)
- def __init__(self):
- self._registry = {}
+ def __init__(self) -> None:
+ self._registry = {} # type: "Dict[str, Union[FuncWrapper, HelpersRegistry]]"
- def register(self, func, name=None):
+ def register(self, func: Union[F, str], name: Optional[str] = None) -> F:
"""
- Register's a new function as a helper
+ Register's a new function as a helper.
"""
if isinstance(func, str):
- return partial(self.register, name=func)
+ return cast(F, partial(self.register, name=func))
if name is None:
name = func.__name__
@@ -77,41 +101,69 @@ class HelpersRegistry:
self._registry[name] = wraps(func)(FuncWrapper(func))
return func
- def __getattribute__(self, name):
+ def __getattribute__(self, name: str) -> Any:
+ """
+ Return an attribute from the registry or register a new namespace.
+ """
if name in ("__class__", "_registry", "register"):
return object.__getattribute__(self, name)
return self._registry.setdefault(name, self.__class__())
- def __repr__(self):
+ def __repr__(self) -> str:
+ """
+ Return a string representation of the class.
+ """
return "{} {!r}>".format(self.__class__.__name__, self._registry)
- def __call__(self, *_, **__):
- raise RuntimeError("The helper being called was not registred")
+ def __call__(self, *_: Any, **__: Any) -> Any:
+ """
+ Show a warning when calling an unregistered helper function.
+ """
+ raise RuntimeError("The helper being called was not registered")
- def __contains__(self, key):
+ def __contains__(self, key: str) -> bool:
+ """
+ Check for the presence of a helper name in the registry.
+ """
return key in self._registry
if PYTEST_61 is False: # pragma: no cover
- def __fspath__(self):
+ def __fspath__(self) -> str:
+ """
+ Compatibility method against newer Pytest versions.
+ """
# Compatibility with PyTest 6.0.x
return __file__
-def pytest_load_initial_conftests(*_):
+def pytest_load_initial_conftests(*_: Any) -> None:
+ """
+ Hook into pytest to inject our custom ``helpers`` registry.
+ """
try:
pytest.helpers # pragma: no cover
except AttributeError:
pytest.helpers = HelpersRegistry()
-@pytest.hookimpl(trylast=True)
-def pytest_sessionstart(session):
+@pytest.hookimpl(trylast=True) # type: ignore[misc]
+def pytest_sessionstart(session: "Session") -> None:
+ """
+ Register our plugin with pytest.
+ """
session.config.pluginmanager.register(pytest.helpers, "helpers-namespace")
-def pytest_unconfigure(): # pragma: no cover
+def pytest_unconfigure() -> None: # pragma: no cover
+ """
+ Delete our custom ``helpers`` registry from the ``pytest`` module namespace.
+ """
try:
delattr(pytest, "helpers")
except AttributeError:
pass
+
+
+if TYPE_CHECKING:
+ setattr(pytest, "helpers", HelpersRegistry())
diff --git a/src/pytest_helpers_namespace/py.typed b/src/pytest_helpers_namespace/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/src/pytest_helpers_namespace/version.py b/src/pytest_helpers_namespace/version.py
index 8755f94..42cbdd6 100644
--- a/src/pytest_helpers_namespace/version.py
+++ b/src/pytest_helpers_namespace/version.py
@@ -1 +1,3 @@
-__version__ = "2021.4.29"
\ No newline at end of file
+# pylint: skip-file
+
+__version__ = "2021.12.29"
diff --git a/tests/conftest.py b/tests/conftest.py
index 383fa44..e93bc7b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,2 +1,40 @@
-# pragma: no cover
-pytest_plugins = "pytester"
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
+import logging
+
+import pytest
+
+try: # pragma: no cover
+ import importlib.metadata
+
+ pkg_version = importlib.metadata.version
+except ImportError: # pragma: no cover
+ try:
+ import importlib_metadata
+
+ pkg_version = importlib_metadata.version
+ except ImportError: # pragma: no cover
+ import pkg_resources
+
+ def pkg_version(package):
+ return pkg_resources.get_distribution(package).version
+
+
+log = logging.getLogger(__name__)
+
+
+def pkg_version_info(package):
+ """
+ Return a version info tuple for the given package.
+ """
+ return tuple(int(part) for part in pkg_version(package).split(".") if part.isdigit())
+
+
+if pkg_version_info("pytest") >= (6, 2):
+ pytest_plugins = ["pytester"]
+else: # pragma: no cover
+
+ @pytest.fixture
+ def pytester():
+ pytest.skip("The pytester fixture is not available in Pytest < 6.2.0")
diff --git a/tests/test_helpers_namespace.py b/tests/test_helpers_namespace.py
index 27f4743..a47f05d 100644
--- a/tests/test_helpers_namespace.py
+++ b/tests/test_helpers_namespace.py
@@ -1,7 +1,10 @@
+# Copyright 2021 VMware, Inc.
+# SPDX-License-Identifier: Apache-2.0
+#
import pytest
-@pytest.fixture
+@pytest.fixture(autouse=True)
def reset_helpers_namespace(request):
try:
yield
@@ -10,8 +13,8 @@ def reset_helpers_namespace(request):
plugin._registry.clear()
-def test_namespace(testdir):
- testdir.makeconftest(
+def test_namespace(pytester):
+ pytester.makeconftest(
"""
import pytest
@@ -21,7 +24,7 @@ def test_namespace(testdir):
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
@@ -31,7 +34,7 @@ def test_namespace(testdir):
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines(
@@ -44,8 +47,8 @@ def test_namespace(testdir):
assert result.ret == 0
-def test_nested_namespace(testdir):
- testdir.makeconftest(
+def test_nested_namespace(pytester):
+ pytester.makeconftest(
"""
import pytest
@@ -55,7 +58,7 @@ def test_nested_namespace(testdir):
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
@@ -65,7 +68,7 @@ def test_nested_namespace(testdir):
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines(
@@ -78,20 +81,21 @@ def test_nested_namespace(testdir):
assert result.ret == 0
-def test_unregistered_namespace(testdir):
- testdir.makepyfile(
+def test_unregistered_namespace(pytester):
+ pytester.makepyfile(
"""
import pytest
def test_helpers():
with pytest.raises(RuntimeError) as exc:
assert pytest.helpers.foo(True) is True
- assert 'The helper being called was not registred' in str(exc)
+ strexc = str(exc)
+ assert 'The helper being called was not registered' in strexc
print('PASSED')
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines(
@@ -104,8 +108,8 @@ def test_unregistered_namespace(testdir):
assert result.ret == 0
-def test_namespace_override(testdir):
- testdir.makeconftest(
+def test_namespace_override(pytester):
+ pytester.makeconftest(
"""
import pytest
@@ -118,19 +122,19 @@ def test_namespace_override(testdir):
return bar
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
def test_helpers():
with pytest.raises(RuntimeError) as exc:
assert pytest.helpers.foo(True) is True
- assert 'The helper being called was not registred' in str(exc)
+ assert 'The helper being called was not registered' in str(exc)
print('PASSED')
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stderr.fnmatch_lines(
@@ -141,8 +145,8 @@ def test_namespace_override(testdir):
assert result.ret != 0
-def test_namespace_override_2(testdir):
- testdir.makeconftest(
+def test_helper_override(pytester):
+ pytester.makeconftest(
"""
import pytest
@@ -150,93 +154,80 @@ def test_namespace_override_2(testdir):
def foo(bar):
return bar
- @pytest.helpers.foo.register
- def bar(bar):
+ @pytest.helpers.register
+ def foo(bar):
return bar
"""
)
- testdir.makepyfile(
+ pytester.makepyfile(
"""
import pytest
def test_helpers():
with pytest.raises(RuntimeError) as exc:
assert pytest.helpers.foo(True) is True
- assert 'The helper being called was not registred' in str(exc)
+ assert 'The helper being called was not registered' in str(exc)
print('PASSED')
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stderr.fnmatch_lines(
- ["*RuntimeError: A namespace is already registered under the name: bar"]
+ ["*RuntimeError: A helper function is already registered under the name: foo"]
)
# make sure that that we get a '0' exit code for the test suite
assert result.ret != 0
-def test_helper_override(testdir):
- testdir.makeconftest(
+def test_helper_as_regular_function(pytester):
+ pytester.makepyfile(
"""
import pytest
@pytest.helpers.register
- def foo(bar):
- return bar
-
- @pytest.helpers.register
- def foo(bar):
- return bar
- """
- )
- testdir.makepyfile(
- """
- import pytest
+ def foo2():
+ return 'bar'
def test_helpers():
- with pytest.raises(RuntimeError) as exc:
- assert pytest.helpers.foo(True) is True
- assert 'The helper being called was not registred' in str(exc)
- print('PASSED')
- """
+ assert pytest.helpers.foo2() == 'bar'
+ assert foo2() == 'bar'
+ """
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-svv", "--log-cli-level=debug")
# fnmatch_lines does an assertion internally
- result.stderr.fnmatch_lines(
- ["*RuntimeError: A helper function is already registered under the name: foo"]
- )
+ result.stdout.fnmatch_lines(["test_helper_as_regular_function.py::test_helpers PASSED"])
# make sure that that we get a '0' exit code for the test suite
- assert result.ret != 0
+ assert result.ret == 0
-def test_helper_as_regular_function(testdir):
- testdir.makepyfile(
+def test_helper_with_custom_name(pytester):
+ pytester.makepyfile(
"""
import pytest
- @pytest.helpers.register
+ @pytest.helpers.register('jump')
def foo():
return 'bar'
def test_helpers():
- assert pytest.helpers.foo() == 'bar'
+ assert pytest.helpers.jump() == 'bar'
assert foo() == 'bar'
print('PASSED')
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
result.stdout.fnmatch_lines(
[
- "test_helper_as_regular_function.py PASSED",
+ "test_helper_with_custom_name.py PASSED",
]
)
@@ -244,42 +235,64 @@ def test_helper_as_regular_function(testdir):
assert result.ret == 0
-def test_helper_with_custom_name(testdir):
- testdir.makepyfile(
+def test_helper_contains_method(pytester):
+ pytester.makeconftest(
"""
import pytest
- @pytest.helpers.register('jump')
- def foo():
- return 'bar'
+ assert "bar" not in pytest.helpers
+
+ @pytest.helpers.register
+ def bar():
+ return True
+ """
+ )
+ pytester.makepyfile(
+ """
+ import pytest
+
+ def test_it():
+ assert "bar" in pytest.helpers
+ assert pytest.helpers.bar() is True
+ """
+ )
+
+ result = pytester.runpytest("-vv")
+ result.assert_outcomes(passed=1)
+
+
+def test_call_register_on_helper_function(pytester):
+ pytester.makeconftest(
+ """
+ import pytest
+
+ @pytest.helpers.register
+ def foo(bar):
+ return bar
+
+ @pytest.helpers.foo.register
+ def blah(blah):
+ return bar
+ """
+ )
+ pytester.makepyfile(
+ """
+ import pytest
def test_helpers():
- assert pytest.helpers.jump() == 'bar'
- assert foo() == 'bar'
- print('PASSED')
+ with pytest.raises(RuntimeError) as exc:
+ assert pytest.helpers.foo(True) is True
"""
)
- result = testdir.runpytest_subprocess("-s")
+ result = pytester.runpytest("-s")
# fnmatch_lines does an assertion internally
- result.stdout.fnmatch_lines(
+ result.stderr.fnmatch_lines(
[
- "test_helper_with_custom_name.py PASSED",
+ "*RuntimeError: Helper functions cannot be used to register new helper functions. "
+ "Register and use a namespace for that.*",
]
)
-
# make sure that that we get a '0' exit code for the test suite
- assert result.ret == 0
-
-
-@pytest.mark.usefixtures("reset_helpers_namespace")
-def test_helper_contains_method():
- assert "bar" not in pytest.helpers
-
- @pytest.helpers.register
- def bar():
- return True
-
- assert "bar" in pytest.helpers
- assert pytest.helpers.bar() is True
+ assert result.ret != 0