Compare commits

..

1 Commits

Author SHA1 Message Date
Harmen Stoppels
1d78283946 troubleshoot ci 2025-05-12 16:46:58 +02:00
9351 changed files with 9228 additions and 30365 deletions

View File

@@ -1,73 +0,0 @@
name: audit
on:
workflow_call:
inputs:
with_coverage:
required: true
type: string
python_version:
required: true
type: string
concurrency:
group: audit-${{inputs.python_version}}-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
jobs:
# Run audits on all the packages in the built-in repository
package-audits:
runs-on: ${{ matrix.system.os }}
strategy:
matrix:
system:
- { os: windows-latest, shell: 'powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}' }
- { os: ubuntu-latest, shell: bash }
- { os: macos-latest, shell: bash }
defaults:
run:
shell: ${{ matrix.system.shell }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: ${{inputs.python_version}}
- name: Install Python packages
run: |
pip install --upgrade pip setuptools pytest coverage[toml]
- name: Setup for Windows run
if: runner.os == 'Windows'
run: |
python -m pip install --upgrade pywin32
- name: Package audits (with coverage)
env:
COVERAGE_FILE: coverage/.coverage-audits-${{ matrix.system.os }}
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
run: |
. share/spack/setup-env.sh
coverage run $(which spack) audit packages
coverage run $(which spack) audit configs
coverage run $(which spack) -d audit externals
coverage combine
- name: Package audits (without coverage)
if: ${{ inputs.with_coverage == 'false' && runner.os != 'Windows' }}
run: |
. share/spack/setup-env.sh
spack -d audit packages
spack -d audit configs
spack -d audit externals
- name: Package audits (without coverage)
if: ${{ runner.os == 'Windows' }}
run: |
spack -d audit packages
./share/spack/qa/validate_last_exit.ps1
spack -d audit configs
./share/spack/qa/validate_last_exit.ps1
spack -d audit externals
./share/spack/qa/validate_last_exit.ps1
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b
if: ${{ inputs.with_coverage == 'true' && runner.os != 'Windows' }}
with:
name: coverage-audits-${{ matrix.system.os }}
path: coverage
include-hidden-files: true

View File

@@ -1,194 +0,0 @@
name: Bootstrapping
on:
# This Workflow can be triggered manually
workflow_dispatch:
workflow_call:
schedule:
# nightly at 2:16 AM
- cron: '16 2 * * *'
concurrency:
group: bootstrap-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
jobs:
distros-clingo-sources:
runs-on: ubuntu-latest
container: ${{ matrix.image }}
strategy:
matrix:
image: ["fedora:latest", "opensuse/leap:latest"]
steps:
- name: Setup Fedora
if: ${{ matrix.image == 'fedora:latest' }}
run: |
dnf install -y \
bzip2 curl file gcc-c++ gcc gcc-gfortran git gzip \
make patch unzip which xz python3 python3-devel tree \
cmake bison bison-devel libstdc++-static gawk
- name: Setup OpenSUSE
if: ${{ matrix.image == 'opensuse/leap:latest' }}
run: |
# Harden CI by applying the workaround described here: https://www.suse.com/support/kb/doc/?id=000019505
zypper update -y || zypper update -y
zypper install -y \
bzip2 curl file gcc-c++ gcc gcc-fortran tar git gpg2 gzip \
make patch unzip which xz python3 python3-devel tree \
cmake bison
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Bootstrap clingo
run: |
source share/spack/setup-env.sh
spack bootstrap disable github-actions-v0.6
spack bootstrap disable github-actions-v0.5
spack external find cmake bison
spack -d solve zlib
tree ~/.spack/bootstrap/store/
clingo-sources:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
runner: ['macos-13', 'macos-14', "ubuntu-latest"]
steps:
- name: Setup macOS
if: ${{ matrix.runner != 'ubuntu-latest' }}
run: |
brew install cmake bison tree
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: "3.12"
- name: Bootstrap clingo
run: |
source share/spack/setup-env.sh
spack bootstrap disable github-actions-v0.6
spack bootstrap disable github-actions-v0.5
spack external find --not-buildable cmake bison
spack -d solve zlib
tree $HOME/.spack/bootstrap/store/
gnupg-sources:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
runner: [ 'macos-13', 'macos-14', "ubuntu-latest" ]
steps:
- name: Setup macOS
if: ${{ matrix.runner != 'ubuntu-latest' }}
run: brew install tree gawk
- name: Remove system executables
run: |
while [ -n "$(command -v gpg gpg2 patchelf)" ]; do
sudo rm $(command -v gpg gpg2 patchelf)
done
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Bootstrap GnuPG
run: |
source share/spack/setup-env.sh
spack solve zlib
spack bootstrap disable github-actions-v0.6
spack bootstrap disable github-actions-v0.5
spack -d gpg list
tree ~/.spack/bootstrap/store/
from-binaries:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
runner: ['macos-13', 'macos-14', "ubuntu-latest"]
steps:
- name: Setup macOS
if: ${{ matrix.runner != 'ubuntu-latest' }}
run: brew install tree
- name: Remove system executables
run: |
while [ -n "$(command -v gpg gpg2 patchelf)" ]; do
sudo rm $(command -v gpg gpg2 patchelf)
done
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: |
3.8
3.9
3.10
3.11
3.12
3.13
- name: Set bootstrap sources
run: |
source share/spack/setup-env.sh
spack bootstrap disable github-actions-v0.5
spack bootstrap disable spack-install
- name: Bootstrap clingo
run: |
set -e
for ver in '3.8' '3.9' '3.10' '3.11' '3.12' '3.13'; do
not_found=1
ver_dir="$(find $RUNNER_TOOL_CACHE/Python -wholename "*/${ver}.*/*/bin" | grep . || true)"
if [[ -d "$ver_dir" ]] ; then
echo "Testing $ver_dir"
if $ver_dir/python --version ; then
export PYTHON="$ver_dir/python"
not_found=0
old_path="$PATH"
export PATH="$ver_dir:$PATH"
./bin/spack-tmpconfig -b ./.github/workflows/bin/bootstrap-test.sh
export PATH="$old_path"
fi
fi
if (($not_found)) ; then
echo Required python version $ver not found in runner!
exit 1
fi
done
- name: Bootstrap GnuPG
run: |
source share/spack/setup-env.sh
spack -d gpg list
tree $HOME/.spack/bootstrap/store/
windows:
runs-on: "windows-latest"
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: "3.12"
- name: Setup Windows
run: |
Remove-Item -Path (Get-Command gpg).Path
Remove-Item -Path (Get-Command file).Path
- name: Bootstrap clingo
run: |
./share/spack/setup-env.ps1
spack bootstrap disable github-actions-v0.6
spack bootstrap disable github-actions-v0.5
spack external find --not-buildable cmake bison
spack -d solve zlib
./share/spack/qa/validate_last_exit.ps1
tree $env:userprofile/.spack/bootstrap/store/
- name: Bootstrap GnuPG
run: |
./share/spack/setup-env.ps1
spack -d gpg list
./share/spack/qa/validate_last_exit.ps1
tree $env:userprofile/.spack/bootstrap/store/

View File

@@ -1,140 +0,0 @@
name: Containers
on:
# This Workflow can be triggered manually
workflow_dispatch:
# Build new Spack develop containers nightly.
schedule:
- cron: '34 0 * * *'
# Run on pull requests that modify this file
pull_request:
branches:
- develop
paths:
- '.github/workflows/build-containers.yml'
- 'share/spack/docker/*'
- 'share/spack/templates/container/*'
- 'lib/spack/spack/container/*'
# Let's also build & tag Spack containers on releases.
release:
types: [published]
concurrency:
group: build_containers-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
jobs:
deploy-images:
runs-on: ubuntu-latest
permissions:
packages: write
strategy:
# Even if one container fails to build we still want the others
# to continue their builds.
fail-fast: false
# A matrix of Dockerfile paths, associated tags, and which architectures
# they support.
matrix:
# Meaning of the various items in the matrix list
# 0: Container name (e.g. ubuntu-bionic)
# 1: Platforms to build for
# 2: Base image (e.g. ubuntu:22.04)
dockerfile: [[amazon-linux, 'linux/amd64,linux/arm64', 'amazonlinux:2'],
[centos-stream9, 'linux/amd64,linux/arm64', 'centos:stream9'],
[leap15, 'linux/amd64,linux/arm64', 'opensuse/leap:15'],
[ubuntu-focal, 'linux/amd64,linux/arm64', 'ubuntu:20.04'],
[ubuntu-jammy, 'linux/amd64,linux/arm64', 'ubuntu:22.04'],
[ubuntu-noble, 'linux/amd64,linux/arm64', 'ubuntu:24.04'],
[almalinux8, 'linux/amd64,linux/arm64', 'almalinux:8'],
[almalinux9, 'linux/amd64,linux/arm64', 'almalinux:9'],
[rockylinux8, 'linux/amd64,linux/arm64', 'rockylinux:8'],
[rockylinux9, 'linux/amd64,linux/arm64', 'rockylinux:9'],
[fedora39, 'linux/amd64,linux/arm64', 'fedora:39'],
[fedora40, 'linux/amd64,linux/arm64', 'fedora:40']]
name: Build ${{ matrix.dockerfile[0] }}
if: github.repository == 'spack/spack'
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Determine latest release tag
id: latest
run: |
git fetch --quiet --tags
echo "tag=$(git tag --list --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)" | tee -a $GITHUB_OUTPUT
- uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96
id: docker_meta
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ matrix.dockerfile[0] }}
${{ github.repository_owner }}/${{ matrix.dockerfile[0] }}
tags: |
type=schedule,pattern=nightly
type=schedule,pattern=develop
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable=${{ github.ref == format('refs/tags/{0}', steps.latest.outputs.tag) }}
- name: Generate the Dockerfile
env:
SPACK_YAML_OS: "${{ matrix.dockerfile[2] }}"
run: |
.github/workflows/bin/generate_spack_yaml_containerize.sh
. share/spack/setup-env.sh
mkdir -p dockerfiles/${{ matrix.dockerfile[0] }}
spack containerize --last-stage=bootstrap | tee dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile
printf "Preparing to build ${{ env.container }} from dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile"
if [ ! -f "dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile" ]; then
printf "dockerfiles/${{ matrix.dockerfile[0] }}/Dockerfile does not exist"
exit 1;
fi
- name: Upload Dockerfile
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b
with:
name: dockerfiles_${{ matrix.dockerfile[0] }}
path: dockerfiles
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5
- name: Log in to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build & Deploy ${{ matrix.dockerfile[0] }}
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355
with:
context: dockerfiles/${{ matrix.dockerfile[0] }}
platforms: ${{ matrix.dockerfile[1] }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
merge-dockerfiles:
runs-on: ubuntu-latest
needs: deploy-images
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b
with:
name: dockerfiles
pattern: dockerfiles_*
delete-merged: true

View File

@@ -1,130 +0,0 @@
name: ci
on:
push:
branches:
- develop
- releases/**
pull_request:
branches:
- develop
- releases/**
merge_group:
concurrency:
group: ci-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
jobs:
# Check which files have been updated by the PR
changes:
runs-on: ubuntu-latest
# Set job outputs to values from filter step
outputs:
bootstrap: ${{ steps.filter.outputs.bootstrap }}
core: ${{ steps.filter.outputs.core }}
packages: ${{ steps.filter.outputs.packages }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
if: ${{ github.event_name == 'push' || github.event_name == 'merge_group' }}
with:
fetch-depth: 0
# For pull requests it's not necessary to checkout the code
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
id: filter
with:
# For merge group events, compare against the target branch (main)
base: ${{ github.event_name == 'merge_group' && github.event.merge_group.base_ref || '' }}
# For merge group events, use the merge group head ref
ref: ${{ github.event_name == 'merge_group' && github.event.merge_group.head_sha || github.ref }}
# See https://github.com/dorny/paths-filter/issues/56 for the syntax used below
# Don't run if we only modified packages in the
# built-in repository or documentation
filters: |
bootstrap:
- 'var/spack/repos/spack_repo/builtin/packages/clingo-bootstrap/**'
- 'var/spack/repos/spack_repo/builtin/packages/clingo/**'
- 'var/spack/repos/spack_repo/builtin/packages/python/**'
- 'var/spack/repos/spack_repo/builtin/packages/re2c/**'
- 'var/spack/repos/spack_repo/builtin/packages/gnupg/**'
- 'var/spack/repos/spack_repo/builtin/packages/libassuan/**'
- 'var/spack/repos/spack_repo/builtin/packages/libgcrypt/**'
- 'var/spack/repos/spack_repo/builtin/packages/libgpg-error/**'
- 'var/spack/repos/spack_repo/builtin/packages/libksba/**'
- 'var/spack/repos/spack_repo/builtin/packages/npth/**'
- 'var/spack/repos/spack_repo/builtin/packages/pinentry/**'
- 'lib/spack/**'
- 'share/spack/**'
- '.github/workflows/bootstrap.yml'
- '.github/workflows/ci.yaml'
core:
- './!(var/**)/**'
packages:
- 'var/**'
# Some links for easier reference:
#
# "github" context: https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context
# job outputs: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs
# setting environment variables from earlier steps: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
#
bootstrap:
if: ${{ github.repository == 'spack/spack' && needs.changes.outputs.bootstrap == 'true' }}
needs: [ prechecks, changes ]
uses: ./.github/workflows/bootstrap.yml
secrets: inherit
unit-tests:
if: ${{ github.repository == 'spack/spack' && needs.changes.outputs.core == 'true' }}
needs: [ prechecks, changes ]
uses: ./.github/workflows/unit_tests.yaml
secrets: inherit
prechecks:
needs: [ changes ]
uses: ./.github/workflows/prechecks.yml
secrets: inherit
with:
with_coverage: ${{ needs.changes.outputs.core }}
with_packages: ${{ needs.changes.outputs.packages }}
import-check:
needs: [ changes ]
uses: ./.github/workflows/import-check.yaml
all-prechecks:
needs: [ prechecks ]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Success
run: |
if [ "${{ needs.prechecks.result }}" == "failure" ] || [ "${{ needs.prechecks.result }}" == "canceled" ]; then
echo "Unit tests failed."
exit 1
else
exit 0
fi
coverage:
needs: [ unit-tests, prechecks ]
if: ${{ needs.changes.outputs.core }}
uses: ./.github/workflows/coverage.yml
secrets: inherit
all:
needs: [ unit-tests, coverage, bootstrap ]
if: ${{ always() }}
runs-on: ubuntu-latest
# See https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#needs-context
steps:
- name: Status summary
run: |
if [ "${{ needs.unit-tests.result }}" == "failure" ] || [ "${{ needs.unit-tests.result }}" == "canceled" ]; then
echo "Unit tests failed."
exit 1
elif [ "${{ needs.bootstrap.result }}" == "failure" ] || [ "${{ needs.bootstrap.result }}" == "canceled" ]; then
echo "Bootstrap tests failed."
exit 1
else
exit 0
fi

View File

@@ -1,36 +0,0 @@
name: coverage
on:
workflow_call:
jobs:
# Upload coverage reports to codecov once as a single bundle
upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: '3.11'
cache: 'pip'
- name: Install python dependencies
run: pip install -r .github/workflows/requirements/coverage/requirements.txt
- name: Download coverage artifact files
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
with:
pattern: coverage-*
path: coverage
merge-multiple: true
- run: ls -la coverage
- run: coverage combine -a coverage/.coverage*
- run: coverage xml
- name: "Upload coverage report to CodeCov"
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303
with:
verbose: true
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,50 +0,0 @@
name: import-check
on:
workflow_call:
jobs:
# Check we don't make the situation with circular imports worse
import-check:
continue-on-error: true
runs-on: ubuntu-latest
steps:
- uses: julia-actions/setup-julia@v2
with:
version: '1.10'
- uses: julia-actions/cache@v2
# PR: use the base of the PR as the old commit
- name: Checkout PR base commit
if: github.event_name == 'pull_request'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
ref: ${{ github.event.pull_request.base.sha }}
path: old
# not a PR: use the previous commit as the old commit
- name: Checkout previous commit
if: github.event_name != 'pull_request'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 2
path: old
- name: Checkout previous commit
if: github.event_name != 'pull_request'
run: git -C old reset --hard HEAD^
- name: Checkout new commit
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: new
- name: Install circular import checker
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: haampie/circular-import-fighter
ref: 4cdb0bf15f04ab6b49041d5ef1bfd9644cce7f33
path: circular-import-fighter
- name: Install dependencies
working-directory: circular-import-fighter
run: make -j dependencies
- name: Circular import check
working-directory: circular-import-fighter
run: make -j compare "SPACK_ROOT=../old ../new"

View File

@@ -1,31 +0,0 @@
name: Windows Paraview Nightly
on:
schedule:
- cron: '0 2 * * *' # Run at 2 am
defaults:
run:
shell:
powershell Invoke-Expression -Command "./share/spack/qa/windows_test_setup.ps1"; {0}
jobs:
build-paraview-deps:
runs-on: windows-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: 3.9
- name: Install Python packages
run: |
python -m pip install --upgrade pip six pywin32 setuptools coverage
- name: Build Test
run: |
spack compiler find
spack external find cmake ninja win-sdk win-wdk wgl msmpi
spack -d install -y --cdash-upload-url https://cdash.spack.io/submit.php?project=Spack+on+Windows --cdash-track Nightly --only dependencies paraview
exit 0

View File

@@ -1,108 +0,0 @@
name: prechecks
on:
workflow_call:
inputs:
with_coverage:
required: true
type: string
with_packages:
required: true
type: string
concurrency:
group: style-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
jobs:
# Validate that the code can be run on all the Python versions supported by Spack
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: '.github/workflows/requirements/style/requirements.txt'
- name: Install Python Packages
run: |
pip install -r .github/workflows/requirements/style/requirements.txt
- name: vermin (Spack's Core)
run: |
vermin --backport importlib --backport argparse --violations --backport typing -t=3.6- -vvv lib/spack/spack/ lib/spack/llnl/ bin/
- name: vermin (Repositories)
run: |
vermin --backport importlib --backport argparse --violations --backport typing -t=3.6- -vvv var/spack/repos var/spack/test_repos
# Run style checks on the files that have been changed
style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: '.github/workflows/requirements/style/requirements.txt'
- name: Install Python packages
run: |
pip install -r .github/workflows/requirements/style/requirements.txt
- name: Run style tests
run: |
bin/spack style --base HEAD^1
bin/spack license verify
pylint -j $(nproc) --disable=all --enable=unspecified-encoding --ignore-paths=lib/spack/external lib
audit:
uses: ./.github/workflows/audit.yaml
secrets: inherit
with:
with_coverage: ${{ inputs.with_coverage }}
python_version: '3.13'
verify-checksums:
# do not run if the commit message or PR description contains [skip-verify-checksums]
if: >-
${{ inputs.with_packages == 'true' &&
!contains(github.event.pull_request.body, '[skip-verify-checksums]') &&
!contains(github.event.head_commit.message, '[skip-verify-checksums]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
fetch-depth: 2
- name: Verify Added Checksums
run: |
bin/spack ci verify-versions HEAD^1 HEAD
# Check that spack can bootstrap the development environment on Python 3.6 - RHEL8
bootstrap-dev-rhel8:
runs-on: ubuntu-latest
container: registry.access.redhat.com/ubi8/ubi
steps:
- name: Install dependencies
run: |
dnf install -y \
bzip2 curl file gcc-c++ gcc gcc-gfortran git gnupg2 gzip \
make patch tcl unzip which xz
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup repo and non-root user
run: |
git --version
git config --global --add safe.directory '*'
git fetch --unshallow
. .github/workflows/bin/setup_git.sh
useradd spack-test
chown -R spack-test .
- name: Bootstrap Spack development environment
shell: runuser -u spack-test -- bash {0}
run: |
source share/spack/setup-env.sh
spack debug report
spack -d bootstrap now --dev
spack -d style -t black
spack unit-test -V

View File

@@ -1,37 +0,0 @@
name: sync with spack/spack-packages
on:
push:
branches:
- develop
jobs:
sync:
if: github.repository == 'spack/spack'
runs-on: ubuntu-latest
steps:
- name: Checkout spack/spack
run: git clone https://github.com/spack/spack.git
- name: Checkout spack/spack-packages
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
ssh-key: ${{ secrets.SYNC_PACKAGES_KEY }}
path: spack-packages
repository: spack/spack-packages
- name: Install git-filter-repo
run: |
curl -LfsO https://raw.githubusercontent.com/newren/git-filter-repo/refs/tags/v2.47.0/git-filter-repo
echo "67447413e273fc76809289111748870b6f6072f08b17efe94863a92d810b7d94 git-filter-repo" | sha256sum -c -
chmod +x git-filter-repo
sudo mv git-filter-repo /usr/local/bin/
- name: Sync spack/spack-packages with spack/spack
run: |
cd spack-packages
git-filter-repo --quiet --source ../spack \
--path var/spack/repos/ --path-rename var/spack/repos/:python/ \
--path share/spack/gitlab/cloud_pipelines/ --path-rename share/spack/gitlab/cloud_pipelines/:.ci/gitlab/ \
--refs develop
- name: Push
run: |
cd spack-packages
git push git@github.com:spack/spack-packages.git develop:develop --force

View File

@@ -1,12 +1,7 @@
name: unit tests
on:
workflow_dispatch:
workflow_call:
concurrency:
group: unit_tests-${{github.ref}}-${{github.event.pull_request.number || github.run_number}}
cancel-in-progress: true
pull_request:
jobs:
# Run unit tests with different configurations on linux
@@ -88,146 +83,10 @@ jobs:
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
path: coverage
include-hidden-files: true
# Test shell integration
shell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: '3.11'
- name: Install System packages
run: |
sudo apt-get -y update
# Needed for shell tests
sudo apt-get install -y coreutils csh zsh tcsh fish dash bash subversion
# On ubuntu 24.04, kcov was removed. It may come back in some future Ubuntu
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@40e9946c182a64b3db1bf51be0dcb915f7802aa9
- name: Install kcov with brew
run: "brew install kcov"
- name: Install Python packages
run: |
pip install --upgrade pip setuptools pytest coverage[toml] pytest-xdist
- name: Setup git configuration
run: |
# Need this for the git tests to succeed.
git --version
. .github/workflows/bin/setup_git.sh
- name: Run shell tests
env:
COVERAGE: true
run: |
share/spack/qa/run-shell-tests
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b
with:
name: coverage-shell
path: coverage
include-hidden-files: true
- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3
# Test RHEL8 UBI with platform Python. This job is run
# only on PRs modifying core Spack
rhel8-platform-python:
runs-on: ubuntu-latest
container: registry.access.redhat.com/ubi8/ubi
steps:
- name: Install dependencies
run: |
dnf install -y \
bzip2 curl gcc-c++ gcc gcc-gfortran git gnupg2 gzip \
make patch tcl unzip which xz
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Setup repo and non-root user
run: |
git --version
git config --global --add safe.directory '*'
git fetch --unshallow
. .github/workflows/bin/setup_git.sh
useradd spack-test
chown -R spack-test .
- name: Run unit tests
shell: runuser -u spack-test -- bash {0}
run: |
source share/spack/setup-env.sh
spack -d bootstrap now --dev
spack unit-test -k 'not cvs and not svn and not hg' -x --verbose
# Test for the clingo based solver (using clingo-cffi)
clingo-cffi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: '3.13'
- name: Install System packages
run: |
sudo apt-get -y update
sudo apt-get -y install coreutils gfortran graphviz gnupg2
- name: Install Python packages
run: |
pip install --upgrade pip setuptools pytest coverage[toml] pytest-cov clingo
pip install --upgrade flake8 "isort>=4.3.5" "mypy>=0.900" "click" "black"
- name: Run unit tests (full suite with coverage)
env:
COVERAGE: true
COVERAGE_FILE: coverage/.coverage-clingo-cffi
run: |
. share/spack/setup-env.sh
spack bootstrap disable spack-install
spack bootstrap disable github-actions-v0.5
spack bootstrap disable github-actions-v0.6
spack bootstrap status
spack solve zlib
spack unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml lib/spack/spack/test/concretization/core.py
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b
with:
name: coverage-clingo-cffi
path: coverage
include-hidden-files: true
# Run unit tests on MacOS
macos:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-13, macos-14]
python-version: ["3.11"]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b
with:
python-version: ${{ matrix.python-version }}
- name: Install Python packages
run: |
pip install --upgrade pip setuptools
pip install --upgrade pytest coverage[toml] pytest-xdist pytest-cov
- name: Setup Homebrew packages
run: |
brew install dash fish gcc gnupg kcov
- name: Run unit tests
env:
SPACK_TEST_PARALLEL: 4
COVERAGE_FILE: coverage/.coverage-${{ matrix.os }}-python${{ matrix.python-version }}
run: |
git --version
. .github/workflows/bin/setup_git.sh
. share/spack/setup-env.sh
$(which spack) bootstrap disable spack-install
$(which spack) solve zlib
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
$(which spack) unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b
with:
name: coverage-${{ matrix.os }}-python${{ matrix.python-version }}
path: coverage
include-hidden-files: true
# Run unit tests on Windows
windows:
defaults:
run:
@@ -258,3 +117,6 @@ jobs:
name: coverage-windows
path: coverage
include-hidden-files: true
- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3

View File

@@ -1,4 +0,0 @@
include:
- path: "${platform}"
optional: true
- path: base

View File

@@ -276,7 +276,7 @@ remove dependent packages *before* removing their dependencies or use the
Garbage collection
^^^^^^^^^^^^^^^^^^
When Spack builds software from sources, it often installs tools that are needed
When Spack builds software from sources, if often installs tools that are needed
just to build or test other software. These are not necessary at runtime.
To support cases where removing these tools can be a benefit Spack provides
the ``spack gc`` ("garbage collector") command, which will uninstall all unneeded packages:

View File

@@ -89,7 +89,7 @@ You can see that the mirror is added with ``spack mirror list`` as follows:
spack-public https://spack-llnl-mirror.s3-us-west-2.amazonaws.com/
At this point, you've created a buildcache, but Spack hasn't indexed it, so if
At this point, you've create a buildcache, but spack hasn't indexed it, so if
you run ``spack buildcache list`` you won't see any results. You need to index
this new build cache as follows:
@@ -318,7 +318,7 @@ other system dependencies. However, they are still compatible with tools like
``skopeo``, ``podman``, and ``docker`` for pulling and pushing.
.. note::
The Docker ``overlayfs2`` storage driver is limited to 128 layers, above which a
The docker ``overlayfs2`` storage driver is limited to 128 layers, above which a
``max depth exceeded`` error may be produced when pulling the image. There
are `alternative drivers <https://docs.docker.com/storage/storagedriver/>`_.

View File

@@ -14,7 +14,7 @@ is an entire command dedicated to the management of every aspect of bootstrappin
.. command-output:: spack bootstrap --help
Spack is configured to bootstrap its dependencies lazily by default; i.e., the first time they are needed and
Spack is configured to bootstrap its dependencies lazily by default; i.e. the first time they are needed and
can't be found. You can readily check if any prerequisite for using Spack is missing by running:
.. code-block:: console
@@ -36,8 +36,8 @@ can't be found. You can readily check if any prerequisite for using Spack is mis
In the case of the output shown above Spack detected that both ``clingo`` and ``gnupg``
are missing and it's giving detailed information on why they are needed and whether
they can be bootstrapped. The return code of this command summarizes the results; if any
dependencies are missing, the return code is ``1``, otherwise ``0``. Running a command that
they can be bootstrapped. The return code of this command summarizes the results, if any
dependencies are missing the return code is ``1``, otherwise ``0``. Running a command that
concretizes a spec, like:
.. code-block:: console

View File

@@ -66,7 +66,7 @@ on these ideas for each distinct build system that Spack supports:
build_systems/rocmpackage
build_systems/sourceforgepackage
For reference, the :py:mod:`Build System API docs <spack_repo.builtin.build_systems>`
For reference, the :py:mod:`Build System API docs <spack.build_systems>`
provide a list of build systems and methods/attributes that can be
overridden. If you are curious about the implementation of a particular
build system, you can view the source code by running:
@@ -90,7 +90,7 @@ packages. You can quickly find examples by running:
You can then view these packages with ``spack edit``.
This guide is intended to supplement the
:py:mod:`Build System API docs <spack_repo.builtin.build_systems>` with examples of
:py:mod:`Build System API docs <spack.build_systems>` with examples of
how to override commonly used methods. It also provides rules of thumb
and suggestions for package developers who are unfamiliar with a
particular build system.

View File

@@ -129,8 +129,8 @@ Adding flags to cmake
To add additional flags to the ``cmake`` call, simply override the
``cmake_args`` function. The following example defines values for the flags
``WHATEVER``, ``ENABLE_BROKEN_FEATURE``, ``DETECT_HDF5``, and ``THREADS`` with
and without the :meth:`~spack_repo.builtin.build_systems.cmake.CMakeBuilder.define` and
:meth:`~spack_repo.builtin.build_systems.cmake.CMakeBuilder.define_from_variant` helper functions:
and without the :meth:`~spack.build_systems.cmake.CMakeBuilder.define` and
:meth:`~spack.build_systems.cmake.CMakeBuilder.define_from_variant` helper functions:
.. code-block:: python

View File

@@ -35,8 +35,8 @@
if not os.path.exists(link_name):
os.symlink(os.path.abspath("../../.."), link_name, target_is_directory=True)
sys.path.insert(0, os.path.abspath("_spack_root/lib/spack/external"))
sys.path.insert(0, os.path.abspath("_spack_root/lib/spack/external/_vendoring"))
sys.path.append(os.path.abspath("_spack_root/lib/spack/"))
sys.path.append(os.path.abspath("_spack_root/var/spack/repos/"))
# Add the Spack bin directory to the path so that we can use its output in docs.
os.environ["SPACK_ROOT"] = os.path.abspath("_spack_root")
@@ -76,20 +76,11 @@
apidoc_args
+ [
"_spack_root/lib/spack/spack",
"_spack_root/lib/spack/spack/package.py", # sphinx struggles with os.chdir re-export.
"_spack_root/lib/spack/spack/test/*.py",
"_spack_root/lib/spack/spack/test/cmd/*.py",
]
)
sphinx_apidoc(apidoc_args + ["_spack_root/lib/spack/llnl"])
sphinx_apidoc(
apidoc_args
+ [
"--implicit-namespaces",
"_spack_root/var/spack/repos/spack_repo",
"_spack_root/var/spack/repos/spack_repo/builtin/packages",
]
)
# Enable todo items
todo_include_todos = True
@@ -218,7 +209,7 @@ def setup(sphinx):
# Spack classes that are private and we don't want to expose
("py:class", "spack.provider_index._IndexBase"),
("py:class", "spack.repo._PrependFileLoader"),
("py:class", "spack_repo.builtin.build_systems._checks.BuilderWithDefaults"),
("py:class", "spack.build_systems._checks.BuilderWithDefaults"),
# Spack classes that intersphinx is unable to resolve
("py:class", "spack.version.StandardVersion"),
("py:class", "spack.spec.DependencySpec"),
@@ -228,7 +219,7 @@ def setup(sphinx):
("py:class", "spack.install_test.Pb"),
("py:class", "spack.filesystem_view.SimpleFilesystemView"),
("py:class", "spack.traverse.EdgeAndDepth"),
("py:class", "_vendoring.archspec.cpu.microarchitecture.Microarchitecture"),
("py:class", "archspec.cpu.microarchitecture.Microarchitecture"),
("py:class", "spack.compiler.CompilerCache"),
# TypeVar that is not handled correctly
("py:class", "llnl.util.lang.T"),

View File

@@ -148,8 +148,8 @@ this can expose you to attacks. Use at your own risk.
``ssl_certs``
--------------------
Path to custom certificates for SSL verification. The value can be a
filesystem path, or an environment variable that expands to an absolute file path.
Path to custom certificats for SSL verification. The value can be a
filesytem path, or an environment variable that expands to an absolute file path.
The default value is set to the environment variable ``SSL_CERT_FILE``
to use the same syntax used by many other applications that automatically
detect custom certificates.

View File

@@ -11,7 +11,7 @@ Container Images
Spack :ref:`environments` can easily be turned into container images. This page
outlines two ways in which this can be done:
1. By installing the environment on the host system and copying the installations
1. By installing the environment on the host system, and copying the installations
into the container image. This approach does not require any tools like Docker
or Singularity to be installed.
2. By generating a Docker or Singularity recipe that can be used to build the
@@ -56,8 +56,8 @@ environment roots and its runtime dependencies.
.. note::
When using registries like GHCR and Docker Hub, the ``--oci-password`` flag specifies not
the password for your account, but rather a personal access token you need to generate separately.
When using registries like GHCR and Docker Hub, the ``--oci-password`` flag is not
the password for your account, but a personal access token you need to generate separately.
The specified ``--base-image`` should have a libc that is compatible with the host system.
For example if your host system is Ubuntu 20.04, you can use ``ubuntu:20.04``, ``ubuntu:22.04``

View File

@@ -20,7 +20,7 @@ be present on the machine where Spack is run:
:header-rows: 1
These requirements can be easily installed on most modern Linux systems;
on macOS, the Command Line Tools package is required, and a full Xcode suite
on macOS, the Command Line Tools package is required, and a full XCode suite
may be necessary for some packages such as Qt and apple-gl. Spack is designed
to run on HPC platforms like Cray. Not all packages should be expected
to work on all platforms.

View File

@@ -103,7 +103,6 @@ or refer to the full manual below.
:caption: API Docs
Spack API Docs <spack>
Spack Builtin Repo <spack_repo>
LLNL API Docs <llnl>
==================

View File

@@ -8,7 +8,7 @@
Modules (modules.yaml)
======================
The use of module systems to manage user environments in a controlled way
The use of module systems to manage user environment in a controlled way
is a common practice at HPC centers that is sometimes embraced also by
individual programmers on their development machines. To support this
common practice Spack integrates with `Environment Modules
@@ -490,7 +490,7 @@ that are already in the Lmod hierarchy.
.. note::
Tcl and Lua modules also allow for explicit conflicts between module files.
Tcl and Lua modules also allow for explicit conflicts between modulefiles.
.. code-block:: yaml
@@ -513,7 +513,7 @@ that are already in the Lmod hierarchy.
:meth:`~spack.spec.Spec.format` method.
For Lmod and Environment Modules versions prior 4.2, it is important to
express the conflict on both module files conflicting with each other.
express the conflict on both modulefiles conflicting with each other.
.. note::
@@ -550,7 +550,7 @@ that are already in the Lmod hierarchy.
.. warning::
Consistency of Core packages
The user is responsible for maintaining consistency among core packages, as ``core_specs``
The user is responsible for maintining consistency among core packages, as ``core_specs``
bypasses the hierarchy that allows Lmod to safely switch between coherent software stacks.
.. warning::

View File

@@ -69,7 +69,7 @@ An example for ``CMake`` is, for instance:
The predefined steps for each build system are called "phases".
In general, the name and order in which the phases will be executed can be
obtained by either reading the API docs at :py:mod:`~.spack_repo.builtin.build_systems`, or
obtained by either reading the API docs at :py:mod:`~.spack.build_systems`, or
using the ``spack info`` command:
.. code-block:: console
@@ -158,7 +158,7 @@ builder class explicitly. Using the same example as above, this reads:
url_fmt = "https://github.com/uclouvain/openjpeg/archive/version.{0}.tar.gz"
return url_fmt.format(version)
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
def cmake_args(self):
args = [
self.define_from_variant("BUILD_CODEC", "codec"),
@@ -179,7 +179,7 @@ Spack can be found at :ref:`package_class_structure`.
.. code-block:: python
class Foo(CMakePackage):
class Foo(CmakePackage):
def cmake_args(self):
...
@@ -256,7 +256,7 @@ for details):
#
# See the Spack documentation for more information on packaging.
# ----------------------------------------------------------------------------
import spack_repo.builtin.build_systems.autotools
import spack.build_systems.autotools
from spack.package import *
@@ -1212,7 +1212,7 @@ class-level tarball URL and VCS. For example:
version("master", branch="master")
version("12.12.1", md5="ecd4606fa332212433c98bf950a69cc7")
version("12.10.1", md5="667333dbd7c0f031d47d7c5511fd0810")
version("12.8.1", md5="9f37f683ee2b427b5540db8a20ed6b15")
version("12.8.1", "9f37f683ee2b427b5540db8a20ed6b15")
If a package contains both a ``url`` and ``git`` class-level attribute,
Spack decides which to use based on the arguments to the ``version()``
@@ -1343,7 +1343,7 @@ Submodules
version("1.0.1", tag="v1.0.1", submodules=True)
If a package needs more fine-grained control over submodules, define
If a package has needs more fine-grained control over submodules, define
``submodules`` to be a callable function that takes the package instance as
its only argument. The function should return a list of submodules to be fetched.
@@ -2253,15 +2253,22 @@ RPATHs in Spack are handled in one of three ways:
set in standard variables like ``CC``, ``CXX``, ``F77``, and ``FC``,
so most build systems (autotools and many gmake systems) pick them
up and use them.
#. CMake has its own RPATH handling, and distinguishes between build and
install RPATHs. By default, during the build it registers RPATHs to
all libraries it links to, so that just-built executables can be run
during the build itself. Upon installation, these RPATHs are cleared,
unless the user defines the install RPATHs. When inheriting from
``CMakePackage``, Spack handles this automatically, and sets
``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` and ``CMAKE_INSTALL_RPATH``,
so that libraries of dependencies and the package's own libraries
can be found at runtime.
#. CMake also respects Spack's compiler wrappers, but many CMake
builds have logic to overwrite RPATHs when binaries are
installed. Spack provides the ``std_cmake_args`` variable, which
includes parameters necessary for CMake build use the right
installation RPATH. It can be used like this when ``cmake`` is
invoked:
.. code-block:: python
class MyPackage(Package):
...
def install(self, spec, prefix):
cmake("..", *std_cmake_args)
make()
make("install")
#. If you need to modify the build to add your own RPATHs, you can
use the ``self.rpath`` property of your package, which will
return a list of all the RPATHs that Spack will use when it
@@ -2308,19 +2315,31 @@ looks like this:
parallel = False
You can also disable parallel builds only for specific make
invocation:
Similarly, you can disable parallel builds only for specific make
commands, as ``libdwarf`` does:
.. code-block:: python
:emphasize-lines: 5
:emphasize-lines: 9, 12
:linenos:
class Libelf(Package):
...
def install(self, spec, prefix):
configure("--prefix=" + prefix,
"--enable-shared",
"--disable-dependency-tracking",
"--disable-debug")
make()
# The mkdir commands in libelf's install can fail in parallel
make("install", parallel=False)
The first make will run in parallel here, but the second will not. If
you set ``parallel`` to ``False`` at the package level, then each call
to ``make()`` will be sequential by default, but packagers can call
``make(parallel=True)`` to override it.
Note that the ``--jobs`` option works out of the box for all standard
build systems. If you are using a non-standard build system instead, you
can use the variable ``make_jobs`` to extract the number of jobs specified
@@ -2495,7 +2514,7 @@ necessary when there are breaking changes in the dependency that the
package cannot handle. In Spack we often add forward compatibility
bounds only at the time a new, breaking version of a dependency is
released. As with backward compatibility, it is typical to see a list
of forward compatibility bounds in a package file as separate lines:
of forward compatibility bounds in a package file as seperate lines:
.. code-block:: python
@@ -3371,7 +3390,7 @@ the above attribute implementations:
"/opt/spack/linux-fedora35-haswell/gcc-11.3.1/foo-1.0-ca3rczp5omy7dfzoqw4p7oc2yh3u7lt6/baz/lib/libFooBaz.so"
])
# baz library directories in the baz subdirectory of the foo prefix
# baz library directories in the baz subdirectory of the foo porefix
>>> spec["baz"].libs.directories
[
"/opt/spack/linux-fedora35-haswell/gcc-11.3.1/foo-1.0-ca3rczp5omy7dfzoqw4p7oc2yh3u7lt6/baz/lib"
@@ -3685,57 +3704,60 @@ the build system. The build systems currently supported by Spack are:
+----------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+==========================================================+==================================+
| :class:`~spack_repo.builtin.build_systems.generic` | Generic build system without any |
| :class:`~spack.build_systems.generic` | Generic build system without any |
| | base implementation |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.makefile` | Specialized build system for |
| :class:`~spack.build_systems.makefile` | Specialized build system for |
| | software built invoking |
| | hand-written Makefiles |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.autotools` | Specialized build system for |
| :class:`~spack.build_systems.autotools` | Specialized build system for |
| | software built using |
| | GNU Autotools |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.cmake` | Specialized build system for |
| :class:`~spack.build_systems.cmake` | Specialized build system for |
| | software built using CMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.maven` | Specialized build system for |
| :class:`~spack.build_systems.maven` | Specialized build system for |
| | software built using Maven |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.meson` | Specialized build system for |
| :class:`~spack.build_systems.meson` | Specialized build system for |
| | software built using Meson |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.nmake` | Specialized build system for |
| :class:`~spack.build_systems.nmake` | Specialized build system for |
| | software built using NMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.qmake` | Specialized build system for |
| :class:`~spack.build_systems.qmake` | Specialized build system for |
| | software built using QMake |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.scons` | Specialized build system for |
| :class:`~spack.build_systems.scons` | Specialized build system for |
| | software built using SCons |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.waf` | Specialized build system for |
| :class:`~spack.build_systems.waf` | Specialized build system for |
| | software built using Waf |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.r` | Specialized build system for |
| :class:`~spack.build_systems.r` | Specialized build system for |
| | R extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.octave` | Specialized build system for |
| :class:`~spack.build_systems.octave` | Specialized build system for |
| | Octave packages |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.python` | Specialized build system for |
| :class:`~spack.build_systems.python` | Specialized build system for |
| | Python extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.perl` | Specialized build system for |
| :class:`~spack.build_systems.perl` | Specialized build system for |
| | Perl extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.ruby` | Specialized build system for |
| :class:`~spack.build_systems.ruby` | Specialized build system for |
| | Ruby extensions |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.oneapi` | Specialized build system for |
| :class:`~spack.build_systems.intel` | Specialized build system for |
| | licensed Intel software |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.oneapi` | Specialized build system for |
| | Intel oneAPI software |
+----------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.aspell_dict` | Specialized build system for |
| :class:`~spack.build_systems.aspell_dict` | Specialized build system for |
| | Aspell dictionaries |
+----------------------------------------------------------+----------------------------------+
@@ -3747,7 +3769,7 @@ the build system. The build systems currently supported by Spack are:
rare cases where manual intervention is needed we need to stress that a
package base class depends on the *build system* being used, not the language of the package.
For example, a Python extension installed with CMake would ``extends("python")`` and
subclass from :class:`~spack_repo.builtin.build_systems.cmake.CMakePackage`.
subclass from :class:`~spack.build_systems.cmake.CMakePackage`.
^^^^^^^^^^^^^^^^^^^^^^^^^^
Overriding builder methods
@@ -3755,7 +3777,7 @@ Overriding builder methods
Build-system "phases" have default implementations that fit most of the common cases:
.. literalinclude:: _spack_root/var/spack/repos/spack_repo/builtin/build_systems/autotools.py
.. literalinclude:: _spack_root/lib/spack/spack/build_systems/autotools.py
:pyobject: AutotoolsBuilder.configure
:linenos:
@@ -3769,7 +3791,7 @@ configure arguments:
Each specific build system has a list of attributes and methods that can be overridden to
fine-tune the installation of a package without overriding an entire phase. To
have more information on them the place to go is the API docs of the :py:mod:`~.spack_repo.builtin.build_systems`
have more information on them the place to go is the API docs of the :py:mod:`~.spack.build_systems`
module.
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3811,7 +3833,7 @@ If the ``package.py`` has build instructions in a separate
.. code-block:: python
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
def install(self, pkg, spec, prefix):
...
@@ -3824,32 +3846,31 @@ Mixin base classes
Besides build systems, there are other cases where common metadata and behavior can be extracted
and reused by many packages. For instance, packages that depend on ``Cuda`` or ``Rocm``, share
common dependencies and constraints. To factor these attributes into a single place, Spack provides
a few mixin classes in the ``spack_repo.builtin.build_systems`` module:
a few mixin classes in the ``spack.build_systems`` module:
+----------------------------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+============================================================================+==================================+
| :class:`~spack_repo.builtin.build_systems.cuda.CudaPackage` | A helper class for packages that |
| | use CUDA |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.rocm.ROCmPackage` | A helper class for packages that |
| | use ROCm |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.gnu.GNUMirrorPackage` | A helper class for GNU packages |
| | |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.python.PythonExtension` | A helper class for Python |
| | extensions |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.sourceforge.SourceforgePackage` | A helper class for packages |
| | from sourceforge.org |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.sourceware.SourcewarePackage` | A helper class for packages |
| | from sourceware.org |
+----------------------------------------------------------------------------+----------------------------------+
| :class:`~spack_repo.builtin.build_systems.xorg.XorgPackage` | A helper class for x.org |
| | packages |
+----------------------------------------------------------------------------+----------------------------------+
+---------------------------------------------------------------+----------------------------------+
| **API docs** | **Description** |
+===============================================================+==================================+
| :class:`~spack.build_systems.cuda.CudaPackage` | A helper class for packages that |
| | use CUDA |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.rocm.ROCmPackage` | A helper class for packages that |
| | use ROCm |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.gnu.GNUMirrorPackage` | A helper class for GNU packages |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.python.PythonExtension` | A helper class for Python |
| | extensions |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.sourceforge.SourceforgePackage` | A helper class for packages |
| | from sourceforge.org |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.sourceware.SourcewarePackage` | A helper class for packages |
| | from sourceware.org |
+---------------------------------------------------------------+----------------------------------+
| :class:`~spack.build_systems.xorg.XorgPackage` | A helper class for x.org |
| | packages |
+---------------------------------------------------------------+----------------------------------+
These classes should be used by adding them to the inheritance tree of the package that needs them,
for instance:
@@ -3893,13 +3914,13 @@ Additional build instructions are split into separate builder classes:
.. code-block:: python
class CMakeBuilder(spack_repo.builtin.build_systems.cmake.CMakeBuilder):
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
def cmake_args(self):
return [
self.define_from_variant("MY_FEATURE", "my_feature")
]
class AutotoolsBuilder(spack_repo.builtin.build_systems.autotools.AutotoolsBuilder):
class AutotoolsBuilder(spack.build_systems.autotools.AutotoolsBuilder):
def configure_args(self):
return self.with_or_without("my-feature", variant="my_feature")
@@ -5728,7 +5749,7 @@ running each executable, ``foo`` and ``bar``, as independent test parts.
.. note::
The method name ``copy_test_files`` here is for illustration purposes.
You are free to use a name that is better suited to your package.
You are free to use a name that is more suited to your package.
The key to copying files for stand-alone testing at build time is use
of the ``run_after`` directive, which ensures the associated files are
@@ -7237,7 +7258,7 @@ which are not, there is the `checked_by` parameter in the license directive:
license("<license>", when="<when>", checked_by="<github username>")
When you have validated a package license, either when doing so explicitly or
When you have validated a github license, either when doing so explicitly or
as part of packaging a new package, please set the `checked_by` parameter
to your Github username to signal that the license has been manually
verified.

View File

@@ -214,7 +214,7 @@ package versions, simply run the following commands:
Running ``spack mark -i --all`` tells Spack to mark all of the existing
packages within an environment as "implicitly" installed. This tells
Spack's garbage collection system that these packages should be cleaned up.
spack's garbage collection system that these packages should be cleaned up.
Don't worry however, this will not remove your entire environment.
Running ``spack install`` will reexamine your spack environment after

View File

@@ -0,0 +1 @@
from _pyrsistent_version import *

View File

@@ -0,0 +1 @@
from altgraph import *

View File

@@ -1,8 +1,8 @@
"""
_vendoring.altgraph.Dot - Interface to the dot language
altgraph.Dot - Interface to the dot language
============================================
The :py:mod:`~_vendoring.altgraph.Dot` module provides a simple interface to the
The :py:mod:`~altgraph.Dot` module provides a simple interface to the
file format used in the
`graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
program. The module is intended to offload the most tedious part of the process
@@ -20,7 +20,7 @@
Here is a typical usage::
from _vendoring.altgraph import Graph, Dot
from altgraph import Graph, Dot
# create a graph
edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
@@ -77,7 +77,7 @@
.. note::
dotty (invoked via :py:func:`~_vendoring.altgraph.Dot.display`) may not be able to
dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
display all graphics styles. To verify the output save it to an image file
and look at it that way.
@@ -111,7 +111,7 @@
import os
import warnings
from _vendoring.altgraph import GraphError
from altgraph import GraphError
class Dot(object):

View File

@@ -1,5 +1,5 @@
"""
_vendoring.altgraph.Graph - Base Graph class
altgraph.Graph - Base Graph class
=================================
..
@@ -15,7 +15,7 @@
from collections import deque
from _vendoring.altgraph import GraphError
from altgraph import GraphError
class Graph(object):

View File

@@ -1,8 +1,8 @@
"""
_vendoring.altgraph.GraphAlgo - Graph algorithms
altgraph.GraphAlgo - Graph algorithms
=====================================
"""
from _vendoring.altgraph import GraphError
from altgraph import GraphError
def dijkstra(graph, start, end=None):
@@ -25,7 +25,7 @@ def dijkstra(graph, start, end=None):
and will raise an exception if it discovers that a negative edge has
caused it to make a mistake.
Adapted to _vendoring.altgraph by Istvan Albert, Pennsylvania State University -
Adapted to altgraph by Istvan Albert, Pennsylvania State University -
June, 9 2004
"""
D = {} # dictionary of final distances

View File

@@ -1,5 +1,5 @@
"""
_vendoring.altgraph.GraphStat - Functions providing various graph statistics
altgraph.GraphStat - Functions providing various graph statistics
=================================================================
"""

View File

@@ -1,17 +1,17 @@
"""
_vendoring.altgraph.GraphUtil - Utility classes and functions
altgraph.GraphUtil - Utility classes and functions
==================================================
"""
import random
from collections import deque
from _vendoring.altgraph import Graph, GraphError
from altgraph import Graph, GraphError
def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=False):
"""
Generates and returns a :py:class:`~_vendoring.altgraph.Graph.Graph` instance with
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance with
*node_num* nodes randomly connected by *edge_num* edges.
"""
g = Graph.Graph()
@@ -52,7 +52,7 @@ def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=Fals
def generate_scale_free_graph(steps, growth_num, self_loops=False, multi_edges=False):
"""
Generates and returns a :py:class:`~_vendoring.altgraph.Graph.Graph` instance that
Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that
will have *steps* \\* *growth_num* nodes and a scale free (powerlaw)
connectivity. Starting with a fully connected graph with *growth_num*
nodes at every step *growth_num* nodes are added to the graph and are

View File

@@ -1,14 +1,14 @@
"""
_vendoring.altgraph.ObjectGraph - Graph of objects with an identifier
altgraph.ObjectGraph - Graph of objects with an identifier
==========================================================
A graph of objects that have a "graphident" attribute.
graphident is the key for the object in the graph
"""
from _vendoring.altgraph import GraphError
from _vendoring.altgraph.Graph import Graph
from _vendoring.altgraph.GraphUtil import filter_stack
from altgraph import GraphError
from altgraph.Graph import Graph
from altgraph.GraphUtil import filter_stack
class ObjectGraph(object):

View File

@@ -1,18 +1,18 @@
"""
_vendoring.altgraph - a python graph library
altgraph - a python graph library
=================================
_vendoring.altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
to use newer Python 2.3+ features, including additional support used by the
py2app suite (modulegraph and _vendoring.macholib, specifically).
py2app suite (modulegraph and macholib, specifically).
_vendoring.altgraph is a python based graph (network) representation and manipulation
altgraph is a python based graph (network) representation and manipulation
package. It has started out as an extension to the
`graph_lib module
<http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
written by Nathan Denny it has been significantly optimized and expanded.
The :class:`_vendoring.altgraph.Graph.Graph` class is loosely modeled after the
The :class:`altgraph.Graph.Graph` class is loosely modeled after the
`LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_
(Library of Efficient Datatypes) representation. The library
includes methods for constructing graphs, BFS and DFS traversals,
@@ -22,22 +22,22 @@
The package contains the following modules:
- the :py:mod:`_vendoring.altgraph.Graph` module contains the
:class:`~_vendoring.altgraph.Graph.Graph` class that stores the graph data
- the :py:mod:`altgraph.Graph` module contains the
:class:`~altgraph.Graph.Graph` class that stores the graph data
- the :py:mod:`_vendoring.altgraph.GraphAlgo` module implements graph algorithms
operating on graphs (:py:class:`~_vendoring.altgraph.Graph.Graph`} instances)
- the :py:mod:`altgraph.GraphAlgo` module implements graph algorithms
operating on graphs (:py:class:`~altgraph.Graph.Graph`} instances)
- the :py:mod:`_vendoring.altgraph.GraphStat` module contains functions for
- the :py:mod:`altgraph.GraphStat` module contains functions for
computing statistical measures on graphs
- the :py:mod:`_vendoring.altgraph.GraphUtil` module contains functions for
- the :py:mod:`altgraph.GraphUtil` module contains functions for
generating, reading and saving graphs
- the :py:mod:`_vendoring.altgraph.Dot` module contains functions for displaying
- the :py:mod:`altgraph.Dot` module contains functions for displaying
graphs via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
- the :py:mod:`_vendoring.altgraph.ObjectGraph` module implements a graph of
- the :py:mod:`altgraph.ObjectGraph` module implements a graph of
objects with a unique identifier
Installation
@@ -62,7 +62,7 @@
Lets assume that we want to analyze the graph below (links to the full picture)
GRAPH_IMG. Our script then might look the following way::
from _vendoring.altgraph import Graph, GraphAlgo, Dot
from altgraph import Graph, GraphAlgo, Dot
# these are the edges
edges = [ (1,2), (2,4), (1,3), (2,4), (3,4), (4,5), (6,5),
@@ -141,7 +141,7 @@
"""
import pkg_resources
__version__ = pkg_resources.require("_vendoring.altgraph")[0].version
__version__ = pkg_resources.require("altgraph")[0].version
class GraphError(ValueError):

View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Anders Høst
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -38,7 +38,7 @@
"typing.ClassVar",
"t.ClassVar",
"ClassVar",
"_vendoring.typing_extensions.ClassVar",
"typing_extensions.ClassVar",
)
# we don't use a double-underscore prefix because that triggers
# name mangling when trying to create a slot for the field

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr import (
from attr import (
NOTHING,
Attribute,
Factory,
@@ -28,7 +28,7 @@
resolve_types,
validate,
)
from _vendoring.attr._next_gen import asdict, astuple
from attr._next_gen import asdict, astuple
from . import converters, exceptions, filters, setters, validators

View File

@@ -1,3 +1,3 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr.converters import * # noqa
from attr.converters import * # noqa

View File

@@ -1,3 +1,3 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr.exceptions import * # noqa
from attr.exceptions import * # noqa

View File

@@ -1,3 +1,3 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr.filters import * # noqa
from attr.filters import * # noqa

View File

@@ -1,3 +1,3 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr.setters import * # noqa
from attr.setters import * # noqa

View File

@@ -1,3 +1,3 @@
# SPDX-License-Identifier: MIT
from _vendoring.attr.validators import * # noqa
from attr.validators import * # noqa

View File

@@ -19,7 +19,7 @@
from types import CodeType
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
class _MemcachedClient(te.Protocol):
@@ -101,7 +101,7 @@ def bytecode_to_string(self) -> bytes:
class BytecodeCache:
"""To implement your own bytecode cache you have to subclass this class
and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of
these methods are passed a :class:`~_vendoring.jinja2.bccache.Bucket`.
these methods are passed a :class:`~jinja2.bccache.Bucket`.
A very basic bytecode cache that saves the bytecode on the file system::
@@ -193,7 +193,7 @@ class FileSystemBytecodeCache(BytecodeCache):
is created for the user in the system temp directory.
The pattern can be used to have multiple separate caches operate on the
same directory. The default pattern is ``'___vendoring.jinja2_%s.cache'``. ``%s``
same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s``
is replaced with the cache key.
>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
@@ -202,7 +202,7 @@ class FileSystemBytecodeCache(BytecodeCache):
"""
def __init__(
self, directory: t.Optional[str] = None, pattern: str = "___vendoring.jinja2_%s.cache"
self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache"
) -> None:
if directory is None:
directory = self._get_default_cache_dir()
@@ -225,7 +225,7 @@ def _unsafe_dir() -> "te.NoReturn":
if not hasattr(os, "getuid"):
_unsafe_dir()
dirname = f"__vendoring.jinja2-cache-{os.getuid()}"
dirname = f"_jinja2-cache-{os.getuid()}"
actual_dir = os.path.join(tmpdir, dirname)
try:
@@ -332,7 +332,7 @@ class MemcachedBytecodeCache(BytecodeCache):
def __init__(
self,
client: "_MemcachedClient",
prefix: str = "_vendoring.jinja2/bytecode/",
prefix: str = "jinja2/bytecode/",
timeout: t.Optional[int] = None,
ignore_memcache_errors: bool = True,
):

View File

@@ -6,8 +6,8 @@
from itertools import chain
from keyword import iskeyword as is_python_keyword
from _vendoring.markupsafe import escape
from _vendoring.markupsafe import Markup
from markupsafe import escape
from markupsafe import Markup
from . import nodes
from .exceptions import TemplateAssertionError
@@ -23,7 +23,7 @@
from .visitor import NodeVisitor
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
@@ -836,7 +836,7 @@ def visit_Template(
exported_names = sorted(exported)
self.writeline("from __future__ import generator_stop") # Python < 3.7
self.writeline("from _vendoring.jinja2.runtime import " + ", ".join(exported_names))
self.writeline("from jinja2.runtime import " + ", ".join(exported_names))
# if we want a deferred initialization we cannot move the
# environment into a local name

View File

@@ -8,7 +8,7 @@
from .utils import Namespace
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
# defaults for the parser / lexer
BLOCK_START_STRING = "{%"

View File

@@ -12,7 +12,7 @@
from functools import reduce
from types import CodeType
from _vendoring.markupsafe import Markup
from markupsafe import Markup
from . import nodes
from .compiler import CodeGenerator
@@ -55,7 +55,7 @@
from .utils import missing
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .bccache import BytecodeCache
from .ext import Extension
from .loaders import BaseLoader
@@ -126,7 +126,7 @@ def _environment_config_check(environment: "Environment") -> "Environment":
"""Perform a sanity check on the environment."""
assert issubclass(
environment.undefined, Undefined
), "'undefined' must be a subclass of '_vendoring.jinja2.Undefined'."
), "'undefined' must be a subclass of 'jinja2.Undefined'."
assert (
environment.block_start_string
!= environment.variable_start_string
@@ -221,7 +221,7 @@ class Environment:
`autoescape`
If set to ``True`` the XML/HTML autoescaping feature is enabled by
default. For more details about autoescaping see
:class:`~_vendoring.markupsafe.Markup`. As of Jinja 2.4 this can also
:class:`~markupsafe.Markup`. As of Jinja 2.4 this can also
be a callable that is passed the template name and has to
return ``True`` or ``False`` depending on autoescape should be
enabled by default.
@@ -264,7 +264,7 @@ class Environment:
#: if this environment is sandboxed. Modifying this variable won't make
#: the environment sandboxed though. For a real sandboxed environment
#: have a look at _vendoring.jinja2.sandbox. This flag alone controls the code
#: have a look at jinja2.sandbox. This flag alone controls the code
#: generation by the compiler.
sandboxed = False
@@ -279,11 +279,11 @@ class Environment:
shared = False
#: the class that is used for code generation. See
#: :class:`~_vendoring.jinja2.compiler.CodeGenerator` for more information.
#: :class:`~jinja2.compiler.CodeGenerator` for more information.
code_generator_class: t.Type["CodeGenerator"] = CodeGenerator
#: the context class that is used for templates. See
#: :class:`~_vendoring.jinja2.runtime.Context` for more information.
#: :class:`~jinja2.runtime.Context` for more information.
context_class: t.Type[Context] = Context
template_class: t.Type["Template"]
@@ -650,7 +650,7 @@ def _tokenize(
state: t.Optional[str] = None,
) -> TokenStream:
"""Called by the parser to do the preprocessing and filtering
for all the extensions. Returns a :class:`~_vendoring.jinja2.lexer.TokenStream`.
for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`.
"""
source = self.preprocess(source, name, filename)
stream = self.lexer.tokenize(source, name, filename, state)
@@ -1547,7 +1547,7 @@ def __repr__(self) -> str:
class TemplateExpression:
"""The :meth:`_vendoring.jinja2.Environment.compile_expression` method returns an
"""The :meth:`jinja2.Environment.compile_expression` method returns an
instance of this object. It encapsulates the expression-like access
to the template with an expression it wraps.
"""

View File

@@ -4,7 +4,7 @@
import typing as t
import warnings
from _vendoring.markupsafe import Markup
from markupsafe import Markup
from . import defaults
from . import nodes
@@ -18,7 +18,7 @@
from .utils import pass_context
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .lexer import Token
from .lexer import TokenStream
from .parser import Parser
@@ -108,10 +108,10 @@ def preprocess(
def filter_stream(
self, stream: "TokenStream"
) -> t.Union["TokenStream", t.Iterable["Token"]]:
"""It's passed a :class:`~_vendoring.jinja2.lexer.TokenStream` that can be used
"""It's passed a :class:`~jinja2.lexer.TokenStream` that can be used
to filter tokens returned. This method has to return an iterable of
:class:`~_vendoring.jinja2.lexer.Token`\\s, but it doesn't have to return a
:class:`~_vendoring.jinja2.lexer.TokenStream`.
:class:`~jinja2.lexer.Token`\\s, but it doesn't have to return a
:class:`~jinja2.lexer.TokenStream`.
"""
return stream
@@ -145,7 +145,7 @@ def call_method(
lineno: t.Optional[int] = None,
) -> nodes.Call:
"""Call a method of the extension. This is a shortcut for
:meth:`attr` + :class:`_vendoring.jinja2.nodes.Call`.
:meth:`attr` + :class:`jinja2.nodes.Call`.
"""
if args is None:
args = []
@@ -629,9 +629,9 @@ class DebugExtension(Extension):
.. code-block:: text
{'context': {'cycler': <class '_vendoring.jinja2.utils.Cycler'>,
{'context': {'cycler': <class 'jinja2.utils.Cycler'>,
...,
'namespace': <class '_vendoring.jinja2.utils.Namespace'>},
'namespace': <class 'jinja2.utils.Namespace'>},
'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
@@ -679,7 +679,7 @@ def extract_from_ast(
This example explains the behavior:
>>> from _vendoring.jinja2 import Environment
>>> from jinja2 import Environment
>>> env = Environment()
>>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
>>> list(extract_from_ast(node))

View File

@@ -9,9 +9,9 @@
from itertools import chain
from itertools import groupby
from _vendoring.markupsafe import escape
from _vendoring.markupsafe import Markup
from _vendoring.markupsafe import soft_str
from markupsafe import escape
from markupsafe import Markup
from markupsafe import soft_str
from .async_utils import async_variant
from .async_utils import auto_aiter
@@ -28,7 +28,7 @@
from .utils import urlize
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
from .nodes import EvalContext
from .runtime import Context
@@ -48,7 +48,7 @@ def contextfilter(f: F) -> F:
"""Pass the context as the first argument to the decorated function.
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use :func:`~_vendoring.jinja2.pass_context`
Will be removed in Jinja 3.1. Use :func:`~jinja2.pass_context`
instead.
"""
warnings.warn(
@@ -66,7 +66,7 @@ def evalcontextfilter(f: F) -> F:
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use
:func:`~_vendoring.jinja2.pass_eval_context` instead.
:func:`~jinja2.pass_eval_context` instead.
.. versionadded:: 2.4
"""
@@ -85,7 +85,7 @@ def environmentfilter(f: F) -> F:
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use
:func:`~_vendoring.jinja2.pass_environment` instead.
:func:`~jinja2.pass_environment` instead.
"""
warnings.warn(
"'environmentfilter' is renamed to 'pass_environment', the old"
@@ -547,10 +547,10 @@ def do_default(
{{ ''|default('the string was empty', true) }}
.. versionchanged:: 2.11
It's now possible to configure the :class:`~_vendoring.jinja2.Environment` with
:class:`~_vendoring.jinja2.ChainableUndefined` to make the `default` filter work
It's now possible to configure the :class:`~jinja2.Environment` with
:class:`~jinja2.ChainableUndefined` to make the `default` filter work
on nested elements and attributes that may contain undefined values
in the chain without getting an :exc:`~_vendoring.jinja2.UndefinedError`.
in the chain without getting an :exc:`~jinja2.UndefinedError`.
"""
if isinstance(value, Undefined) or (boolean and not value):
return default_value

View File

@@ -14,7 +14,7 @@
from .utils import LRUCache
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
# cache for the lexers. Exists in order to be able to have multiple
@@ -400,7 +400,7 @@ def close(self) -> None:
def expect(self, expr: str) -> Token:
"""Expect a given token type and return it. This accepts the same
argument as :meth:`_vendoring.jinja2.lexer.Token.test`.
argument as :meth:`jinja2.lexer.Token.test`.
"""
if not self.current.test(expr):
expr = describe_token_expr(expr)

View File

@@ -47,7 +47,7 @@ class BaseLoader:
A very basic example for a loader that looks up templates on the file
system could look like this::
from _vendoring.jinja2 import BaseLoader, TemplateNotFound
from jinja2 import BaseLoader, TemplateNotFound
from os.path import join, exists, getmtime
class MyLoader(BaseLoader):
@@ -594,7 +594,7 @@ class ModuleLoader(BaseLoader):
def __init__(
self, path: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]]
) -> None:
package_name = f"__vendoring.jinja2_module_templates_{id(self):x}"
package_name = f"_jinja2_module_templates_{id(self):x}"
# create a fake module that looks for the templates in the
# path given.

View File

@@ -36,7 +36,7 @@ def find_undeclared_variables(ast: nodes.Template) -> t.Set[str]:
variables will be used depending on the path the execution takes at
runtime, all variables are returned.
>>> from _vendoring.jinja2 import Environment, meta
>>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
>>> meta.find_undeclared_variables(ast) == {'bar'}
@@ -64,7 +64,7 @@ def find_referenced_templates(ast: nodes.Template) -> t.Iterator[t.Optional[str]
imports. If dynamic inheritance or inclusion is used, `None` will be
yielded.
>>> from _vendoring.jinja2 import Environment, meta
>>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
>>> list(meta.find_referenced_templates(ast))

View File

@@ -7,12 +7,12 @@
import typing as t
from collections import deque
from _vendoring.markupsafe import Markup
from markupsafe import Markup
from .utils import _PassArg
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
_NodeBound = t.TypeVar("_NodeBound", bound="Node")
@@ -1041,7 +1041,7 @@ class ExtensionAttribute(Expr):
The identifier is the identifier of the :class:`Extension`.
This node is usually constructed by calling the
:meth:`~_vendoring.jinja2.ext.Extension.attr` method on an extension.
:meth:`~jinja2.ext.Extension.attr` method on an extension.
"""
fields = ("identifier", "name")
@@ -1063,7 +1063,7 @@ class ImportedName(Expr):
class InternalName(Expr):
"""An internal name in the compiler. You cannot create these nodes
yourself but the parser provides a
:meth:`~_vendoring.jinja2.parser.Parser.free_identifier` method that creates
:meth:`~jinja2.parser.Parser.free_identifier` method that creates
a new identifier for you. This identifier is not available from the
template and is not treated specially by the compiler.
"""
@@ -1114,7 +1114,7 @@ def as_const(
class ContextReference(Expr):
"""Returns the current template context. It can be used like a
:class:`Name` node, with a ``'load'`` ctx and will return the
current :class:`~_vendoring.jinja2.runtime.Context` object.
current :class:`~jinja2.runtime.Context` object.
Here an example that assigns the current template name to a
variable named `foo`::
@@ -1123,7 +1123,7 @@ class ContextReference(Expr):
Getattr(ContextReference(), 'name'))
This is basically equivalent to using the
:func:`~_vendoring.jinja2.pass_context` decorator when using the high-level
:func:`~jinja2.pass_context` decorator when using the high-level
API, which causes a reference to the context to be passed as the
first argument to a function.
"""
@@ -1188,7 +1188,7 @@ class EvalContextModifier(Stmt):
class ScopedEvalContextModifier(EvalContextModifier):
"""Modifies the eval context and reverts it later. Works exactly like
:class:`EvalContextModifier` but will only modify the
:class:`~_vendoring.jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
:class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
"""
fields = ("body",)

View File

@@ -9,7 +9,7 @@
from .lexer import describe_token_expr
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
_ImportInclude = t.TypeVar("_ImportInclude", nodes.Import, nodes.Include)
@@ -156,7 +156,7 @@ def is_tuple_end(
return False
def free_identifier(self, lineno: t.Optional[int] = None) -> nodes.InternalName:
"""Return a new free identifier as :class:`~_vendoring.jinja2.nodes.InternalName`."""
"""Return a new free identifier as :class:`~jinja2.nodes.InternalName`."""
self._last_identifier += 1
rv = object.__new__(nodes.InternalName)
nodes.Node.__init__(rv, f"fi{self._last_identifier}", lineno=lineno)
@@ -687,7 +687,7 @@ def parse_tuple(
explicit_parentheses: bool = False,
) -> t.Union[nodes.Tuple, nodes.Expr]:
"""Works like `parse_expression` but if multiple expressions are
delimited by a comma a :class:`~_vendoring.jinja2.nodes.Tuple` node is created.
delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
This method could also return a regular expression instead of a tuple
if no commas where found.

View File

@@ -5,9 +5,9 @@
from collections import abc
from itertools import chain
from _vendoring.markupsafe import escape # noqa: F401
from _vendoring.markupsafe import Markup
from _vendoring.markupsafe import soft_str
from markupsafe import escape # noqa: F401
from markupsafe import Markup
from markupsafe import soft_str
from .async_utils import auto_aiter
from .async_utils import auto_await # noqa: F401
@@ -28,7 +28,7 @@
if t.TYPE_CHECKING:
import logging
import _vendoring.typing_extensions as te
import typing_extensions as te
from .environment import Environment
class LoopRenderFunc(te.Protocol):
@@ -849,7 +849,7 @@ class Undefined:
>>> foo + 42
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = (
@@ -1020,7 +1020,7 @@ class ChainableUndefined(Undefined):
>>> foo.bar['baz'] + 42
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
.. versionadded:: 2.11.0
"""
@@ -1047,7 +1047,7 @@ class DebugUndefined(Undefined):
>>> foo + 42
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()
@@ -1077,15 +1077,15 @@ class StrictUndefined(Undefined):
>>> str(foo)
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> not foo
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> foo + 42
Traceback (most recent call last):
...
_vendoring.jinja2.exceptions.UndefinedError: 'foo' is undefined
jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()

View File

@@ -9,8 +9,8 @@
from collections import deque
from string import Formatter
from _vendoring.markupsafe import EscapeFormatter
from _vendoring.markupsafe import Markup
from markupsafe import EscapeFormatter
from markupsafe import Markup
from .environment import Environment
from .exceptions import SecurityError
@@ -128,7 +128,7 @@ def is_internal_attribute(obj: t.Any, attr: str) -> bool:
python objects. This is useful if the environment method
:meth:`~SandboxedEnvironment.is_safe_attribute` is overridden.
>>> from _vendoring.jinja2.sandbox import is_internal_attribute
>>> from jinja2.sandbox import is_internal_attribute
>>> is_internal_attribute(str, "mro")
True
>>> is_internal_attribute(str, "upper")

View File

@@ -12,10 +12,10 @@
from types import CodeType
from urllib.parse import quote_from_bytes
import _vendoring.markupsafe
import markupsafe
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
@@ -28,7 +28,7 @@
def pass_context(f: F) -> F:
"""Pass the :class:`~_vendoring.jinja2.runtime.Context` as the first argument
"""Pass the :class:`~jinja2.runtime.Context` as the first argument
to the decorated function when called while rendering a template.
Can be used on functions, filters, and tests.
@@ -45,7 +45,7 @@ def pass_context(f: F) -> F:
def pass_eval_context(f: F) -> F:
"""Pass the :class:`~_vendoring.jinja2.nodes.EvalContext` as the first argument
"""Pass the :class:`~jinja2.nodes.EvalContext` as the first argument
to the decorated function when called while rendering a template.
See :ref:`eval-context`.
@@ -62,7 +62,7 @@ def pass_eval_context(f: F) -> F:
def pass_environment(f: F) -> F:
"""Pass the :class:`~_vendoring.jinja2.Environment` as the first argument to
"""Pass the :class:`~jinja2.Environment` as the first argument to
the decorated function when called while rendering a template.
Can be used on functions, filters, and tests.
@@ -104,7 +104,7 @@ def contextfunction(f: F) -> F:
"""Pass the context as the first argument to the decorated function.
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use :func:`~_vendoring.jinja2.pass_context`
Will be removed in Jinja 3.1. Use :func:`~jinja2.pass_context`
instead.
"""
warnings.warn(
@@ -122,7 +122,7 @@ def evalcontextfunction(f: F) -> F:
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use
:func:`~_vendoring.jinja2.pass_eval_context` instead.
:func:`~jinja2.pass_eval_context` instead.
.. versionadded:: 2.4
"""
@@ -141,7 +141,7 @@ def environmentfunction(f: F) -> F:
.. deprecated:: 3.0
Will be removed in Jinja 3.1. Use
:func:`~_vendoring.jinja2.pass_environment` instead.
:func:`~jinja2.pass_environment` instead.
"""
warnings.warn(
"'environmentfunction' is renamed to 'pass_environment', the"
@@ -335,9 +335,9 @@ def trim_url(x: str) -> str:
def trim_url(x: str) -> str:
return x
words = re.split(r"(\s+)", str(_vendoring.markupsafe.escape(text)))
rel_attr = f' rel="{_vendoring.markupsafe.escape(rel)}"' if rel else ""
target_attr = f' target="{_vendoring.markupsafe.escape(target)}"' if target else ""
words = re.split(r"(\s+)", str(markupsafe.escape(text)))
rel_attr = f' rel="{markupsafe.escape(rel)}"' if rel else ""
target_attr = f' target="{markupsafe.escape(target)}"' if target else ""
for i, word in enumerate(words):
head, middle, tail = "", word, ""
@@ -455,8 +455,8 @@ def generate_lorem_ipsum(
if not html:
return "\n\n".join(result)
return _vendoring.markupsafe.Markup(
"\n".join(f"<p>{_vendoring.markupsafe.escape(x)}</p>" for x in result)
return markupsafe.Markup(
"\n".join(f"<p>{markupsafe.escape(x)}</p>" for x in result)
)
@@ -658,7 +658,7 @@ def select_autoescape(
If you want to enable it for all templates created from strings or
for all templates with `.html` and `.xml` extensions::
from _vendoring.jinja2 import Environment, select_autoescape
from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
enabled_extensions=('html', 'xml'),
default_for_string=True,
@@ -667,7 +667,7 @@ def select_autoescape(
Example configuration to turn it on at all times except if the template
ends with `.txt`::
from _vendoring.jinja2 import Environment, select_autoescape
from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
disabled_extensions=('txt',),
default_for_string=True,
@@ -703,10 +703,10 @@ def autoescape(template_name: t.Optional[str]) -> bool:
def htmlsafe_json_dumps(
obj: t.Any, dumps: t.Optional[t.Callable[..., str]] = None, **kwargs: t.Any
) -> _vendoring.markupsafe.Markup:
) -> markupsafe.Markup:
"""Serialize an object to a string of JSON with :func:`json.dumps`,
then replace HTML-unsafe characters with Unicode escapes and mark
the result safe with :class:`~_vendoring.markupsafe.Markup`.
the result safe with :class:`~markupsafe.Markup`.
This is available in templates as the ``|tojson`` filter.
@@ -732,7 +732,7 @@ def htmlsafe_json_dumps(
if dumps is None:
dumps = json.dumps
return _vendoring.markupsafe.Markup(
return markupsafe.Markup(
dumps(obj, **kwargs)
.replace("<", "\\u003c")
.replace(">", "\\u003e")
@@ -833,11 +833,11 @@ def __repr__(self) -> str:
return f"<Namespace {self.__attrs!r}>"
class Markup(_vendoring.markupsafe.Markup):
class Markup(markupsafe.Markup):
def __new__(cls, base="", encoding=None, errors="strict"): # type: ignore
warnings.warn(
"'_vendoring.jinja2.Markup' is deprecated and will be removed in Jinja"
" 3.1. Import '_vendoring.markupsafe.Markup' instead.",
"'jinja2.Markup' is deprecated and will be removed in Jinja"
" 3.1. Import 'markupsafe.Markup' instead.",
DeprecationWarning,
stacklevel=2,
)
@@ -846,9 +846,9 @@ def __new__(cls, base="", encoding=None, errors="strict"): # type: ignore
def escape(s: t.Any) -> str:
warnings.warn(
"'_vendoring.jinja2.escape' is deprecated and will be removed in Jinja"
" 3.1. Import '_vendoring.markupsafe.escape' instead.",
"'jinja2.escape' is deprecated and will be removed in Jinja"
" 3.1. Import 'markupsafe.escape' instead.",
DeprecationWarning,
stacklevel=2,
)
return _vendoring.markupsafe.escape(s)
return markupsafe.escape(s)

View File

@@ -6,7 +6,7 @@
from .nodes import Node
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
class VisitCallable(te.Protocol):
def __call__(self, node: Node, *args: t.Any, **kwargs: t.Any) -> t.Any:

View File

@@ -0,0 +1 @@
from jsonschema import *

View File

@@ -8,18 +8,18 @@
instance under a schema, and will create a validator for you.
"""
from _vendoring.jsonschema.exceptions import (
from jsonschema.exceptions import (
ErrorTree, FormatError, RefResolutionError, SchemaError, ValidationError
)
from _vendoring.jsonschema._format import (
from jsonschema._format import (
FormatChecker,
draft3_format_checker,
draft4_format_checker,
draft6_format_checker,
draft7_format_checker,
)
from _vendoring.jsonschema._types import TypeChecker
from _vendoring.jsonschema.validators import (
from jsonschema._types import TypeChecker
from jsonschema.validators import (
Draft3Validator,
Draft4Validator,
Draft6Validator,

View File

@@ -1,2 +1,2 @@
from _vendoring.jsonschema.cli import main
from jsonschema.cli import main
main()

View File

@@ -3,8 +3,8 @@
import socket
import struct
from _vendoring.jsonschema.compat import str_types
from _vendoring.jsonschema.exceptions import FormatError
from jsonschema.compat import str_types
from jsonschema.exceptions import FormatError
class FormatChecker(object):

View File

@@ -1,6 +1,6 @@
from _vendoring.jsonschema import _utils
from _vendoring.jsonschema.compat import iteritems
from _vendoring.jsonschema.exceptions import ValidationError
from jsonschema import _utils
from jsonschema.compat import iteritems
from jsonschema.exceptions import ValidationError
def dependencies_draft3(validator, dependencies, instance, schema):

View File

@@ -9,7 +9,7 @@
import sys
from _vendoring.jsonschema.compat import PY3
from jsonschema.compat import PY3
class _NoModuleFound(Exception):

View File

@@ -1,10 +1,10 @@
import numbers
from _vendoring.pyrsistent import pmap
import _vendoring.attr
from pyrsistent import pmap
import attr
from _vendoring.jsonschema.compat import int_types, str_types
from _vendoring.jsonschema.exceptions import UndefinedTypeCheck
from jsonschema.compat import int_types, str_types
from jsonschema.exceptions import UndefinedTypeCheck
def is_array(checker, instance):
@@ -45,7 +45,7 @@ def is_any(checker, instance):
return True
@_vendoring.attr.s(frozen=True)
@attr.s(frozen=True)
class TypeChecker(object):
"""
A ``type`` property checker.
@@ -61,7 +61,7 @@ class TypeChecker(object):
The initial mapping of types to their checking functions.
"""
_type_checkers = _vendoring.attr.ib(default=pmap(), converter=pmap)
_type_checkers = attr.ib(default=pmap(), converter=pmap)
def is_type(self, instance, type):
"""
@@ -131,7 +131,7 @@ def redefine_many(self, definitions=()):
A new `TypeChecker` instance.
"""
return _vendoring.attr.evolve(
return attr.evolve(
self, type_checkers=self._type_checkers.update(definitions),
)
@@ -162,7 +162,7 @@ def remove(self, *types):
checkers = checkers.remove(each)
except KeyError:
raise UndefinedTypeCheck(each)
return _vendoring.attr.evolve(self, type_checkers=checkers)
return attr.evolve(self, type_checkers=checkers)
draft3_type_checker = TypeChecker(

View File

@@ -3,7 +3,7 @@
import pkgutil
import re
from _vendoring.jsonschema.compat import MutableMapping, str_types, urlsplit
from jsonschema.compat import MutableMapping, str_types, urlsplit
class URIDict(MutableMapping):
@@ -51,7 +51,7 @@ def load_schema(name):
Load a schema from ./schemas/``name``.json and return it.
"""
data = pkgutil.get_data("_vendoring.jsonschema", "schemas/{0}.json".format(name))
data = pkgutil.get_data("jsonschema", "schemas/{0}.json".format(name))
return json.loads(data.decode("utf-8"))

View File

@@ -1,6 +1,6 @@
import re
from _vendoring.jsonschema._utils import (
from jsonschema._utils import (
ensure_list,
equal,
extras_msg,
@@ -9,8 +9,8 @@
unbool,
uniq,
)
from _vendoring.jsonschema.exceptions import FormatError, ValidationError
from _vendoring.jsonschema.compat import iteritems
from jsonschema.exceptions import FormatError, ValidationError
from jsonschema.compat import iteritems
def patternProperties(validator, patternProperties, instance, schema):

View File

@@ -6,10 +6,10 @@
"""
from twisted.python.filepath import FilePath
from pyperf import Runner
from _vendoring.pyrsistent import m
from pyrsistent import m
from _vendoring.jsonschema.tests._suite import Version
import _vendoring.jsonschema
from jsonschema.tests._suite import Version
import jsonschema
issue232 = Version(

View File

@@ -7,7 +7,7 @@
"""
from pyperf import Runner
from _vendoring.jsonschema.tests._suite import Suite
from jsonschema.tests._suite import Suite
if __name__ == "__main__":

View File

@@ -6,9 +6,9 @@
import json
import sys
from _vendoring.jsonschema import __version__
from _vendoring.jsonschema._reflect import namedAny
from _vendoring.jsonschema.validators import validator_for
from jsonschema import __version__
from jsonschema._reflect import namedAny
from jsonschema.validators import validator_for
def _namedAnyWithDefault(name):

View File

@@ -6,10 +6,10 @@
import pprint
import textwrap
import _vendoring.attr
import attr
from _vendoring.jsonschema import _utils
from _vendoring.jsonschema.compat import PY3, iteritems
from jsonschema import _utils
from jsonschema.compat import PY3, iteritems
WEAK_MATCHES = frozenset(["anyOf", "oneOf"])
@@ -149,13 +149,13 @@ class SchemaError(_Error):
_word_for_instance_in_error_message = "schema"
@_vendoring.attr.s(hash=True)
@attr.s(hash=True)
class RefResolutionError(Exception):
"""
A ref could not be resolved.
"""
_cause = _vendoring.attr.ib()
_cause = attr.ib()
def __str__(self):
return str(self._cause)

View File

@@ -0,0 +1,5 @@
def bug(issue=None):
message = "A known bug."
if issue is not None:
message += " See issue #{issue}.".format(issue=issue)
return message

View File

@@ -0,0 +1,239 @@
"""
Python representations of the JSON Schema Test Suite tests.
"""
from functools import partial
import json
import os
import re
import subprocess
import sys
import unittest
from twisted.python.filepath import FilePath
import attr
from jsonschema.compat import PY3
from jsonschema.validators import validators
import jsonschema
def _find_suite():
root = os.environ.get("JSON_SCHEMA_TEST_SUITE")
if root is not None:
return FilePath(root)
root = FilePath(jsonschema.__file__).parent().sibling("json")
if not root.isdir(): # pragma: no cover
raise ValueError(
(
"Can't find the JSON-Schema-Test-Suite directory. "
"Set the 'JSON_SCHEMA_TEST_SUITE' environment "
"variable or run the tests from alongside a checkout "
"of the suite."
),
)
return root
@attr.s(hash=True)
class Suite(object):
_root = attr.ib(default=attr.Factory(_find_suite))
def _remotes(self):
jsonschema_suite = self._root.descendant(["bin", "jsonschema_suite"])
remotes = subprocess.check_output(
[sys.executable, jsonschema_suite.path, "remotes"],
)
return {
"http://localhost:1234/" + name: schema
for name, schema in json.loads(remotes.decode("utf-8")).items()
}
def benchmark(self, runner): # pragma: no cover
for name in validators:
self.version(name=name).benchmark(runner=runner)
def version(self, name):
return Version(
name=name,
path=self._root.descendant(["tests", name]),
remotes=self._remotes(),
)
@attr.s(hash=True)
class Version(object):
_path = attr.ib()
_remotes = attr.ib()
name = attr.ib()
def benchmark(self, runner, **kwargs): # pragma: no cover
for suite in self.tests():
for test in suite:
runner.bench_func(
test.fully_qualified_name,
partial(test.validate_ignoring_errors, **kwargs),
)
def tests(self):
return (
test
for child in self._path.globChildren("*.json")
for test in self._tests_in(
subject=child.basename()[:-5],
path=child,
)
)
def format_tests(self):
path = self._path.descendant(["optional", "format"])
return (
test
for child in path.globChildren("*.json")
for test in self._tests_in(
subject=child.basename()[:-5],
path=child,
)
)
def tests_of(self, name):
return self._tests_in(
subject=name,
path=self._path.child(name + ".json"),
)
def optional_tests_of(self, name):
return self._tests_in(
subject=name,
path=self._path.descendant(["optional", name + ".json"]),
)
def to_unittest_testcase(self, *suites, **kwargs):
name = kwargs.pop("name", "Test" + self.name.title())
methods = {
test.method_name: test.to_unittest_method(**kwargs)
for suite in suites
for tests in suite
for test in tests
}
cls = type(name, (unittest.TestCase,), methods)
try:
cls.__module__ = _someone_save_us_the_module_of_the_caller()
except Exception: # pragma: no cover
# We're doing crazy things, so if they go wrong, like a function
# behaving differently on some other interpreter, just make them
# not happen.
pass
return cls
def _tests_in(self, subject, path):
for each in json.loads(path.getContent().decode("utf-8")):
yield (
_Test(
version=self,
subject=subject,
case_description=each["description"],
schema=each["schema"],
remotes=self._remotes,
**test
) for test in each["tests"]
)
@attr.s(hash=True, repr=False)
class _Test(object):
version = attr.ib()
subject = attr.ib()
case_description = attr.ib()
description = attr.ib()
data = attr.ib()
schema = attr.ib(repr=False)
valid = attr.ib()
_remotes = attr.ib()
def __repr__(self): # pragma: no cover
return "<Test {}>".format(self.fully_qualified_name)
@property
def fully_qualified_name(self): # pragma: no cover
return " > ".join(
[
self.version.name,
self.subject,
self.case_description,
self.description,
]
)
@property
def method_name(self):
delimiters = r"[\W\- ]+"
name = "test_%s_%s_%s" % (
re.sub(delimiters, "_", self.subject),
re.sub(delimiters, "_", self.case_description),
re.sub(delimiters, "_", self.description),
)
if not PY3: # pragma: no cover
name = name.encode("utf-8")
return name
def to_unittest_method(self, skip=lambda test: None, **kwargs):
if self.valid:
def fn(this):
self.validate(**kwargs)
else:
def fn(this):
with this.assertRaises(jsonschema.ValidationError):
self.validate(**kwargs)
fn.__name__ = self.method_name
reason = skip(self)
return unittest.skipIf(reason is not None, reason)(fn)
def validate(self, Validator, **kwargs):
resolver = jsonschema.RefResolver.from_schema(
schema=self.schema,
store=self._remotes,
id_of=Validator.ID_OF,
)
jsonschema.validate(
instance=self.data,
schema=self.schema,
cls=Validator,
resolver=resolver,
**kwargs
)
def validate_ignoring_errors(self, Validator): # pragma: no cover
try:
self.validate(Validator=Validator)
except jsonschema.ValidationError:
pass
def _someone_save_us_the_module_of_the_caller():
"""
The FQON of the module 2nd stack frames up from here.
This is intended to allow us to dynamicallly return test case classes that
are indistinguishable from being defined in the module that wants them.
Otherwise, trial will mis-print the FQON, and copy pasting it won't re-run
the class that really is running.
Save us all, this is all so so so so so terrible.
"""
return sys._getframe(2).f_globals["__name__"]

View File

@@ -0,0 +1,151 @@
from unittest import TestCase
import json
import subprocess
import sys
from jsonschema import Draft4Validator, ValidationError, cli, __version__
from jsonschema.compat import NativeIO
from jsonschema.exceptions import SchemaError
def fake_validator(*errors):
errors = list(reversed(errors))
class FakeValidator(object):
def __init__(self, *args, **kwargs):
pass
def iter_errors(self, instance):
if errors:
return errors.pop()
return []
def check_schema(self, schema):
pass
return FakeValidator
class TestParser(TestCase):
FakeValidator = fake_validator()
instance_file = "foo.json"
schema_file = "schema.json"
def setUp(self):
cli.open = self.fake_open
self.addCleanup(delattr, cli, "open")
def fake_open(self, path):
if path == self.instance_file:
contents = ""
elif path == self.schema_file:
contents = {}
else: # pragma: no cover
self.fail("What is {!r}".format(path))
return NativeIO(json.dumps(contents))
def test_find_validator_by_fully_qualified_object_name(self):
arguments = cli.parse_args(
[
"--validator",
"jsonschema.tests.test_cli.TestParser.FakeValidator",
"--instance", self.instance_file,
self.schema_file,
]
)
self.assertIs(arguments["validator"], self.FakeValidator)
def test_find_validator_in_jsonschema(self):
arguments = cli.parse_args(
[
"--validator", "Draft4Validator",
"--instance", self.instance_file,
self.schema_file,
]
)
self.assertIs(arguments["validator"], Draft4Validator)
class TestCLI(TestCase):
def test_draft3_schema_draft4_validator(self):
stdout, stderr = NativeIO(), NativeIO()
with self.assertRaises(SchemaError):
cli.run(
{
"validator": Draft4Validator,
"schema": {
"anyOf": [
{"minimum": 20},
{"type": "string"},
{"required": True},
],
},
"instances": [1],
"error_format": "{error.message}",
},
stdout=stdout,
stderr=stderr,
)
def test_successful_validation(self):
stdout, stderr = NativeIO(), NativeIO()
exit_code = cli.run(
{
"validator": fake_validator(),
"schema": {},
"instances": [1],
"error_format": "{error.message}",
},
stdout=stdout,
stderr=stderr,
)
self.assertFalse(stdout.getvalue())
self.assertFalse(stderr.getvalue())
self.assertEqual(exit_code, 0)
def test_unsuccessful_validation(self):
error = ValidationError("I am an error!", instance=1)
stdout, stderr = NativeIO(), NativeIO()
exit_code = cli.run(
{
"validator": fake_validator([error]),
"schema": {},
"instances": [1],
"error_format": "{error.instance} - {error.message}",
},
stdout=stdout,
stderr=stderr,
)
self.assertFalse(stdout.getvalue())
self.assertEqual(stderr.getvalue(), "1 - I am an error!")
self.assertEqual(exit_code, 1)
def test_unsuccessful_validation_multiple_instances(self):
first_errors = [
ValidationError("9", instance=1),
ValidationError("8", instance=1),
]
second_errors = [ValidationError("7", instance=2)]
stdout, stderr = NativeIO(), NativeIO()
exit_code = cli.run(
{
"validator": fake_validator(first_errors, second_errors),
"schema": {},
"instances": [1, 2],
"error_format": "{error.instance} - {error.message}\t",
},
stdout=stdout,
stderr=stderr,
)
self.assertFalse(stdout.getvalue())
self.assertEqual(stderr.getvalue(), "1 - 9\t1 - 8\t2 - 7\t")
self.assertEqual(exit_code, 1)
def test_version(self):
version = subprocess.check_output(
[sys.executable, "-m", "jsonschema", "--version"],
stderr=subprocess.STDOUT,
)
version = version.decode("utf-8").strip()
self.assertEqual(version, __version__)

View File

@@ -0,0 +1,462 @@
from unittest import TestCase
import textwrap
from jsonschema import Draft4Validator, exceptions
from jsonschema.compat import PY3
class TestBestMatch(TestCase):
def best_match(self, errors):
errors = list(errors)
best = exceptions.best_match(errors)
reversed_best = exceptions.best_match(reversed(errors))
msg = "Didn't return a consistent best match!\nGot: {0}\n\nThen: {1}"
self.assertEqual(
best._contents(), reversed_best._contents(),
msg=msg.format(best, reversed_best),
)
return best
def test_shallower_errors_are_better_matches(self):
validator = Draft4Validator(
{
"properties": {
"foo": {
"minProperties": 2,
"properties": {"bar": {"type": "object"}},
},
},
},
)
best = self.best_match(validator.iter_errors({"foo": {"bar": []}}))
self.assertEqual(best.validator, "minProperties")
def test_oneOf_and_anyOf_are_weak_matches(self):
"""
A property you *must* match is probably better than one you have to
match a part of.
"""
validator = Draft4Validator(
{
"minProperties": 2,
"anyOf": [{"type": "string"}, {"type": "number"}],
"oneOf": [{"type": "string"}, {"type": "number"}],
}
)
best = self.best_match(validator.iter_errors({}))
self.assertEqual(best.validator, "minProperties")
def test_if_the_most_relevant_error_is_anyOf_it_is_traversed(self):
"""
If the most relevant error is an anyOf, then we traverse its context
and select the otherwise *least* relevant error, since in this case
that means the most specific, deep, error inside the instance.
I.e. since only one of the schemas must match, we look for the most
relevant one.
"""
validator = Draft4Validator(
{
"properties": {
"foo": {
"anyOf": [
{"type": "string"},
{"properties": {"bar": {"type": "array"}}},
],
},
},
},
)
best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
self.assertEqual(best.validator_value, "array")
def test_if_the_most_relevant_error_is_oneOf_it_is_traversed(self):
"""
If the most relevant error is an oneOf, then we traverse its context
and select the otherwise *least* relevant error, since in this case
that means the most specific, deep, error inside the instance.
I.e. since only one of the schemas must match, we look for the most
relevant one.
"""
validator = Draft4Validator(
{
"properties": {
"foo": {
"oneOf": [
{"type": "string"},
{"properties": {"bar": {"type": "array"}}},
],
},
},
},
)
best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
self.assertEqual(best.validator_value, "array")
def test_if_the_most_relevant_error_is_allOf_it_is_traversed(self):
"""
Now, if the error is allOf, we traverse but select the *most* relevant
error from the context, because all schemas here must match anyways.
"""
validator = Draft4Validator(
{
"properties": {
"foo": {
"allOf": [
{"type": "string"},
{"properties": {"bar": {"type": "array"}}},
],
},
},
},
)
best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
self.assertEqual(best.validator_value, "string")
def test_nested_context_for_oneOf(self):
validator = Draft4Validator(
{
"properties": {
"foo": {
"oneOf": [
{"type": "string"},
{
"oneOf": [
{"type": "string"},
{
"properties": {
"bar": {"type": "array"},
},
},
],
},
],
},
},
},
)
best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
self.assertEqual(best.validator_value, "array")
def test_one_error(self):
validator = Draft4Validator({"minProperties": 2})
error, = validator.iter_errors({})
self.assertEqual(
exceptions.best_match(validator.iter_errors({})).validator,
"minProperties",
)
def test_no_errors(self):
validator = Draft4Validator({})
self.assertIsNone(exceptions.best_match(validator.iter_errors({})))
class TestByRelevance(TestCase):
def test_short_paths_are_better_matches(self):
shallow = exceptions.ValidationError("Oh no!", path=["baz"])
deep = exceptions.ValidationError("Oh yes!", path=["foo", "bar"])
match = max([shallow, deep], key=exceptions.relevance)
self.assertIs(match, shallow)
match = max([deep, shallow], key=exceptions.relevance)
self.assertIs(match, shallow)
def test_global_errors_are_even_better_matches(self):
shallow = exceptions.ValidationError("Oh no!", path=[])
deep = exceptions.ValidationError("Oh yes!", path=["foo"])
errors = sorted([shallow, deep], key=exceptions.relevance)
self.assertEqual(
[list(error.path) for error in errors],
[["foo"], []],
)
errors = sorted([deep, shallow], key=exceptions.relevance)
self.assertEqual(
[list(error.path) for error in errors],
[["foo"], []],
)
def test_weak_validators_are_lower_priority(self):
weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
best_match = exceptions.by_relevance(weak="a")
match = max([weak, normal], key=best_match)
self.assertIs(match, normal)
match = max([normal, weak], key=best_match)
self.assertIs(match, normal)
def test_strong_validators_are_higher_priority(self):
weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
strong = exceptions.ValidationError("Oh fine!", path=[], validator="c")
best_match = exceptions.by_relevance(weak="a", strong="c")
match = max([weak, normal, strong], key=best_match)
self.assertIs(match, strong)
match = max([strong, normal, weak], key=best_match)
self.assertIs(match, strong)
class TestErrorTree(TestCase):
def test_it_knows_how_many_total_errors_it_contains(self):
# FIXME: https://github.com/Julian/jsonschema/issues/442
errors = [
exceptions.ValidationError("Something", validator=i)
for i in range(8)
]
tree = exceptions.ErrorTree(errors)
self.assertEqual(tree.total_errors, 8)
def test_it_contains_an_item_if_the_item_had_an_error(self):
errors = [exceptions.ValidationError("a message", path=["bar"])]
tree = exceptions.ErrorTree(errors)
self.assertIn("bar", tree)
def test_it_does_not_contain_an_item_if_the_item_had_no_error(self):
errors = [exceptions.ValidationError("a message", path=["bar"])]
tree = exceptions.ErrorTree(errors)
self.assertNotIn("foo", tree)
def test_validators_that_failed_appear_in_errors_dict(self):
error = exceptions.ValidationError("a message", validator="foo")
tree = exceptions.ErrorTree([error])
self.assertEqual(tree.errors, {"foo": error})
def test_it_creates_a_child_tree_for_each_nested_path(self):
errors = [
exceptions.ValidationError("a bar message", path=["bar"]),
exceptions.ValidationError("a bar -> 0 message", path=["bar", 0]),
]
tree = exceptions.ErrorTree(errors)
self.assertIn(0, tree["bar"])
self.assertNotIn(1, tree["bar"])
def test_children_have_their_errors_dicts_built(self):
e1, e2 = (
exceptions.ValidationError("1", validator="foo", path=["bar", 0]),
exceptions.ValidationError("2", validator="quux", path=["bar", 0]),
)
tree = exceptions.ErrorTree([e1, e2])
self.assertEqual(tree["bar"][0].errors, {"foo": e1, "quux": e2})
def test_multiple_errors_with_instance(self):
e1, e2 = (
exceptions.ValidationError(
"1",
validator="foo",
path=["bar", "bar2"],
instance="i1"),
exceptions.ValidationError(
"2",
validator="quux",
path=["foobar", 2],
instance="i2"),
)
exceptions.ErrorTree([e1, e2])
def test_it_does_not_contain_subtrees_that_are_not_in_the_instance(self):
error = exceptions.ValidationError("123", validator="foo", instance=[])
tree = exceptions.ErrorTree([error])
with self.assertRaises(IndexError):
tree[0]
def test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error(self):
"""
If a validator is dumb (like :validator:`required` in draft 3) and
refers to a path that isn't in the instance, the tree still properly
returns a subtree for that path.
"""
error = exceptions.ValidationError(
"a message", validator="foo", instance={}, path=["foo"],
)
tree = exceptions.ErrorTree([error])
self.assertIsInstance(tree["foo"], exceptions.ErrorTree)
class TestErrorInitReprStr(TestCase):
def make_error(self, **kwargs):
defaults = dict(
message=u"hello",
validator=u"type",
validator_value=u"string",
instance=5,
schema={u"type": u"string"},
)
defaults.update(kwargs)
return exceptions.ValidationError(**defaults)
def assertShows(self, expected, **kwargs):
if PY3: # pragma: no cover
expected = expected.replace("u'", "'")
expected = textwrap.dedent(expected).rstrip("\n")
error = self.make_error(**kwargs)
message_line, _, rest = str(error).partition("\n")
self.assertEqual(message_line, error.message)
self.assertEqual(rest, expected)
def test_it_calls_super_and_sets_args(self):
error = self.make_error()
self.assertGreater(len(error.args), 1)
def test_repr(self):
self.assertEqual(
repr(exceptions.ValidationError(message="Hello!")),
"<ValidationError: %r>" % "Hello!",
)
def test_unset_error(self):
error = exceptions.ValidationError("message")
self.assertEqual(str(error), "message")
kwargs = {
"validator": "type",
"validator_value": "string",
"instance": 5,
"schema": {"type": "string"},
}
# Just the message should show if any of the attributes are unset
for attr in kwargs:
k = dict(kwargs)
del k[attr]
error = exceptions.ValidationError("message", **k)
self.assertEqual(str(error), "message")
def test_empty_paths(self):
self.assertShows(
"""
Failed validating u'type' in schema:
{u'type': u'string'}
On instance:
5
""",
path=[],
schema_path=[],
)
def test_one_item_paths(self):
self.assertShows(
"""
Failed validating u'type' in schema:
{u'type': u'string'}
On instance[0]:
5
""",
path=[0],
schema_path=["items"],
)
def test_multiple_item_paths(self):
self.assertShows(
"""
Failed validating u'type' in schema[u'items'][0]:
{u'type': u'string'}
On instance[0][u'a']:
5
""",
path=[0, u"a"],
schema_path=[u"items", 0, 1],
)
def test_uses_pprint(self):
self.assertShows(
"""
Failed validating u'maxLength' in schema:
{0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
10: 10,
11: 11,
12: 12,
13: 13,
14: 14,
15: 15,
16: 16,
17: 17,
18: 18,
19: 19}
On instance:
[0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24]
""",
instance=list(range(25)),
schema=dict(zip(range(20), range(20))),
validator=u"maxLength",
)
def test_str_works_with_instances_having_overriden_eq_operator(self):
"""
Check for https://github.com/Julian/jsonschema/issues/164 which
rendered exceptions unusable when a `ValidationError` involved
instances with an `__eq__` method that returned truthy values.
"""
class DontEQMeBro(object):
def __eq__(this, other): # pragma: no cover
self.fail("Don't!")
def __ne__(this, other): # pragma: no cover
self.fail("Don't!")
instance = DontEQMeBro()
error = exceptions.ValidationError(
"a message",
validator="foo",
instance=instance,
validator_value="some",
schema="schema",
)
self.assertIn(repr(instance), str(error))
class TestHashable(TestCase):
def test_hashable(self):
set([exceptions.ValidationError("")])
set([exceptions.SchemaError("")])

View File

@@ -0,0 +1,89 @@
"""
Tests for the parts of jsonschema related to the :validator:`format` property.
"""
from unittest import TestCase
from jsonschema import FormatError, ValidationError, FormatChecker
from jsonschema.validators import Draft4Validator
BOOM = ValueError("Boom!")
BANG = ZeroDivisionError("Bang!")
def boom(thing):
if thing == "bang":
raise BANG
raise BOOM
class TestFormatChecker(TestCase):
def test_it_can_validate_no_formats(self):
checker = FormatChecker(formats=())
self.assertFalse(checker.checkers)
def test_it_raises_a_key_error_for_unknown_formats(self):
with self.assertRaises(KeyError):
FormatChecker(formats=["o noes"])
def test_it_can_register_cls_checkers(self):
original = dict(FormatChecker.checkers)
self.addCleanup(FormatChecker.checkers.pop, "boom")
FormatChecker.cls_checks("boom")(boom)
self.assertEqual(
FormatChecker.checkers,
dict(original, boom=(boom, ())),
)
def test_it_can_register_checkers(self):
checker = FormatChecker()
checker.checks("boom")(boom)
self.assertEqual(
checker.checkers,
dict(FormatChecker.checkers, boom=(boom, ()))
)
def test_it_catches_registered_errors(self):
checker = FormatChecker()
checker.checks("boom", raises=type(BOOM))(boom)
with self.assertRaises(FormatError) as cm:
checker.check(instance=12, format="boom")
self.assertIs(cm.exception.cause, BOOM)
self.assertIs(cm.exception.__cause__, BOOM)
# Unregistered errors should not be caught
with self.assertRaises(type(BANG)):
checker.check(instance="bang", format="boom")
def test_format_error_causes_become_validation_error_causes(self):
checker = FormatChecker()
checker.checks("boom", raises=ValueError)(boom)
validator = Draft4Validator({"format": "boom"}, format_checker=checker)
with self.assertRaises(ValidationError) as cm:
validator.validate("BOOM")
self.assertIs(cm.exception.cause, BOOM)
self.assertIs(cm.exception.__cause__, BOOM)
def test_format_checkers_come_with_defaults(self):
# This is bad :/ but relied upon.
# The docs for quite awhile recommended people do things like
# validate(..., format_checker=FormatChecker())
# We should change that, but we can't without deprecation...
checker = FormatChecker()
with self.assertRaises(FormatError):
checker.check(instance="not-an-ipv4", format="ipv4")
def test_repr(self):
checker = FormatChecker(formats=())
checker.checks("foo")(lambda thing: True)
checker.checks("bar")(lambda thing: True)
checker.checks("baz")(lambda thing: True)
self.assertEqual(
repr(checker),
"<FormatChecker checkers=['bar', 'baz', 'foo']>",
)

View File

@@ -0,0 +1,277 @@
"""
Test runner for the JSON Schema official test suite
Tests comprehensive correctness of each draft's validator.
See https://github.com/json-schema-org/JSON-Schema-Test-Suite for details.
"""
import sys
import warnings
from jsonschema import (
Draft3Validator,
Draft4Validator,
Draft6Validator,
Draft7Validator,
draft3_format_checker,
draft4_format_checker,
draft6_format_checker,
draft7_format_checker,
)
from jsonschema.tests._helpers import bug
from jsonschema.tests._suite import Suite
from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create
SUITE = Suite()
DRAFT3 = SUITE.version(name="draft3")
DRAFT4 = SUITE.version(name="draft4")
DRAFT6 = SUITE.version(name="draft6")
DRAFT7 = SUITE.version(name="draft7")
def skip(message, **kwargs):
def skipper(test):
if all(value == getattr(test, attr) for attr, value in kwargs.items()):
return message
return skipper
def missing_format(checker):
def missing_format(test):
schema = test.schema
if schema is True or schema is False or "format" not in schema:
return
if schema["format"] not in checker.checkers:
return "Format checker {0!r} not found.".format(schema["format"])
return missing_format
is_narrow_build = sys.maxunicode == 2 ** 16 - 1
if is_narrow_build: # pragma: no cover
message = "Not running surrogate Unicode case, this Python is narrow."
def narrow_unicode_build(test): # pragma: no cover
return skip(
message=message,
description="one supplementary Unicode code point is not long enough",
)(test) or skip(
message=message,
description="two supplementary Unicode code points is long enough",
)(test)
else:
def narrow_unicode_build(test): # pragma: no cover
return
TestDraft3 = DRAFT3.to_unittest_testcase(
DRAFT3.tests(),
DRAFT3.optional_tests_of(name="bignum"),
DRAFT3.optional_tests_of(name="format"),
DRAFT3.optional_tests_of(name="zeroTerminatedFloats"),
Validator=Draft3Validator,
format_checker=draft3_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
or missing_format(draft3_format_checker)(test)
or skip(
message="Upstream bug in strict_rfc3339",
subject="format",
description="case-insensitive T and Z",
)(test)
),
)
TestDraft4 = DRAFT4.to_unittest_testcase(
DRAFT4.tests(),
DRAFT4.optional_tests_of(name="bignum"),
DRAFT4.optional_tests_of(name="format"),
DRAFT4.optional_tests_of(name="zeroTerminatedFloats"),
Validator=Draft4Validator,
format_checker=draft4_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
or missing_format(draft4_format_checker)(test)
or skip(
message=bug(),
subject="ref",
case_description="Recursive references between schemas",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description="Location-independent identifier",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with absolute URI"
),
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with base URI change in subschema"
),
)(test)
or skip(
message=bug(),
subject="refRemote",
case_description="base URI change - change folder in subschema",
)(test)
or skip(
message="Upstream bug in strict_rfc3339",
subject="format",
description="case-insensitive T and Z",
)(test)
),
)
TestDraft6 = DRAFT6.to_unittest_testcase(
DRAFT6.tests(),
DRAFT6.optional_tests_of(name="bignum"),
DRAFT6.optional_tests_of(name="format"),
DRAFT6.optional_tests_of(name="zeroTerminatedFloats"),
Validator=Draft6Validator,
format_checker=draft6_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
or missing_format(draft6_format_checker)(test)
or skip(
message=bug(),
subject="ref",
case_description="Recursive references between schemas",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description="Location-independent identifier",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with absolute URI"
),
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with base URI change in subschema"
),
)(test)
or skip(
message=bug(),
subject="refRemote",
case_description="base URI change - change folder in subschema",
)(test)
or skip(
message="Upstream bug in strict_rfc3339",
subject="format",
description="case-insensitive T and Z",
)(test)
),
)
TestDraft7 = DRAFT7.to_unittest_testcase(
DRAFT7.tests(),
DRAFT7.format_tests(),
DRAFT7.optional_tests_of(name="bignum"),
DRAFT7.optional_tests_of(name="content"),
DRAFT7.optional_tests_of(name="zeroTerminatedFloats"),
Validator=Draft7Validator,
format_checker=draft7_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
or missing_format(draft7_format_checker)(test)
or skip(
message=bug(),
subject="ref",
case_description="Recursive references between schemas",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description="Location-independent identifier",
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with absolute URI"
),
)(test)
or skip(
message=bug(371),
subject="ref",
case_description=(
"Location-independent identifier with base URI change in subschema"
),
)(test)
or skip(
message=bug(),
subject="refRemote",
case_description="base URI change - change folder in subschema",
)(test)
or skip(
message="Upstream bug in strict_rfc3339",
subject="date-time",
description="case-insensitive T and Z",
)(test)
or skip(
message=bug(593),
subject="content",
case_description=(
"validation of string-encoded content based on media type"
),
)(test)
or skip(
message=bug(593),
subject="content",
case_description="validation of binary string-encoding",
)(test)
or skip(
message=bug(593),
subject="content",
case_description=(
"validation of binary-encoded media type documents"
),
)(test)
),
)
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
TestDraft3LegacyTypeCheck = DRAFT3.to_unittest_testcase(
# Interestingly the any part couldn't really be done w/the old API.
(
(test for test in each if test.schema != {"type": "any"})
for each in DRAFT3.tests_of(name="type")
),
name="TestDraft3LegacyTypeCheck",
Validator=create(
meta_schema=Draft3Validator.META_SCHEMA,
validators=Draft3Validator.VALIDATORS,
default_types=_DEPRECATED_DEFAULT_TYPES,
),
)
TestDraft4LegacyTypeCheck = DRAFT4.to_unittest_testcase(
DRAFT4.tests_of(name="type"),
name="TestDraft4LegacyTypeCheck",
Validator=create(
meta_schema=Draft4Validator.META_SCHEMA,
validators=Draft4Validator.VALIDATORS,
default_types=_DEPRECATED_DEFAULT_TYPES,
),
)

View File

@@ -0,0 +1,190 @@
"""
Tests on the new type interface. The actual correctness of the type checking
is handled in test_jsonschema_test_suite; these tests check that TypeChecker
functions correctly and can facilitate extensions to type checking
"""
from collections import namedtuple
from unittest import TestCase
from jsonschema import ValidationError, _validators
from jsonschema._types import TypeChecker
from jsonschema.exceptions import UndefinedTypeCheck
from jsonschema.validators import Draft4Validator, extend
def equals_2(checker, instance):
return instance == 2
def is_namedtuple(instance):
return isinstance(instance, tuple) and getattr(instance, "_fields", None)
def is_object_or_named_tuple(checker, instance):
if Draft4Validator.TYPE_CHECKER.is_type(instance, "object"):
return True
return is_namedtuple(instance)
def coerce_named_tuple(fn):
def coerced(validator, value, instance, schema):
if is_namedtuple(instance):
instance = instance._asdict()
return fn(validator, value, instance, schema)
return coerced
required = coerce_named_tuple(_validators.required)
properties = coerce_named_tuple(_validators.properties)
class TestTypeChecker(TestCase):
def test_is_type(self):
checker = TypeChecker({"two": equals_2})
self.assertEqual(
(
checker.is_type(instance=2, type="two"),
checker.is_type(instance="bar", type="two"),
),
(True, False),
)
def test_is_unknown_type(self):
with self.assertRaises(UndefinedTypeCheck) as context:
TypeChecker().is_type(4, "foobar")
self.assertIn("foobar", str(context.exception))
def test_checks_can_be_added_at_init(self):
checker = TypeChecker({"two": equals_2})
self.assertEqual(checker, TypeChecker().redefine("two", equals_2))
def test_redefine_existing_type(self):
self.assertEqual(
TypeChecker().redefine("two", object()).redefine("two", equals_2),
TypeChecker().redefine("two", equals_2),
)
def test_remove(self):
self.assertEqual(
TypeChecker({"two": equals_2}).remove("two"),
TypeChecker(),
)
def test_remove_unknown_type(self):
with self.assertRaises(UndefinedTypeCheck) as context:
TypeChecker().remove("foobar")
self.assertIn("foobar", str(context.exception))
def test_redefine_many(self):
self.assertEqual(
TypeChecker().redefine_many({"foo": int, "bar": str}),
TypeChecker().redefine("foo", int).redefine("bar", str),
)
def test_remove_multiple(self):
self.assertEqual(
TypeChecker({"foo": int, "bar": str}).remove("foo", "bar"),
TypeChecker(),
)
def test_type_check_can_raise_key_error(self):
"""
Make sure no one writes:
try:
self._type_checkers[type](...)
except KeyError:
ignoring the fact that the function itself can raise that.
"""
error = KeyError("Stuff")
def raises_keyerror(checker, instance):
raise error
with self.assertRaises(KeyError) as context:
TypeChecker({"foo": raises_keyerror}).is_type(4, "foo")
self.assertIs(context.exception, error)
class TestCustomTypes(TestCase):
def test_simple_type_can_be_extended(self):
def int_or_str_int(checker, instance):
if not isinstance(instance, (int, str)):
return False
try:
int(instance)
except ValueError:
return False
return True
CustomValidator = extend(
Draft4Validator,
type_checker=Draft4Validator.TYPE_CHECKER.redefine(
"integer", int_or_str_int,
),
)
validator = CustomValidator({"type": "integer"})
validator.validate(4)
validator.validate("4")
with self.assertRaises(ValidationError):
validator.validate(4.4)
def test_object_can_be_extended(self):
schema = {"type": "object"}
Point = namedtuple("Point", ["x", "y"])
type_checker = Draft4Validator.TYPE_CHECKER.redefine(
u"object", is_object_or_named_tuple,
)
CustomValidator = extend(Draft4Validator, type_checker=type_checker)
validator = CustomValidator(schema)
validator.validate(Point(x=4, y=5))
def test_object_extensions_require_custom_validators(self):
schema = {"type": "object", "required": ["x"]}
type_checker = Draft4Validator.TYPE_CHECKER.redefine(
u"object", is_object_or_named_tuple,
)
CustomValidator = extend(Draft4Validator, type_checker=type_checker)
validator = CustomValidator(schema)
Point = namedtuple("Point", ["x", "y"])
# Cannot handle required
with self.assertRaises(ValidationError):
validator.validate(Point(x=4, y=5))
def test_object_extensions_can_handle_custom_validators(self):
schema = {
"type": "object",
"required": ["x"],
"properties": {"x": {"type": "integer"}},
}
type_checker = Draft4Validator.TYPE_CHECKER.redefine(
u"object", is_object_or_named_tuple,
)
CustomValidator = extend(
Draft4Validator,
type_checker=type_checker,
validators={"required": required, "properties": properties},
)
validator = CustomValidator(schema)
Point = namedtuple("Point", ["x", "y"])
# Can now process required and properties
validator.validate(Point(x=4, y=5))
with self.assertRaises(ValidationError):
validator.validate(Point(x="not an integer", y=5))

File diff suppressed because it is too large Load Diff

View File

@@ -8,16 +8,16 @@
import json
import numbers
from _vendoring.six import add_metaclass
from six import add_metaclass
from _vendoring.jsonschema import (
from jsonschema import (
_legacy_validators,
_types,
_utils,
_validators,
exceptions,
)
from _vendoring.jsonschema.compat import (
from jsonschema.compat import (
Sequence,
int_types,
iteritems,
@@ -33,7 +33,7 @@
# Sigh. https://gitlab.com/pycqa/flake8/issues/280
# https://github.com/pyga/ebb-lint/issues/7
# Imported for backwards compatibility.
from _vendoring.jsonschema.exceptions import ErrorTree
from jsonschema.exceptions import ErrorTree
ErrorTree

View File

@@ -0,0 +1 @@
from macholib import *

View File

@@ -7,7 +7,7 @@
import struct
import sys
from _vendoring.macholib.util import fileview
from macholib.util import fileview
from .mach_o import (
FAT_MAGIC,
@@ -41,7 +41,7 @@
from .ptypes import sizeof
try:
from _vendoring.macholib.compat import bytes
from macholib.compat import bytes
except ImportError:
pass

View File

@@ -5,11 +5,11 @@
import os
import sys
from _vendoring.altgraph.ObjectGraph import ObjectGraph
from altgraph.ObjectGraph import ObjectGraph
from _vendoring.macholib.dyld import dyld_find
from _vendoring.macholib.itergraphreport import itergraphreport
from _vendoring.macholib.MachO import MachO
from macholib.dyld import dyld_find
from macholib.itergraphreport import itergraphreport
from macholib.MachO import MachO
__all__ = ["MachOGraph"]

View File

@@ -1,9 +1,9 @@
import os
from collections import deque
from _vendoring.macholib.dyld import framework_info
from _vendoring.macholib.MachOGraph import MachOGraph, MissingMachO
from _vendoring.macholib.util import (
from macholib.dyld import framework_info
from macholib.MachOGraph import MachOGraph, MissingMachO
from macholib.util import (
flipwritable,
has_filename_filter,
in_system_path,

View File

@@ -5,7 +5,7 @@
import sys
from _vendoring.macholib.mach_o import (
from macholib.mach_o import (
MH_CIGAM_64,
MH_MAGIC_64,
dylib_module,

View File

@@ -3,8 +3,8 @@
import os
import sys
from _vendoring.macholib import macho_dump, macho_standalone
from _vendoring.macholib.util import is_platform_file
from macholib import macho_dump, macho_standalone
from macholib.util import is_platform_file
gCommand = None
@@ -43,10 +43,10 @@ def walk_tree(callback, paths):
def print_usage(fp):
print("Usage:", file=fp)
print(" python -m_vendoring.macholib [help|--help]", file=fp)
print(" python -m_vendoring.macholib dump FILE ...", file=fp)
print(" python -m_vendoring.macholib find DIR ...", file=fp)
print(" python -m_vendoring.macholib standalone DIR ...", file=fp)
print(" python -mmacholib [help|--help]", file=fp)
print(" python -mmacholib dump FILE ...", file=fp)
print(" python -mmacholib find DIR ...", file=fp)
print(" python -mmacholib standalone DIR ...", file=fp)
def main():

View File

@@ -6,7 +6,7 @@
import os
import sys
from _vendoring.macholib.util import is_platform_file
from macholib.util import is_platform_file
def check_file(fp, path, callback):

View File

@@ -8,8 +8,8 @@
import sys
from itertools import chain
from _vendoring.macholib.dylib import dylib_info
from _vendoring.macholib.framework import framework_info
from macholib.dylib import dylib_info
from macholib.framework import framework_info
__all__ = ["dyld_find", "framework_find", "framework_info", "dylib_info"]

View File

@@ -13,7 +13,7 @@
import time
from _vendoring.macholib.ptypes import (
from macholib.ptypes import (
Structure,
p_int32,
p_int64,

View File

@@ -4,9 +4,9 @@
import sys
from _vendoring.macholib._cmdline import main as _main
from _vendoring.macholib.mach_o import CPU_TYPE_NAMES, MH_CIGAM_64, MH_MAGIC_64, get_cpu_subtype
from _vendoring.macholib.MachO import MachO
from macholib._cmdline import main as _main
from macholib.mach_o import CPU_TYPE_NAMES, MH_CIGAM_64, MH_MAGIC_64, get_cpu_subtype
from macholib.MachO import MachO
ARCH_MAP = {
("<", "64-bit"): "x86_64",
@@ -45,7 +45,7 @@ def print_file(fp, path):
def main():
print(
"WARNING: 'macho_dump' is deprecated, use 'python -m_vendoring.macholib dump' " "instead"
"WARNING: 'macho_dump' is deprecated, use 'python -mmacholib dump' " "instead"
)
_main(print_file)

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
from __future__ import print_function
from _vendoring.macholib._cmdline import main as _main
from macholib._cmdline import main as _main
def print_file(fp, path):
@@ -10,7 +10,7 @@ def print_file(fp, path):
def main():
print(
"WARNING: 'macho_find' is deprecated, " "use 'python -m_vendoring.macholib dump' instead"
"WARNING: 'macho_find' is deprecated, " "use 'python -mmacholib dump' instead"
)
_main(print_file)

View File

@@ -3,8 +3,8 @@
import os
import sys
from _vendoring.macholib.MachOStandalone import MachOStandalone
from _vendoring.macholib.util import strip_files
from macholib.MachOStandalone import MachOStandalone
from macholib.util import strip_files
def standaloneApp(path):
@@ -18,7 +18,7 @@ def standaloneApp(path):
def main():
print(
"WARNING: 'macho_standalone' is deprecated, use "
"'python -m_vendoring.macholib standalone' instead"
"'python -mmacholib standalone' instead"
)
if not sys.argv[1:]:
raise SystemExit("usage: %s [appbundle ...]" % (sys.argv[0],))

View File

@@ -4,7 +4,7 @@
import struct
import sys
from _vendoring.macholib import mach_o
from macholib import mach_o
MAGIC = [
struct.pack("!L", getattr(mach_o, "MH_" + _))

View File

@@ -4,7 +4,7 @@
import typing as t
if t.TYPE_CHECKING:
import _vendoring.typing_extensions as te
import typing_extensions as te
class HasHTML(te.Protocol):
def __html__(self) -> str:

View File

@@ -1,35 +1,35 @@
# -*- coding: utf-8 -*-
from _vendoring.pyrsistent._pmap import pmap, m, PMap
from pyrsistent._pmap import pmap, m, PMap
from _vendoring.pyrsistent._pvector import pvector, v, PVector
from pyrsistent._pvector import pvector, v, PVector
from _vendoring.pyrsistent._pset import pset, s, PSet
from pyrsistent._pset import pset, s, PSet
from _vendoring.pyrsistent._pbag import pbag, b, PBag
from pyrsistent._pbag import pbag, b, PBag
from _vendoring.pyrsistent._plist import plist, l, PList
from pyrsistent._plist import plist, l, PList
from _vendoring.pyrsistent._pdeque import pdeque, dq, PDeque
from pyrsistent._pdeque import pdeque, dq, PDeque
from _vendoring.pyrsistent._checked_types import (
from pyrsistent._checked_types import (
CheckedPMap, CheckedPVector, CheckedPSet, InvariantException, CheckedKeyTypeError,
CheckedValueTypeError, CheckedType, optional)
from _vendoring.pyrsistent._field_common import (
from pyrsistent._field_common import (
field, PTypeError, pset_field, pmap_field, pvector_field)
from _vendoring.pyrsistent._precord import PRecord
from pyrsistent._precord import PRecord
from _vendoring.pyrsistent._pclass import PClass, PClassMeta
from pyrsistent._pclass import PClass, PClassMeta
from _vendoring.pyrsistent._immutable import immutable
from pyrsistent._immutable import immutable
from _vendoring.pyrsistent._helpers import freeze, thaw, mutant
from pyrsistent._helpers import freeze, thaw, mutant
from _vendoring.pyrsistent._transformations import inc, discard, rex, ny
from pyrsistent._transformations import inc, discard, rex, ny
from _vendoring.pyrsistent._toolz import get_in
from pyrsistent._toolz import get_in
__all__ = ('pmap', 'm', 'PMap',

View File

@@ -0,0 +1,213 @@
# flake8: noqa: E704
# from https://gist.github.com/WuTheFWasThat/091a17d4b5cab597dfd5d4c2d96faf09
# Stubs for pyrsistent (Python 3.6)
from typing import Any
from typing import AnyStr
from typing import Callable
from typing import Iterable
from typing import Iterator
from typing import List
from typing import Optional
from typing import Mapping
from typing import MutableMapping
from typing import Sequence
from typing import Set
from typing import Union
from typing import Tuple
from typing import Type
from typing import TypeVar
from typing import overload
# see commit 08519aa for explanation of the re-export
from pyrsistent.typing import CheckedKeyTypeError as CheckedKeyTypeError
from pyrsistent.typing import CheckedPMap as CheckedPMap
from pyrsistent.typing import CheckedPSet as CheckedPSet
from pyrsistent.typing import CheckedPVector as CheckedPVector
from pyrsistent.typing import CheckedType as CheckedType
from pyrsistent.typing import CheckedValueTypeError as CheckedValueTypeError
from pyrsistent.typing import InvariantException as InvariantException
from pyrsistent.typing import PClass as PClass
from pyrsistent.typing import PBag as PBag
from pyrsistent.typing import PDeque as PDeque
from pyrsistent.typing import PList as PList
from pyrsistent.typing import PMap as PMap
from pyrsistent.typing import PMapEvolver as PMapEvolver
from pyrsistent.typing import PSet as PSet
from pyrsistent.typing import PSetEvolver as PSetEvolver
from pyrsistent.typing import PTypeError as PTypeError
from pyrsistent.typing import PVector as PVector
from pyrsistent.typing import PVectorEvolver as PVectorEvolver
T = TypeVar('T')
KT = TypeVar('KT')
VT = TypeVar('VT')
def pmap(initial: Union[Mapping[KT, VT], Iterable[Tuple[KT, VT]]] = {}, pre_size: int = 0) -> PMap[KT, VT]: ...
def m(**kwargs: VT) -> PMap[str, VT]: ...
def pvector(iterable: Iterable[T] = ...) -> PVector[T]: ...
def v(*iterable: T) -> PVector[T]: ...
def pset(iterable: Iterable[T] = (), pre_size: int = 8) -> PSet[T]: ...
def s(*iterable: T) -> PSet[T]: ...
# see class_test.py for use cases
Invariant = Tuple[bool, Optional[Union[str, Callable[[], str]]]]
@overload
def field(
type: Union[Type[T], Sequence[Type[T]]] = ...,
invariant: Callable[[Any], Union[Invariant, Iterable[Invariant]]] = lambda _: (True, None),
initial: Any = object(),
mandatory: bool = False,
factory: Callable[[Any], T] = lambda x: x,
serializer: Callable[[Any, T], Any] = lambda _, value: value,
) -> T: ...
# The actual return value (_PField) is irrelevant after a PRecord has been instantiated,
# see https://github.com/tobgu/pyrsistent/blob/master/pyrsistent/_precord.py#L10
@overload
def field(
type: Any = ...,
invariant: Callable[[Any], Union[Invariant, Iterable[Invariant]]] = lambda _: (True, None),
initial: Any = object(),
mandatory: bool = False,
factory: Callable[[Any], Any] = lambda x: x,
serializer: Callable[[Any, Any], Any] = lambda _, value: value,
) -> Any: ...
# Use precise types for the simplest use cases, but fall back to Any for
# everything else. See record_test.py for the wide range of possible types for
# item_type
@overload
def pset_field(
item_type: Type[T],
optional: bool = False,
initial: Iterable[T] = ...,
) -> PSet[T]: ...
@overload
def pset_field(
item_type: Any,
optional: bool = False,
initial: Any = (),
) -> PSet[Any]: ...
@overload
def pmap_field(
key_type: Type[KT],
value_type: Type[VT],
optional: bool = False,
invariant: Callable[[Any], Tuple[bool, Optional[str]]] = lambda _: (True, None),
) -> PMap[KT, VT]: ...
@overload
def pmap_field(
key_type: Any,
value_type: Any,
optional: bool = False,
invariant: Callable[[Any], Tuple[bool, Optional[str]]] = lambda _: (True, None),
) -> PMap[Any, Any]: ...
@overload
def pvector_field(
item_type: Type[T],
optional: bool = False,
initial: Iterable[T] = ...,
) -> PVector[T]: ...
@overload
def pvector_field(
item_type: Any,
optional: bool = False,
initial: Any = (),
) -> PVector[Any]: ...
def pbag(elements: Iterable[T]) -> PBag[T]: ...
def b(*elements: T) -> PBag[T]: ...
def plist(iterable: Iterable[T] = (), reverse: bool = False) -> PList[T]: ...
def l(*elements: T) -> PList[T]: ...
def pdeque(iterable: Optional[Iterable[T]] = None, maxlen: Optional[int] = None) -> PDeque[T]: ...
def dq(*iterable: T) -> PDeque[T]: ...
@overload
def optional(type: T) -> Tuple[T, Type[None]]: ...
@overload
def optional(*typs: Any) -> Tuple[Any, ...]: ...
T_PRecord = TypeVar('T_PRecord', bound='PRecord')
class PRecord(PMap[AnyStr, Any]):
_precord_fields: Mapping
_precord_initial_values: Mapping
def __hash__(self) -> int: ...
def __init__(self, **kwargs: Any) -> None: ...
def __iter__(self) -> Iterator[Any]: ...
def __len__(self) -> int: ...
@classmethod
def create(
cls: Type[T_PRecord],
kwargs: Mapping,
_factory_fields: Optional[Iterable] = None,
ignore_extra: bool = False,
) -> T_PRecord: ...
# This is OK because T_PRecord is a concrete type
def discard(self: T_PRecord, key: KT) -> T_PRecord: ...
def remove(self: T_PRecord, key: KT) -> T_PRecord: ...
def serialize(self, format: Optional[Any] = ...) -> MutableMapping: ...
# From pyrsistent documentation:
# This set function differs slightly from that in the PMap
# class. First of all it accepts key-value pairs. Second it accepts multiple key-value
# pairs to perform one, atomic, update of multiple fields.
@overload
def set(self, key: KT, val: VT) -> Any: ...
@overload
def set(self, **kwargs: VT) -> Any: ...
def immutable(
members: Union[str, Iterable[str]] = '',
name: str = 'Immutable',
verbose: bool = False,
) -> Tuple: ... # actually a namedtuple
# ignore mypy warning "Overloaded function signatures 1 and 5 overlap with
# incompatible return types"
@overload
def freeze(o: Mapping[KT, VT]) -> PMap[KT, VT]: ... # type: ignore
@overload
def freeze(o: List[T]) -> PVector[T]: ... # type: ignore
@overload
def freeze(o: Tuple[T, ...]) -> Tuple[T, ...]: ...
@overload
def freeze(o: Set[T]) -> PSet[T]: ... # type: ignore
@overload
def freeze(o: T) -> T: ...
@overload
def thaw(o: PMap[KT, VT]) -> MutableMapping[KT, VT]: ... # type: ignore
@overload
def thaw(o: PVector[T]) -> List[T]: ... # type: ignore
@overload
def thaw(o: Tuple[T, ...]) -> Tuple[T, ...]: ...
# collections.abc.MutableSet is kind of garbage:
# https://stackoverflow.com/questions/24977898/why-does-collections-mutableset-not-bestow-an-update-method
@overload
def thaw(o: PSet[T]) -> Set[T]: ... # type: ignore
@overload
def thaw(o: T) -> T: ...
def mutant(fn: Callable) -> Callable: ...
def inc(x: int) -> int: ...
@overload
def discard(evolver: PMapEvolver[KT, VT], key: KT) -> None: ...
@overload
def discard(evolver: PVectorEvolver[T], key: int) -> None: ...
@overload
def discard(evolver: PSetEvolver[T], key: T) -> None: ...
def rex(expr: str) -> Callable[[Any], bool]: ...
def ny(_: Any) -> bool: ...
def get_in(keys: Iterable, coll: Mapping, default: Optional[Any] = None, no_default: bool = False) -> Any: ...

View File

@@ -3,9 +3,9 @@
from abc import abstractmethod, ABCMeta
from collections.abc import Iterable
from _vendoring.pyrsistent._pmap import PMap, pmap
from _vendoring.pyrsistent._pset import PSet, pset
from _vendoring.pyrsistent._pvector import PythonPVector, python_pvector
from pyrsistent._pmap import PMap, pmap
from pyrsistent._pset import PSet, pset
from pyrsistent._pvector import PythonPVector, python_pvector
class CheckedType(object):

View File

@@ -1,6 +1,6 @@
import sys
from _vendoring.pyrsistent._checked_types import (
from pyrsistent._checked_types import (
CheckedPMap,
CheckedPSet,
CheckedPVector,
@@ -11,8 +11,8 @@
maybe_parse_user_type,
maybe_parse_many_user_types,
)
from _vendoring.pyrsistent._checked_types import optional as optional_type
from _vendoring.pyrsistent._checked_types import wrap_invariant
from pyrsistent._checked_types import optional as optional_type
from pyrsistent._checked_types import wrap_invariant
import inspect
PY2 = sys.version_info[0] < 3

View File

@@ -1,11 +1,11 @@
from functools import wraps
from _vendoring.pyrsistent._pmap import PMap, pmap
from _vendoring.pyrsistent._pset import PSet, pset
from _vendoring.pyrsistent._pvector import PVector, pvector
from pyrsistent._pmap import PMap, pmap
from pyrsistent._pset import PSet, pset
from pyrsistent._pvector import PVector, pvector
def freeze(o, strict=True):
"""
Recursively convert simple Python containers into _vendoring.pyrsistent versions
Recursively convert simple Python containers into pyrsistent versions
of those containers.
- list is converted to pvector, recursively
@@ -47,7 +47,7 @@ def freeze(o, strict=True):
def thaw(o, strict=True):
"""
Recursively convert _vendoring.pyrsistent containers into simple Python containers.
Recursively convert pyrsistent containers into simple Python containers.
- pvector is converted to list, recursively
- pmap is converted to dict, recursively on values (but not keys)
@@ -59,7 +59,7 @@ def thaw(o, strict=True):
- thaw is called on elements of lists
- thaw is called on values in dicts
>>> from _vendoring.pyrsistent import s, m, v
>>> from pyrsistent import s, m, v
>>> thaw(s(1, 2))
{1, 2}
>>> thaw(v(1, m(a=3)))

View File

@@ -94,7 +94,7 @@ def set(self, **kwargs):
print(template)
from collections import namedtuple
namespace = dict(namedtuple=namedtuple, __name__='_vendoring.pyrsistent_immutable')
namespace = dict(namedtuple=namedtuple, __name__='pyrsistent_immutable')
try:
exec(template, namespace)
except SyntaxError as e:

Some files were not shown because too many files have changed in this diff Show More