mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Compare commits
181 Commits
2025-08-04
...
2025-11-10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9792001703 | ||
|
|
d8a4a09ec0 | ||
|
|
ed9a61d956 | ||
|
|
5cad66cebf | ||
|
|
377151a57f | ||
|
|
a7e8ac684b | ||
|
|
e096ce7bc7 | ||
|
|
9e7d291b63 | ||
|
|
614028f9a8 | ||
|
|
8f048dd9fd | ||
|
|
fda9ceea54 | ||
|
|
2acc3be6cf | ||
|
|
b6e8a875ac | ||
|
|
6b25fe5c95 | ||
|
|
0e15e771c3 | ||
|
|
d63e44aa3a | ||
|
|
9a2792a44b | ||
|
|
517b55b8b5 | ||
|
|
37915336ea | ||
|
|
2e7a8b4735 | ||
|
|
c6c931aa0b | ||
|
|
1d23f6e8df | ||
|
|
9825d8a376 | ||
|
|
79dcba8fe7 | ||
|
|
3ec905e08a | ||
|
|
2463bdff0e | ||
|
|
153d0eef51 | ||
|
|
f22aed2614 | ||
|
|
0fb7d0fae2 | ||
|
|
efd3a4e44b | ||
|
|
5d9e62390c | ||
|
|
a50cc9b915 | ||
|
|
715529bef1 | ||
|
|
68e7310d22 | ||
|
|
604b708741 | ||
|
|
e069244f89 | ||
|
|
296da56190 | ||
|
|
624a561145 | ||
|
|
3f7deb49c8 | ||
|
|
9557acb1c3 | ||
|
|
aa56ebb057 | ||
|
|
84b254209f | ||
|
|
e18354b990 | ||
|
|
360f8caead | ||
|
|
9b400a9b6f | ||
|
|
19b6241ef9 | ||
|
|
b15e537692 | ||
|
|
2faa05dcfb | ||
|
|
25a464eeae | ||
|
|
13329f0a48 | ||
|
|
fcf196935e | ||
|
|
9a5d5d6194 | ||
|
|
3473d824a8 | ||
|
|
3b48dcc7c1 | ||
|
|
b56e469a5f | ||
|
|
7986fee56f | ||
|
|
c979059eeb | ||
|
|
3a6fda4daf | ||
|
|
1aea1467da | ||
|
|
3c01be29c4 | ||
|
|
24f4fbad82 | ||
|
|
30cbc41298 | ||
|
|
150e8ef43d | ||
|
|
4b91e985ac | ||
|
|
fdae128cec | ||
|
|
11e1330758 | ||
|
|
aa0eb4bedf | ||
|
|
141ed72693 | ||
|
|
62067aefd3 | ||
|
|
b7d9d7d9ae | ||
|
|
67958ec791 | ||
|
|
b666c52df9 | ||
|
|
6ead82154e | ||
|
|
ca95366219 | ||
|
|
43d643ad09 | ||
|
|
cc4ebe6256 | ||
|
|
f429ac4939 | ||
|
|
0c3d14affc | ||
|
|
63de4387e7 | ||
|
|
7044d43dc8 | ||
|
|
74c2d490ac | ||
|
|
59d71be85f | ||
|
|
9da2e04880 | ||
|
|
1d53e0c923 | ||
|
|
da71b92dd3 | ||
|
|
b640ef1241 | ||
|
|
c5c2bd050d | ||
|
|
85ca28094e | ||
|
|
48d8031f0c | ||
|
|
0c8ae3a384 | ||
|
|
056795eed4 | ||
|
|
cca4fe6d80 | ||
|
|
d17dcd817e | ||
|
|
1688e744ba | ||
|
|
8b6e1e398b | ||
|
|
fa91df6539 | ||
|
|
2b67f40c34 | ||
|
|
1d1aa663f0 | ||
|
|
1fe5fd55d3 | ||
|
|
711f95ec09 | ||
|
|
020692e56b | ||
|
|
de3cb8cdbb | ||
|
|
2e16f51c68 | ||
|
|
a2b194a6f8 | ||
|
|
373de5ee57 | ||
|
|
a1c11cdc40 | ||
|
|
41fb6c5a1a | ||
|
|
e00a95d15c | ||
|
|
d732c307dc | ||
|
|
6a3c348351 | ||
|
|
ec8f37dcd6 | ||
|
|
88506059f9 | ||
|
|
15b1b62adb | ||
|
|
6a4d4b727c | ||
|
|
d9ffc47c43 | ||
|
|
ed6caed3d9 | ||
|
|
37324b443b | ||
|
|
88b12bafc9 | ||
|
|
b56082a980 | ||
|
|
75093873b8 | ||
|
|
8437b06dad | ||
|
|
dc4be47751 | ||
|
|
51cbf57470 | ||
|
|
1c992f84e5 | ||
|
|
763d5d48b5 | ||
|
|
f4543f5f51 | ||
|
|
be54bc0dfd | ||
|
|
b807bc7fc4 | ||
|
|
21fb4aafcf | ||
|
|
4b638011bb | ||
|
|
a109a596c8 | ||
|
|
8ae2dc75f6 | ||
|
|
50c557419e | ||
|
|
c6d1a5784a | ||
|
|
776cabb883 | ||
|
|
16cdcfb96f | ||
|
|
711b1a62d5 | ||
|
|
dae95849ea | ||
|
|
5c6f92d497 | ||
|
|
e7c87969f0 | ||
|
|
6cb00e2ae9 | ||
|
|
d28164c150 | ||
|
|
61bc6e8d1c | ||
|
|
6a232a8830 | ||
|
|
d82554124c | ||
|
|
1fbd1cd28f | ||
|
|
7e03ec7812 | ||
|
|
fa3ecba7a5 | ||
|
|
2de20539a9 | ||
|
|
933db1075f | ||
|
|
c0b3cc9048 | ||
|
|
713cb7043e | ||
|
|
b4d086b540 | ||
|
|
e3e0e8a364 | ||
|
|
e909e32f31 | ||
|
|
9417e1023d | ||
|
|
109e64c2ba | ||
|
|
ceb7046bc4 | ||
|
|
bfc513e997 | ||
|
|
527ce3a872 | ||
|
|
44a8c9f0b3 | ||
|
|
e6001a48d7 | ||
|
|
242814fa72 | ||
|
|
ddc08498cc | ||
|
|
a9a9e3bf11 | ||
|
|
d56fcd0774 | ||
|
|
33ea50c2e9 | ||
|
|
e922722191 | ||
|
|
158c027c23 | ||
|
|
133aada0b7 | ||
|
|
4ae5a1f894 | ||
|
|
93eacdac20 | ||
|
|
cac4948afe | ||
|
|
b480d234dd | ||
|
|
91979a3d0e | ||
|
|
f5a77a1f68 | ||
|
|
a58d582001 | ||
|
|
c4a805107f | ||
|
|
72fc3c0ba4 | ||
|
|
566d9aabae | ||
|
|
18a9bf0caf |
@@ -3,3 +3,6 @@ rustflags = "-C link-arg=/STACK:8000000"
|
||||
|
||||
[target.'cfg(all(target_os = "windows", not(target_env = "msvc")))']
|
||||
rustflags = "-C link-args=-Wl,--stack,8000000"
|
||||
|
||||
[target.wasm32-unknown-unknown]
|
||||
rustflags = ["--cfg=getrandom_backend=\"wasm_js\""]
|
||||
|
||||
@@ -23,6 +23,7 @@ freevars
|
||||
fromlist
|
||||
heaptype
|
||||
HIGHRES
|
||||
Itertool
|
||||
IMMUTABLETYPE
|
||||
kwonlyarg
|
||||
kwonlyargs
|
||||
@@ -58,4 +59,4 @@ weakreflist
|
||||
withitem
|
||||
withs
|
||||
xstat
|
||||
XXPRIME
|
||||
XXPRIME
|
||||
|
||||
6
.github/copilot-instructions.md
vendored
6
.github/copilot-instructions.md
vendored
@@ -206,7 +206,7 @@ cargo run --features ssl
|
||||
|
||||
## Documentation
|
||||
|
||||
- Check the [architecture document](architecture/architecture.md) for a high-level overview
|
||||
- Read the [development guide](DEVELOPMENT.md) for detailed setup instructions
|
||||
- Check the [architecture document](/architecture/architecture.md) for a high-level overview
|
||||
- Read the [development guide](/DEVELOPMENT.md) for detailed setup instructions
|
||||
- Generate documentation with `cargo doc --no-deps --all`
|
||||
- Online documentation is available at [docs.rs/rustpython](https://docs.rs/rustpython/)
|
||||
- Online documentation is available at [docs.rs/rustpython](https://docs.rs/rustpython/)
|
||||
|
||||
18
.github/dependabot.yml
vendored
18
.github/dependabot.yml
vendored
@@ -1,13 +1,15 @@
|
||||
# Keep GitHub Actions up to date with GitHub's Dependabot...
|
||||
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
|
||||
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
- package-ecosystem: cargo
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
ignore:
|
||||
# TODO: Remove when we use ruff from crates.io
|
||||
# for some reason dependabot only updates the Cargo.lock file when dealing
|
||||
# with git dependencies. i.e. not updating the version in Cargo.toml
|
||||
- dependency-name: "ruff_*"
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*" # Group all Actions updates into a single larger pull request
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
||||
24
.github/workflows/ci.yaml
vendored
24
.github/workflows/ci.yaml
vendored
@@ -119,7 +119,7 @@ jobs:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: clippy
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
target: i686-unknown-linux-gnu
|
||||
@@ -245,10 +245,10 @@ jobs:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: Set up the Windows environment
|
||||
@@ -267,7 +267,7 @@ jobs:
|
||||
- name: build rustpython
|
||||
run: cargo build --release --verbose --features=threading ${{ env.CARGO_ARGS }},jit
|
||||
if: runner.os != 'macOS'
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: run snippets
|
||||
@@ -310,7 +310,7 @@ jobs:
|
||||
name: Check Rust code with rustfmt and clippy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
@@ -318,7 +318,7 @@ jobs:
|
||||
run: cargo fmt --check
|
||||
- name: run clippy on wasm
|
||||
run: cargo clippy --manifest-path=wasm/lib/Cargo.toml -- -Dwarnings
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: install ruff
|
||||
@@ -351,7 +351,7 @@ jobs:
|
||||
env:
|
||||
NIGHTLY_CHANNEL: nightly
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
@@ -373,7 +373,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@@ -384,12 +384,12 @@ jobs:
|
||||
wget https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-linux64.tar.gz
|
||||
mkdir geckodriver
|
||||
tar -xzf geckodriver-v0.36.0-linux64.tar.gz -C geckodriver
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- run: python -m pip install -r requirements.txt
|
||||
working-directory: ./wasm/tests
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "wasm/demo/package-lock.json"
|
||||
@@ -434,7 +434,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
target: wasm32-wasip1
|
||||
|
||||
35
.github/workflows/cron-ci.yaml
vendored
35
.github/workflows/cron-ci.yaml
vendored
@@ -1,6 +1,6 @@
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 6'
|
||||
- cron: "0 0 * * 6"
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
@@ -18,11 +18,13 @@ jobs:
|
||||
codecov:
|
||||
name: Collect code coverage data
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: taiki-e/install-action@cargo-llvm-cov
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- run: sudo apt-get update && sudo apt-get -y install lcov
|
||||
@@ -32,7 +34,7 @@ jobs:
|
||||
run: python scripts/cargo-llvm-cov.py
|
||||
continue-on-error: true
|
||||
- name: Run cargo-llvm-cov with Python test suite.
|
||||
run: cargo llvm-cov --no-report run -- -m test -u all --slowest --fail-env-changed
|
||||
run: cargo llvm-cov --no-report run -- -m test -u all --slowest --fail-env-changed
|
||||
continue-on-error: true
|
||||
- name: Prepare code coverage data
|
||||
run: cargo llvm-cov report --lcov --output-path='codecov.lcov'
|
||||
@@ -44,6 +46,8 @@ jobs:
|
||||
testdata:
|
||||
name: Collect regression test data
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -73,10 +77,12 @@ jobs:
|
||||
whatsleft:
|
||||
name: Collect what is left data
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
- name: build rustpython
|
||||
@@ -103,6 +109,23 @@ jobs:
|
||||
rm ./_data/whats_left/modules.csv
|
||||
echo -e "module" > ./_data/whats_left/modules.csv
|
||||
cat ./_data/whats_left.temp | grep "(entire module)" | cut -d ' ' -f 1 | sort >> ./_data/whats_left/modules.csv
|
||||
awk -f - ./_data/whats_left.temp > ./_data/whats_left/builtin_items.csv <<'EOF'
|
||||
BEGIN {
|
||||
OFS=","
|
||||
print "builtin,name,is_inherited"
|
||||
}
|
||||
/^# builtin items/ { in_section=1; next }
|
||||
/^$/ { if (in_section) exit }
|
||||
in_section {
|
||||
split($1, a, ".")
|
||||
rest = ""
|
||||
idx = index($0, " ")
|
||||
if (idx > 0) {
|
||||
rest = substr($0, idx+1)
|
||||
}
|
||||
print a[1], $1, rest
|
||||
}
|
||||
EOF
|
||||
git add -A
|
||||
if git -c user.name="Github Actions" -c user.email="actions@github.com" commit -m "Update what is left results" --author="$GITHUB_ACTOR"; then
|
||||
git push
|
||||
@@ -111,10 +134,12 @@ jobs:
|
||||
benchmark:
|
||||
name: Collect benchmark data
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.9
|
||||
- run: cargo install cargo-criterion
|
||||
|
||||
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@@ -21,6 +21,8 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
@@ -81,13 +83,15 @@ jobs:
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
- name: Upload Binary Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}
|
||||
path: target/rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}*
|
||||
|
||||
build-wasm:
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
@@ -101,14 +105,14 @@ jobs:
|
||||
run: cp target/wasm32-wasip1/release/rustpython.wasm target/rustpython-release-wasm32-wasip1.wasm
|
||||
|
||||
- name: Upload Binary Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: rustpython-release-wasm32-wasip1
|
||||
path: target/rustpython-release-wasm32-wasip1.wasm
|
||||
|
||||
- name: install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: mwilliamson/setup-wabt-action@v3
|
||||
with: { wabt-version: "1.0.30" }
|
||||
- name: build demo
|
||||
@@ -136,10 +140,12 @@ jobs:
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
# Disable this scheduled job when running on a fork.
|
||||
if: ${{ github.repository == 'RustPython/RustPython' || github.event_name != 'schedule' }}
|
||||
needs: [build, build-wasm]
|
||||
steps:
|
||||
- name: Download Binary Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
path: bin
|
||||
pattern: rustpython-*
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -21,3 +21,8 @@ flamescope.json
|
||||
|
||||
extra_tests/snippets/resources
|
||||
extra_tests/not_impl.py
|
||||
|
||||
Lib/site-packages/*
|
||||
!Lib/site-packages/README.txt
|
||||
Lib/test/data/*
|
||||
!Lib/test/data/README
|
||||
|
||||
1056
Cargo.lock
generated
1056
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
46
Cargo.toml
46
Cargo.toml
@@ -51,7 +51,7 @@ rustyline = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { workspace = true }
|
||||
pyo3 = { version = "0.24", features = ["auto-initialize"] }
|
||||
pyo3 = { version = "0.26", features = ["auto-initialize"] }
|
||||
|
||||
[[bench]]
|
||||
name = "execution"
|
||||
@@ -90,7 +90,7 @@ lto = "thin"
|
||||
git = "https://github.com/microsoft/vcpkg"
|
||||
# The revision of the vcpkg repository to use
|
||||
# https://github.com/microsoft/vcpkg/tags
|
||||
rev = "2024.02.14"
|
||||
rev = "2025.09.17"
|
||||
|
||||
[package.metadata.vcpkg.target]
|
||||
x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md", dev-dependencies = ["openssl" ] }
|
||||
@@ -138,7 +138,7 @@ members = [
|
||||
version = "0.4.0"
|
||||
authors = ["RustPython Team"]
|
||||
edition = "2024"
|
||||
rust-version = "1.85.0"
|
||||
rust-version = "1.89.0"
|
||||
repository = "https://github.com/RustPython/RustPython"
|
||||
license = "MIT"
|
||||
|
||||
@@ -158,33 +158,33 @@ rustpython-sre_engine = { path = "vm/sre_engine", version = "0.4.0" }
|
||||
rustpython-wtf8 = { path = "wtf8", version = "0.4.0" }
|
||||
rustpython-doc = { git = "https://github.com/RustPython/__doc__", tag = "0.3.0", version = "0.3.0" }
|
||||
|
||||
ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" }
|
||||
ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" }
|
||||
ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" }
|
||||
ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "0.11.0" }
|
||||
ruff_python_parser = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" }
|
||||
ruff_python_ast = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" }
|
||||
ruff_text_size = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" }
|
||||
ruff_source_file = { git = "https://github.com/astral-sh/ruff.git", tag = "0.14.1" }
|
||||
|
||||
ahash = "0.8.11"
|
||||
ahash = "0.8.12"
|
||||
ascii = "1.1"
|
||||
bitflags = "2.9.1"
|
||||
bitflags = "2.9.4"
|
||||
bstr = "1"
|
||||
cfg-if = "1.0"
|
||||
chrono = "0.4.39"
|
||||
chrono = "0.4.42"
|
||||
constant_time_eq = "0.4"
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
criterion = { version = "0.7", features = ["html_reports"] }
|
||||
crossbeam-utils = "0.8.21"
|
||||
flame = "0.2.2"
|
||||
getrandom = { version = "0.3", features = ["std"] }
|
||||
glob = "0.3"
|
||||
hex = "0.4.3"
|
||||
indexmap = { version = "2.10.0", features = ["std"] }
|
||||
indexmap = { version = "2.11.3", features = ["std"] }
|
||||
insta = "1.42"
|
||||
itertools = "0.14.0"
|
||||
is-macro = "0.3.7"
|
||||
junction = "1.2.0"
|
||||
junction = "1.3.0"
|
||||
libc = "0.2.169"
|
||||
libffi = "4.1"
|
||||
log = "0.4.27"
|
||||
nix = { version = "0.29", features = ["fs", "user", "process", "term", "time", "signal", "ioctl", "socket", "sched", "zerocopy", "dir", "hostname", "net", "poll"] }
|
||||
log = "0.4.28"
|
||||
nix = { version = "0.30", features = ["fs", "user", "process", "term", "time", "signal", "ioctl", "socket", "sched", "zerocopy", "dir", "hostname", "net", "poll"] }
|
||||
malachite-bigint = "0.6"
|
||||
malachite-q = "0.6"
|
||||
malachite-base = "0.6"
|
||||
@@ -204,24 +204,26 @@ radium = "1.1.1"
|
||||
rand = "0.9"
|
||||
rand_core = { version = "0.9", features = ["os_rng"] }
|
||||
rustix = { version = "1.0", features = ["event"] }
|
||||
rustyline = "15.0.0"
|
||||
serde = { version = "1.0.133", default-features = false }
|
||||
schannel = "0.1.27"
|
||||
rustyline = "17.0.1"
|
||||
serde = { version = "1.0.225", default-features = false }
|
||||
schannel = "0.1.28"
|
||||
scoped-tls = "1"
|
||||
scopeguard = "1"
|
||||
static_assertions = "1.1"
|
||||
strum = "0.27"
|
||||
strum_macros = "0.27"
|
||||
syn = "2"
|
||||
thiserror = "2.0"
|
||||
thread_local = "1.1.8"
|
||||
unicode-casing = "0.1.0"
|
||||
thread_local = "1.1.9"
|
||||
unicode-casing = "0.1.1"
|
||||
unic-char-property = "0.9.0"
|
||||
unic-normal = "0.9.0"
|
||||
unic-ucd-age = "0.9.0"
|
||||
unic-ucd-bidi = "0.9.0"
|
||||
unic-ucd-category = "0.9.0"
|
||||
unic-ucd-ident = "0.9.0"
|
||||
unicode_names2 = "1.3.0"
|
||||
unicode-bidi-mirroring = "0.2"
|
||||
unicode_names2 = "2.0.0"
|
||||
unicode-bidi-mirroring = "0.4"
|
||||
widestring = "1.2.0"
|
||||
windows-sys = "0.59.0"
|
||||
wasm-bindgen = "0.2.100"
|
||||
|
||||
16
Lib/_android_support.py
vendored
16
Lib/_android_support.py
vendored
@@ -29,15 +29,19 @@ def init_streams(android_log_write, stdout_prio, stderr_prio):
|
||||
|
||||
global logcat
|
||||
logcat = Logcat(android_log_write)
|
||||
|
||||
sys.stdout = TextLogStream(
|
||||
stdout_prio, "python.stdout", sys.stdout.fileno())
|
||||
sys.stderr = TextLogStream(
|
||||
stderr_prio, "python.stderr", sys.stderr.fileno())
|
||||
sys.stdout = TextLogStream(stdout_prio, "python.stdout", sys.stdout)
|
||||
sys.stderr = TextLogStream(stderr_prio, "python.stderr", sys.stderr)
|
||||
|
||||
|
||||
class TextLogStream(io.TextIOWrapper):
|
||||
def __init__(self, prio, tag, fileno=None, **kwargs):
|
||||
def __init__(self, prio, tag, original=None, **kwargs):
|
||||
# Respect the -u option.
|
||||
if original:
|
||||
kwargs.setdefault("write_through", original.write_through)
|
||||
fileno = original.fileno()
|
||||
else:
|
||||
fileno = None
|
||||
|
||||
# The default is surrogateescape for stdout and backslashreplace for
|
||||
# stderr, but in the context of an Android log, readability is more
|
||||
# important than reversibility.
|
||||
|
||||
14
Lib/_collections_abc.py
vendored
14
Lib/_collections_abc.py
vendored
@@ -512,7 +512,7 @@ class _CallableGenericAlias(GenericAlias):
|
||||
new_args = (t_args, t_result)
|
||||
return _CallableGenericAlias(Callable, tuple(new_args))
|
||||
|
||||
# TODO: RUSTPYTHON patch for common call
|
||||
# TODO: RUSTPYTHON; patch for common call
|
||||
def __or__(self, other):
|
||||
super().__or__(other)
|
||||
|
||||
@@ -1087,7 +1087,7 @@ class _DeprecateByteStringMeta(ABCMeta):
|
||||
|
||||
warnings._deprecated(
|
||||
"collections.abc.ByteString",
|
||||
remove=(3, 14),
|
||||
remove=(3, 17),
|
||||
)
|
||||
return super().__new__(cls, name, bases, namespace, **kwargs)
|
||||
|
||||
@@ -1096,14 +1096,18 @@ class _DeprecateByteStringMeta(ABCMeta):
|
||||
|
||||
warnings._deprecated(
|
||||
"collections.abc.ByteString",
|
||||
remove=(3, 14),
|
||||
remove=(3, 17),
|
||||
)
|
||||
return super().__instancecheck__(instance)
|
||||
|
||||
class ByteString(Sequence, metaclass=_DeprecateByteStringMeta):
|
||||
"""This unifies bytes and bytearray.
|
||||
"""Deprecated ABC serving as a common supertype of ``bytes`` and ``bytearray``.
|
||||
|
||||
XXX Should add all their methods.
|
||||
This ABC is scheduled for removal in Python 3.17.
|
||||
Use ``isinstance(obj, collections.abc.Buffer)`` to test if ``obj``
|
||||
implements the buffer protocol at runtime. For use in type annotations,
|
||||
either use ``Buffer`` or a union that explicitly specifies the types your
|
||||
code supports (e.g., ``bytes | bytearray | memoryview``).
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
343
Lib/_opcode_metadata.py
vendored
Normal file
343
Lib/_opcode_metadata.py
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
# This file is generated by Tools/cases_generator/py_metadata_generator.py
|
||||
# from:
|
||||
# Python/bytecodes.c
|
||||
# Do not edit!
|
||||
_specializations = {
|
||||
"RESUME": [
|
||||
"RESUME_CHECK",
|
||||
],
|
||||
"TO_BOOL": [
|
||||
"TO_BOOL_ALWAYS_TRUE",
|
||||
"TO_BOOL_BOOL",
|
||||
"TO_BOOL_INT",
|
||||
"TO_BOOL_LIST",
|
||||
"TO_BOOL_NONE",
|
||||
"TO_BOOL_STR",
|
||||
],
|
||||
"BINARY_OP": [
|
||||
"BINARY_OP_MULTIPLY_INT",
|
||||
"BINARY_OP_ADD_INT",
|
||||
"BINARY_OP_SUBTRACT_INT",
|
||||
"BINARY_OP_MULTIPLY_FLOAT",
|
||||
"BINARY_OP_ADD_FLOAT",
|
||||
"BINARY_OP_SUBTRACT_FLOAT",
|
||||
"BINARY_OP_ADD_UNICODE",
|
||||
"BINARY_OP_INPLACE_ADD_UNICODE",
|
||||
],
|
||||
"BINARY_SUBSCR": [
|
||||
"BINARY_SUBSCR_DICT",
|
||||
"BINARY_SUBSCR_GETITEM",
|
||||
"BINARY_SUBSCR_LIST_INT",
|
||||
"BINARY_SUBSCR_STR_INT",
|
||||
"BINARY_SUBSCR_TUPLE_INT",
|
||||
],
|
||||
"STORE_SUBSCR": [
|
||||
"STORE_SUBSCR_DICT",
|
||||
"STORE_SUBSCR_LIST_INT",
|
||||
],
|
||||
"SEND": [
|
||||
"SEND_GEN",
|
||||
],
|
||||
"UNPACK_SEQUENCE": [
|
||||
"UNPACK_SEQUENCE_TWO_TUPLE",
|
||||
"UNPACK_SEQUENCE_TUPLE",
|
||||
"UNPACK_SEQUENCE_LIST",
|
||||
],
|
||||
"STORE_ATTR": [
|
||||
"STORE_ATTR_INSTANCE_VALUE",
|
||||
"STORE_ATTR_SLOT",
|
||||
"STORE_ATTR_WITH_HINT",
|
||||
],
|
||||
"LOAD_GLOBAL": [
|
||||
"LOAD_GLOBAL_MODULE",
|
||||
"LOAD_GLOBAL_BUILTIN",
|
||||
],
|
||||
"LOAD_SUPER_ATTR": [
|
||||
"LOAD_SUPER_ATTR_ATTR",
|
||||
"LOAD_SUPER_ATTR_METHOD",
|
||||
],
|
||||
"LOAD_ATTR": [
|
||||
"LOAD_ATTR_INSTANCE_VALUE",
|
||||
"LOAD_ATTR_MODULE",
|
||||
"LOAD_ATTR_WITH_HINT",
|
||||
"LOAD_ATTR_SLOT",
|
||||
"LOAD_ATTR_CLASS",
|
||||
"LOAD_ATTR_PROPERTY",
|
||||
"LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
|
||||
"LOAD_ATTR_METHOD_WITH_VALUES",
|
||||
"LOAD_ATTR_METHOD_NO_DICT",
|
||||
"LOAD_ATTR_METHOD_LAZY_DICT",
|
||||
"LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
|
||||
"LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
|
||||
],
|
||||
"COMPARE_OP": [
|
||||
"COMPARE_OP_FLOAT",
|
||||
"COMPARE_OP_INT",
|
||||
"COMPARE_OP_STR",
|
||||
],
|
||||
"CONTAINS_OP": [
|
||||
"CONTAINS_OP_SET",
|
||||
"CONTAINS_OP_DICT",
|
||||
],
|
||||
"FOR_ITER": [
|
||||
"FOR_ITER_LIST",
|
||||
"FOR_ITER_TUPLE",
|
||||
"FOR_ITER_RANGE",
|
||||
"FOR_ITER_GEN",
|
||||
],
|
||||
"CALL": [
|
||||
"CALL_BOUND_METHOD_EXACT_ARGS",
|
||||
"CALL_PY_EXACT_ARGS",
|
||||
"CALL_TYPE_1",
|
||||
"CALL_STR_1",
|
||||
"CALL_TUPLE_1",
|
||||
"CALL_BUILTIN_CLASS",
|
||||
"CALL_BUILTIN_O",
|
||||
"CALL_BUILTIN_FAST",
|
||||
"CALL_BUILTIN_FAST_WITH_KEYWORDS",
|
||||
"CALL_LEN",
|
||||
"CALL_ISINSTANCE",
|
||||
"CALL_LIST_APPEND",
|
||||
"CALL_METHOD_DESCRIPTOR_O",
|
||||
"CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
|
||||
"CALL_METHOD_DESCRIPTOR_NOARGS",
|
||||
"CALL_METHOD_DESCRIPTOR_FAST",
|
||||
"CALL_ALLOC_AND_ENTER_INIT",
|
||||
"CALL_PY_GENERAL",
|
||||
"CALL_BOUND_METHOD_GENERAL",
|
||||
"CALL_NON_PY_GENERAL",
|
||||
],
|
||||
}
|
||||
|
||||
_specialized_opmap = {
|
||||
'BINARY_OP_ADD_FLOAT': 150,
|
||||
'BINARY_OP_ADD_INT': 151,
|
||||
'BINARY_OP_ADD_UNICODE': 152,
|
||||
'BINARY_OP_INPLACE_ADD_UNICODE': 3,
|
||||
'BINARY_OP_MULTIPLY_FLOAT': 153,
|
||||
'BINARY_OP_MULTIPLY_INT': 154,
|
||||
'BINARY_OP_SUBTRACT_FLOAT': 155,
|
||||
'BINARY_OP_SUBTRACT_INT': 156,
|
||||
'BINARY_SUBSCR_DICT': 157,
|
||||
'BINARY_SUBSCR_GETITEM': 158,
|
||||
'BINARY_SUBSCR_LIST_INT': 159,
|
||||
'BINARY_SUBSCR_STR_INT': 160,
|
||||
'BINARY_SUBSCR_TUPLE_INT': 161,
|
||||
'CALL_ALLOC_AND_ENTER_INIT': 162,
|
||||
'CALL_BOUND_METHOD_EXACT_ARGS': 163,
|
||||
'CALL_BOUND_METHOD_GENERAL': 164,
|
||||
'CALL_BUILTIN_CLASS': 165,
|
||||
'CALL_BUILTIN_FAST': 166,
|
||||
'CALL_BUILTIN_FAST_WITH_KEYWORDS': 167,
|
||||
'CALL_BUILTIN_O': 168,
|
||||
'CALL_ISINSTANCE': 169,
|
||||
'CALL_LEN': 170,
|
||||
'CALL_LIST_APPEND': 171,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST': 172,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 173,
|
||||
'CALL_METHOD_DESCRIPTOR_NOARGS': 174,
|
||||
'CALL_METHOD_DESCRIPTOR_O': 175,
|
||||
'CALL_NON_PY_GENERAL': 176,
|
||||
'CALL_PY_EXACT_ARGS': 177,
|
||||
'CALL_PY_GENERAL': 178,
|
||||
'CALL_STR_1': 179,
|
||||
'CALL_TUPLE_1': 180,
|
||||
'CALL_TYPE_1': 181,
|
||||
'COMPARE_OP_FLOAT': 182,
|
||||
'COMPARE_OP_INT': 183,
|
||||
'COMPARE_OP_STR': 184,
|
||||
'CONTAINS_OP_DICT': 185,
|
||||
'CONTAINS_OP_SET': 186,
|
||||
'FOR_ITER_GEN': 187,
|
||||
'FOR_ITER_LIST': 188,
|
||||
'FOR_ITER_RANGE': 189,
|
||||
'FOR_ITER_TUPLE': 190,
|
||||
'LOAD_ATTR_CLASS': 191,
|
||||
'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 192,
|
||||
'LOAD_ATTR_INSTANCE_VALUE': 193,
|
||||
'LOAD_ATTR_METHOD_LAZY_DICT': 194,
|
||||
'LOAD_ATTR_METHOD_NO_DICT': 195,
|
||||
'LOAD_ATTR_METHOD_WITH_VALUES': 196,
|
||||
'LOAD_ATTR_MODULE': 197,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 198,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 199,
|
||||
'LOAD_ATTR_PROPERTY': 200,
|
||||
'LOAD_ATTR_SLOT': 201,
|
||||
'LOAD_ATTR_WITH_HINT': 202,
|
||||
'LOAD_GLOBAL_BUILTIN': 203,
|
||||
'LOAD_GLOBAL_MODULE': 204,
|
||||
'LOAD_SUPER_ATTR_ATTR': 205,
|
||||
'LOAD_SUPER_ATTR_METHOD': 206,
|
||||
'RESUME_CHECK': 207,
|
||||
'SEND_GEN': 208,
|
||||
'STORE_ATTR_INSTANCE_VALUE': 209,
|
||||
'STORE_ATTR_SLOT': 210,
|
||||
'STORE_ATTR_WITH_HINT': 211,
|
||||
'STORE_SUBSCR_DICT': 212,
|
||||
'STORE_SUBSCR_LIST_INT': 213,
|
||||
'TO_BOOL_ALWAYS_TRUE': 214,
|
||||
'TO_BOOL_BOOL': 215,
|
||||
'TO_BOOL_INT': 216,
|
||||
'TO_BOOL_LIST': 217,
|
||||
'TO_BOOL_NONE': 218,
|
||||
'TO_BOOL_STR': 219,
|
||||
'UNPACK_SEQUENCE_LIST': 220,
|
||||
'UNPACK_SEQUENCE_TUPLE': 221,
|
||||
'UNPACK_SEQUENCE_TWO_TUPLE': 222,
|
||||
}
|
||||
|
||||
opmap = {
|
||||
'CACHE': 0,
|
||||
'RESERVED': 17,
|
||||
'RESUME': 149,
|
||||
'INSTRUMENTED_LINE': 254,
|
||||
'BEFORE_ASYNC_WITH': 1,
|
||||
'BEFORE_WITH': 2,
|
||||
'BINARY_SLICE': 4,
|
||||
'BINARY_SUBSCR': 5,
|
||||
'CHECK_EG_MATCH': 6,
|
||||
'CHECK_EXC_MATCH': 7,
|
||||
'CLEANUP_THROW': 8,
|
||||
'DELETE_SUBSCR': 9,
|
||||
'END_ASYNC_FOR': 10,
|
||||
'END_FOR': 11,
|
||||
'END_SEND': 12,
|
||||
'EXIT_INIT_CHECK': 13,
|
||||
'FORMAT_SIMPLE': 14,
|
||||
'FORMAT_WITH_SPEC': 15,
|
||||
'GET_AITER': 16,
|
||||
'GET_ANEXT': 18,
|
||||
'GET_ITER': 19,
|
||||
'GET_LEN': 20,
|
||||
'GET_YIELD_FROM_ITER': 21,
|
||||
'INTERPRETER_EXIT': 22,
|
||||
'LOAD_ASSERTION_ERROR': 23,
|
||||
'LOAD_BUILD_CLASS': 24,
|
||||
'LOAD_LOCALS': 25,
|
||||
'MAKE_FUNCTION': 26,
|
||||
'MATCH_KEYS': 27,
|
||||
'MATCH_MAPPING': 28,
|
||||
'MATCH_SEQUENCE': 29,
|
||||
'NOP': 30,
|
||||
'POP_EXCEPT': 31,
|
||||
'POP_TOP': 32,
|
||||
'PUSH_EXC_INFO': 33,
|
||||
'PUSH_NULL': 34,
|
||||
'RETURN_GENERATOR': 35,
|
||||
'RETURN_VALUE': 36,
|
||||
'SETUP_ANNOTATIONS': 37,
|
||||
'STORE_SLICE': 38,
|
||||
'STORE_SUBSCR': 39,
|
||||
'TO_BOOL': 40,
|
||||
'UNARY_INVERT': 41,
|
||||
'UNARY_NEGATIVE': 42,
|
||||
'UNARY_NOT': 43,
|
||||
'WITH_EXCEPT_START': 44,
|
||||
'BINARY_OP': 45,
|
||||
'BUILD_CONST_KEY_MAP': 46,
|
||||
'BUILD_LIST': 47,
|
||||
'BUILD_MAP': 48,
|
||||
'BUILD_SET': 49,
|
||||
'BUILD_SLICE': 50,
|
||||
'BUILD_STRING': 51,
|
||||
'BUILD_TUPLE': 52,
|
||||
'CALL': 53,
|
||||
'CALL_FUNCTION_EX': 54,
|
||||
'CALL_INTRINSIC_1': 55,
|
||||
'CALL_INTRINSIC_2': 56,
|
||||
'CALL_KW': 57,
|
||||
'COMPARE_OP': 58,
|
||||
'CONTAINS_OP': 59,
|
||||
'CONVERT_VALUE': 60,
|
||||
'COPY': 61,
|
||||
'COPY_FREE_VARS': 62,
|
||||
'DELETE_ATTR': 63,
|
||||
'DELETE_DEREF': 64,
|
||||
'DELETE_FAST': 65,
|
||||
'DELETE_GLOBAL': 66,
|
||||
'DELETE_NAME': 67,
|
||||
'DICT_MERGE': 68,
|
||||
'DICT_UPDATE': 69,
|
||||
'ENTER_EXECUTOR': 70,
|
||||
'EXTENDED_ARG': 71,
|
||||
'FOR_ITER': 72,
|
||||
'GET_AWAITABLE': 73,
|
||||
'IMPORT_FROM': 74,
|
||||
'IMPORT_NAME': 75,
|
||||
'IS_OP': 76,
|
||||
'JUMP_BACKWARD': 77,
|
||||
'JUMP_BACKWARD_NO_INTERRUPT': 78,
|
||||
'JUMP_FORWARD': 79,
|
||||
'LIST_APPEND': 80,
|
||||
'LIST_EXTEND': 81,
|
||||
'LOAD_ATTR': 82,
|
||||
'LOAD_CONST': 83,
|
||||
'LOAD_DEREF': 84,
|
||||
'LOAD_FAST': 85,
|
||||
'LOAD_FAST_AND_CLEAR': 86,
|
||||
'LOAD_FAST_CHECK': 87,
|
||||
'LOAD_FAST_LOAD_FAST': 88,
|
||||
'LOAD_FROM_DICT_OR_DEREF': 89,
|
||||
'LOAD_FROM_DICT_OR_GLOBALS': 90,
|
||||
'LOAD_GLOBAL': 91,
|
||||
'LOAD_NAME': 92,
|
||||
'LOAD_SUPER_ATTR': 93,
|
||||
'MAKE_CELL': 94,
|
||||
'MAP_ADD': 95,
|
||||
'MATCH_CLASS': 96,
|
||||
'POP_JUMP_IF_FALSE': 97,
|
||||
'POP_JUMP_IF_NONE': 98,
|
||||
'POP_JUMP_IF_NOT_NONE': 99,
|
||||
'POP_JUMP_IF_TRUE': 100,
|
||||
'RAISE_VARARGS': 101,
|
||||
'RERAISE': 102,
|
||||
'RETURN_CONST': 103,
|
||||
'SEND': 104,
|
||||
'SET_ADD': 105,
|
||||
'SET_FUNCTION_ATTRIBUTE': 106,
|
||||
'SET_UPDATE': 107,
|
||||
'STORE_ATTR': 108,
|
||||
'STORE_DEREF': 109,
|
||||
'STORE_FAST': 110,
|
||||
'STORE_FAST_LOAD_FAST': 111,
|
||||
'STORE_FAST_STORE_FAST': 112,
|
||||
'STORE_GLOBAL': 113,
|
||||
'STORE_NAME': 114,
|
||||
'SWAP': 115,
|
||||
'UNPACK_EX': 116,
|
||||
'UNPACK_SEQUENCE': 117,
|
||||
'YIELD_VALUE': 118,
|
||||
'INSTRUMENTED_RESUME': 236,
|
||||
'INSTRUMENTED_END_FOR': 237,
|
||||
'INSTRUMENTED_END_SEND': 238,
|
||||
'INSTRUMENTED_RETURN_VALUE': 239,
|
||||
'INSTRUMENTED_RETURN_CONST': 240,
|
||||
'INSTRUMENTED_YIELD_VALUE': 241,
|
||||
'INSTRUMENTED_LOAD_SUPER_ATTR': 242,
|
||||
'INSTRUMENTED_FOR_ITER': 243,
|
||||
'INSTRUMENTED_CALL': 244,
|
||||
'INSTRUMENTED_CALL_KW': 245,
|
||||
'INSTRUMENTED_CALL_FUNCTION_EX': 246,
|
||||
'INSTRUMENTED_INSTRUCTION': 247,
|
||||
'INSTRUMENTED_JUMP_FORWARD': 248,
|
||||
'INSTRUMENTED_JUMP_BACKWARD': 249,
|
||||
'INSTRUMENTED_POP_JUMP_IF_TRUE': 250,
|
||||
'INSTRUMENTED_POP_JUMP_IF_FALSE': 251,
|
||||
'INSTRUMENTED_POP_JUMP_IF_NONE': 252,
|
||||
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 253,
|
||||
'JUMP': 256,
|
||||
'JUMP_NO_INTERRUPT': 257,
|
||||
'LOAD_CLOSURE': 258,
|
||||
'LOAD_METHOD': 259,
|
||||
'LOAD_SUPER_METHOD': 260,
|
||||
'LOAD_ZERO_SUPER_ATTR': 261,
|
||||
'LOAD_ZERO_SUPER_METHOD': 262,
|
||||
'POP_BLOCK': 263,
|
||||
'SETUP_CLEANUP': 264,
|
||||
'SETUP_FINALLY': 265,
|
||||
'SETUP_WITH': 266,
|
||||
'STORE_FAST_MAYBE_NULL': 267,
|
||||
}
|
||||
|
||||
HAVE_ARGUMENT = 44
|
||||
MIN_INSTRUMENTED_OPCODE = 236
|
||||
375
Lib/_strptime.py
vendored
375
Lib/_strptime.py
vendored
@@ -10,10 +10,13 @@ FUNCTIONS:
|
||||
strptime -- Calculates the time struct represented by the passed-in string
|
||||
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
import locale
|
||||
import calendar
|
||||
import re
|
||||
from re import compile as re_compile
|
||||
from re import sub as re_sub
|
||||
from re import IGNORECASE
|
||||
from re import escape as re_escape
|
||||
from datetime import (date as datetime_date,
|
||||
@@ -27,6 +30,41 @@ def _getlang():
|
||||
# Figure out what the current language is set to.
|
||||
return locale.getlocale(locale.LC_TIME)
|
||||
|
||||
def _findall(haystack, needle):
|
||||
# Find all positions of needle in haystack.
|
||||
if not needle:
|
||||
return
|
||||
i = 0
|
||||
while True:
|
||||
i = haystack.find(needle, i)
|
||||
if i < 0:
|
||||
break
|
||||
yield i
|
||||
i += len(needle)
|
||||
|
||||
def _fixmonths(months):
|
||||
yield from months
|
||||
# The lower case of 'İ' ('\u0130') is 'i\u0307'.
|
||||
# The re module only supports 1-to-1 character matching in
|
||||
# case-insensitive mode.
|
||||
for s in months:
|
||||
if 'i\u0307' in s:
|
||||
yield s.replace('i\u0307', '\u0130')
|
||||
|
||||
lzh_TW_alt_digits = (
|
||||
# 〇:一:二:三:四:五:六:七:八:九
|
||||
'\u3007', '\u4e00', '\u4e8c', '\u4e09', '\u56db',
|
||||
'\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d',
|
||||
# 十:十一:十二:十三:十四:十五:十六:十七:十八:十九
|
||||
'\u5341', '\u5341\u4e00', '\u5341\u4e8c', '\u5341\u4e09', '\u5341\u56db',
|
||||
'\u5341\u4e94', '\u5341\u516d', '\u5341\u4e03', '\u5341\u516b', '\u5341\u4e5d',
|
||||
# 廿:廿一:廿二:廿三:廿四:廿五:廿六:廿七:廿八:廿九
|
||||
'\u5eff', '\u5eff\u4e00', '\u5eff\u4e8c', '\u5eff\u4e09', '\u5eff\u56db',
|
||||
'\u5eff\u4e94', '\u5eff\u516d', '\u5eff\u4e03', '\u5eff\u516b', '\u5eff\u4e5d',
|
||||
# 卅:卅一
|
||||
'\u5345', '\u5345\u4e00')
|
||||
|
||||
|
||||
class LocaleTime(object):
|
||||
"""Stores and handles locale-specific information related to time.
|
||||
|
||||
@@ -70,6 +108,7 @@ class LocaleTime(object):
|
||||
self.__calc_weekday()
|
||||
self.__calc_month()
|
||||
self.__calc_am_pm()
|
||||
self.__calc_alt_digits()
|
||||
self.__calc_timezone()
|
||||
self.__calc_date_time()
|
||||
if _getlang() != self.lang:
|
||||
@@ -101,53 +140,184 @@ class LocaleTime(object):
|
||||
am_pm = []
|
||||
for hour in (1, 22):
|
||||
time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0))
|
||||
am_pm.append(time.strftime("%p", time_tuple).lower())
|
||||
# br_FR has AM/PM info (' ',' ').
|
||||
am_pm.append(time.strftime("%p", time_tuple).lower().strip())
|
||||
self.am_pm = am_pm
|
||||
|
||||
def __calc_alt_digits(self):
|
||||
# Set self.LC_alt_digits by using time.strftime().
|
||||
|
||||
# The magic data should contain all decimal digits.
|
||||
time_tuple = time.struct_time((1998, 1, 27, 10, 43, 56, 1, 27, 0))
|
||||
s = time.strftime("%x%X", time_tuple)
|
||||
if s.isascii():
|
||||
# Fast path -- all digits are ASCII.
|
||||
self.LC_alt_digits = ()
|
||||
return
|
||||
|
||||
digits = ''.join(sorted(set(re.findall(r'\d', s))))
|
||||
if len(digits) == 10 and ord(digits[-1]) == ord(digits[0]) + 9:
|
||||
# All 10 decimal digits from the same set.
|
||||
if digits.isascii():
|
||||
# All digits are ASCII.
|
||||
self.LC_alt_digits = ()
|
||||
return
|
||||
|
||||
self.LC_alt_digits = [a + b for a in digits for b in digits]
|
||||
# Test whether the numbers contain leading zero.
|
||||
time_tuple2 = time.struct_time((2000, 1, 1, 1, 1, 1, 5, 1, 0))
|
||||
if self.LC_alt_digits[1] not in time.strftime("%x %X", time_tuple2):
|
||||
self.LC_alt_digits[:10] = digits
|
||||
return
|
||||
|
||||
# Either non-Gregorian calendar or non-decimal numbers.
|
||||
if {'\u4e00', '\u4e03', '\u4e5d', '\u5341', '\u5eff'}.issubset(s):
|
||||
# lzh_TW
|
||||
self.LC_alt_digits = lzh_TW_alt_digits
|
||||
return
|
||||
|
||||
self.LC_alt_digits = None
|
||||
|
||||
def __calc_date_time(self):
|
||||
# Set self.date_time, self.date, & self.time by using
|
||||
# time.strftime().
|
||||
# Set self.LC_date_time, self.LC_date, self.LC_time and
|
||||
# self.LC_time_ampm by using time.strftime().
|
||||
|
||||
# Use (1999,3,17,22,44,55,2,76,0) for magic date because the amount of
|
||||
# overloaded numbers is minimized. The order in which searches for
|
||||
# values within the format string is very important; it eliminates
|
||||
# possible ambiguity for what something represents.
|
||||
time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0))
|
||||
date_time = [None, None, None]
|
||||
date_time[0] = time.strftime("%c", time_tuple).lower()
|
||||
date_time[1] = time.strftime("%x", time_tuple).lower()
|
||||
date_time[2] = time.strftime("%X", time_tuple).lower()
|
||||
replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'),
|
||||
(self.f_month[3], '%B'), (self.a_weekday[2], '%a'),
|
||||
(self.a_month[3], '%b'), (self.am_pm[1], '%p'),
|
||||
('1999', '%Y'), ('99', '%y'), ('22', '%H'),
|
||||
('44', '%M'), ('55', '%S'), ('76', '%j'),
|
||||
('17', '%d'), ('03', '%m'), ('3', '%m'),
|
||||
# '3' needed for when no leading zero.
|
||||
('2', '%w'), ('10', '%I')]
|
||||
replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone
|
||||
for tz in tz_values])
|
||||
for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')):
|
||||
current_format = date_time[offset]
|
||||
for old, new in replacement_pairs:
|
||||
time_tuple2 = time.struct_time((1999,1,3,1,1,1,6,3,0))
|
||||
replacement_pairs = []
|
||||
|
||||
# Non-ASCII digits
|
||||
if self.LC_alt_digits or self.LC_alt_digits is None:
|
||||
for n, d in [(19, '%OC'), (99, '%Oy'), (22, '%OH'),
|
||||
(44, '%OM'), (55, '%OS'), (17, '%Od'),
|
||||
(3, '%Om'), (2, '%Ow'), (10, '%OI')]:
|
||||
if self.LC_alt_digits is None:
|
||||
s = chr(0x660 + n // 10) + chr(0x660 + n % 10)
|
||||
replacement_pairs.append((s, d))
|
||||
if n < 10:
|
||||
replacement_pairs.append((s[1], d))
|
||||
elif len(self.LC_alt_digits) > n:
|
||||
replacement_pairs.append((self.LC_alt_digits[n], d))
|
||||
else:
|
||||
replacement_pairs.append((time.strftime(d, time_tuple), d))
|
||||
replacement_pairs += [
|
||||
('1999', '%Y'), ('99', '%y'), ('22', '%H'),
|
||||
('44', '%M'), ('55', '%S'), ('76', '%j'),
|
||||
('17', '%d'), ('03', '%m'), ('3', '%m'),
|
||||
# '3' needed for when no leading zero.
|
||||
('2', '%w'), ('10', '%I'),
|
||||
]
|
||||
|
||||
date_time = []
|
||||
for directive in ('%c', '%x', '%X', '%r'):
|
||||
current_format = time.strftime(directive, time_tuple).lower()
|
||||
current_format = current_format.replace('%', '%%')
|
||||
# The month and the day of the week formats are treated specially
|
||||
# because of a possible ambiguity in some locales where the full
|
||||
# and abbreviated names are equal or names of different types
|
||||
# are equal. See doc of __find_month_format for more details.
|
||||
lst, fmt = self.__find_weekday_format(directive)
|
||||
if lst:
|
||||
current_format = current_format.replace(lst[2], fmt, 1)
|
||||
lst, fmt = self.__find_month_format(directive)
|
||||
if lst:
|
||||
current_format = current_format.replace(lst[3], fmt, 1)
|
||||
if self.am_pm[1]:
|
||||
# Must deal with possible lack of locale info
|
||||
# manifesting itself as the empty string (e.g., Swedish's
|
||||
# lack of AM/PM info) or a platform returning a tuple of empty
|
||||
# strings (e.g., MacOS 9 having timezone as ('','')).
|
||||
if old:
|
||||
current_format = current_format.replace(old, new)
|
||||
current_format = current_format.replace(self.am_pm[1], '%p')
|
||||
for tz_values in self.timezone:
|
||||
for tz in tz_values:
|
||||
if tz:
|
||||
current_format = current_format.replace(tz, "%Z")
|
||||
# Transform all non-ASCII digits to digits in range U+0660 to U+0669.
|
||||
if not current_format.isascii() and self.LC_alt_digits is None:
|
||||
current_format = re_sub(r'\d(?<![0-9])',
|
||||
lambda m: chr(0x0660 + int(m[0])),
|
||||
current_format)
|
||||
for old, new in replacement_pairs:
|
||||
current_format = current_format.replace(old, new)
|
||||
# If %W is used, then Sunday, 2005-01-03 will fall on week 0 since
|
||||
# 2005-01-03 occurs before the first Monday of the year. Otherwise
|
||||
# %U is used.
|
||||
time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0))
|
||||
if '00' in time.strftime(directive, time_tuple):
|
||||
if '00' in time.strftime(directive, time_tuple2):
|
||||
U_W = '%W'
|
||||
else:
|
||||
U_W = '%U'
|
||||
date_time[offset] = current_format.replace('11', U_W)
|
||||
current_format = current_format.replace('11', U_W)
|
||||
date_time.append(current_format)
|
||||
self.LC_date_time = date_time[0]
|
||||
self.LC_date = date_time[1]
|
||||
self.LC_time = date_time[2]
|
||||
self.LC_time_ampm = date_time[3]
|
||||
|
||||
def __find_month_format(self, directive):
|
||||
"""Find the month format appropriate for the current locale.
|
||||
|
||||
In some locales (for example French and Hebrew), the default month
|
||||
used in __calc_date_time has the same name in full and abbreviated
|
||||
form. Also, the month name can by accident match other part of the
|
||||
representation: the day of the week name (for example in Morisyen)
|
||||
or the month number (for example in Japanese). Thus, cycle months
|
||||
of the year and find all positions that match the month name for
|
||||
each month, If no common positions are found, the representation
|
||||
does not use the month name.
|
||||
"""
|
||||
full_indices = abbr_indices = None
|
||||
for m in range(1, 13):
|
||||
time_tuple = time.struct_time((1999, m, 17, 22, 44, 55, 2, 76, 0))
|
||||
datetime = time.strftime(directive, time_tuple).lower()
|
||||
indices = set(_findall(datetime, self.f_month[m]))
|
||||
if full_indices is None:
|
||||
full_indices = indices
|
||||
else:
|
||||
full_indices &= indices
|
||||
indices = set(_findall(datetime, self.a_month[m]))
|
||||
if abbr_indices is None:
|
||||
abbr_indices = set(indices)
|
||||
else:
|
||||
abbr_indices &= indices
|
||||
if not full_indices and not abbr_indices:
|
||||
return None, None
|
||||
if full_indices:
|
||||
return self.f_month, '%B'
|
||||
if abbr_indices:
|
||||
return self.a_month, '%b'
|
||||
return None, None
|
||||
|
||||
def __find_weekday_format(self, directive):
|
||||
"""Find the day of the week format appropriate for the current locale.
|
||||
|
||||
Similar to __find_month_format().
|
||||
"""
|
||||
full_indices = abbr_indices = None
|
||||
for wd in range(7):
|
||||
time_tuple = time.struct_time((1999, 3, 17, 22, 44, 55, wd, 76, 0))
|
||||
datetime = time.strftime(directive, time_tuple).lower()
|
||||
indices = set(_findall(datetime, self.f_weekday[wd]))
|
||||
if full_indices is None:
|
||||
full_indices = indices
|
||||
else:
|
||||
full_indices &= indices
|
||||
if self.f_weekday[wd] != self.a_weekday[wd]:
|
||||
indices = set(_findall(datetime, self.a_weekday[wd]))
|
||||
if abbr_indices is None:
|
||||
abbr_indices = set(indices)
|
||||
else:
|
||||
abbr_indices &= indices
|
||||
if not full_indices and not abbr_indices:
|
||||
return None, None
|
||||
if full_indices:
|
||||
return self.f_weekday, '%A'
|
||||
if abbr_indices:
|
||||
return self.a_weekday, '%a'
|
||||
return None, None
|
||||
|
||||
def __calc_timezone(self):
|
||||
# Set self.timezone by using time.tzname.
|
||||
@@ -181,12 +351,14 @@ class TimeRE(dict):
|
||||
else:
|
||||
self.locale_time = LocaleTime()
|
||||
base = super()
|
||||
base.__init__({
|
||||
mapping = {
|
||||
# The " [1-9]" part of the regex is to make %c from ANSI C work
|
||||
'd': r"(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])",
|
||||
'f': r"(?P<f>[0-9]{1,6})",
|
||||
'H': r"(?P<H>2[0-3]|[0-1]\d|\d)",
|
||||
'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])",
|
||||
'H': r"(?P<H>2[0-3]|[0-1]\d|\d| \d)",
|
||||
'k': r"(?P<H>2[0-3]|[0-1]\d|\d| \d)",
|
||||
'I': r"(?P<I>1[0-2]|0[1-9]|[1-9]| [1-9])",
|
||||
'l': r"(?P<I>1[0-2]|0[1-9]|[1-9]| [1-9])",
|
||||
'G': r"(?P<G>\d\d\d\d)",
|
||||
'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])",
|
||||
'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])",
|
||||
@@ -198,25 +370,60 @@ class TimeRE(dict):
|
||||
'V': r"(?P<V>5[0-3]|0[1-9]|[1-4]\d|\d)",
|
||||
# W is set below by using 'U'
|
||||
'y': r"(?P<y>\d\d)",
|
||||
#XXX: Does 'Y' need to worry about having less or more than
|
||||
# 4 digits?
|
||||
'Y': r"(?P<Y>\d\d\d\d)",
|
||||
'z': r"(?P<z>[+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?|(?-i:Z))",
|
||||
'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
|
||||
'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
|
||||
'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
|
||||
'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'),
|
||||
'B': self.__seqToRE(_fixmonths(self.locale_time.f_month[1:]), 'B'),
|
||||
'b': self.__seqToRE(_fixmonths(self.locale_time.a_month[1:]), 'b'),
|
||||
'p': self.__seqToRE(self.locale_time.am_pm, 'p'),
|
||||
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
|
||||
for tz in tz_names),
|
||||
'Z'),
|
||||
'%': '%'})
|
||||
base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
|
||||
base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
|
||||
base.__setitem__('x', self.pattern(self.locale_time.LC_date))
|
||||
base.__setitem__('X', self.pattern(self.locale_time.LC_time))
|
||||
'%': '%'}
|
||||
if self.locale_time.LC_alt_digits is None:
|
||||
for d in 'dmyCHIMS':
|
||||
mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d
|
||||
mapping['Ow'] = r'(?P<w>\d)'
|
||||
else:
|
||||
mapping.update({
|
||||
'Od': self.__seqToRE(self.locale_time.LC_alt_digits[1:32], 'd',
|
||||
'3[0-1]|[1-2][0-9]|0[1-9]|[1-9]'),
|
||||
'Om': self.__seqToRE(self.locale_time.LC_alt_digits[1:13], 'm',
|
||||
'1[0-2]|0[1-9]|[1-9]'),
|
||||
'Ow': self.__seqToRE(self.locale_time.LC_alt_digits[:7], 'w',
|
||||
'[0-6]'),
|
||||
'Oy': self.__seqToRE(self.locale_time.LC_alt_digits, 'y',
|
||||
'[0-9][0-9]'),
|
||||
'OC': self.__seqToRE(self.locale_time.LC_alt_digits, 'C',
|
||||
'[0-9][0-9]'),
|
||||
'OH': self.__seqToRE(self.locale_time.LC_alt_digits[:24], 'H',
|
||||
'2[0-3]|[0-1][0-9]|[0-9]'),
|
||||
'OI': self.__seqToRE(self.locale_time.LC_alt_digits[1:13], 'I',
|
||||
'1[0-2]|0[1-9]|[1-9]'),
|
||||
'OM': self.__seqToRE(self.locale_time.LC_alt_digits[:60], 'M',
|
||||
'[0-5][0-9]|[0-9]'),
|
||||
'OS': self.__seqToRE(self.locale_time.LC_alt_digits[:62], 'S',
|
||||
'6[0-1]|[0-5][0-9]|[0-9]'),
|
||||
})
|
||||
mapping.update({
|
||||
'e': mapping['d'],
|
||||
'Oe': mapping['Od'],
|
||||
'P': mapping['p'],
|
||||
'Op': mapping['p'],
|
||||
'W': mapping['U'].replace('U', 'W'),
|
||||
})
|
||||
mapping['W'] = mapping['U'].replace('U', 'W')
|
||||
|
||||
def __seqToRE(self, to_convert, directive):
|
||||
base.__init__(mapping)
|
||||
base.__setitem__('T', self.pattern('%H:%M:%S'))
|
||||
base.__setitem__('R', self.pattern('%H:%M'))
|
||||
base.__setitem__('r', self.pattern(self.locale_time.LC_time_ampm))
|
||||
base.__setitem__('X', self.pattern(self.locale_time.LC_time))
|
||||
base.__setitem__('x', self.pattern(self.locale_time.LC_date))
|
||||
base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
|
||||
|
||||
def __seqToRE(self, to_convert, directive, altregex=None):
|
||||
"""Convert a list to a regex string for matching a directive.
|
||||
|
||||
Want possible matching values to be from longest to shortest. This
|
||||
@@ -232,8 +439,9 @@ class TimeRE(dict):
|
||||
else:
|
||||
return ''
|
||||
regex = '|'.join(re_escape(stuff) for stuff in to_convert)
|
||||
regex = '(?P<%s>%s' % (directive, regex)
|
||||
return '%s)' % regex
|
||||
if altregex is not None:
|
||||
regex += '|' + altregex
|
||||
return '(?P<%s>%s)' % (directive, regex)
|
||||
|
||||
def pattern(self, format):
|
||||
"""Return regex pattern for the format string.
|
||||
@@ -242,21 +450,36 @@ class TimeRE(dict):
|
||||
regex syntax are escaped.
|
||||
|
||||
"""
|
||||
processed_format = ''
|
||||
# The sub() call escapes all characters that might be misconstrued
|
||||
# as regex syntax. Cannot use re.escape since we have to deal with
|
||||
# format directives (%m, etc.).
|
||||
regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])")
|
||||
format = regex_chars.sub(r"\\\1", format)
|
||||
whitespace_replacement = re_compile(r'\s+')
|
||||
format = whitespace_replacement.sub(r'\\s+', format)
|
||||
while '%' in format:
|
||||
directive_index = format.index('%')+1
|
||||
processed_format = "%s%s%s" % (processed_format,
|
||||
format[:directive_index-1],
|
||||
self[format[directive_index]])
|
||||
format = format[directive_index+1:]
|
||||
return "%s%s" % (processed_format, format)
|
||||
format = re_sub(r"([\\.^$*+?\(\){}\[\]|])", r"\\\1", format)
|
||||
format = re_sub(r'\s+', r'\\s+', format)
|
||||
format = re_sub(r"'", "['\u02bc]", format) # needed for br_FR
|
||||
year_in_format = False
|
||||
day_of_month_in_format = False
|
||||
def repl(m):
|
||||
format_char = m[1]
|
||||
match format_char:
|
||||
case 'Y' | 'y' | 'G':
|
||||
nonlocal year_in_format
|
||||
year_in_format = True
|
||||
case 'd':
|
||||
nonlocal day_of_month_in_format
|
||||
day_of_month_in_format = True
|
||||
return self[format_char]
|
||||
format = re_sub(r'%[-_0^#]*[0-9]*([OE]?\\?.?)', repl, format)
|
||||
if day_of_month_in_format and not year_in_format:
|
||||
import warnings
|
||||
warnings.warn("""\
|
||||
Parsing dates involving a day of month without a year specified is ambiguious
|
||||
and fails to parse leap day. The default behavior will change in Python 3.15
|
||||
to either always raise an exception or to use a different default year (TBD).
|
||||
To avoid trouble, add a specific year to the input & format.
|
||||
See https://github.com/python/cpython/issues/70647.""",
|
||||
DeprecationWarning,
|
||||
skip_file_prefixes=(os.path.dirname(__file__),))
|
||||
return format
|
||||
|
||||
def compile(self, format):
|
||||
"""Return a compiled re object for the format string."""
|
||||
@@ -319,14 +542,13 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
||||
# \\, in which case it was a stray % but with a space after it
|
||||
except KeyError as err:
|
||||
bad_directive = err.args[0]
|
||||
if bad_directive == "\\":
|
||||
bad_directive = "%"
|
||||
del err
|
||||
bad_directive = bad_directive.replace('\\s', '')
|
||||
if not bad_directive:
|
||||
raise ValueError("stray %% in format '%s'" % format) from None
|
||||
bad_directive = bad_directive.replace('\\', '', 1)
|
||||
raise ValueError("'%s' is a bad directive in format '%s'" %
|
||||
(bad_directive, format)) from None
|
||||
# IndexError only occurs when the format string is "%"
|
||||
except IndexError:
|
||||
raise ValueError("stray %% in format '%s'" % format) from None
|
||||
_regex_cache[format] = format_regex
|
||||
found = format_regex.match(data_string)
|
||||
if not found:
|
||||
@@ -348,6 +570,15 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
||||
# values
|
||||
weekday = julian = None
|
||||
found_dict = found.groupdict()
|
||||
if locale_time.LC_alt_digits:
|
||||
def parse_int(s):
|
||||
try:
|
||||
return locale_time.LC_alt_digits.index(s)
|
||||
except ValueError:
|
||||
return int(s)
|
||||
else:
|
||||
parse_int = int
|
||||
|
||||
for group_key in found_dict.keys():
|
||||
# Directives not explicitly handled below:
|
||||
# c, x, X
|
||||
@@ -355,30 +586,34 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
||||
# U, W
|
||||
# worthless without day of the week
|
||||
if group_key == 'y':
|
||||
year = int(found_dict['y'])
|
||||
# Open Group specification for strptime() states that a %y
|
||||
#value in the range of [00, 68] is in the century 2000, while
|
||||
#[69,99] is in the century 1900
|
||||
if year <= 68:
|
||||
year += 2000
|
||||
year = parse_int(found_dict['y'])
|
||||
if 'C' in found_dict:
|
||||
century = parse_int(found_dict['C'])
|
||||
year += century * 100
|
||||
else:
|
||||
year += 1900
|
||||
# Open Group specification for strptime() states that a %y
|
||||
#value in the range of [00, 68] is in the century 2000, while
|
||||
#[69,99] is in the century 1900
|
||||
if year <= 68:
|
||||
year += 2000
|
||||
else:
|
||||
year += 1900
|
||||
elif group_key == 'Y':
|
||||
year = int(found_dict['Y'])
|
||||
elif group_key == 'G':
|
||||
iso_year = int(found_dict['G'])
|
||||
elif group_key == 'm':
|
||||
month = int(found_dict['m'])
|
||||
month = parse_int(found_dict['m'])
|
||||
elif group_key == 'B':
|
||||
month = locale_time.f_month.index(found_dict['B'].lower())
|
||||
elif group_key == 'b':
|
||||
month = locale_time.a_month.index(found_dict['b'].lower())
|
||||
elif group_key == 'd':
|
||||
day = int(found_dict['d'])
|
||||
day = parse_int(found_dict['d'])
|
||||
elif group_key == 'H':
|
||||
hour = int(found_dict['H'])
|
||||
hour = parse_int(found_dict['H'])
|
||||
elif group_key == 'I':
|
||||
hour = int(found_dict['I'])
|
||||
hour = parse_int(found_dict['I'])
|
||||
ampm = found_dict.get('p', '').lower()
|
||||
# If there was no AM/PM indicator, we'll treat this like AM
|
||||
if ampm in ('', locale_time.am_pm[0]):
|
||||
@@ -394,9 +629,9 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
|
||||
if hour != 12:
|
||||
hour += 12
|
||||
elif group_key == 'M':
|
||||
minute = int(found_dict['M'])
|
||||
minute = parse_int(found_dict['M'])
|
||||
elif group_key == 'S':
|
||||
second = int(found_dict['S'])
|
||||
second = parse_int(found_dict['S'])
|
||||
elif group_key == 'f':
|
||||
s = found_dict['f']
|
||||
# Pad to always return microseconds.
|
||||
|
||||
0
Lib/base64.py
vendored
Normal file → Executable file
0
Lib/base64.py
vendored
Normal file → Executable file
13
Lib/codecs.py
vendored
13
Lib/codecs.py
vendored
@@ -111,6 +111,9 @@ class CodecInfo(tuple):
|
||||
(self.__class__.__module__, self.__class__.__qualname__,
|
||||
self.name, id(self))
|
||||
|
||||
def __getnewargs__(self):
|
||||
return tuple(self)
|
||||
|
||||
class Codec:
|
||||
|
||||
""" Defines the interface for stateless encoders/decoders.
|
||||
@@ -615,7 +618,7 @@ class StreamReader(Codec):
|
||||
method and are included in the list entries.
|
||||
|
||||
sizehint, if given, is ignored since there is no efficient
|
||||
way to finding the true end-of-line.
|
||||
way of finding the true end-of-line.
|
||||
|
||||
"""
|
||||
data = self.read()
|
||||
@@ -706,13 +709,13 @@ class StreamReaderWriter:
|
||||
|
||||
return self.reader.read(size)
|
||||
|
||||
def readline(self, size=None):
|
||||
def readline(self, size=None, keepends=True):
|
||||
|
||||
return self.reader.readline(size)
|
||||
return self.reader.readline(size, keepends)
|
||||
|
||||
def readlines(self, sizehint=None):
|
||||
def readlines(self, sizehint=None, keepends=True):
|
||||
|
||||
return self.reader.readlines(sizehint)
|
||||
return self.reader.readlines(sizehint, keepends)
|
||||
|
||||
def __next__(self):
|
||||
|
||||
|
||||
372
Lib/configparser.py
vendored
372
Lib/configparser.py
vendored
@@ -18,8 +18,8 @@ ConfigParser -- responsible for parsing a list of
|
||||
delimiters=('=', ':'), comment_prefixes=('#', ';'),
|
||||
inline_comment_prefixes=None, strict=True,
|
||||
empty_lines_in_values=True, default_section='DEFAULT',
|
||||
interpolation=<unset>, converters=<unset>):
|
||||
|
||||
interpolation=<unset>, converters=<unset>,
|
||||
allow_unnamed_section=False):
|
||||
Create the parser. When `defaults` is given, it is initialized into the
|
||||
dictionary or intrinsic defaults. The keys must be strings, the values
|
||||
must be appropriate for %()s string interpolation.
|
||||
@@ -68,6 +68,10 @@ ConfigParser -- responsible for parsing a list of
|
||||
converter gets its corresponding get*() method on the parser object and
|
||||
section proxies.
|
||||
|
||||
When `allow_unnamed_section` is True (default: False), options
|
||||
without section are accepted: the section for these is
|
||||
``configparser.UNNAMED_SECTION``.
|
||||
|
||||
sections()
|
||||
Return all the configuration section names, sans DEFAULT.
|
||||
|
||||
@@ -139,24 +143,28 @@ ConfigParser -- responsible for parsing a list of
|
||||
between keys and values are surrounded by spaces.
|
||||
"""
|
||||
|
||||
from collections.abc import MutableMapping
|
||||
# Do not import dataclasses; overhead is unacceptable (gh-117703)
|
||||
|
||||
from collections.abc import Iterable, MutableMapping
|
||||
from collections import ChainMap as _ChainMap
|
||||
import contextlib
|
||||
import functools
|
||||
import io
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
import types
|
||||
|
||||
__all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
|
||||
"NoOptionError", "InterpolationError", "InterpolationDepthError",
|
||||
"InterpolationMissingOptionError", "InterpolationSyntaxError",
|
||||
"ParsingError", "MissingSectionHeaderError",
|
||||
"MultilineContinuationError",
|
||||
"ConfigParser", "RawConfigParser",
|
||||
"Interpolation", "BasicInterpolation", "ExtendedInterpolation",
|
||||
"LegacyInterpolation", "SectionProxy", "ConverterMapping",
|
||||
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH")
|
||||
"SectionProxy", "ConverterMapping",
|
||||
"DEFAULTSECT", "MAX_INTERPOLATION_DEPTH", "UNNAMED_SECTION")
|
||||
|
||||
_default_dict = dict
|
||||
DEFAULTSECT = "DEFAULT"
|
||||
@@ -298,15 +306,33 @@ class InterpolationDepthError(InterpolationError):
|
||||
class ParsingError(Error):
|
||||
"""Raised when a configuration file does not follow legal syntax."""
|
||||
|
||||
def __init__(self, source):
|
||||
def __init__(self, source, *args):
|
||||
super().__init__(f'Source contains parsing errors: {source!r}')
|
||||
self.source = source
|
||||
self.errors = []
|
||||
self.args = (source, )
|
||||
if args:
|
||||
self.append(*args)
|
||||
|
||||
def append(self, lineno, line):
|
||||
self.errors.append((lineno, line))
|
||||
self.message += '\n\t[line %2d]: %s' % (lineno, line)
|
||||
self.message += '\n\t[line %2d]: %s' % (lineno, repr(line))
|
||||
|
||||
def combine(self, others):
|
||||
for other in others:
|
||||
for error in other.errors:
|
||||
self.append(*error)
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def _raise_all(exceptions: Iterable['ParsingError']):
|
||||
"""
|
||||
Combine any number of ParsingErrors into one and raise it.
|
||||
"""
|
||||
exceptions = iter(exceptions)
|
||||
with contextlib.suppress(StopIteration):
|
||||
raise next(exceptions).combine(exceptions)
|
||||
|
||||
|
||||
|
||||
class MissingSectionHeaderError(ParsingError):
|
||||
@@ -323,6 +349,28 @@ class MissingSectionHeaderError(ParsingError):
|
||||
self.args = (filename, lineno, line)
|
||||
|
||||
|
||||
class MultilineContinuationError(ParsingError):
|
||||
"""Raised when a key without value is followed by continuation line"""
|
||||
def __init__(self, filename, lineno, line):
|
||||
Error.__init__(
|
||||
self,
|
||||
"Key without value continued with an indented line.\n"
|
||||
"file: %r, line: %d\n%r"
|
||||
%(filename, lineno, line))
|
||||
self.source = filename
|
||||
self.lineno = lineno
|
||||
self.line = line
|
||||
self.args = (filename, lineno, line)
|
||||
|
||||
class _UnnamedSection:
|
||||
|
||||
def __repr__(self):
|
||||
return "<UNNAMED_SECTION>"
|
||||
|
||||
|
||||
UNNAMED_SECTION = _UnnamedSection()
|
||||
|
||||
|
||||
# Used in parser getters to indicate the default behaviour when a specific
|
||||
# option is not found it to raise an exception. Created to enable `None` as
|
||||
# a valid fallback value.
|
||||
@@ -478,6 +526,8 @@ class ExtendedInterpolation(Interpolation):
|
||||
except (KeyError, NoSectionError, NoOptionError):
|
||||
raise InterpolationMissingOptionError(
|
||||
option, section, rawval, ":".join(path)) from None
|
||||
if v is None:
|
||||
continue
|
||||
if "$" in v:
|
||||
self._interpolate_some(parser, opt, accum, v, sect,
|
||||
dict(parser.items(sect, raw=True)),
|
||||
@@ -491,51 +541,50 @@ class ExtendedInterpolation(Interpolation):
|
||||
"found: %r" % (rest,))
|
||||
|
||||
|
||||
class LegacyInterpolation(Interpolation):
|
||||
"""Deprecated interpolation used in old versions of ConfigParser.
|
||||
Use BasicInterpolation or ExtendedInterpolation instead."""
|
||||
class _ReadState:
|
||||
elements_added : set[str]
|
||||
cursect : dict[str, str] | None = None
|
||||
sectname : str | None = None
|
||||
optname : str | None = None
|
||||
lineno : int = 0
|
||||
indent_level : int = 0
|
||||
errors : list[ParsingError]
|
||||
|
||||
_KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
|
||||
def __init__(self):
|
||||
self.elements_added = set()
|
||||
self.errors = list()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
warnings.warn(
|
||||
"LegacyInterpolation has been deprecated since Python 3.2 "
|
||||
"and will be removed from the configparser module in Python 3.13. "
|
||||
"Use BasicInterpolation or ExtendedInterpolation instead.",
|
||||
DeprecationWarning, stacklevel=2
|
||||
|
||||
class _Line(str):
|
||||
|
||||
def __new__(cls, val, *args, **kwargs):
|
||||
return super().__new__(cls, val)
|
||||
|
||||
def __init__(self, val, prefixes):
|
||||
self.prefixes = prefixes
|
||||
|
||||
@functools.cached_property
|
||||
def clean(self):
|
||||
return self._strip_full() and self._strip_inline()
|
||||
|
||||
@property
|
||||
def has_comments(self):
|
||||
return self.strip() != self.clean
|
||||
|
||||
def _strip_inline(self):
|
||||
"""
|
||||
Search for the earliest prefix at the beginning of the line or following a space.
|
||||
"""
|
||||
matcher = re.compile(
|
||||
'|'.join(fr'(^|\s)({re.escape(prefix)})' for prefix in self.prefixes.inline)
|
||||
# match nothing if no prefixes
|
||||
or '(?!)'
|
||||
)
|
||||
match = matcher.search(self)
|
||||
return self[:match.start() if match else None].strip()
|
||||
|
||||
def before_get(self, parser, section, option, value, vars):
|
||||
rawval = value
|
||||
depth = MAX_INTERPOLATION_DEPTH
|
||||
while depth: # Loop through this until it's done
|
||||
depth -= 1
|
||||
if value and "%(" in value:
|
||||
replace = functools.partial(self._interpolation_replace,
|
||||
parser=parser)
|
||||
value = self._KEYCRE.sub(replace, value)
|
||||
try:
|
||||
value = value % vars
|
||||
except KeyError as e:
|
||||
raise InterpolationMissingOptionError(
|
||||
option, section, rawval, e.args[0]) from None
|
||||
else:
|
||||
break
|
||||
if value and "%(" in value:
|
||||
raise InterpolationDepthError(option, section, rawval)
|
||||
return value
|
||||
|
||||
def before_set(self, parser, section, option, value):
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def _interpolation_replace(match, parser):
|
||||
s = match.group(1)
|
||||
if s is None:
|
||||
return match.group()
|
||||
else:
|
||||
return "%%(%s)s" % parser.optionxform(s)
|
||||
def _strip_full(self):
|
||||
return '' if any(map(self.strip().startswith, self.prefixes.full)) else True
|
||||
|
||||
|
||||
class RawConfigParser(MutableMapping):
|
||||
@@ -584,7 +633,8 @@ class RawConfigParser(MutableMapping):
|
||||
comment_prefixes=('#', ';'), inline_comment_prefixes=None,
|
||||
strict=True, empty_lines_in_values=True,
|
||||
default_section=DEFAULTSECT,
|
||||
interpolation=_UNSET, converters=_UNSET):
|
||||
interpolation=_UNSET, converters=_UNSET,
|
||||
allow_unnamed_section=False,):
|
||||
|
||||
self._dict = dict_type
|
||||
self._sections = self._dict()
|
||||
@@ -603,8 +653,10 @@ class RawConfigParser(MutableMapping):
|
||||
else:
|
||||
self._optcre = re.compile(self._OPT_TMPL.format(delim=d),
|
||||
re.VERBOSE)
|
||||
self._comment_prefixes = tuple(comment_prefixes or ())
|
||||
self._inline_comment_prefixes = tuple(inline_comment_prefixes or ())
|
||||
self._prefixes = types.SimpleNamespace(
|
||||
full=tuple(comment_prefixes or ()),
|
||||
inline=tuple(inline_comment_prefixes or ()),
|
||||
)
|
||||
self._strict = strict
|
||||
self._allow_no_value = allow_no_value
|
||||
self._empty_lines_in_values = empty_lines_in_values
|
||||
@@ -623,6 +675,7 @@ class RawConfigParser(MutableMapping):
|
||||
self._converters.update(converters)
|
||||
if defaults:
|
||||
self._read_defaults(defaults)
|
||||
self._allow_unnamed_section = allow_unnamed_section
|
||||
|
||||
def defaults(self):
|
||||
return self._defaults
|
||||
@@ -896,13 +949,19 @@ class RawConfigParser(MutableMapping):
|
||||
if self._defaults:
|
||||
self._write_section(fp, self.default_section,
|
||||
self._defaults.items(), d)
|
||||
if UNNAMED_SECTION in self._sections:
|
||||
self._write_section(fp, UNNAMED_SECTION, self._sections[UNNAMED_SECTION].items(), d, unnamed=True)
|
||||
|
||||
for section in self._sections:
|
||||
if section is UNNAMED_SECTION:
|
||||
continue
|
||||
self._write_section(fp, section,
|
||||
self._sections[section].items(), d)
|
||||
|
||||
def _write_section(self, fp, section_name, section_items, delimiter):
|
||||
"""Write a single section to the specified `fp`."""
|
||||
fp.write("[{}]\n".format(section_name))
|
||||
def _write_section(self, fp, section_name, section_items, delimiter, unnamed=False):
|
||||
"""Write a single section to the specified `fp'."""
|
||||
if not unnamed:
|
||||
fp.write("[{}]\n".format(section_name))
|
||||
for key, value in section_items:
|
||||
value = self._interpolation.before_write(self, section_name, key,
|
||||
value)
|
||||
@@ -988,110 +1047,113 @@ class RawConfigParser(MutableMapping):
|
||||
in an otherwise empty line or may be entered in lines holding values or
|
||||
section names. Please note that comments get stripped off when reading configuration files.
|
||||
"""
|
||||
elements_added = set()
|
||||
cursect = None # None, or a dictionary
|
||||
sectname = None
|
||||
optname = None
|
||||
lineno = 0
|
||||
indent_level = 0
|
||||
e = None # None, or an exception
|
||||
for lineno, line in enumerate(fp, start=1):
|
||||
comment_start = sys.maxsize
|
||||
# strip inline comments
|
||||
inline_prefixes = {p: -1 for p in self._inline_comment_prefixes}
|
||||
while comment_start == sys.maxsize and inline_prefixes:
|
||||
next_prefixes = {}
|
||||
for prefix, index in inline_prefixes.items():
|
||||
index = line.find(prefix, index+1)
|
||||
if index == -1:
|
||||
continue
|
||||
next_prefixes[prefix] = index
|
||||
if index == 0 or (index > 0 and line[index-1].isspace()):
|
||||
comment_start = min(comment_start, index)
|
||||
inline_prefixes = next_prefixes
|
||||
# strip full line comments
|
||||
for prefix in self._comment_prefixes:
|
||||
if line.strip().startswith(prefix):
|
||||
comment_start = 0
|
||||
break
|
||||
if comment_start == sys.maxsize:
|
||||
comment_start = None
|
||||
value = line[:comment_start].strip()
|
||||
if not value:
|
||||
|
||||
try:
|
||||
ParsingError._raise_all(self._read_inner(fp, fpname))
|
||||
finally:
|
||||
self._join_multiline_values()
|
||||
|
||||
def _read_inner(self, fp, fpname):
|
||||
st = _ReadState()
|
||||
|
||||
Line = functools.partial(_Line, prefixes=self._prefixes)
|
||||
for st.lineno, line in enumerate(map(Line, fp), start=1):
|
||||
if not line.clean:
|
||||
if self._empty_lines_in_values:
|
||||
# add empty line to the value, but only if there was no
|
||||
# comment on the line
|
||||
if (comment_start is None and
|
||||
cursect is not None and
|
||||
optname and
|
||||
cursect[optname] is not None):
|
||||
cursect[optname].append('') # newlines added at join
|
||||
if (not line.has_comments and
|
||||
st.cursect is not None and
|
||||
st.optname and
|
||||
st.cursect[st.optname] is not None):
|
||||
st.cursect[st.optname].append('') # newlines added at join
|
||||
else:
|
||||
# empty line marks end of value
|
||||
indent_level = sys.maxsize
|
||||
st.indent_level = sys.maxsize
|
||||
continue
|
||||
# continuation line?
|
||||
|
||||
first_nonspace = self.NONSPACECRE.search(line)
|
||||
cur_indent_level = first_nonspace.start() if first_nonspace else 0
|
||||
if (cursect is not None and optname and
|
||||
cur_indent_level > indent_level):
|
||||
cursect[optname].append(value)
|
||||
# a section header or option header?
|
||||
else:
|
||||
indent_level = cur_indent_level
|
||||
# is it a section header?
|
||||
mo = self.SECTCRE.match(value)
|
||||
if mo:
|
||||
sectname = mo.group('header')
|
||||
if sectname in self._sections:
|
||||
if self._strict and sectname in elements_added:
|
||||
raise DuplicateSectionError(sectname, fpname,
|
||||
lineno)
|
||||
cursect = self._sections[sectname]
|
||||
elements_added.add(sectname)
|
||||
elif sectname == self.default_section:
|
||||
cursect = self._defaults
|
||||
else:
|
||||
cursect = self._dict()
|
||||
self._sections[sectname] = cursect
|
||||
self._proxies[sectname] = SectionProxy(self, sectname)
|
||||
elements_added.add(sectname)
|
||||
# So sections can't start with a continuation line
|
||||
optname = None
|
||||
# no section header in the file?
|
||||
elif cursect is None:
|
||||
raise MissingSectionHeaderError(fpname, lineno, line)
|
||||
# an option line?
|
||||
else:
|
||||
mo = self._optcre.match(value)
|
||||
if mo:
|
||||
optname, vi, optval = mo.group('option', 'vi', 'value')
|
||||
if not optname:
|
||||
e = self._handle_error(e, fpname, lineno, line)
|
||||
optname = self.optionxform(optname.rstrip())
|
||||
if (self._strict and
|
||||
(sectname, optname) in elements_added):
|
||||
raise DuplicateOptionError(sectname, optname,
|
||||
fpname, lineno)
|
||||
elements_added.add((sectname, optname))
|
||||
# This check is fine because the OPTCRE cannot
|
||||
# match if it would set optval to None
|
||||
if optval is not None:
|
||||
optval = optval.strip()
|
||||
cursect[optname] = [optval]
|
||||
else:
|
||||
# valueless option handling
|
||||
cursect[optname] = None
|
||||
else:
|
||||
# a non-fatal parsing error occurred. set up the
|
||||
# exception but keep going. the exception will be
|
||||
# raised at the end of the file and will contain a
|
||||
# list of all bogus lines
|
||||
e = self._handle_error(e, fpname, lineno, line)
|
||||
self._join_multiline_values()
|
||||
# if any parsing errors occurred, raise an exception
|
||||
if e:
|
||||
raise e
|
||||
st.cur_indent_level = first_nonspace.start() if first_nonspace else 0
|
||||
|
||||
if self._handle_continuation_line(st, line, fpname):
|
||||
continue
|
||||
|
||||
self._handle_rest(st, line, fpname)
|
||||
|
||||
return st.errors
|
||||
|
||||
def _handle_continuation_line(self, st, line, fpname):
|
||||
# continuation line?
|
||||
is_continue = (st.cursect is not None and st.optname and
|
||||
st.cur_indent_level > st.indent_level)
|
||||
if is_continue:
|
||||
if st.cursect[st.optname] is None:
|
||||
raise MultilineContinuationError(fpname, st.lineno, line)
|
||||
st.cursect[st.optname].append(line.clean)
|
||||
return is_continue
|
||||
|
||||
def _handle_rest(self, st, line, fpname):
|
||||
# a section header or option header?
|
||||
if self._allow_unnamed_section and st.cursect is None:
|
||||
self._handle_header(st, UNNAMED_SECTION, fpname)
|
||||
|
||||
st.indent_level = st.cur_indent_level
|
||||
# is it a section header?
|
||||
mo = self.SECTCRE.match(line.clean)
|
||||
|
||||
if not mo and st.cursect is None:
|
||||
raise MissingSectionHeaderError(fpname, st.lineno, line)
|
||||
|
||||
self._handle_header(st, mo.group('header'), fpname) if mo else self._handle_option(st, line, fpname)
|
||||
|
||||
def _handle_header(self, st, sectname, fpname):
|
||||
st.sectname = sectname
|
||||
if st.sectname in self._sections:
|
||||
if self._strict and st.sectname in st.elements_added:
|
||||
raise DuplicateSectionError(st.sectname, fpname,
|
||||
st.lineno)
|
||||
st.cursect = self._sections[st.sectname]
|
||||
st.elements_added.add(st.sectname)
|
||||
elif st.sectname == self.default_section:
|
||||
st.cursect = self._defaults
|
||||
else:
|
||||
st.cursect = self._dict()
|
||||
self._sections[st.sectname] = st.cursect
|
||||
self._proxies[st.sectname] = SectionProxy(self, st.sectname)
|
||||
st.elements_added.add(st.sectname)
|
||||
# So sections can't start with a continuation line
|
||||
st.optname = None
|
||||
|
||||
def _handle_option(self, st, line, fpname):
|
||||
# an option line?
|
||||
st.indent_level = st.cur_indent_level
|
||||
|
||||
mo = self._optcre.match(line.clean)
|
||||
if not mo:
|
||||
# a non-fatal parsing error occurred. set up the
|
||||
# exception but keep going. the exception will be
|
||||
# raised at the end of the file and will contain a
|
||||
# list of all bogus lines
|
||||
st.errors.append(ParsingError(fpname, st.lineno, line))
|
||||
return
|
||||
|
||||
st.optname, vi, optval = mo.group('option', 'vi', 'value')
|
||||
if not st.optname:
|
||||
st.errors.append(ParsingError(fpname, st.lineno, line))
|
||||
st.optname = self.optionxform(st.optname.rstrip())
|
||||
if (self._strict and
|
||||
(st.sectname, st.optname) in st.elements_added):
|
||||
raise DuplicateOptionError(st.sectname, st.optname,
|
||||
fpname, st.lineno)
|
||||
st.elements_added.add((st.sectname, st.optname))
|
||||
# This check is fine because the OPTCRE cannot
|
||||
# match if it would set optval to None
|
||||
if optval is not None:
|
||||
optval = optval.strip()
|
||||
st.cursect[st.optname] = [optval]
|
||||
else:
|
||||
# valueless option handling
|
||||
st.cursect[st.optname] = None
|
||||
|
||||
def _join_multiline_values(self):
|
||||
defaults = self.default_section, self._defaults
|
||||
@@ -1111,12 +1173,6 @@ class RawConfigParser(MutableMapping):
|
||||
for key, value in defaults.items():
|
||||
self._defaults[self.optionxform(key)] = value
|
||||
|
||||
def _handle_error(self, exc, fpname, lineno, line):
|
||||
if not exc:
|
||||
exc = ParsingError(fpname)
|
||||
exc.append(lineno, repr(line))
|
||||
return exc
|
||||
|
||||
def _unify_values(self, section, vars):
|
||||
"""Create a sequence of lookups with 'vars' taking priority over
|
||||
the 'section' which takes priority over the DEFAULTSECT.
|
||||
|
||||
4
Lib/ctypes/__init__.py
vendored
4
Lib/ctypes/__init__.py
vendored
@@ -299,9 +299,7 @@ def create_unicode_buffer(init, size=None):
|
||||
return buf
|
||||
elif isinstance(init, int):
|
||||
_sys.audit("ctypes.create_unicode_buffer", None, init)
|
||||
# XXX: RUSTPYTHON
|
||||
# buftype = c_wchar * init
|
||||
buftype = c_wchar.__mul__(init)
|
||||
buftype = c_wchar * init
|
||||
buf = buftype()
|
||||
return buf
|
||||
raise TypeError(init)
|
||||
|
||||
21
Lib/difflib.py
vendored
21
Lib/difflib.py
vendored
@@ -1200,6 +1200,25 @@ def context_diff(a, b, fromfile='', tofile='',
|
||||
strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
|
||||
The modification times are normally expressed in the ISO 8601 format.
|
||||
If not specified, the strings default to blanks.
|
||||
|
||||
Example:
|
||||
|
||||
>>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(True),
|
||||
... 'zero\none\ntree\nfour\n'.splitlines(True), 'Original', 'Current')),
|
||||
... end="")
|
||||
*** Original
|
||||
--- Current
|
||||
***************
|
||||
*** 1,4 ****
|
||||
one
|
||||
! two
|
||||
! three
|
||||
four
|
||||
--- 1,4 ----
|
||||
+ zero
|
||||
one
|
||||
! tree
|
||||
four
|
||||
"""
|
||||
|
||||
_check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm)
|
||||
@@ -1609,7 +1628,7 @@ _file_template = """
|
||||
</html>"""
|
||||
|
||||
_styles = """
|
||||
table.diff {font-family:Courier; border:medium;}
|
||||
table.diff {font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; border:medium}
|
||||
.diff_header {background-color:#e0e0e0}
|
||||
td.diff_header {text-align:right}
|
||||
.diff_next {background-color:#c0c0c0}
|
||||
|
||||
1
Lib/encodings/aliases.py
vendored
1
Lib/encodings/aliases.py
vendored
@@ -209,6 +209,7 @@ aliases = {
|
||||
'ms932' : 'cp932',
|
||||
'mskanji' : 'cp932',
|
||||
'ms_kanji' : 'cp932',
|
||||
'windows_31j' : 'cp932',
|
||||
|
||||
# cp949 codec
|
||||
'949' : 'cp949',
|
||||
|
||||
166
Lib/encodings/idna.py
vendored
166
Lib/encodings/idna.py
vendored
@@ -11,7 +11,7 @@ ace_prefix = b"xn--"
|
||||
sace_prefix = "xn--"
|
||||
|
||||
# This assumes query strings, so AllowUnassigned is true
|
||||
def nameprep(label):
|
||||
def nameprep(label): # type: (str) -> str
|
||||
# Map
|
||||
newlabel = []
|
||||
for c in label:
|
||||
@@ -25,7 +25,7 @@ def nameprep(label):
|
||||
label = unicodedata.normalize("NFKC", label)
|
||||
|
||||
# Prohibit
|
||||
for c in label:
|
||||
for i, c in enumerate(label):
|
||||
if stringprep.in_table_c12(c) or \
|
||||
stringprep.in_table_c22(c) or \
|
||||
stringprep.in_table_c3(c) or \
|
||||
@@ -35,7 +35,7 @@ def nameprep(label):
|
||||
stringprep.in_table_c7(c) or \
|
||||
stringprep.in_table_c8(c) or \
|
||||
stringprep.in_table_c9(c):
|
||||
raise UnicodeError("Invalid character %r" % c)
|
||||
raise UnicodeEncodeError("idna", label, i, i+1, f"Invalid character {c!r}")
|
||||
|
||||
# Check bidi
|
||||
RandAL = [stringprep.in_table_d1(x) for x in label]
|
||||
@@ -46,29 +46,38 @@ def nameprep(label):
|
||||
# This is table C.8, which was already checked
|
||||
# 2) If a string contains any RandALCat character, the string
|
||||
# MUST NOT contain any LCat character.
|
||||
if any(stringprep.in_table_d2(x) for x in label):
|
||||
raise UnicodeError("Violation of BIDI requirement 2")
|
||||
for i, x in enumerate(label):
|
||||
if stringprep.in_table_d2(x):
|
||||
raise UnicodeEncodeError("idna", label, i, i+1,
|
||||
"Violation of BIDI requirement 2")
|
||||
# 3) If a string contains any RandALCat character, a
|
||||
# RandALCat character MUST be the first character of the
|
||||
# string, and a RandALCat character MUST be the last
|
||||
# character of the string.
|
||||
if not RandAL[0] or not RandAL[-1]:
|
||||
raise UnicodeError("Violation of BIDI requirement 3")
|
||||
if not RandAL[0]:
|
||||
raise UnicodeEncodeError("idna", label, 0, 1,
|
||||
"Violation of BIDI requirement 3")
|
||||
if not RandAL[-1]:
|
||||
raise UnicodeEncodeError("idna", label, len(label)-1, len(label),
|
||||
"Violation of BIDI requirement 3")
|
||||
|
||||
return label
|
||||
|
||||
def ToASCII(label):
|
||||
def ToASCII(label): # type: (str) -> bytes
|
||||
try:
|
||||
# Step 1: try ASCII
|
||||
label = label.encode("ascii")
|
||||
except UnicodeError:
|
||||
label_ascii = label.encode("ascii")
|
||||
except UnicodeEncodeError:
|
||||
pass
|
||||
else:
|
||||
# Skip to step 3: UseSTD3ASCIIRules is false, so
|
||||
# Skip to step 8.
|
||||
if 0 < len(label) < 64:
|
||||
return label
|
||||
raise UnicodeError("label empty or too long")
|
||||
if 0 < len(label_ascii) < 64:
|
||||
return label_ascii
|
||||
if len(label) == 0:
|
||||
raise UnicodeEncodeError("idna", label, 0, 1, "label empty")
|
||||
else:
|
||||
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
|
||||
|
||||
# Step 2: nameprep
|
||||
label = nameprep(label)
|
||||
@@ -76,29 +85,34 @@ def ToASCII(label):
|
||||
# Step 3: UseSTD3ASCIIRules is false
|
||||
# Step 4: try ASCII
|
||||
try:
|
||||
label = label.encode("ascii")
|
||||
except UnicodeError:
|
||||
label_ascii = label.encode("ascii")
|
||||
except UnicodeEncodeError:
|
||||
pass
|
||||
else:
|
||||
# Skip to step 8.
|
||||
if 0 < len(label) < 64:
|
||||
return label
|
||||
raise UnicodeError("label empty or too long")
|
||||
return label_ascii
|
||||
if len(label) == 0:
|
||||
raise UnicodeEncodeError("idna", label, 0, 1, "label empty")
|
||||
else:
|
||||
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
|
||||
|
||||
# Step 5: Check ACE prefix
|
||||
if label.startswith(sace_prefix):
|
||||
raise UnicodeError("Label starts with ACE prefix")
|
||||
if label.lower().startswith(sace_prefix):
|
||||
raise UnicodeEncodeError(
|
||||
"idna", label, 0, len(sace_prefix), "Label starts with ACE prefix")
|
||||
|
||||
# Step 6: Encode with PUNYCODE
|
||||
label = label.encode("punycode")
|
||||
label_ascii = label.encode("punycode")
|
||||
|
||||
# Step 7: Prepend ACE prefix
|
||||
label = ace_prefix + label
|
||||
label_ascii = ace_prefix + label_ascii
|
||||
|
||||
# Step 8: Check size
|
||||
if 0 < len(label) < 64:
|
||||
return label
|
||||
raise UnicodeError("label empty or too long")
|
||||
# do not check for empty as we prepend ace_prefix.
|
||||
if len(label_ascii) < 64:
|
||||
return label_ascii
|
||||
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
|
||||
|
||||
def ToUnicode(label):
|
||||
if len(label) > 1024:
|
||||
@@ -110,7 +124,9 @@ def ToUnicode(label):
|
||||
# per https://www.rfc-editor.org/rfc/rfc3454#section-3.1 while still
|
||||
# preventing us from wasting time decoding a big thing that'll just
|
||||
# hit the actual <= 63 length limit in Step 6.
|
||||
raise UnicodeError("label way too long")
|
||||
if isinstance(label, str):
|
||||
label = label.encode("utf-8", errors="backslashreplace")
|
||||
raise UnicodeDecodeError("idna", label, 0, len(label), "label way too long")
|
||||
# Step 1: Check for ASCII
|
||||
if isinstance(label, bytes):
|
||||
pure_ascii = True
|
||||
@@ -118,25 +134,32 @@ def ToUnicode(label):
|
||||
try:
|
||||
label = label.encode("ascii")
|
||||
pure_ascii = True
|
||||
except UnicodeError:
|
||||
except UnicodeEncodeError:
|
||||
pure_ascii = False
|
||||
if not pure_ascii:
|
||||
assert isinstance(label, str)
|
||||
# Step 2: Perform nameprep
|
||||
label = nameprep(label)
|
||||
# It doesn't say this, but apparently, it should be ASCII now
|
||||
try:
|
||||
label = label.encode("ascii")
|
||||
except UnicodeError:
|
||||
raise UnicodeError("Invalid character in IDN label")
|
||||
except UnicodeEncodeError as exc:
|
||||
raise UnicodeEncodeError("idna", label, exc.start, exc.end,
|
||||
"Invalid character in IDN label")
|
||||
# Step 3: Check for ACE prefix
|
||||
if not label.startswith(ace_prefix):
|
||||
assert isinstance(label, bytes)
|
||||
if not label.lower().startswith(ace_prefix):
|
||||
return str(label, "ascii")
|
||||
|
||||
# Step 4: Remove ACE prefix
|
||||
label1 = label[len(ace_prefix):]
|
||||
|
||||
# Step 5: Decode using PUNYCODE
|
||||
result = label1.decode("punycode")
|
||||
try:
|
||||
result = label1.decode("punycode")
|
||||
except UnicodeDecodeError as exc:
|
||||
offset = len(ace_prefix)
|
||||
raise UnicodeDecodeError("idna", label, offset+exc.start, offset+exc.end, exc.reason)
|
||||
|
||||
# Step 6: Apply ToASCII
|
||||
label2 = ToASCII(result)
|
||||
@@ -144,7 +167,8 @@ def ToUnicode(label):
|
||||
# Step 7: Compare the result of step 6 with the one of step 3
|
||||
# label2 will already be in lower case.
|
||||
if str(label, "ascii").lower() != str(label2, "ascii"):
|
||||
raise UnicodeError("IDNA does not round-trip", label, label2)
|
||||
raise UnicodeDecodeError("idna", label, 0, len(label),
|
||||
f"IDNA does not round-trip, '{label!r}' != '{label2!r}'")
|
||||
|
||||
# Step 8: return the result of step 5
|
||||
return result
|
||||
@@ -156,7 +180,7 @@ class Codec(codecs.Codec):
|
||||
|
||||
if errors != 'strict':
|
||||
# IDNA is quite clear that implementations must be strict
|
||||
raise UnicodeError("unsupported error handling "+errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {errors}")
|
||||
|
||||
if not input:
|
||||
return b'', 0
|
||||
@@ -168,11 +192,16 @@ class Codec(codecs.Codec):
|
||||
else:
|
||||
# ASCII name: fast path
|
||||
labels = result.split(b'.')
|
||||
for label in labels[:-1]:
|
||||
if not (0 < len(label) < 64):
|
||||
raise UnicodeError("label empty or too long")
|
||||
if len(labels[-1]) >= 64:
|
||||
raise UnicodeError("label too long")
|
||||
for i, label in enumerate(labels[:-1]):
|
||||
if len(label) == 0:
|
||||
offset = sum(len(l) for l in labels[:i]) + i
|
||||
raise UnicodeEncodeError("idna", input, offset, offset+1,
|
||||
"label empty")
|
||||
for i, label in enumerate(labels):
|
||||
if len(label) >= 64:
|
||||
offset = sum(len(l) for l in labels[:i]) + i
|
||||
raise UnicodeEncodeError("idna", input, offset, offset+len(label),
|
||||
"label too long")
|
||||
return result, len(input)
|
||||
|
||||
result = bytearray()
|
||||
@@ -182,17 +211,27 @@ class Codec(codecs.Codec):
|
||||
del labels[-1]
|
||||
else:
|
||||
trailing_dot = b''
|
||||
for label in labels:
|
||||
for i, label in enumerate(labels):
|
||||
if result:
|
||||
# Join with U+002E
|
||||
result.extend(b'.')
|
||||
result.extend(ToASCII(label))
|
||||
try:
|
||||
result.extend(ToASCII(label))
|
||||
except (UnicodeEncodeError, UnicodeDecodeError) as exc:
|
||||
offset = sum(len(l) for l in labels[:i]) + i
|
||||
raise UnicodeEncodeError(
|
||||
"idna",
|
||||
input,
|
||||
offset + exc.start,
|
||||
offset + exc.end,
|
||||
exc.reason,
|
||||
)
|
||||
return bytes(result+trailing_dot), len(input)
|
||||
|
||||
def decode(self, input, errors='strict'):
|
||||
|
||||
if errors != 'strict':
|
||||
raise UnicodeError("Unsupported error handling "+errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {errors}")
|
||||
|
||||
if not input:
|
||||
return "", 0
|
||||
@@ -202,7 +241,7 @@ class Codec(codecs.Codec):
|
||||
# XXX obviously wrong, see #3232
|
||||
input = bytes(input)
|
||||
|
||||
if ace_prefix not in input:
|
||||
if ace_prefix not in input.lower():
|
||||
# Fast path
|
||||
try:
|
||||
return input.decode('ascii'), len(input)
|
||||
@@ -218,8 +257,15 @@ class Codec(codecs.Codec):
|
||||
trailing_dot = ''
|
||||
|
||||
result = []
|
||||
for label in labels:
|
||||
result.append(ToUnicode(label))
|
||||
for i, label in enumerate(labels):
|
||||
try:
|
||||
u_label = ToUnicode(label)
|
||||
except (UnicodeEncodeError, UnicodeDecodeError) as exc:
|
||||
offset = sum(len(x) for x in labels[:i]) + len(labels[:i])
|
||||
raise UnicodeDecodeError(
|
||||
"idna", input, offset+exc.start, offset+exc.end, exc.reason)
|
||||
else:
|
||||
result.append(u_label)
|
||||
|
||||
return ".".join(result)+trailing_dot, len(input)
|
||||
|
||||
@@ -227,7 +273,7 @@ class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
|
||||
def _buffer_encode(self, input, errors, final):
|
||||
if errors != 'strict':
|
||||
# IDNA is quite clear that implementations must be strict
|
||||
raise UnicodeError("unsupported error handling "+errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {errors}")
|
||||
|
||||
if not input:
|
||||
return (b'', 0)
|
||||
@@ -251,7 +297,16 @@ class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
|
||||
# Join with U+002E
|
||||
result.extend(b'.')
|
||||
size += 1
|
||||
result.extend(ToASCII(label))
|
||||
try:
|
||||
result.extend(ToASCII(label))
|
||||
except (UnicodeEncodeError, UnicodeDecodeError) as exc:
|
||||
raise UnicodeEncodeError(
|
||||
"idna",
|
||||
input,
|
||||
size + exc.start,
|
||||
size + exc.end,
|
||||
exc.reason,
|
||||
)
|
||||
size += len(label)
|
||||
|
||||
result += trailing_dot
|
||||
@@ -261,7 +316,7 @@ class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
|
||||
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
||||
def _buffer_decode(self, input, errors, final):
|
||||
if errors != 'strict':
|
||||
raise UnicodeError("Unsupported error handling "+errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {errors}")
|
||||
|
||||
if not input:
|
||||
return ("", 0)
|
||||
@@ -271,7 +326,11 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
||||
labels = dots.split(input)
|
||||
else:
|
||||
# Must be ASCII string
|
||||
input = str(input, "ascii")
|
||||
try:
|
||||
input = str(input, "ascii")
|
||||
except (UnicodeEncodeError, UnicodeDecodeError) as exc:
|
||||
raise UnicodeDecodeError("idna", input,
|
||||
exc.start, exc.end, exc.reason)
|
||||
labels = input.split(".")
|
||||
|
||||
trailing_dot = ''
|
||||
@@ -288,7 +347,18 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
||||
result = []
|
||||
size = 0
|
||||
for label in labels:
|
||||
result.append(ToUnicode(label))
|
||||
try:
|
||||
u_label = ToUnicode(label)
|
||||
except (UnicodeEncodeError, UnicodeDecodeError) as exc:
|
||||
raise UnicodeDecodeError(
|
||||
"idna",
|
||||
input.encode("ascii", errors="backslashreplace"),
|
||||
size + exc.start,
|
||||
size + exc.end,
|
||||
exc.reason,
|
||||
)
|
||||
else:
|
||||
result.append(u_label)
|
||||
if size:
|
||||
size += 1
|
||||
size += len(label)
|
||||
|
||||
2
Lib/encodings/palmos.py
vendored
2
Lib/encodings/palmos.py
vendored
@@ -201,7 +201,7 @@ decoding_table = (
|
||||
'\u02dc' # 0x98 -> SMALL TILDE
|
||||
'\u2122' # 0x99 -> TRADE MARK SIGN
|
||||
'\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON
|
||||
'\x9b' # 0x9B -> <control>
|
||||
'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
'\u0153' # 0x9C -> LATIN SMALL LIGATURE OE
|
||||
'\x9d' # 0x9D -> <control>
|
||||
'\x9e' # 0x9E -> <control>
|
||||
|
||||
42
Lib/encodings/punycode.py
vendored
42
Lib/encodings/punycode.py
vendored
@@ -1,4 +1,4 @@
|
||||
""" Codec for the Punicode encoding, as specified in RFC 3492
|
||||
""" Codec for the Punycode encoding, as specified in RFC 3492
|
||||
|
||||
Written by Martin v. Löwis.
|
||||
"""
|
||||
@@ -131,10 +131,11 @@ def decode_generalized_number(extended, extpos, bias, errors):
|
||||
j = 0
|
||||
while 1:
|
||||
try:
|
||||
char = ord(extended[extpos])
|
||||
char = extended[extpos]
|
||||
except IndexError:
|
||||
if errors == "strict":
|
||||
raise UnicodeError("incomplete punicode string")
|
||||
raise UnicodeDecodeError("punycode", extended, extpos, extpos+1,
|
||||
"incomplete punycode string")
|
||||
return extpos + 1, None
|
||||
extpos += 1
|
||||
if 0x41 <= char <= 0x5A: # A-Z
|
||||
@@ -142,8 +143,8 @@ def decode_generalized_number(extended, extpos, bias, errors):
|
||||
elif 0x30 <= char <= 0x39:
|
||||
digit = char - 22 # 0x30-26
|
||||
elif errors == "strict":
|
||||
raise UnicodeError("Invalid extended code point '%s'"
|
||||
% extended[extpos-1])
|
||||
raise UnicodeDecodeError("punycode", extended, extpos-1, extpos,
|
||||
f"Invalid extended code point '{extended[extpos-1]}'")
|
||||
else:
|
||||
return extpos, None
|
||||
t = T(j, bias)
|
||||
@@ -155,11 +156,14 @@ def decode_generalized_number(extended, extpos, bias, errors):
|
||||
|
||||
|
||||
def insertion_sort(base, extended, errors):
|
||||
"""3.2 Insertion unsort coding"""
|
||||
"""3.2 Insertion sort coding"""
|
||||
# This function raises UnicodeDecodeError with position in the extended.
|
||||
# Caller should add the offset.
|
||||
char = 0x80
|
||||
pos = -1
|
||||
bias = 72
|
||||
extpos = 0
|
||||
|
||||
while extpos < len(extended):
|
||||
newpos, delta = decode_generalized_number(extended, extpos,
|
||||
bias, errors)
|
||||
@@ -171,7 +175,9 @@ def insertion_sort(base, extended, errors):
|
||||
char += pos // (len(base) + 1)
|
||||
if char > 0x10FFFF:
|
||||
if errors == "strict":
|
||||
raise UnicodeError("Invalid character U+%x" % char)
|
||||
raise UnicodeDecodeError(
|
||||
"punycode", extended, pos-1, pos,
|
||||
f"Invalid character U+{char:x}")
|
||||
char = ord('?')
|
||||
pos = pos % (len(base) + 1)
|
||||
base = base[:pos] + chr(char) + base[pos:]
|
||||
@@ -187,11 +193,21 @@ def punycode_decode(text, errors):
|
||||
pos = text.rfind(b"-")
|
||||
if pos == -1:
|
||||
base = ""
|
||||
extended = str(text, "ascii").upper()
|
||||
extended = text.upper()
|
||||
else:
|
||||
base = str(text[:pos], "ascii", errors)
|
||||
extended = str(text[pos+1:], "ascii").upper()
|
||||
return insertion_sort(base, extended, errors)
|
||||
try:
|
||||
base = str(text[:pos], "ascii", errors)
|
||||
except UnicodeDecodeError as exc:
|
||||
raise UnicodeDecodeError("ascii", text, exc.start, exc.end,
|
||||
exc.reason) from None
|
||||
extended = text[pos+1:].upper()
|
||||
try:
|
||||
return insertion_sort(base, extended, errors)
|
||||
except UnicodeDecodeError as exc:
|
||||
offset = pos + 1
|
||||
raise UnicodeDecodeError("punycode", text,
|
||||
offset+exc.start, offset+exc.end,
|
||||
exc.reason) from None
|
||||
|
||||
### Codec APIs
|
||||
|
||||
@@ -203,7 +219,7 @@ class Codec(codecs.Codec):
|
||||
|
||||
def decode(self, input, errors='strict'):
|
||||
if errors not in ('strict', 'replace', 'ignore'):
|
||||
raise UnicodeError("Unsupported error handling "+errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {errors}")
|
||||
res = punycode_decode(input, errors)
|
||||
return res, len(input)
|
||||
|
||||
@@ -214,7 +230,7 @@ class IncrementalEncoder(codecs.IncrementalEncoder):
|
||||
class IncrementalDecoder(codecs.IncrementalDecoder):
|
||||
def decode(self, input, final=False):
|
||||
if self.errors not in ('strict', 'replace', 'ignore'):
|
||||
raise UnicodeError("Unsupported error handling "+self.errors)
|
||||
raise UnicodeError(f"Unsupported error handling: {self.errors}")
|
||||
return punycode_decode(input, self.errors)
|
||||
|
||||
class StreamWriter(Codec,codecs.StreamWriter):
|
||||
|
||||
2
Lib/encodings/undefined.py
vendored
2
Lib/encodings/undefined.py
vendored
@@ -1,6 +1,6 @@
|
||||
""" Python 'undefined' Codec
|
||||
|
||||
This codec will always raise a ValueError exception when being
|
||||
This codec will always raise a UnicodeError exception when being
|
||||
used. It is intended for use by the site.py file to switch off
|
||||
automatic string to Unicode coercion.
|
||||
|
||||
|
||||
4
Lib/encodings/utf_16.py
vendored
4
Lib/encodings/utf_16.py
vendored
@@ -64,7 +64,7 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
||||
elif byteorder == 1:
|
||||
self.decoder = codecs.utf_16_be_decode
|
||||
elif consumed >= 2:
|
||||
raise UnicodeError("UTF-16 stream does not start with BOM")
|
||||
raise UnicodeDecodeError("utf-16", input, 0, 2, "Stream does not start with BOM")
|
||||
return (output, consumed)
|
||||
return self.decoder(input, self.errors, final)
|
||||
|
||||
@@ -138,7 +138,7 @@ class StreamReader(codecs.StreamReader):
|
||||
elif byteorder == 1:
|
||||
self.decode = codecs.utf_16_be_decode
|
||||
elif consumed>=2:
|
||||
raise UnicodeError("UTF-16 stream does not start with BOM")
|
||||
raise UnicodeDecodeError("utf-16", input, 0, 2, "Stream does not start with BOM")
|
||||
return (object, consumed)
|
||||
|
||||
### encodings module API
|
||||
|
||||
6
Lib/encodings/utf_32.py
vendored
6
Lib/encodings/utf_32.py
vendored
@@ -59,7 +59,7 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
|
||||
elif byteorder == 1:
|
||||
self.decoder = codecs.utf_32_be_decode
|
||||
elif consumed >= 4:
|
||||
raise UnicodeError("UTF-32 stream does not start with BOM")
|
||||
raise UnicodeDecodeError("utf-32", input, 0, 4, "Stream does not start with BOM")
|
||||
return (output, consumed)
|
||||
return self.decoder(input, self.errors, final)
|
||||
|
||||
@@ -132,8 +132,8 @@ class StreamReader(codecs.StreamReader):
|
||||
self.decode = codecs.utf_32_le_decode
|
||||
elif byteorder == 1:
|
||||
self.decode = codecs.utf_32_be_decode
|
||||
elif consumed>=4:
|
||||
raise UnicodeError("UTF-32 stream does not start with BOM")
|
||||
elif consumed >= 4:
|
||||
raise UnicodeDecodeError("utf-32", input, 0, 4, "Stream does not start with BOM")
|
||||
return (object, consumed)
|
||||
|
||||
### encodings module API
|
||||
|
||||
123
Lib/ensurepip/__init__.py
vendored
123
Lib/ensurepip/__init__.py
vendored
@@ -1,78 +1,64 @@
|
||||
import collections
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import tempfile
|
||||
from contextlib import nullcontext
|
||||
from importlib import resources
|
||||
from pathlib import Path
|
||||
from shutil import copy2
|
||||
|
||||
|
||||
__all__ = ["version", "bootstrap"]
|
||||
_PACKAGE_NAMES = ('pip',)
|
||||
_PIP_VERSION = "23.2.1"
|
||||
_PROJECTS = [
|
||||
("pip", _PIP_VERSION, "py3"),
|
||||
]
|
||||
|
||||
# Packages bundled in ensurepip._bundled have wheel_name set.
|
||||
# Packages from WHEEL_PKG_DIR have wheel_path set.
|
||||
_Package = collections.namedtuple('Package',
|
||||
('version', 'wheel_name', 'wheel_path'))
|
||||
_PIP_VERSION = "25.2"
|
||||
|
||||
# Directory of system wheel packages. Some Linux distribution packaging
|
||||
# policies recommend against bundling dependencies. For example, Fedora
|
||||
# installs wheel packages in the /usr/share/python-wheels/ directory and don't
|
||||
# install the ensurepip._bundled package.
|
||||
_WHEEL_PKG_DIR = sysconfig.get_config_var('WHEEL_PKG_DIR')
|
||||
if (_pkg_dir := sysconfig.get_config_var('WHEEL_PKG_DIR')) is not None:
|
||||
_WHEEL_PKG_DIR = Path(_pkg_dir).resolve()
|
||||
else:
|
||||
_WHEEL_PKG_DIR = None
|
||||
|
||||
|
||||
def _find_packages(path):
|
||||
packages = {}
|
||||
def _find_wheel_pkg_dir_pip():
|
||||
if _WHEEL_PKG_DIR is None:
|
||||
# NOTE: The compile-time `WHEEL_PKG_DIR` is unset so there is no place
|
||||
# NOTE: for looking up the wheels.
|
||||
return None
|
||||
|
||||
dist_matching_wheels = _WHEEL_PKG_DIR.glob('pip-*.whl')
|
||||
try:
|
||||
filenames = os.listdir(path)
|
||||
except OSError:
|
||||
# Ignore: path doesn't exist or permission error
|
||||
filenames = ()
|
||||
# Make the code deterministic if a directory contains multiple wheel files
|
||||
# of the same package, but don't attempt to implement correct version
|
||||
# comparison since this case should not happen.
|
||||
filenames = sorted(filenames)
|
||||
for filename in filenames:
|
||||
# filename is like 'pip-21.2.4-py3-none-any.whl'
|
||||
if not filename.endswith(".whl"):
|
||||
continue
|
||||
for name in _PACKAGE_NAMES:
|
||||
prefix = name + '-'
|
||||
if filename.startswith(prefix):
|
||||
break
|
||||
else:
|
||||
continue
|
||||
last_matching_dist_wheel = sorted(dist_matching_wheels)[-1]
|
||||
except IndexError:
|
||||
# NOTE: `WHEEL_PKG_DIR` does not contain any wheel files for `pip`.
|
||||
return None
|
||||
|
||||
# Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl'
|
||||
version = filename.removeprefix(prefix).partition('-')[0]
|
||||
wheel_path = os.path.join(path, filename)
|
||||
packages[name] = _Package(version, None, wheel_path)
|
||||
return packages
|
||||
return nullcontext(last_matching_dist_wheel)
|
||||
|
||||
|
||||
def _get_packages():
|
||||
global _PACKAGES, _WHEEL_PKG_DIR
|
||||
if _PACKAGES is not None:
|
||||
return _PACKAGES
|
||||
def _get_pip_whl_path_ctx():
|
||||
# Prefer pip from the wheel package directory, if present.
|
||||
if (alternative_pip_wheel_path := _find_wheel_pkg_dir_pip()) is not None:
|
||||
return alternative_pip_wheel_path
|
||||
|
||||
packages = {}
|
||||
for name, version, py_tag in _PROJECTS:
|
||||
wheel_name = f"{name}-{version}-{py_tag}-none-any.whl"
|
||||
packages[name] = _Package(version, wheel_name, None)
|
||||
if _WHEEL_PKG_DIR:
|
||||
dir_packages = _find_packages(_WHEEL_PKG_DIR)
|
||||
# only used the wheel package directory if all packages are found there
|
||||
if all(name in dir_packages for name in _PACKAGE_NAMES):
|
||||
packages = dir_packages
|
||||
_PACKAGES = packages
|
||||
return packages
|
||||
_PACKAGES = None
|
||||
return resources.as_file(
|
||||
resources.files('ensurepip')
|
||||
/ '_bundled'
|
||||
/ f'pip-{_PIP_VERSION}-py3-none-any.whl'
|
||||
)
|
||||
|
||||
|
||||
def _get_pip_version():
|
||||
with _get_pip_whl_path_ctx() as bundled_wheel_path:
|
||||
wheel_name = bundled_wheel_path.name
|
||||
return (
|
||||
# Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl'
|
||||
wheel_name.
|
||||
removeprefix('pip-').
|
||||
partition('-')[0]
|
||||
)
|
||||
|
||||
|
||||
def _run_pip(args, additional_paths=None):
|
||||
@@ -105,7 +91,7 @@ def version():
|
||||
"""
|
||||
Returns a string specifying the bundled version of pip.
|
||||
"""
|
||||
return _get_packages()['pip'].version
|
||||
return _get_pip_version()
|
||||
|
||||
|
||||
def _disable_pip_configuration_settings():
|
||||
@@ -167,24 +153,10 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
# Put our bundled wheels into a temporary directory and construct the
|
||||
# additional paths that need added to sys.path
|
||||
additional_paths = []
|
||||
for name, package in _get_packages().items():
|
||||
if package.wheel_name:
|
||||
# Use bundled wheel package
|
||||
wheel_name = package.wheel_name
|
||||
wheel_path = resources.files("ensurepip") / "_bundled" / wheel_name
|
||||
whl = wheel_path.read_bytes()
|
||||
else:
|
||||
# Use the wheel package directory
|
||||
with open(package.wheel_path, "rb") as fp:
|
||||
whl = fp.read()
|
||||
wheel_name = os.path.basename(package.wheel_path)
|
||||
|
||||
filename = os.path.join(tmpdir, wheel_name)
|
||||
with open(filename, "wb") as fp:
|
||||
fp.write(whl)
|
||||
|
||||
additional_paths.append(filename)
|
||||
tmpdir_path = Path(tmpdir)
|
||||
with _get_pip_whl_path_ctx() as bundled_wheel_path:
|
||||
tmp_wheel_path = tmpdir_path / bundled_wheel_path.name
|
||||
copy2(bundled_wheel_path, tmp_wheel_path)
|
||||
|
||||
# Construct the arguments to be passed to the pip command
|
||||
args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
|
||||
@@ -197,7 +169,8 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
|
||||
if verbosity:
|
||||
args += ["-" + "v" * verbosity]
|
||||
|
||||
return _run_pip([*args, *_PACKAGE_NAMES], additional_paths)
|
||||
return _run_pip([*args, "pip"], [os.fsdecode(tmp_wheel_path)])
|
||||
|
||||
|
||||
def _uninstall_helper(*, verbosity=0):
|
||||
"""Helper to support a clean default uninstall process on Windows
|
||||
@@ -227,7 +200,7 @@ def _uninstall_helper(*, verbosity=0):
|
||||
if verbosity:
|
||||
args += ["-" + "v" * verbosity]
|
||||
|
||||
return _run_pip([*args, *reversed(_PACKAGE_NAMES)])
|
||||
return _run_pip([*args, "pip"])
|
||||
|
||||
|
||||
def _main(argv=None):
|
||||
|
||||
BIN
Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl
vendored
BIN
Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl
vendored
Binary file not shown.
BIN
Lib/ensurepip/_bundled/pip-25.2-py3-none-any.whl
vendored
Normal file
BIN
Lib/ensurepip/_bundled/pip-25.2-py3-none-any.whl
vendored
Normal file
Binary file not shown.
37
Lib/fnmatch.py
vendored
37
Lib/fnmatch.py
vendored
@@ -16,12 +16,6 @@ import functools
|
||||
|
||||
__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"]
|
||||
|
||||
# Build a thread-safe incrementing counter to help create unique regexp group
|
||||
# names across calls.
|
||||
from itertools import count
|
||||
_nextgroupnum = count().__next__
|
||||
del count
|
||||
|
||||
def fnmatch(name, pat):
|
||||
"""Test whether FILENAME matches PATTERN.
|
||||
|
||||
@@ -41,7 +35,7 @@ def fnmatch(name, pat):
|
||||
pat = os.path.normcase(pat)
|
||||
return fnmatchcase(name, pat)
|
||||
|
||||
@functools.lru_cache(maxsize=256, typed=True)
|
||||
@functools.lru_cache(maxsize=32768, typed=True)
|
||||
def _compile_pattern(pat):
|
||||
if isinstance(pat, bytes):
|
||||
pat_str = str(pat, 'ISO-8859-1')
|
||||
@@ -84,6 +78,11 @@ def translate(pat):
|
||||
"""
|
||||
|
||||
STAR = object()
|
||||
parts = _translate(pat, STAR, '.')
|
||||
return _join_translated_parts(parts, STAR)
|
||||
|
||||
|
||||
def _translate(pat, STAR, QUESTION_MARK):
|
||||
res = []
|
||||
add = res.append
|
||||
i, n = 0, len(pat)
|
||||
@@ -95,7 +94,7 @@ def translate(pat):
|
||||
if (not res) or res[-1] is not STAR:
|
||||
add(STAR)
|
||||
elif c == '?':
|
||||
add('.')
|
||||
add(QUESTION_MARK)
|
||||
elif c == '[':
|
||||
j = i
|
||||
if j < n and pat[j] == '!':
|
||||
@@ -152,9 +151,11 @@ def translate(pat):
|
||||
else:
|
||||
add(re.escape(c))
|
||||
assert i == n
|
||||
return res
|
||||
|
||||
|
||||
def _join_translated_parts(inp, STAR):
|
||||
# Deal with STARs.
|
||||
inp = res
|
||||
res = []
|
||||
add = res.append
|
||||
i, n = 0, len(inp)
|
||||
@@ -165,17 +166,10 @@ def translate(pat):
|
||||
# Now deal with STAR fixed STAR fixed ...
|
||||
# For an interior `STAR fixed` pairing, we want to do a minimal
|
||||
# .*? match followed by `fixed`, with no possibility of backtracking.
|
||||
# We can't spell that directly, but can trick it into working by matching
|
||||
# .*?fixed
|
||||
# in a lookahead assertion, save the matched part in a group, then
|
||||
# consume that group via a backreference. If the overall match fails,
|
||||
# the lookahead assertion won't try alternatives. So the translation is:
|
||||
# (?=(?P<name>.*?fixed))(?P=name)
|
||||
# Group names are created as needed: g0, g1, g2, ...
|
||||
# The numbers are obtained from _nextgroupnum() to ensure they're unique
|
||||
# across calls and across threads. This is because people rely on the
|
||||
# undocumented ability to join multiple translate() results together via
|
||||
# "|" to build large regexps matching "one of many" shell patterns.
|
||||
# Atomic groups ("(?>...)") allow us to spell that directly.
|
||||
# Note: people rely on the undocumented ability to join multiple
|
||||
# translate() results together via "|" to build large regexps matching
|
||||
# "one of many" shell patterns.
|
||||
while i < n:
|
||||
assert inp[i] is STAR
|
||||
i += 1
|
||||
@@ -192,8 +186,7 @@ def translate(pat):
|
||||
add(".*")
|
||||
add(fixed)
|
||||
else:
|
||||
groupnum = _nextgroupnum()
|
||||
add(f"(?=(?P<g{groupnum}>.*?{fixed}))(?P=g{groupnum})")
|
||||
add(f"(?>.*?{fixed})")
|
||||
assert i == n
|
||||
res = "".join(res)
|
||||
return fr'(?s:{res})\Z'
|
||||
|
||||
91
Lib/functools.py
vendored
91
Lib/functools.py
vendored
@@ -19,8 +19,9 @@ from collections import namedtuple
|
||||
# import types, weakref # Deferred to single_dispatch()
|
||||
from reprlib import recursive_repr
|
||||
from _thread import RLock
|
||||
from types import GenericAlias
|
||||
|
||||
# Avoid importing types, so we can speedup import time
|
||||
GenericAlias = type(list[int])
|
||||
|
||||
################################################################################
|
||||
### update_wrapper() and wraps() decorator
|
||||
@@ -236,14 +237,16 @@ _initial_missing = object()
|
||||
|
||||
def reduce(function, sequence, initial=_initial_missing):
|
||||
"""
|
||||
reduce(function, iterable[, initial]) -> value
|
||||
reduce(function, iterable[, initial], /) -> value
|
||||
|
||||
Apply a function of two arguments cumulatively to the items of a sequence
|
||||
or iterable, from left to right, so as to reduce the iterable to a single
|
||||
value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
|
||||
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
|
||||
of the iterable in the calculation, and serves as a default when the
|
||||
iterable is empty.
|
||||
Apply a function of two arguments cumulatively to the items of an iterable, from left to right.
|
||||
|
||||
This effectively reduces the iterable to a single value. If initial is present,
|
||||
it is placed before the items of the iterable in the calculation, and serves as
|
||||
a default when the iterable is empty.
|
||||
|
||||
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
|
||||
calculates ((((1 + 2) + 3) + 4) + 5).
|
||||
"""
|
||||
|
||||
it = iter(sequence)
|
||||
@@ -284,7 +287,7 @@ class partial:
|
||||
if not callable(func):
|
||||
raise TypeError("the first argument must be callable")
|
||||
|
||||
if hasattr(func, "func"):
|
||||
if isinstance(func, partial):
|
||||
args = func.args + args
|
||||
keywords = {**func.keywords, **keywords}
|
||||
func = func.func
|
||||
@@ -302,13 +305,23 @@ class partial:
|
||||
|
||||
@recursive_repr()
|
||||
def __repr__(self):
|
||||
qualname = type(self).__qualname__
|
||||
cls = type(self)
|
||||
qualname = cls.__qualname__
|
||||
module = cls.__module__
|
||||
args = [repr(self.func)]
|
||||
args.extend(repr(x) for x in self.args)
|
||||
args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items())
|
||||
if type(self).__module__ == "functools":
|
||||
return f"functools.{qualname}({', '.join(args)})"
|
||||
return f"{qualname}({', '.join(args)})"
|
||||
return f"{module}.{qualname}({', '.join(args)})"
|
||||
|
||||
def __get__(self, obj, objtype=None):
|
||||
if obj is None:
|
||||
return self
|
||||
import warnings
|
||||
warnings.warn('functools.partial will be a method descriptor in '
|
||||
'future Python versions; wrap it in staticmethod() '
|
||||
'if you want to preserve the old behavior',
|
||||
FutureWarning, 2)
|
||||
return self
|
||||
|
||||
def __reduce__(self):
|
||||
return type(self), (self.func,), (self.func, self.args,
|
||||
@@ -338,6 +351,9 @@ class partial:
|
||||
self.args = args
|
||||
self.keywords = kwds
|
||||
|
||||
__class_getitem__ = classmethod(GenericAlias)
|
||||
|
||||
|
||||
try:
|
||||
from _functools import partial
|
||||
except ImportError:
|
||||
@@ -372,28 +388,26 @@ class partialmethod(object):
|
||||
self.keywords = keywords
|
||||
|
||||
def __repr__(self):
|
||||
args = ", ".join(map(repr, self.args))
|
||||
keywords = ", ".join("{}={!r}".format(k, v)
|
||||
for k, v in self.keywords.items())
|
||||
format_string = "{module}.{cls}({func}, {args}, {keywords})"
|
||||
return format_string.format(module=self.__class__.__module__,
|
||||
cls=self.__class__.__qualname__,
|
||||
func=self.func,
|
||||
args=args,
|
||||
keywords=keywords)
|
||||
cls = type(self)
|
||||
module = cls.__module__
|
||||
qualname = cls.__qualname__
|
||||
args = [repr(self.func)]
|
||||
args.extend(map(repr, self.args))
|
||||
args.extend(f"{k}={v!r}" for k, v in self.keywords.items())
|
||||
return f"{module}.{qualname}({', '.join(args)})"
|
||||
|
||||
def _make_unbound_method(self):
|
||||
def _method(cls_or_self, /, *args, **keywords):
|
||||
keywords = {**self.keywords, **keywords}
|
||||
return self.func(cls_or_self, *self.args, *args, **keywords)
|
||||
_method.__isabstractmethod__ = self.__isabstractmethod__
|
||||
_method._partialmethod = self
|
||||
_method.__partialmethod__ = self
|
||||
return _method
|
||||
|
||||
def __get__(self, obj, cls=None):
|
||||
get = getattr(self.func, "__get__", None)
|
||||
result = None
|
||||
if get is not None:
|
||||
if get is not None and not isinstance(self.func, partial):
|
||||
new_func = get(obj, cls)
|
||||
if new_func is not self.func:
|
||||
# Assume __get__ returning something new indicates the
|
||||
@@ -423,6 +437,17 @@ def _unwrap_partial(func):
|
||||
func = func.func
|
||||
return func
|
||||
|
||||
def _unwrap_partialmethod(func):
|
||||
prev = None
|
||||
while func is not prev:
|
||||
prev = func
|
||||
while isinstance(getattr(func, "__partialmethod__", None), partialmethod):
|
||||
func = func.__partialmethod__
|
||||
while isinstance(func, partialmethod):
|
||||
func = getattr(func, 'func')
|
||||
func = _unwrap_partial(func)
|
||||
return func
|
||||
|
||||
################################################################################
|
||||
### LRU Cache function decorator
|
||||
################################################################################
|
||||
@@ -483,8 +508,9 @@ def lru_cache(maxsize=128, typed=False):
|
||||
can grow without bound.
|
||||
|
||||
If *typed* is True, arguments of different types will be cached separately.
|
||||
For example, f(3.0) and f(3) will be treated as distinct calls with
|
||||
distinct results.
|
||||
For example, f(decimal.Decimal("3.0")) and f(3.0) will be treated as
|
||||
distinct calls with distinct results. Some types such as str and int may
|
||||
be cached separately even when typed is false.
|
||||
|
||||
Arguments to the cached function must be hashable.
|
||||
|
||||
@@ -660,7 +686,7 @@ def cache(user_function, /):
|
||||
def _c3_merge(sequences):
|
||||
"""Merges MROs in *sequences* to a single MRO using the C3 algorithm.
|
||||
|
||||
Adapted from https://www.python.org/download/releases/2.3/mro/.
|
||||
Adapted from https://docs.python.org/3/howto/mro.html.
|
||||
|
||||
"""
|
||||
result = []
|
||||
@@ -905,7 +931,6 @@ def singledispatch(func):
|
||||
if not args:
|
||||
raise TypeError(f'{funcname} requires at least '
|
||||
'1 positional argument')
|
||||
|
||||
return dispatch(args[0].__class__)(*args, **kw)
|
||||
|
||||
funcname = getattr(func, '__name__', 'singledispatch function')
|
||||
@@ -941,13 +966,18 @@ class singledispatchmethod:
|
||||
return self.dispatcher.register(cls, func=method)
|
||||
|
||||
def __get__(self, obj, cls=None):
|
||||
dispatch = self.dispatcher.dispatch
|
||||
funcname = getattr(self.func, '__name__', 'singledispatchmethod method')
|
||||
def _method(*args, **kwargs):
|
||||
method = self.dispatcher.dispatch(args[0].__class__)
|
||||
return method.__get__(obj, cls)(*args, **kwargs)
|
||||
if not args:
|
||||
raise TypeError(f'{funcname} requires at least '
|
||||
'1 positional argument')
|
||||
return dispatch(args[0].__class__).__get__(obj, cls)(*args, **kwargs)
|
||||
|
||||
_method.__isabstractmethod__ = self.__isabstractmethod__
|
||||
_method.register = self.register
|
||||
update_wrapper(_method, self.func)
|
||||
|
||||
return _method
|
||||
|
||||
@property
|
||||
@@ -966,6 +996,7 @@ class cached_property:
|
||||
self.func = func
|
||||
self.attrname = None
|
||||
self.__doc__ = func.__doc__
|
||||
self.__module__ = func.__module__
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
if self.attrname is None:
|
||||
|
||||
37
Lib/genericpath.py
vendored
37
Lib/genericpath.py
vendored
@@ -7,8 +7,8 @@ import os
|
||||
import stat
|
||||
|
||||
__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
|
||||
'getsize', 'isdir', 'isfile', 'islink', 'samefile', 'sameopenfile',
|
||||
'samestat']
|
||||
'getsize', 'isdevdrive', 'isdir', 'isfile', 'isjunction', 'islink',
|
||||
'lexists', 'samefile', 'sameopenfile', 'samestat', 'ALLOW_MISSING']
|
||||
|
||||
|
||||
# Does a path exist?
|
||||
@@ -22,6 +22,15 @@ def exists(path):
|
||||
return True
|
||||
|
||||
|
||||
# Being true for dangling symbolic links is also useful.
|
||||
def lexists(path):
|
||||
"""Test whether a path exists. Returns True for broken symbolic links"""
|
||||
try:
|
||||
os.lstat(path)
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
return True
|
||||
|
||||
# This follows symbolic links, so both islink() and isdir() can be true
|
||||
# for the same path on systems that support symlinks
|
||||
def isfile(path):
|
||||
@@ -57,6 +66,21 @@ def islink(path):
|
||||
return stat.S_ISLNK(st.st_mode)
|
||||
|
||||
|
||||
# Is a path a junction?
|
||||
def isjunction(path):
|
||||
"""Test whether a path is a junction
|
||||
Junctions are not supported on the current platform"""
|
||||
os.fspath(path)
|
||||
return False
|
||||
|
||||
|
||||
def isdevdrive(path):
|
||||
"""Determines whether the specified path is on a Windows Dev Drive.
|
||||
Dev Drives are not supported on the current platform"""
|
||||
os.fspath(path)
|
||||
return False
|
||||
|
||||
|
||||
def getsize(filename):
|
||||
"""Return the size of a file, reported by os.stat()."""
|
||||
return os.stat(filename).st_size
|
||||
@@ -165,3 +189,12 @@ def _check_arg_types(funcname, *args):
|
||||
f'os.PathLike object, not {s.__class__.__name__!r}') from None
|
||||
if hasstr and hasbytes:
|
||||
raise TypeError("Can't mix strings and bytes in path components") from None
|
||||
|
||||
# A singleton with a true boolean value.
|
||||
@object.__new__
|
||||
class ALLOW_MISSING:
|
||||
"""Special value for use in realpath()."""
|
||||
def __repr__(self):
|
||||
return 'os.path.ALLOW_MISSING'
|
||||
def __reduce__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
25
Lib/gettext.py
vendored
25
Lib/gettext.py
vendored
@@ -46,6 +46,7 @@ internationalized, to the local language and cultural habits.
|
||||
# find this format documented anywhere.
|
||||
|
||||
|
||||
import operator
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
@@ -166,14 +167,28 @@ def _parse(tokens, priority=-1):
|
||||
|
||||
def _as_int(n):
|
||||
try:
|
||||
i = round(n)
|
||||
round(n)
|
||||
except TypeError:
|
||||
raise TypeError('Plural value must be an integer, got %s' %
|
||||
(n.__class__.__name__,)) from None
|
||||
return _as_int2(n)
|
||||
|
||||
def _as_int2(n):
|
||||
try:
|
||||
return operator.index(n)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
import warnings
|
||||
frame = sys._getframe(1)
|
||||
stacklevel = 2
|
||||
while frame.f_back is not None and frame.f_globals.get('__name__') == __name__:
|
||||
stacklevel += 1
|
||||
frame = frame.f_back
|
||||
warnings.warn('Plural value must be an integer, got %s' %
|
||||
(n.__class__.__name__,),
|
||||
DeprecationWarning, 4)
|
||||
DeprecationWarning,
|
||||
stacklevel)
|
||||
return n
|
||||
|
||||
|
||||
@@ -200,7 +215,7 @@ def c2py(plural):
|
||||
elif c == ')':
|
||||
depth -= 1
|
||||
|
||||
ns = {'_as_int': _as_int}
|
||||
ns = {'_as_int': _as_int, '__name__': __name__}
|
||||
exec('''if True:
|
||||
def func(n):
|
||||
if not isinstance(n, int):
|
||||
@@ -280,6 +295,7 @@ class NullTranslations:
|
||||
def ngettext(self, msgid1, msgid2, n):
|
||||
if self._fallback:
|
||||
return self._fallback.ngettext(msgid1, msgid2, n)
|
||||
n = _as_int2(n)
|
||||
if n == 1:
|
||||
return msgid1
|
||||
else:
|
||||
@@ -293,6 +309,7 @@ class NullTranslations:
|
||||
def npgettext(self, context, msgid1, msgid2, n):
|
||||
if self._fallback:
|
||||
return self._fallback.npgettext(context, msgid1, msgid2, n)
|
||||
n = _as_int2(n)
|
||||
if n == 1:
|
||||
return msgid1
|
||||
else:
|
||||
@@ -579,6 +596,7 @@ def dngettext(domain, msgid1, msgid2, n):
|
||||
try:
|
||||
t = translation(domain, _localedirs.get(domain, None))
|
||||
except OSError:
|
||||
n = _as_int2(n)
|
||||
if n == 1:
|
||||
return msgid1
|
||||
else:
|
||||
@@ -598,6 +616,7 @@ def dnpgettext(domain, context, msgid1, msgid2, n):
|
||||
try:
|
||||
t = translation(domain, _localedirs.get(domain, None))
|
||||
except OSError:
|
||||
n = _as_int2(n)
|
||||
if n == 1:
|
||||
return msgid1
|
||||
else:
|
||||
|
||||
301
Lib/glob.py
vendored
301
Lib/glob.py
vendored
@@ -4,11 +4,14 @@ import contextlib
|
||||
import os
|
||||
import re
|
||||
import fnmatch
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
import stat
|
||||
import sys
|
||||
|
||||
__all__ = ["glob", "iglob", "escape"]
|
||||
|
||||
__all__ = ["glob", "iglob", "escape", "translate"]
|
||||
|
||||
def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False,
|
||||
include_hidden=False):
|
||||
@@ -104,8 +107,8 @@ def _iglob(pathname, root_dir, dir_fd, recursive, dironly,
|
||||
|
||||
def _glob1(dirname, pattern, dir_fd, dironly, include_hidden=False):
|
||||
names = _listdir(dirname, dir_fd, dironly)
|
||||
if include_hidden or not _ishidden(pattern):
|
||||
names = (x for x in names if include_hidden or not _ishidden(x))
|
||||
if not (include_hidden or _ishidden(pattern)):
|
||||
names = (x for x in names if not _ishidden(x))
|
||||
return fnmatch.filter(names, pattern)
|
||||
|
||||
def _glob0(dirname, basename, dir_fd, dironly, include_hidden=False):
|
||||
@@ -119,12 +122,19 @@ def _glob0(dirname, basename, dir_fd, dironly, include_hidden=False):
|
||||
return [basename]
|
||||
return []
|
||||
|
||||
# Following functions are not public but can be used by third-party code.
|
||||
_deprecated_function_message = (
|
||||
"{name} is deprecated and will be removed in Python {remove}. Use "
|
||||
"glob.glob and pass a directory to its root_dir argument instead."
|
||||
)
|
||||
|
||||
def glob0(dirname, pattern):
|
||||
import warnings
|
||||
warnings._deprecated("glob.glob0", _deprecated_function_message, remove=(3, 15))
|
||||
return _glob0(dirname, pattern, None, False)
|
||||
|
||||
def glob1(dirname, pattern):
|
||||
import warnings
|
||||
warnings._deprecated("glob.glob1", _deprecated_function_message, remove=(3, 15))
|
||||
return _glob1(dirname, pattern, None, False)
|
||||
|
||||
# This helper function recursively yields relative pathnames inside a literal
|
||||
@@ -249,4 +259,287 @@ def escape(pathname):
|
||||
return drive + pathname
|
||||
|
||||
|
||||
_special_parts = ('', '.', '..')
|
||||
_dir_open_flags = os.O_RDONLY | getattr(os, 'O_DIRECTORY', 0)
|
||||
_no_recurse_symlinks = object()
|
||||
|
||||
|
||||
def translate(pat, *, recursive=False, include_hidden=False, seps=None):
|
||||
"""Translate a pathname with shell wildcards to a regular expression.
|
||||
|
||||
If `recursive` is true, the pattern segment '**' will match any number of
|
||||
path segments.
|
||||
|
||||
If `include_hidden` is true, wildcards can match path segments beginning
|
||||
with a dot ('.').
|
||||
|
||||
If a sequence of separator characters is given to `seps`, they will be
|
||||
used to split the pattern into segments and match path separators. If not
|
||||
given, os.path.sep and os.path.altsep (where available) are used.
|
||||
"""
|
||||
if not seps:
|
||||
if os.path.altsep:
|
||||
seps = (os.path.sep, os.path.altsep)
|
||||
else:
|
||||
seps = os.path.sep
|
||||
escaped_seps = ''.join(map(re.escape, seps))
|
||||
any_sep = f'[{escaped_seps}]' if len(seps) > 1 else escaped_seps
|
||||
not_sep = f'[^{escaped_seps}]'
|
||||
if include_hidden:
|
||||
one_last_segment = f'{not_sep}+'
|
||||
one_segment = f'{one_last_segment}{any_sep}'
|
||||
any_segments = f'(?:.+{any_sep})?'
|
||||
any_last_segments = '.*'
|
||||
else:
|
||||
one_last_segment = f'[^{escaped_seps}.]{not_sep}*'
|
||||
one_segment = f'{one_last_segment}{any_sep}'
|
||||
any_segments = f'(?:{one_segment})*'
|
||||
any_last_segments = f'{any_segments}(?:{one_last_segment})?'
|
||||
|
||||
results = []
|
||||
parts = re.split(any_sep, pat)
|
||||
last_part_idx = len(parts) - 1
|
||||
for idx, part in enumerate(parts):
|
||||
if part == '*':
|
||||
results.append(one_segment if idx < last_part_idx else one_last_segment)
|
||||
elif recursive and part == '**':
|
||||
if idx < last_part_idx:
|
||||
if parts[idx + 1] != '**':
|
||||
results.append(any_segments)
|
||||
else:
|
||||
results.append(any_last_segments)
|
||||
else:
|
||||
if part:
|
||||
if not include_hidden and part[0] in '*?':
|
||||
results.append(r'(?!\.)')
|
||||
results.extend(fnmatch._translate(part, f'{not_sep}*', not_sep))
|
||||
if idx < last_part_idx:
|
||||
results.append(any_sep)
|
||||
res = ''.join(results)
|
||||
return fr'(?s:{res})\Z'
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=512)
|
||||
def _compile_pattern(pat, sep, case_sensitive, recursive=True):
|
||||
"""Compile given glob pattern to a re.Pattern object (observing case
|
||||
sensitivity)."""
|
||||
flags = re.NOFLAG if case_sensitive else re.IGNORECASE
|
||||
regex = translate(pat, recursive=recursive, include_hidden=True, seps=sep)
|
||||
return re.compile(regex, flags=flags).match
|
||||
|
||||
|
||||
class _Globber:
|
||||
"""Class providing shell-style pattern matching and globbing.
|
||||
"""
|
||||
|
||||
def __init__(self, sep, case_sensitive, case_pedantic=False, recursive=False):
|
||||
self.sep = sep
|
||||
self.case_sensitive = case_sensitive
|
||||
self.case_pedantic = case_pedantic
|
||||
self.recursive = recursive
|
||||
|
||||
# Low-level methods
|
||||
|
||||
lstat = operator.methodcaller('lstat')
|
||||
add_slash = operator.methodcaller('joinpath', '')
|
||||
|
||||
@staticmethod
|
||||
def scandir(path):
|
||||
"""Emulates os.scandir(), which returns an object that can be used as
|
||||
a context manager. This method is called by walk() and glob().
|
||||
"""
|
||||
return contextlib.nullcontext(path.iterdir())
|
||||
|
||||
@staticmethod
|
||||
def concat_path(path, text):
|
||||
"""Appends text to the given path.
|
||||
"""
|
||||
return path.with_segments(path._raw_path + text)
|
||||
|
||||
@staticmethod
|
||||
def parse_entry(entry):
|
||||
"""Returns the path of an entry yielded from scandir().
|
||||
"""
|
||||
return entry
|
||||
|
||||
# High-level methods
|
||||
|
||||
def compile(self, pat):
|
||||
return _compile_pattern(pat, self.sep, self.case_sensitive, self.recursive)
|
||||
|
||||
def selector(self, parts):
|
||||
"""Returns a function that selects from a given path, walking and
|
||||
filtering according to the glob-style pattern parts in *parts*.
|
||||
"""
|
||||
if not parts:
|
||||
return self.select_exists
|
||||
part = parts.pop()
|
||||
if self.recursive and part == '**':
|
||||
selector = self.recursive_selector
|
||||
elif part in _special_parts:
|
||||
selector = self.special_selector
|
||||
elif not self.case_pedantic and magic_check.search(part) is None:
|
||||
selector = self.literal_selector
|
||||
else:
|
||||
selector = self.wildcard_selector
|
||||
return selector(part, parts)
|
||||
|
||||
def special_selector(self, part, parts):
|
||||
"""Returns a function that selects special children of the given path.
|
||||
"""
|
||||
select_next = self.selector(parts)
|
||||
|
||||
def select_special(path, exists=False):
|
||||
path = self.concat_path(self.add_slash(path), part)
|
||||
return select_next(path, exists)
|
||||
return select_special
|
||||
|
||||
def literal_selector(self, part, parts):
|
||||
"""Returns a function that selects a literal descendant of a path.
|
||||
"""
|
||||
|
||||
# Optimization: consume and join any subsequent literal parts here,
|
||||
# rather than leaving them for the next selector. This reduces the
|
||||
# number of string concatenation operations and calls to add_slash().
|
||||
while parts and magic_check.search(parts[-1]) is None:
|
||||
part += self.sep + parts.pop()
|
||||
|
||||
select_next = self.selector(parts)
|
||||
|
||||
def select_literal(path, exists=False):
|
||||
path = self.concat_path(self.add_slash(path), part)
|
||||
return select_next(path, exists=False)
|
||||
return select_literal
|
||||
|
||||
def wildcard_selector(self, part, parts):
|
||||
"""Returns a function that selects direct children of a given path,
|
||||
filtering by pattern.
|
||||
"""
|
||||
|
||||
match = None if part == '*' else self.compile(part)
|
||||
dir_only = bool(parts)
|
||||
if dir_only:
|
||||
select_next = self.selector(parts)
|
||||
|
||||
def select_wildcard(path, exists=False):
|
||||
try:
|
||||
# We must close the scandir() object before proceeding to
|
||||
# avoid exhausting file descriptors when globbing deep trees.
|
||||
with self.scandir(path) as scandir_it:
|
||||
entries = list(scandir_it)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
for entry in entries:
|
||||
if match is None or match(entry.name):
|
||||
if dir_only:
|
||||
try:
|
||||
if not entry.is_dir():
|
||||
continue
|
||||
except OSError:
|
||||
continue
|
||||
entry_path = self.parse_entry(entry)
|
||||
if dir_only:
|
||||
yield from select_next(entry_path, exists=True)
|
||||
else:
|
||||
yield entry_path
|
||||
return select_wildcard
|
||||
|
||||
def recursive_selector(self, part, parts):
|
||||
"""Returns a function that selects a given path and all its children,
|
||||
recursively, filtering by pattern.
|
||||
"""
|
||||
# Optimization: consume following '**' parts, which have no effect.
|
||||
while parts and parts[-1] == '**':
|
||||
parts.pop()
|
||||
|
||||
# Optimization: consume and join any following non-special parts here,
|
||||
# rather than leaving them for the next selector. They're used to
|
||||
# build a regular expression, which we use to filter the results of
|
||||
# the recursive walk. As a result, non-special pattern segments
|
||||
# following a '**' wildcard don't require additional filesystem access
|
||||
# to expand.
|
||||
follow_symlinks = self.recursive is not _no_recurse_symlinks
|
||||
if follow_symlinks:
|
||||
while parts and parts[-1] not in _special_parts:
|
||||
part += self.sep + parts.pop()
|
||||
|
||||
match = None if part == '**' else self.compile(part)
|
||||
dir_only = bool(parts)
|
||||
select_next = self.selector(parts)
|
||||
|
||||
def select_recursive(path, exists=False):
|
||||
path = self.add_slash(path)
|
||||
match_pos = len(str(path))
|
||||
if match is None or match(str(path), match_pos):
|
||||
yield from select_next(path, exists)
|
||||
stack = [path]
|
||||
while stack:
|
||||
yield from select_recursive_step(stack, match_pos)
|
||||
|
||||
def select_recursive_step(stack, match_pos):
|
||||
path = stack.pop()
|
||||
try:
|
||||
# We must close the scandir() object before proceeding to
|
||||
# avoid exhausting file descriptors when globbing deep trees.
|
||||
with self.scandir(path) as scandir_it:
|
||||
entries = list(scandir_it)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
for entry in entries:
|
||||
is_dir = False
|
||||
try:
|
||||
if entry.is_dir(follow_symlinks=follow_symlinks):
|
||||
is_dir = True
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if is_dir or not dir_only:
|
||||
entry_path = self.parse_entry(entry)
|
||||
if match is None or match(str(entry_path), match_pos):
|
||||
if dir_only:
|
||||
yield from select_next(entry_path, exists=True)
|
||||
else:
|
||||
# Optimization: directly yield the path if this is
|
||||
# last pattern part.
|
||||
yield entry_path
|
||||
if is_dir:
|
||||
stack.append(entry_path)
|
||||
|
||||
return select_recursive
|
||||
|
||||
def select_exists(self, path, exists=False):
|
||||
"""Yields the given path, if it exists.
|
||||
"""
|
||||
if exists:
|
||||
# Optimization: this path is already known to exist, e.g. because
|
||||
# it was returned from os.scandir(), so we skip calling lstat().
|
||||
yield path
|
||||
else:
|
||||
try:
|
||||
self.lstat(path)
|
||||
yield path
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
class _StringGlobber(_Globber):
|
||||
lstat = staticmethod(os.lstat)
|
||||
scandir = staticmethod(os.scandir)
|
||||
parse_entry = operator.attrgetter('path')
|
||||
concat_path = operator.add
|
||||
|
||||
if os.name == 'nt':
|
||||
@staticmethod
|
||||
def add_slash(pathname):
|
||||
tail = os.path.splitroot(pathname)[2]
|
||||
if not tail or tail[-1] in '\\/':
|
||||
return pathname
|
||||
return f'{pathname}\\'
|
||||
else:
|
||||
@staticmethod
|
||||
def add_slash(pathname):
|
||||
if not pathname or pathname[-1] == '/':
|
||||
return pathname
|
||||
return f'{pathname}/'
|
||||
|
||||
240
Lib/html/parser.py
vendored
240
Lib/html/parser.py
vendored
@@ -27,18 +27,48 @@ charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
|
||||
attr_charref = re.compile(r'&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*)[;=]?')
|
||||
|
||||
starttagopen = re.compile('<[a-zA-Z]')
|
||||
endtagopen = re.compile('</[a-zA-Z]')
|
||||
piclose = re.compile('>')
|
||||
commentclose = re.compile(r'--\s*>')
|
||||
commentclose = re.compile(r'--!?>')
|
||||
commentabruptclose = re.compile(r'-?>')
|
||||
# Note:
|
||||
# 1) if you change tagfind/attrfind remember to update locatestarttagend too;
|
||||
# 2) if you change tagfind/attrfind and/or locatestarttagend the parser will
|
||||
# 1) if you change tagfind/attrfind remember to update locatetagend too;
|
||||
# 2) if you change tagfind/attrfind and/or locatetagend the parser will
|
||||
# explode, so don't do it.
|
||||
# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state
|
||||
# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state
|
||||
tagfind_tolerant = re.compile(r'([a-zA-Z][^\t\n\r\f />\x00]*)(?:\s|/(?!>))*')
|
||||
attrfind_tolerant = re.compile(
|
||||
r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*'
|
||||
r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*')
|
||||
# see the HTML5 specs section "13.2.5.6 Tag open state",
|
||||
# "13.2.5.8 Tag name state" and "13.2.5.33 Attribute name state".
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
|
||||
tagfind_tolerant = re.compile(r'([a-zA-Z][^\t\n\r\f />]*)(?:[\t\n\r\f ]|/(?!>))*')
|
||||
attrfind_tolerant = re.compile(r"""
|
||||
(
|
||||
(?<=['"\t\n\r\f /])[^\t\n\r\f />][^\t\n\r\f /=>]* # attribute name
|
||||
)
|
||||
([\t\n\r\f ]*=[\t\n\r\f ]* # value indicator
|
||||
('[^']*' # LITA-enclosed value
|
||||
|"[^"]*" # LIT-enclosed value
|
||||
|(?!['"])[^>\t\n\r\f ]* # bare value
|
||||
)
|
||||
)?
|
||||
(?:[\t\n\r\f ]|/(?!>))* # possibly followed by a space
|
||||
""", re.VERBOSE)
|
||||
locatetagend = re.compile(r"""
|
||||
[a-zA-Z][^\t\n\r\f />]* # tag name
|
||||
[\t\n\r\f /]* # optional whitespace before attribute name
|
||||
(?:(?<=['"\t\n\r\f /])[^\t\n\r\f />][^\t\n\r\f /=>]* # attribute name
|
||||
(?:[\t\n\r\f ]*=[\t\n\r\f ]* # value indicator
|
||||
(?:'[^']*' # LITA-enclosed value
|
||||
|"[^"]*" # LIT-enclosed value
|
||||
|(?!['"])[^>\t\n\r\f ]* # bare value
|
||||
)
|
||||
)?
|
||||
[\t\n\r\f /]* # possibly followed by a space
|
||||
)*
|
||||
>?
|
||||
""", re.VERBOSE)
|
||||
# The following variables are not used, but are temporarily left for
|
||||
# backward compatibility.
|
||||
locatestarttagend_tolerant = re.compile(r"""
|
||||
<[a-zA-Z][^\t\n\r\f />\x00]* # tag name
|
||||
(?:[\s/]* # optional whitespace before attribute name
|
||||
@@ -55,8 +85,6 @@ locatestarttagend_tolerant = re.compile(r"""
|
||||
\s* # trailing whitespace
|
||||
""", re.VERBOSE)
|
||||
endendtag = re.compile('>')
|
||||
# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between
|
||||
# </ and the tag name, so maybe this should be fixed
|
||||
endtagfind = re.compile(r'</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>')
|
||||
|
||||
# Character reference processing logic specific to attribute values
|
||||
@@ -100,6 +128,7 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
"""
|
||||
|
||||
CDATA_CONTENT_ELEMENTS = ("script", "style")
|
||||
RCDATA_CONTENT_ELEMENTS = ("textarea", "title")
|
||||
|
||||
def __init__(self, *, convert_charrefs=True):
|
||||
"""Initialize and reset this instance.
|
||||
@@ -117,6 +146,8 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
self.lasttag = '???'
|
||||
self.interesting = interesting_normal
|
||||
self.cdata_elem = None
|
||||
self._support_cdata = True
|
||||
self._escapable = True
|
||||
super().reset()
|
||||
|
||||
def feed(self, data):
|
||||
@@ -138,13 +169,33 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
"""Return full source of start tag: '<...>'."""
|
||||
return self.__starttag_text
|
||||
|
||||
def set_cdata_mode(self, elem):
|
||||
def set_cdata_mode(self, elem, *, escapable=False):
|
||||
self.cdata_elem = elem.lower()
|
||||
self.interesting = re.compile(r'</\s*%s\s*>' % self.cdata_elem, re.I)
|
||||
self._escapable = escapable
|
||||
if escapable and not self.convert_charrefs:
|
||||
self.interesting = re.compile(r'&|</%s(?=[\t\n\r\f />])' % self.cdata_elem,
|
||||
re.IGNORECASE|re.ASCII)
|
||||
else:
|
||||
self.interesting = re.compile(r'</%s(?=[\t\n\r\f />])' % self.cdata_elem,
|
||||
re.IGNORECASE|re.ASCII)
|
||||
|
||||
def clear_cdata_mode(self):
|
||||
self.interesting = interesting_normal
|
||||
self.cdata_elem = None
|
||||
self._escapable = True
|
||||
|
||||
def _set_support_cdata(self, flag=True):
|
||||
"""Enable or disable support of the CDATA sections.
|
||||
If enabled, "<[CDATA[" starts a CDATA section which ends with "]]>".
|
||||
If disabled, "<[CDATA[" starts a bogus comments which ends with ">".
|
||||
|
||||
This method is not called by default. Its purpose is to be called
|
||||
in custom handle_starttag() and handle_endtag() methods, with
|
||||
value that depends on the adjusted current node.
|
||||
See https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
|
||||
for details.
|
||||
"""
|
||||
self._support_cdata = flag
|
||||
|
||||
# Internal -- handle data as far as reasonable. May leave state
|
||||
# and data to be processed by a subsequent call. If 'end' is
|
||||
@@ -165,7 +216,7 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
# & near the end and see if it's followed by a space or ;.
|
||||
amppos = rawdata.rfind('&', max(i, n-34))
|
||||
if (amppos >= 0 and
|
||||
not re.compile(r'[\s;]').search(rawdata, amppos)):
|
||||
not re.compile(r'[\t\n\r\f ;]').search(rawdata, amppos)):
|
||||
break # wait till we get all the text
|
||||
j = n
|
||||
else:
|
||||
@@ -177,7 +228,7 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
break
|
||||
j = n
|
||||
if i < j:
|
||||
if self.convert_charrefs and not self.cdata_elem:
|
||||
if self.convert_charrefs and self._escapable:
|
||||
self.handle_data(unescape(rawdata[i:j]))
|
||||
else:
|
||||
self.handle_data(rawdata[i:j])
|
||||
@@ -195,7 +246,7 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
k = self.parse_pi(i)
|
||||
elif startswith("<!", i):
|
||||
k = self.parse_html_declaration(i)
|
||||
elif (i + 1) < n:
|
||||
elif (i + 1) < n or end:
|
||||
self.handle_data("<")
|
||||
k = i + 1
|
||||
else:
|
||||
@@ -203,17 +254,35 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
if k < 0:
|
||||
if not end:
|
||||
break
|
||||
k = rawdata.find('>', i + 1)
|
||||
if k < 0:
|
||||
k = rawdata.find('<', i + 1)
|
||||
if k < 0:
|
||||
k = i + 1
|
||||
if starttagopen.match(rawdata, i): # < + letter
|
||||
pass
|
||||
elif startswith("</", i):
|
||||
if i + 2 == n:
|
||||
self.handle_data("</")
|
||||
elif endtagopen.match(rawdata, i): # </ + letter
|
||||
pass
|
||||
else:
|
||||
# bogus comment
|
||||
self.handle_comment(rawdata[i+2:])
|
||||
elif startswith("<!--", i):
|
||||
j = n
|
||||
for suffix in ("--!", "--", "-"):
|
||||
if rawdata.endswith(suffix, i+4):
|
||||
j -= len(suffix)
|
||||
break
|
||||
self.handle_comment(rawdata[i+4:j])
|
||||
elif startswith("<![CDATA[", i) and self._support_cdata:
|
||||
self.unknown_decl(rawdata[i+3:])
|
||||
elif rawdata[i:i+9].lower() == '<!doctype':
|
||||
self.handle_decl(rawdata[i+2:])
|
||||
elif startswith("<!", i):
|
||||
# bogus comment
|
||||
self.handle_comment(rawdata[i+2:])
|
||||
elif startswith("<?", i):
|
||||
self.handle_pi(rawdata[i+2:])
|
||||
else:
|
||||
k += 1
|
||||
if self.convert_charrefs and not self.cdata_elem:
|
||||
self.handle_data(unescape(rawdata[i:k]))
|
||||
else:
|
||||
self.handle_data(rawdata[i:k])
|
||||
raise AssertionError("we should not get here!")
|
||||
k = n
|
||||
i = self.updatepos(i, k)
|
||||
elif startswith("&#", i):
|
||||
match = charref.match(rawdata, i)
|
||||
@@ -261,7 +330,7 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
assert 0, "interesting.search() lied"
|
||||
# end while
|
||||
if end and i < n:
|
||||
if self.convert_charrefs and not self.cdata_elem:
|
||||
if self.convert_charrefs and self._escapable:
|
||||
self.handle_data(unescape(rawdata[i:n]))
|
||||
else:
|
||||
self.handle_data(rawdata[i:n])
|
||||
@@ -278,8 +347,12 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
if rawdata[i:i+4] == '<!--':
|
||||
# this case is actually already handled in goahead()
|
||||
return self.parse_comment(i)
|
||||
elif rawdata[i:i+9] == '<![CDATA[':
|
||||
return self.parse_marked_section(i)
|
||||
elif rawdata[i:i+9] == '<![CDATA[' and self._support_cdata:
|
||||
j = rawdata.find(']]>', i+9)
|
||||
if j < 0:
|
||||
return -1
|
||||
self.unknown_decl(rawdata[i+3: j])
|
||||
return j + 3
|
||||
elif rawdata[i:i+9].lower() == '<!doctype':
|
||||
# find the closing >
|
||||
gtpos = rawdata.find('>', i+9)
|
||||
@@ -290,8 +363,23 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
else:
|
||||
return self.parse_bogus_comment(i)
|
||||
|
||||
# Internal -- parse comment, return length or -1 if not terminated
|
||||
# see https://html.spec.whatwg.org/multipage/parsing.html#comment-start-state
|
||||
def parse_comment(self, i, report=True):
|
||||
rawdata = self.rawdata
|
||||
assert rawdata.startswith('<!--', i), 'unexpected call to parse_comment()'
|
||||
match = commentclose.search(rawdata, i+4)
|
||||
if not match:
|
||||
match = commentabruptclose.match(rawdata, i+4)
|
||||
if not match:
|
||||
return -1
|
||||
if report:
|
||||
j = match.start()
|
||||
self.handle_comment(rawdata[i+4: j])
|
||||
return match.end()
|
||||
|
||||
# Internal -- parse bogus comment, return length or -1 if not terminated
|
||||
# see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state
|
||||
# see https://html.spec.whatwg.org/multipage/parsing.html#bogus-comment-state
|
||||
def parse_bogus_comment(self, i, report=1):
|
||||
rawdata = self.rawdata
|
||||
assert rawdata[i:i+2] in ('<!', '</'), ('unexpected call to '
|
||||
@@ -317,6 +405,8 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
|
||||
# Internal -- handle starttag, return end or -1 if not terminated
|
||||
def parse_starttag(self, i):
|
||||
# See the HTML5 specs section "13.2.5.8 Tag name state"
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
||||
self.__starttag_text = None
|
||||
endpos = self.check_for_whole_start_tag(i)
|
||||
if endpos < 0:
|
||||
@@ -356,82 +446,50 @@ class HTMLParser(_markupbase.ParserBase):
|
||||
self.handle_starttag(tag, attrs)
|
||||
if tag in self.CDATA_CONTENT_ELEMENTS:
|
||||
self.set_cdata_mode(tag)
|
||||
elif tag in self.RCDATA_CONTENT_ELEMENTS:
|
||||
self.set_cdata_mode(tag, escapable=True)
|
||||
return endpos
|
||||
|
||||
# Internal -- check to see if we have a complete starttag; return end
|
||||
# or -1 if incomplete.
|
||||
def check_for_whole_start_tag(self, i):
|
||||
rawdata = self.rawdata
|
||||
m = locatestarttagend_tolerant.match(rawdata, i)
|
||||
if m:
|
||||
j = m.end()
|
||||
next = rawdata[j:j+1]
|
||||
if next == ">":
|
||||
return j + 1
|
||||
if next == "/":
|
||||
if rawdata.startswith("/>", j):
|
||||
return j + 2
|
||||
if rawdata.startswith("/", j):
|
||||
# buffer boundary
|
||||
return -1
|
||||
# else bogus input
|
||||
if j > i:
|
||||
return j
|
||||
else:
|
||||
return i + 1
|
||||
if next == "":
|
||||
# end of input
|
||||
return -1
|
||||
if next in ("abcdefghijklmnopqrstuvwxyz=/"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
|
||||
# end of input in or before attribute value, or we have the
|
||||
# '/' from a '/>' ending
|
||||
return -1
|
||||
if j > i:
|
||||
return j
|
||||
else:
|
||||
return i + 1
|
||||
raise AssertionError("we should not get here!")
|
||||
match = locatetagend.match(rawdata, i+1)
|
||||
assert match
|
||||
j = match.end()
|
||||
if rawdata[j-1] != ">":
|
||||
return -1
|
||||
return j
|
||||
|
||||
# Internal -- parse endtag, return end or -1 if incomplete
|
||||
def parse_endtag(self, i):
|
||||
# See the HTML5 specs section "13.2.5.7 End tag open state"
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
|
||||
rawdata = self.rawdata
|
||||
assert rawdata[i:i+2] == "</", "unexpected call to parse_endtag"
|
||||
match = endendtag.search(rawdata, i+1) # >
|
||||
if not match:
|
||||
if rawdata.find('>', i+2) < 0: # fast check
|
||||
return -1
|
||||
gtpos = match.end()
|
||||
match = endtagfind.match(rawdata, i) # </ + tag + >
|
||||
if not match:
|
||||
if self.cdata_elem is not None:
|
||||
self.handle_data(rawdata[i:gtpos])
|
||||
return gtpos
|
||||
# find the name: w3.org/TR/html5/tokenization.html#tag-name-state
|
||||
namematch = tagfind_tolerant.match(rawdata, i+2)
|
||||
if not namematch:
|
||||
# w3.org/TR/html5/tokenization.html#end-tag-open-state
|
||||
if rawdata[i:i+3] == '</>':
|
||||
return i+3
|
||||
else:
|
||||
return self.parse_bogus_comment(i)
|
||||
tagname = namematch.group(1).lower()
|
||||
# consume and ignore other stuff between the name and the >
|
||||
# Note: this is not 100% correct, since we might have things like
|
||||
# </tag attr=">">, but looking for > after the name should cover
|
||||
# most of the cases and is much simpler
|
||||
gtpos = rawdata.find('>', namematch.end())
|
||||
self.handle_endtag(tagname)
|
||||
return gtpos+1
|
||||
if not endtagopen.match(rawdata, i): # </ + letter
|
||||
if rawdata[i+2:i+3] == '>': # </> is ignored
|
||||
# "missing-end-tag-name" parser error
|
||||
return i+3
|
||||
else:
|
||||
return self.parse_bogus_comment(i)
|
||||
|
||||
elem = match.group(1).lower() # script or style
|
||||
if self.cdata_elem is not None:
|
||||
if elem != self.cdata_elem:
|
||||
self.handle_data(rawdata[i:gtpos])
|
||||
return gtpos
|
||||
match = locatetagend.match(rawdata, i+2)
|
||||
assert match
|
||||
j = match.end()
|
||||
if rawdata[j-1] != ">":
|
||||
return -1
|
||||
|
||||
self.handle_endtag(elem)
|
||||
# find the name: "13.2.5.8 Tag name state"
|
||||
# https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state
|
||||
match = tagfind_tolerant.match(rawdata, i+2)
|
||||
assert match
|
||||
tag = match.group(1).lower()
|
||||
self.handle_endtag(tag)
|
||||
self.clear_cdata_mode()
|
||||
return gtpos
|
||||
return j
|
||||
|
||||
# Overridable -- finish processing of start+end tag: <tag.../>
|
||||
def handle_startendtag(self, tag, attrs):
|
||||
|
||||
6
Lib/importlib/metadata/__init__.py
vendored
6
Lib/importlib/metadata/__init__.py
vendored
@@ -56,12 +56,6 @@ class PackageNotFoundError(ModuleNotFoundError):
|
||||
(name,) = self.args
|
||||
return name
|
||||
|
||||
# TODO: RUSTPYTHON; the entire setter is added to avoid errors
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
import sys
|
||||
sys.stderr.write("set value to PackageNotFoundError ignored\n")
|
||||
|
||||
|
||||
class Sectioned:
|
||||
"""
|
||||
|
||||
15
Lib/io.py
vendored
15
Lib/io.py
vendored
@@ -46,23 +46,17 @@ __all__ = ["BlockingIOError", "open", "open_code", "IOBase", "RawIOBase",
|
||||
"BufferedReader", "BufferedWriter", "BufferedRWPair",
|
||||
"BufferedRandom", "TextIOBase", "TextIOWrapper",
|
||||
"UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END",
|
||||
"DEFAULT_BUFFER_SIZE", "text_encoding",
|
||||
"IncrementalNewlineDecoder"
|
||||
]
|
||||
"DEFAULT_BUFFER_SIZE", "text_encoding", "IncrementalNewlineDecoder"]
|
||||
|
||||
|
||||
import _io
|
||||
import abc
|
||||
|
||||
from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
|
||||
open, open_code, BytesIO, StringIO, BufferedReader,
|
||||
open, open_code, FileIO, BytesIO, StringIO, BufferedReader,
|
||||
BufferedWriter, BufferedRWPair, BufferedRandom,
|
||||
IncrementalNewlineDecoder, text_encoding, TextIOWrapper)
|
||||
|
||||
try:
|
||||
from _io import FileIO
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Pretend this exception was created here.
|
||||
UnsupportedOperation.__module__ = "io"
|
||||
@@ -87,10 +81,7 @@ class BufferedIOBase(_io._BufferedIOBase, IOBase):
|
||||
class TextIOBase(_io._TextIOBase, IOBase):
|
||||
__doc__ = _io._TextIOBase.__doc__
|
||||
|
||||
try:
|
||||
RawIOBase.register(FileIO)
|
||||
except NameError:
|
||||
pass
|
||||
RawIOBase.register(FileIO)
|
||||
|
||||
for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom,
|
||||
BufferedRWPair):
|
||||
|
||||
133
Lib/locale.py
vendored
133
Lib/locale.py
vendored
@@ -25,8 +25,8 @@ import functools
|
||||
# Yuck: LC_MESSAGES is non-standard: can't tell whether it exists before
|
||||
# trying the import. So __all__ is also fiddled at the end of the file.
|
||||
__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error",
|
||||
"setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm",
|
||||
"str", "atof", "atoi", "format", "format_string", "currency",
|
||||
"setlocale", "localeconv", "strcoll", "strxfrm",
|
||||
"str", "atof", "atoi", "format_string", "currency",
|
||||
"normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY",
|
||||
"LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"]
|
||||
|
||||
@@ -247,21 +247,6 @@ def format_string(f, val, grouping=False, monetary=False):
|
||||
|
||||
return new_f % val
|
||||
|
||||
def format(percent, value, grouping=False, monetary=False, *additional):
|
||||
"""Deprecated, use format_string instead."""
|
||||
import warnings
|
||||
warnings.warn(
|
||||
"This method will be removed in a future version of Python. "
|
||||
"Use 'locale.format_string()' instead.",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
|
||||
match = _percent_re.match(percent)
|
||||
if not match or len(match.group())!= len(percent):
|
||||
raise ValueError(("format() must be given exactly one %%char "
|
||||
"format specifier, %s not valid") % repr(percent))
|
||||
return _format(percent, value, grouping, monetary, *additional)
|
||||
|
||||
def currency(val, symbol=True, grouping=False, international=False):
|
||||
"""Formats val according to the currency settings
|
||||
in the current locale."""
|
||||
@@ -556,11 +541,15 @@ def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')):
|
||||
"""
|
||||
|
||||
import warnings
|
||||
warnings.warn(
|
||||
"Use setlocale(), getencoding() and getlocale() instead",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
warnings._deprecated(
|
||||
"locale.getdefaultlocale",
|
||||
"{name!r} is deprecated and slated for removal in Python {remove}. "
|
||||
"Use setlocale(), getencoding() and getlocale() instead.",
|
||||
remove=(3, 15))
|
||||
return _getdefaultlocale(envvars)
|
||||
|
||||
|
||||
def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')):
|
||||
try:
|
||||
# check if it's supported by the _locale module
|
||||
import _locale
|
||||
@@ -625,40 +614,15 @@ def setlocale(category, locale=None):
|
||||
locale = normalize(_build_localename(locale))
|
||||
return _setlocale(category, locale)
|
||||
|
||||
def resetlocale(category=LC_ALL):
|
||||
|
||||
""" Sets the locale for category to the default setting.
|
||||
|
||||
The default setting is determined by calling
|
||||
getdefaultlocale(). category defaults to LC_ALL.
|
||||
|
||||
"""
|
||||
import warnings
|
||||
warnings.warn(
|
||||
'Use locale.setlocale(locale.LC_ALL, "") instead',
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', category=DeprecationWarning)
|
||||
loc = getdefaultlocale()
|
||||
|
||||
_setlocale(category, _build_localename(loc))
|
||||
|
||||
|
||||
try:
|
||||
from _locale import getencoding
|
||||
except ImportError:
|
||||
# When _locale.getencoding() is missing, locale.getencoding() uses the
|
||||
# Python filesystem encoding.
|
||||
def getencoding():
|
||||
if hasattr(sys, 'getandroidapilevel'):
|
||||
# On Android langinfo.h and CODESET are missing, and UTF-8 is
|
||||
# always used in mbstowcs() and wcstombs().
|
||||
return 'utf-8'
|
||||
encoding = getdefaultlocale()[1]
|
||||
if encoding is None:
|
||||
# LANG not set, default to UTF-8
|
||||
encoding = 'utf-8'
|
||||
return encoding
|
||||
return sys.getfilesystemencoding()
|
||||
|
||||
|
||||
try:
|
||||
CODESET
|
||||
@@ -896,6 +860,28 @@ del k, v
|
||||
# updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia'
|
||||
# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154'
|
||||
# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R'
|
||||
#
|
||||
# SS 2025-02-04:
|
||||
# Updated alias mapping with glibc 2.41 supported locales and the latest
|
||||
# X lib alias mapping.
|
||||
#
|
||||
# These are the differences compared to the old mapping (Python 3.13.1
|
||||
# and older):
|
||||
#
|
||||
# updated 'c.utf8' -> 'C.UTF-8' to 'en_US.UTF-8'
|
||||
# updated 'de_it' -> 'de_IT.ISO8859-1' to 'de_IT.UTF-8'
|
||||
# removed 'de_li.utf8'
|
||||
# updated 'en_il' -> 'en_IL.UTF-8' to 'en_IL.ISO8859-1'
|
||||
# removed 'english.iso88591'
|
||||
# updated 'es_cu' -> 'es_CU.UTF-8' to 'es_CU.ISO8859-1'
|
||||
# updated 'russian' -> 'ru_RU.KOI8-R' to 'ru_RU.ISO8859-5'
|
||||
# updated 'sr@latn' -> 'sr_CS.UTF-8@latin' to 'sr_RS.UTF-8@latin'
|
||||
# removed 'univ'
|
||||
# removed 'universal'
|
||||
#
|
||||
# SS 2025-06-10:
|
||||
# Remove 'c.utf8' -> 'en_US.UTF-8' because 'en_US.UTF-8' does not exist
|
||||
# on all platforms.
|
||||
|
||||
locale_alias = {
|
||||
'a3': 'az_AZ.KOI8-C',
|
||||
@@ -975,7 +961,6 @@ locale_alias = {
|
||||
'c.ascii': 'C',
|
||||
'c.en': 'C',
|
||||
'c.iso88591': 'en_US.ISO8859-1',
|
||||
'c.utf8': 'en_US.UTF-8',
|
||||
'c_c': 'C',
|
||||
'c_c.c': 'C',
|
||||
'ca': 'ca_ES.ISO8859-1',
|
||||
@@ -992,6 +977,7 @@ locale_alias = {
|
||||
'chr_us': 'chr_US.UTF-8',
|
||||
'ckb_iq': 'ckb_IQ.UTF-8',
|
||||
'cmn_tw': 'cmn_TW.UTF-8',
|
||||
'crh_ru': 'crh_RU.UTF-8',
|
||||
'crh_ua': 'crh_UA.UTF-8',
|
||||
'croatian': 'hr_HR.ISO8859-2',
|
||||
'cs': 'cs_CZ.ISO8859-2',
|
||||
@@ -1013,11 +999,12 @@ locale_alias = {
|
||||
'de_be': 'de_BE.ISO8859-1',
|
||||
'de_ch': 'de_CH.ISO8859-1',
|
||||
'de_de': 'de_DE.ISO8859-1',
|
||||
'de_it': 'de_IT.ISO8859-1',
|
||||
'de_li.utf8': 'de_LI.UTF-8',
|
||||
'de_it': 'de_IT.UTF-8',
|
||||
'de_li': 'de_LI.ISO8859-1',
|
||||
'de_lu': 'de_LU.ISO8859-1',
|
||||
'deutsch': 'de_DE.ISO8859-1',
|
||||
'doi_in': 'doi_IN.UTF-8',
|
||||
'dsb_de': 'dsb_DE.UTF-8',
|
||||
'dutch': 'nl_NL.ISO8859-1',
|
||||
'dutch.iso88591': 'nl_BE.ISO8859-1',
|
||||
'dv_mv': 'dv_MV.UTF-8',
|
||||
@@ -1040,7 +1027,7 @@ locale_alias = {
|
||||
'en_gb': 'en_GB.ISO8859-1',
|
||||
'en_hk': 'en_HK.ISO8859-1',
|
||||
'en_ie': 'en_IE.ISO8859-1',
|
||||
'en_il': 'en_IL.UTF-8',
|
||||
'en_il': 'en_IL.ISO8859-1',
|
||||
'en_in': 'en_IN.ISO8859-1',
|
||||
'en_ng': 'en_NG.UTF-8',
|
||||
'en_nz': 'en_NZ.ISO8859-1',
|
||||
@@ -1056,7 +1043,6 @@ locale_alias = {
|
||||
'en_zw.utf8': 'en_ZS.UTF-8',
|
||||
'eng_gb': 'en_GB.ISO8859-1',
|
||||
'english': 'en_EN.ISO8859-1',
|
||||
'english.iso88591': 'en_US.ISO8859-1',
|
||||
'english_uk': 'en_GB.ISO8859-1',
|
||||
'english_united-states': 'en_US.ISO8859-1',
|
||||
'english_united-states.437': 'C',
|
||||
@@ -1072,7 +1058,7 @@ locale_alias = {
|
||||
'es_cl': 'es_CL.ISO8859-1',
|
||||
'es_co': 'es_CO.ISO8859-1',
|
||||
'es_cr': 'es_CR.ISO8859-1',
|
||||
'es_cu': 'es_CU.UTF-8',
|
||||
'es_cu': 'es_CU.ISO8859-1',
|
||||
'es_do': 'es_DO.ISO8859-1',
|
||||
'es_ec': 'es_EC.ISO8859-1',
|
||||
'es_es': 'es_ES.ISO8859-1',
|
||||
@@ -1122,6 +1108,7 @@ locale_alias = {
|
||||
'ga_ie': 'ga_IE.ISO8859-1',
|
||||
'galego': 'gl_ES.ISO8859-1',
|
||||
'galician': 'gl_ES.ISO8859-1',
|
||||
'gbm_in': 'gbm_IN.UTF-8',
|
||||
'gd': 'gd_GB.ISO8859-1',
|
||||
'gd_gb': 'gd_GB.ISO8859-1',
|
||||
'ger_de': 'de_DE.ISO8859-1',
|
||||
@@ -1162,6 +1149,7 @@ locale_alias = {
|
||||
'icelandic': 'is_IS.ISO8859-1',
|
||||
'id': 'id_ID.ISO8859-1',
|
||||
'id_id': 'id_ID.ISO8859-1',
|
||||
'ie': 'ie.UTF-8',
|
||||
'ig_ng': 'ig_NG.UTF-8',
|
||||
'ik_ca': 'ik_CA.UTF-8',
|
||||
'in': 'id_ID.ISO8859-1',
|
||||
@@ -1216,6 +1204,7 @@ locale_alias = {
|
||||
'ks_in': 'ks_IN.UTF-8',
|
||||
'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari',
|
||||
'ku_tr': 'ku_TR.ISO8859-9',
|
||||
'kv_ru': 'kv_RU.UTF-8',
|
||||
'kw': 'kw_GB.ISO8859-1',
|
||||
'kw_gb': 'kw_GB.ISO8859-1',
|
||||
'ky': 'ky_KG.UTF-8',
|
||||
@@ -1234,6 +1223,7 @@ locale_alias = {
|
||||
'lo_la.mulelao1': 'lo_LA.MULELAO-1',
|
||||
'lt': 'lt_LT.ISO8859-13',
|
||||
'lt_lt': 'lt_LT.ISO8859-13',
|
||||
'ltg_lv.utf8': 'ltg_LV.UTF-8',
|
||||
'lv': 'lv_LV.ISO8859-13',
|
||||
'lv_lv': 'lv_LV.ISO8859-13',
|
||||
'lzh_tw': 'lzh_TW.UTF-8',
|
||||
@@ -1241,6 +1231,7 @@ locale_alias = {
|
||||
'mai': 'mai_IN.UTF-8',
|
||||
'mai_in': 'mai_IN.UTF-8',
|
||||
'mai_np': 'mai_NP.UTF-8',
|
||||
'mdf_ru': 'mdf_RU.UTF-8',
|
||||
'mfe_mu': 'mfe_MU.UTF-8',
|
||||
'mg_mg': 'mg_MG.ISO8859-15',
|
||||
'mhr_ru': 'mhr_RU.UTF-8',
|
||||
@@ -1254,6 +1245,7 @@ locale_alias = {
|
||||
'ml_in': 'ml_IN.UTF-8',
|
||||
'mn_mn': 'mn_MN.UTF-8',
|
||||
'mni_in': 'mni_IN.UTF-8',
|
||||
'mnw_mm': 'mnw_MM.UTF-8',
|
||||
'mr': 'mr_IN.UTF-8',
|
||||
'mr_in': 'mr_IN.UTF-8',
|
||||
'ms': 'ms_MY.ISO8859-1',
|
||||
@@ -1322,6 +1314,7 @@ locale_alias = {
|
||||
'pt_pt': 'pt_PT.ISO8859-1',
|
||||
'quz_pe': 'quz_PE.UTF-8',
|
||||
'raj_in': 'raj_IN.UTF-8',
|
||||
'rif_ma': 'rif_MA.UTF-8',
|
||||
'ro': 'ro_RO.ISO8859-2',
|
||||
'ro_ro': 'ro_RO.ISO8859-2',
|
||||
'romanian': 'ro_RO.ISO8859-2',
|
||||
@@ -1329,12 +1322,14 @@ locale_alias = {
|
||||
'ru_ru': 'ru_RU.UTF-8',
|
||||
'ru_ua': 'ru_UA.KOI8-U',
|
||||
'rumanian': 'ro_RO.ISO8859-2',
|
||||
'russian': 'ru_RU.KOI8-R',
|
||||
'russian': 'ru_RU.ISO8859-5',
|
||||
'rw': 'rw_RW.ISO8859-1',
|
||||
'rw_rw': 'rw_RW.ISO8859-1',
|
||||
'sa_in': 'sa_IN.UTF-8',
|
||||
'sah_ru': 'sah_RU.UTF-8',
|
||||
'sat_in': 'sat_IN.UTF-8',
|
||||
'sc_it': 'sc_IT.UTF-8',
|
||||
'scn_it': 'scn_IT.UTF-8',
|
||||
'sd': 'sd_IN.UTF-8',
|
||||
'sd_in': 'sd_IN.UTF-8',
|
||||
'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari',
|
||||
@@ -1376,7 +1371,7 @@ locale_alias = {
|
||||
'sq_mk': 'sq_MK.UTF-8',
|
||||
'sr': 'sr_RS.UTF-8',
|
||||
'sr@cyrillic': 'sr_RS.UTF-8',
|
||||
'sr@latn': 'sr_CS.UTF-8@latin',
|
||||
'sr@latn': 'sr_RS.UTF-8@latin',
|
||||
'sr_cs': 'sr_CS.UTF-8',
|
||||
'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2',
|
||||
'sr_cs@latn': 'sr_CS.UTF-8@latin',
|
||||
@@ -1395,14 +1390,17 @@ locale_alias = {
|
||||
'sr_yu@cyrillic': 'sr_RS.UTF-8',
|
||||
'ss': 'ss_ZA.ISO8859-1',
|
||||
'ss_za': 'ss_ZA.ISO8859-1',
|
||||
'ssy_er': 'ssy_ER.UTF-8',
|
||||
'st': 'st_ZA.ISO8859-1',
|
||||
'st_za': 'st_ZA.ISO8859-1',
|
||||
'su_id': 'su_ID.UTF-8',
|
||||
'sv': 'sv_SE.ISO8859-1',
|
||||
'sv_fi': 'sv_FI.ISO8859-1',
|
||||
'sv_se': 'sv_SE.ISO8859-1',
|
||||
'sw_ke': 'sw_KE.UTF-8',
|
||||
'sw_tz': 'sw_TZ.UTF-8',
|
||||
'swedish': 'sv_SE.ISO8859-1',
|
||||
'syr': 'syr.UTF-8',
|
||||
'szl_pl': 'szl_PL.UTF-8',
|
||||
'ta': 'ta_IN.TSCII-0',
|
||||
'ta_in': 'ta_IN.TSCII-0',
|
||||
@@ -1429,6 +1427,7 @@ locale_alias = {
|
||||
'tn': 'tn_ZA.ISO8859-15',
|
||||
'tn_za': 'tn_ZA.ISO8859-15',
|
||||
'to_to': 'to_TO.UTF-8',
|
||||
'tok': 'tok.UTF-8',
|
||||
'tpi_pg': 'tpi_PG.UTF-8',
|
||||
'tr': 'tr_TR.ISO8859-9',
|
||||
'tr_cy': 'tr_CY.ISO8859-9',
|
||||
@@ -1443,8 +1442,7 @@ locale_alias = {
|
||||
'ug_cn': 'ug_CN.UTF-8',
|
||||
'uk': 'uk_UA.KOI8-U',
|
||||
'uk_ua': 'uk_UA.KOI8-U',
|
||||
'univ': 'en_US.utf',
|
||||
'universal': 'en_US.utf',
|
||||
'univ.utf8': 'en_US.UTF-8',
|
||||
'universal.utf8@ucs4': 'en_US.UTF-8',
|
||||
'unm_us': 'unm_US.UTF-8',
|
||||
'ur': 'ur_PK.CP1256',
|
||||
@@ -1473,6 +1471,7 @@ locale_alias = {
|
||||
'yo_ng': 'yo_NG.UTF-8',
|
||||
'yue_hk': 'yue_HK.UTF-8',
|
||||
'yuw_pg': 'yuw_PG.UTF-8',
|
||||
'zgh_ma': 'zgh_MA.UTF-8',
|
||||
'zh': 'zh_CN.eucCN',
|
||||
'zh_cn': 'zh_CN.gb2312',
|
||||
'zh_cn.big5': 'zh_TW.big5',
|
||||
@@ -1496,7 +1495,8 @@ locale_alias = {
|
||||
# to include every locale up to Windows Vista.
|
||||
#
|
||||
# NOTE: this mapping is incomplete. If your language is missing, please
|
||||
# submit a bug report to the Python bug tracker at http://bugs.python.org/
|
||||
# submit a bug report as detailed in the Python devguide at:
|
||||
# https://devguide.python.org/triage/issue-tracker/
|
||||
# Make sure you include the missing language identifier and the suggested
|
||||
# locale code.
|
||||
#
|
||||
@@ -1742,17 +1742,6 @@ def _print_locale():
|
||||
print(' Encoding: ', enc or '(undefined)')
|
||||
print()
|
||||
|
||||
print()
|
||||
print('Locale settings after calling resetlocale():')
|
||||
print('-'*72)
|
||||
resetlocale()
|
||||
for name,category in categories.items():
|
||||
print(name, '...')
|
||||
lang, enc = getlocale(category)
|
||||
print(' Language: ', lang or '(undefined)')
|
||||
print(' Encoding: ', enc or '(undefined)')
|
||||
print()
|
||||
|
||||
try:
|
||||
setlocale(LC_ALL, "")
|
||||
except:
|
||||
|
||||
15
Lib/multiprocessing/forkserver.py
vendored
15
Lib/multiprocessing/forkserver.py
vendored
@@ -127,12 +127,13 @@ class ForkServer(object):
|
||||
cmd = ('from multiprocessing.forkserver import main; ' +
|
||||
'main(%d, %d, %r, **%r)')
|
||||
|
||||
main_kws = {}
|
||||
if self._preload_modules:
|
||||
desired_keys = {'main_path', 'sys_path'}
|
||||
data = spawn.get_preparation_data('ignore')
|
||||
data = {x: y for x, y in data.items() if x in desired_keys}
|
||||
else:
|
||||
data = {}
|
||||
if 'sys_path' in data:
|
||||
main_kws['sys_path'] = data['sys_path']
|
||||
if 'init_main_from_path' in data:
|
||||
main_kws['main_path'] = data['init_main_from_path']
|
||||
|
||||
with socket.socket(socket.AF_UNIX) as listener:
|
||||
address = connection.arbitrary_address('AF_UNIX')
|
||||
@@ -147,7 +148,7 @@ class ForkServer(object):
|
||||
try:
|
||||
fds_to_pass = [listener.fileno(), alive_r]
|
||||
cmd %= (listener.fileno(), alive_r, self._preload_modules,
|
||||
data)
|
||||
main_kws)
|
||||
exe = spawn.get_executable()
|
||||
args = [exe] + util._args_from_interpreter_flags()
|
||||
args += ['-c', cmd]
|
||||
@@ -182,6 +183,10 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# gh-135335: flush stdout/stderr in case any of the preloaded modules
|
||||
# wrote to them, otherwise children might inherit buffered data
|
||||
util._flush_std_streams()
|
||||
|
||||
util._close_stdin()
|
||||
|
||||
sig_r, sig_w = os.pipe()
|
||||
|
||||
4
Lib/multiprocessing/popen_spawn_posix.py
vendored
4
Lib/multiprocessing/popen_spawn_posix.py
vendored
@@ -57,6 +57,10 @@ class Popen(popen_fork.Popen):
|
||||
self._fds.extend([child_r, child_w])
|
||||
self.pid = util.spawnv_passfds(spawn.get_executable(),
|
||||
cmd, self._fds)
|
||||
os.close(child_r)
|
||||
child_r = None
|
||||
os.close(child_w)
|
||||
child_w = None
|
||||
self.sentinel = parent_r
|
||||
with open(parent_w, 'wb', closefd=False) as f:
|
||||
f.write(fp.getbuffer())
|
||||
|
||||
31
Lib/netrc.py
vendored
31
Lib/netrc.py
vendored
@@ -2,11 +2,24 @@
|
||||
|
||||
# Module and documentation by Eric S. Raymond, 21 Dec 1998
|
||||
|
||||
import os, shlex, stat
|
||||
import os, stat
|
||||
|
||||
__all__ = ["netrc", "NetrcParseError"]
|
||||
|
||||
|
||||
def _can_security_check():
|
||||
# On WASI, getuid() is indicated as a stub but it may also be missing.
|
||||
return os.name == 'posix' and hasattr(os, 'getuid')
|
||||
|
||||
|
||||
def _getpwuid(uid):
|
||||
try:
|
||||
import pwd
|
||||
return pwd.getpwuid(uid)[0]
|
||||
except (ImportError, LookupError):
|
||||
return f'uid {uid}'
|
||||
|
||||
|
||||
class NetrcParseError(Exception):
|
||||
"""Exception raised on syntax errors in the .netrc file."""
|
||||
def __init__(self, msg, filename=None, lineno=None):
|
||||
@@ -142,18 +155,12 @@ class netrc:
|
||||
self._security_check(fp, default_netrc, self.hosts[entryname][0])
|
||||
|
||||
def _security_check(self, fp, default_netrc, login):
|
||||
if os.name == 'posix' and default_netrc and login != "anonymous":
|
||||
if _can_security_check() and default_netrc and login != "anonymous":
|
||||
prop = os.fstat(fp.fileno())
|
||||
if prop.st_uid != os.getuid():
|
||||
import pwd
|
||||
try:
|
||||
fowner = pwd.getpwuid(prop.st_uid)[0]
|
||||
except KeyError:
|
||||
fowner = 'uid %s' % prop.st_uid
|
||||
try:
|
||||
user = pwd.getpwuid(os.getuid())[0]
|
||||
except KeyError:
|
||||
user = 'uid %s' % os.getuid()
|
||||
current_user_id = os.getuid()
|
||||
if prop.st_uid != current_user_id:
|
||||
fowner = _getpwuid(prop.st_uid)
|
||||
user = _getpwuid(current_user_id)
|
||||
raise NetrcParseError(
|
||||
(f"~/.netrc file owner ({fowner}, {user}) does not match"
|
||||
" current user"))
|
||||
|
||||
367
Lib/ntpath.py
vendored
367
Lib/ntpath.py
vendored
@@ -19,18 +19,17 @@ devnull = 'nul'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
import genericpath
|
||||
from genericpath import *
|
||||
|
||||
|
||||
__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext",
|
||||
"basename","dirname","commonprefix","getsize","getmtime",
|
||||
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
|
||||
"ismount", "expanduser","expandvars","normpath","abspath",
|
||||
"curdir","pardir","sep","pathsep","defpath","altsep",
|
||||
"ismount","isreserved","expanduser","expandvars","normpath",
|
||||
"abspath","curdir","pardir","sep","pathsep","defpath","altsep",
|
||||
"extsep","devnull","realpath","supports_unicode_filenames","relpath",
|
||||
"samefile", "sameopenfile", "samestat", "commonpath", "isjunction"]
|
||||
"samefile", "sameopenfile", "samestat", "commonpath", "isjunction",
|
||||
"isdevdrive", "ALLOW_MISSING"]
|
||||
|
||||
def _get_bothseps(path):
|
||||
if isinstance(path, bytes):
|
||||
@@ -78,12 +77,6 @@ except ImportError:
|
||||
return s.replace('/', '\\').lower()
|
||||
|
||||
|
||||
# Return whether a path is absolute.
|
||||
# Trivial in Posix, harder on Windows.
|
||||
# For Windows it is absolute if it starts with a slash or backslash (current
|
||||
# volume), or if a pathname after the volume-letter-and-colon or UNC-resource
|
||||
# starts with a slash or backslash.
|
||||
|
||||
def isabs(s):
|
||||
"""Test whether a path is absolute"""
|
||||
s = os.fspath(s)
|
||||
@@ -91,16 +84,15 @@ def isabs(s):
|
||||
sep = b'\\'
|
||||
altsep = b'/'
|
||||
colon_sep = b':\\'
|
||||
double_sep = b'\\\\'
|
||||
else:
|
||||
sep = '\\'
|
||||
altsep = '/'
|
||||
colon_sep = ':\\'
|
||||
double_sep = '\\\\'
|
||||
s = s[:3].replace(altsep, sep)
|
||||
# Absolute: UNC, device, and paths with a drive and root.
|
||||
# LEGACY BUG: isabs("/x") should be false since the path has no drive.
|
||||
if s.startswith(sep) or s.startswith(colon_sep, 1):
|
||||
return True
|
||||
return False
|
||||
return s.startswith(colon_sep, 1) or s.startswith(double_sep)
|
||||
|
||||
|
||||
# Join two (or more) paths.
|
||||
@@ -109,16 +101,14 @@ def join(path, *paths):
|
||||
if isinstance(path, bytes):
|
||||
sep = b'\\'
|
||||
seps = b'\\/'
|
||||
colon = b':'
|
||||
colon_seps = b':\\/'
|
||||
else:
|
||||
sep = '\\'
|
||||
seps = '\\/'
|
||||
colon = ':'
|
||||
colon_seps = ':\\/'
|
||||
try:
|
||||
if not paths:
|
||||
path[:0] + sep #23780: Ensure compatible data type even if p is null.
|
||||
result_drive, result_root, result_path = splitroot(path)
|
||||
for p in map(os.fspath, paths):
|
||||
for p in paths:
|
||||
p_drive, p_root, p_path = splitroot(p)
|
||||
if p_root:
|
||||
# Second path is absolute
|
||||
@@ -142,7 +132,7 @@ def join(path, *paths):
|
||||
result_path = result_path + p_path
|
||||
## add separator between UNC and non-absolute path
|
||||
if (result_path and not result_root and
|
||||
result_drive and result_drive[-1:] not in colon + seps):
|
||||
result_drive and result_drive[-1] not in colon_seps):
|
||||
return result_drive + sep + result_path
|
||||
return result_drive + result_root + result_path
|
||||
except (TypeError, AttributeError, BytesWarning):
|
||||
@@ -176,56 +166,52 @@ def splitdrive(p):
|
||||
return drive, root + tail
|
||||
|
||||
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail. The drive is defined
|
||||
exactly as in splitdrive(). On Windows, the root may be a single path
|
||||
separator or an empty string. The tail contains anything after the root.
|
||||
For example:
|
||||
try:
|
||||
from nt import _path_splitroot_ex as splitroot
|
||||
except ImportError:
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail.
|
||||
|
||||
splitroot('//server/share/') == ('//server/share', '/', '')
|
||||
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
|
||||
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
|
||||
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
|
||||
"""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'\\'
|
||||
altsep = b'/'
|
||||
colon = b':'
|
||||
unc_prefix = b'\\\\?\\UNC\\'
|
||||
empty = b''
|
||||
else:
|
||||
sep = '\\'
|
||||
altsep = '/'
|
||||
colon = ':'
|
||||
unc_prefix = '\\\\?\\UNC\\'
|
||||
empty = ''
|
||||
normp = p.replace(altsep, sep)
|
||||
if normp[:1] == sep:
|
||||
if normp[1:2] == sep:
|
||||
# UNC drives, e.g. \\server\share or \\?\UNC\server\share
|
||||
# Device drives, e.g. \\.\device or \\?\device
|
||||
start = 8 if normp[:8].upper() == unc_prefix else 2
|
||||
index = normp.find(sep, start)
|
||||
if index == -1:
|
||||
return p, empty, empty
|
||||
index2 = normp.find(sep, index + 1)
|
||||
if index2 == -1:
|
||||
return p, empty, empty
|
||||
return p[:index2], p[index2:index2 + 1], p[index2 + 1:]
|
||||
The tail contains anything after the root."""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'\\'
|
||||
altsep = b'/'
|
||||
colon = b':'
|
||||
unc_prefix = b'\\\\?\\UNC\\'
|
||||
empty = b''
|
||||
else:
|
||||
# Relative path with root, e.g. \Windows
|
||||
return empty, p[:1], p[1:]
|
||||
elif normp[1:2] == colon:
|
||||
if normp[2:3] == sep:
|
||||
# Absolute drive-letter path, e.g. X:\Windows
|
||||
return p[:2], p[2:3], p[3:]
|
||||
sep = '\\'
|
||||
altsep = '/'
|
||||
colon = ':'
|
||||
unc_prefix = '\\\\?\\UNC\\'
|
||||
empty = ''
|
||||
normp = p.replace(altsep, sep)
|
||||
if normp[:1] == sep:
|
||||
if normp[1:2] == sep:
|
||||
# UNC drives, e.g. \\server\share or \\?\UNC\server\share
|
||||
# Device drives, e.g. \\.\device or \\?\device
|
||||
start = 8 if normp[:8].upper() == unc_prefix else 2
|
||||
index = normp.find(sep, start)
|
||||
if index == -1:
|
||||
return p, empty, empty
|
||||
index2 = normp.find(sep, index + 1)
|
||||
if index2 == -1:
|
||||
return p, empty, empty
|
||||
return p[:index2], p[index2:index2 + 1], p[index2 + 1:]
|
||||
else:
|
||||
# Relative path with root, e.g. \Windows
|
||||
return empty, p[:1], p[1:]
|
||||
elif normp[1:2] == colon:
|
||||
if normp[2:3] == sep:
|
||||
# Absolute drive-letter path, e.g. X:\Windows
|
||||
return p[:2], p[2:3], p[3:]
|
||||
else:
|
||||
# Relative path with drive, e.g. X:Windows
|
||||
return p[:2], empty, p[2:]
|
||||
else:
|
||||
# Relative path with drive, e.g. X:Windows
|
||||
return p[:2], empty, p[2:]
|
||||
else:
|
||||
# Relative path, e.g. Windows
|
||||
return empty, empty, p
|
||||
# Relative path, e.g. Windows
|
||||
return empty, empty, p
|
||||
|
||||
|
||||
# Split a path in head (everything up to the last '/') and tail (the
|
||||
@@ -277,33 +263,6 @@ def dirname(p):
|
||||
return split(p)[0]
|
||||
|
||||
|
||||
# Is a path a junction?
|
||||
|
||||
if hasattr(os.stat_result, 'st_reparse_tag'):
|
||||
def isjunction(path):
|
||||
"""Test whether a path is a junction"""
|
||||
try:
|
||||
st = os.lstat(path)
|
||||
except (OSError, ValueError, AttributeError):
|
||||
return False
|
||||
return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)
|
||||
else:
|
||||
def isjunction(path):
|
||||
"""Test whether a path is a junction"""
|
||||
os.fspath(path)
|
||||
return False
|
||||
|
||||
|
||||
# Being true for dangling symbolic links is also useful.
|
||||
|
||||
def lexists(path):
|
||||
"""Test whether a path exists. Returns True for broken symbolic links"""
|
||||
try:
|
||||
st = os.lstat(path)
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
return True
|
||||
|
||||
# Is a path a mount point?
|
||||
# Any drive letter root (eg c:\)
|
||||
# Any share UNC (eg \\server\share)
|
||||
@@ -338,6 +297,40 @@ def ismount(path):
|
||||
return False
|
||||
|
||||
|
||||
_reserved_chars = frozenset(
|
||||
{chr(i) for i in range(32)} |
|
||||
{'"', '*', ':', '<', '>', '?', '|', '/', '\\'}
|
||||
)
|
||||
|
||||
_reserved_names = frozenset(
|
||||
{'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} |
|
||||
{f'COM{c}' for c in '123456789\xb9\xb2\xb3'} |
|
||||
{f'LPT{c}' for c in '123456789\xb9\xb2\xb3'}
|
||||
)
|
||||
|
||||
def isreserved(path):
|
||||
"""Return true if the pathname is reserved by the system."""
|
||||
# Refer to "Naming Files, Paths, and Namespaces":
|
||||
# https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
||||
path = os.fsdecode(splitroot(path)[2]).replace(altsep, sep)
|
||||
return any(_isreservedname(name) for name in reversed(path.split(sep)))
|
||||
|
||||
def _isreservedname(name):
|
||||
"""Return true if the filename is reserved by the system."""
|
||||
# Trailing dots and spaces are reserved.
|
||||
if name[-1:] in ('.', ' '):
|
||||
return name not in ('.', '..')
|
||||
# Wildcards, separators, colon, and pipe (*?"<>/\:|) are reserved.
|
||||
# ASCII control characters (0-31) are reserved.
|
||||
# Colon is reserved for file streams (e.g. "name:stream[:type]").
|
||||
if _reserved_chars.intersection(name):
|
||||
return True
|
||||
# DOS device names are reserved (e.g. "nul" or "nul .txt"). The rules
|
||||
# are complex and vary across Windows versions. On the side of
|
||||
# caution, return True for names that may not be reserved.
|
||||
return name.partition('.')[0].rstrip(' ').upper() in _reserved_names
|
||||
|
||||
|
||||
# Expand paths beginning with '~' or '~user'.
|
||||
# '~' means $HOME; '~user' means that user's home directory.
|
||||
# If the path doesn't begin with '~', or if the user or $HOME is unknown,
|
||||
@@ -353,24 +346,23 @@ def expanduser(path):
|
||||
If user or $HOME is unknown, do nothing."""
|
||||
path = os.fspath(path)
|
||||
if isinstance(path, bytes):
|
||||
seps = b'\\/'
|
||||
tilde = b'~'
|
||||
else:
|
||||
seps = '\\/'
|
||||
tilde = '~'
|
||||
if not path.startswith(tilde):
|
||||
return path
|
||||
i, n = 1, len(path)
|
||||
while i < n and path[i] not in _get_bothseps(path):
|
||||
while i < n and path[i] not in seps:
|
||||
i += 1
|
||||
|
||||
if 'USERPROFILE' in os.environ:
|
||||
userhome = os.environ['USERPROFILE']
|
||||
elif not 'HOMEPATH' in os.environ:
|
||||
elif 'HOMEPATH' not in os.environ:
|
||||
return path
|
||||
else:
|
||||
try:
|
||||
drive = os.environ['HOMEDRIVE']
|
||||
except KeyError:
|
||||
drive = ''
|
||||
drive = os.environ.get('HOMEDRIVE', '')
|
||||
userhome = join(drive, os.environ['HOMEPATH'])
|
||||
|
||||
if i != 1: #~user
|
||||
@@ -521,7 +513,7 @@ def expandvars(path):
|
||||
# Previously, this function also truncated pathnames to 8+3 format,
|
||||
# but as this module is called "ntpath", that's obviously wrong!
|
||||
try:
|
||||
from nt import _path_normpath
|
||||
from nt import _path_normpath as normpath
|
||||
|
||||
except ImportError:
|
||||
def normpath(path):
|
||||
@@ -560,37 +552,22 @@ except ImportError:
|
||||
comps.append(curdir)
|
||||
return prefix + sep.join(comps)
|
||||
|
||||
else:
|
||||
def normpath(path):
|
||||
"""Normalize path, eliminating double slashes, etc."""
|
||||
path = os.fspath(path)
|
||||
if isinstance(path, bytes):
|
||||
return os.fsencode(_path_normpath(os.fsdecode(path))) or b"."
|
||||
return _path_normpath(path) or "."
|
||||
|
||||
|
||||
def _abspath_fallback(path):
|
||||
"""Return the absolute version of a path as a fallback function in case
|
||||
`nt._getfullpathname` is not available or raises OSError. See bpo-31047 for
|
||||
more.
|
||||
|
||||
"""
|
||||
|
||||
path = os.fspath(path)
|
||||
if not isabs(path):
|
||||
if isinstance(path, bytes):
|
||||
cwd = os.getcwdb()
|
||||
else:
|
||||
cwd = os.getcwd()
|
||||
path = join(cwd, path)
|
||||
return normpath(path)
|
||||
|
||||
# Return an absolute path.
|
||||
try:
|
||||
from nt import _getfullpathname
|
||||
|
||||
except ImportError: # not running on Windows - mock up something sensible
|
||||
abspath = _abspath_fallback
|
||||
def abspath(path):
|
||||
"""Return the absolute version of a path."""
|
||||
path = os.fspath(path)
|
||||
if not isabs(path):
|
||||
if isinstance(path, bytes):
|
||||
cwd = os.getcwdb()
|
||||
else:
|
||||
cwd = os.getcwd()
|
||||
path = join(cwd, path)
|
||||
return normpath(path)
|
||||
|
||||
else: # use native Windows method on Windows
|
||||
def abspath(path):
|
||||
@@ -598,15 +575,36 @@ else: # use native Windows method on Windows
|
||||
try:
|
||||
return _getfullpathname(normpath(path))
|
||||
except (OSError, ValueError):
|
||||
return _abspath_fallback(path)
|
||||
# See gh-75230, handle outside for cleaner traceback
|
||||
pass
|
||||
path = os.fspath(path)
|
||||
if not isabs(path):
|
||||
if isinstance(path, bytes):
|
||||
sep = b'\\'
|
||||
getcwd = os.getcwdb
|
||||
else:
|
||||
sep = '\\'
|
||||
getcwd = os.getcwd
|
||||
drive, root, path = splitroot(path)
|
||||
# Either drive or root can be nonempty, but not both.
|
||||
if drive or root:
|
||||
try:
|
||||
path = join(_getfullpathname(drive + root), path)
|
||||
except (OSError, ValueError):
|
||||
# Drive "\0:" cannot exist; use the root directory.
|
||||
path = drive + sep + path
|
||||
else:
|
||||
path = join(getcwd(), path)
|
||||
return normpath(path)
|
||||
|
||||
try:
|
||||
from nt import _getfinalpathname, readlink as _nt_readlink
|
||||
from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink
|
||||
except ImportError:
|
||||
# realpath is a no-op on systems without _getfinalpathname support.
|
||||
realpath = abspath
|
||||
def realpath(path, *, strict=False):
|
||||
return abspath(path)
|
||||
else:
|
||||
def _readlink_deep(path):
|
||||
def _readlink_deep(path, ignored_error=OSError):
|
||||
# These error codes indicate that we should stop reading links and
|
||||
# return the path we currently have.
|
||||
# 1: ERROR_INVALID_FUNCTION
|
||||
@@ -639,7 +637,7 @@ else:
|
||||
path = old_path
|
||||
break
|
||||
path = normpath(join(dirname(old_path), path))
|
||||
except OSError as ex:
|
||||
except ignored_error as ex:
|
||||
if ex.winerror in allowed_winerror:
|
||||
break
|
||||
raise
|
||||
@@ -648,7 +646,7 @@ else:
|
||||
break
|
||||
return path
|
||||
|
||||
def _getfinalpathname_nonstrict(path):
|
||||
def _getfinalpathname_nonstrict(path, ignored_error=OSError):
|
||||
# These error codes indicate that we should stop resolving the path
|
||||
# and return the value we currently have.
|
||||
# 1: ERROR_INVALID_FUNCTION
|
||||
@@ -664,9 +662,10 @@ else:
|
||||
# 87: ERROR_INVALID_PARAMETER
|
||||
# 123: ERROR_INVALID_NAME
|
||||
# 161: ERROR_BAD_PATHNAME
|
||||
# 1005: ERROR_UNRECOGNIZED_VOLUME
|
||||
# 1920: ERROR_CANT_ACCESS_FILE
|
||||
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
|
||||
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1920, 1921
|
||||
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1005, 1920, 1921
|
||||
|
||||
# Non-strict algorithm is to find as much of the target directory
|
||||
# as we can and join the rest.
|
||||
@@ -675,23 +674,29 @@ else:
|
||||
try:
|
||||
path = _getfinalpathname(path)
|
||||
return join(path, tail) if tail else path
|
||||
except OSError as ex:
|
||||
except ignored_error as ex:
|
||||
if ex.winerror not in allowed_winerror:
|
||||
raise
|
||||
try:
|
||||
# The OS could not resolve this path fully, so we attempt
|
||||
# to follow the link ourselves. If we succeed, join the tail
|
||||
# and return.
|
||||
new_path = _readlink_deep(path)
|
||||
new_path = _readlink_deep(path,
|
||||
ignored_error=ignored_error)
|
||||
if new_path != path:
|
||||
return join(new_path, tail) if tail else new_path
|
||||
except OSError:
|
||||
except ignored_error:
|
||||
# If we fail to readlink(), let's keep traversing
|
||||
pass
|
||||
path, name = split(path)
|
||||
# TODO (bpo-38186): Request the real file name from the directory
|
||||
# entry using FindFirstFileW. For now, we will return the path
|
||||
# as best we have it
|
||||
# If we get these errors, try to get the real name of the file without accessing it.
|
||||
if ex.winerror in (1, 5, 32, 50, 87, 1920, 1921):
|
||||
try:
|
||||
name = _findfirstfile(path)
|
||||
path, _ = split(path)
|
||||
except ignored_error:
|
||||
path, name = split(path)
|
||||
else:
|
||||
path, name = split(path)
|
||||
if path and not name:
|
||||
return path + tail
|
||||
tail = join(name, tail) if tail else name
|
||||
@@ -705,7 +710,8 @@ else:
|
||||
new_unc_prefix = b'\\\\'
|
||||
cwd = os.getcwdb()
|
||||
# bpo-38081: Special case for realpath(b'nul')
|
||||
if normcase(path) == normcase(os.fsencode(devnull)):
|
||||
devnull = b'nul'
|
||||
if normcase(path) == devnull:
|
||||
return b'\\\\.\\NUL'
|
||||
else:
|
||||
prefix = '\\\\?\\'
|
||||
@@ -713,9 +719,19 @@ else:
|
||||
new_unc_prefix = '\\\\'
|
||||
cwd = os.getcwd()
|
||||
# bpo-38081: Special case for realpath('nul')
|
||||
if normcase(path) == normcase(devnull):
|
||||
devnull = 'nul'
|
||||
if normcase(path) == devnull:
|
||||
return '\\\\.\\NUL'
|
||||
had_prefix = path.startswith(prefix)
|
||||
|
||||
if strict is ALLOW_MISSING:
|
||||
ignored_error = FileNotFoundError
|
||||
strict = True
|
||||
elif strict:
|
||||
ignored_error = ()
|
||||
else:
|
||||
ignored_error = OSError
|
||||
|
||||
if not had_prefix and not isabs(path):
|
||||
path = join(cwd, path)
|
||||
try:
|
||||
@@ -723,17 +739,16 @@ else:
|
||||
initial_winerror = 0
|
||||
except ValueError as ex:
|
||||
# gh-106242: Raised for embedded null characters
|
||||
# In strict mode, we convert into an OSError.
|
||||
# In strict modes, we convert into an OSError.
|
||||
# Non-strict mode returns the path as-is, since we've already
|
||||
# made it absolute.
|
||||
if strict:
|
||||
raise OSError(str(ex)) from None
|
||||
path = normpath(path)
|
||||
except OSError as ex:
|
||||
if strict:
|
||||
raise
|
||||
except ignored_error as ex:
|
||||
initial_winerror = ex.winerror
|
||||
path = _getfinalpathname_nonstrict(path)
|
||||
path = _getfinalpathname_nonstrict(path,
|
||||
ignored_error=ignored_error)
|
||||
# The path returned by _getfinalpathname will always start with \\?\ -
|
||||
# strip off that prefix unless it was already provided on the original
|
||||
# path.
|
||||
@@ -766,6 +781,9 @@ supports_unicode_filenames = True
|
||||
def relpath(path, start=None):
|
||||
"""Return a relative version of a path"""
|
||||
path = os.fspath(path)
|
||||
if not path:
|
||||
raise ValueError("no path specified")
|
||||
|
||||
if isinstance(path, bytes):
|
||||
sep = b'\\'
|
||||
curdir = b'.'
|
||||
@@ -777,22 +795,20 @@ def relpath(path, start=None):
|
||||
|
||||
if start is None:
|
||||
start = curdir
|
||||
else:
|
||||
start = os.fspath(start)
|
||||
|
||||
if not path:
|
||||
raise ValueError("no path specified")
|
||||
|
||||
start = os.fspath(start)
|
||||
try:
|
||||
start_abs = abspath(normpath(start))
|
||||
path_abs = abspath(normpath(path))
|
||||
start_abs = abspath(start)
|
||||
path_abs = abspath(path)
|
||||
start_drive, _, start_rest = splitroot(start_abs)
|
||||
path_drive, _, path_rest = splitroot(path_abs)
|
||||
if normcase(start_drive) != normcase(path_drive):
|
||||
raise ValueError("path is on mount %r, start on mount %r" % (
|
||||
path_drive, start_drive))
|
||||
|
||||
start_list = [x for x in start_rest.split(sep) if x]
|
||||
path_list = [x for x in path_rest.split(sep) if x]
|
||||
start_list = start_rest.split(sep) if start_rest else []
|
||||
path_list = path_rest.split(sep) if path_rest else []
|
||||
# Work out how much of the filepath is shared by start and path.
|
||||
i = 0
|
||||
for e1, e2 in zip(start_list, path_list):
|
||||
@@ -803,29 +819,28 @@ def relpath(path, start=None):
|
||||
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||
if not rel_list:
|
||||
return curdir
|
||||
return join(*rel_list)
|
||||
return sep.join(rel_list)
|
||||
except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning):
|
||||
genericpath._check_arg_types('relpath', path, start)
|
||||
raise
|
||||
|
||||
|
||||
# Return the longest common sub-path of the sequence of paths given as input.
|
||||
# Return the longest common sub-path of the iterable of paths given as input.
|
||||
# The function is case-insensitive and 'separator-insensitive', i.e. if the
|
||||
# only difference between two paths is the use of '\' versus '/' as separator,
|
||||
# they are deemed to be equal.
|
||||
#
|
||||
# However, the returned path will have the standard '\' separator (even if the
|
||||
# given paths had the alternative '/' separator) and will have the case of the
|
||||
# first path given in the sequence. Additionally, any trailing separator is
|
||||
# first path given in the iterable. Additionally, any trailing separator is
|
||||
# stripped from the returned path.
|
||||
|
||||
def commonpath(paths):
|
||||
"""Given a sequence of path names, returns the longest common sub-path."""
|
||||
|
||||
if not paths:
|
||||
raise ValueError('commonpath() arg is an empty sequence')
|
||||
|
||||
"""Given an iterable of path names, returns the longest common sub-path."""
|
||||
paths = tuple(map(os.fspath, paths))
|
||||
if not paths:
|
||||
raise ValueError('commonpath() arg is an empty iterable')
|
||||
|
||||
if isinstance(paths[0], bytes):
|
||||
sep = b'\\'
|
||||
altsep = b'/'
|
||||
@@ -839,9 +854,6 @@ def commonpath(paths):
|
||||
drivesplits = [splitroot(p.replace(altsep, sep).lower()) for p in paths]
|
||||
split_paths = [p.split(sep) for d, r, p in drivesplits]
|
||||
|
||||
if len({r for d, r, p in drivesplits}) != 1:
|
||||
raise ValueError("Can't mix absolute and relative paths")
|
||||
|
||||
# Check that all drive letters or UNC paths match. The check is made only
|
||||
# now otherwise type errors for mixing strings and bytes would not be
|
||||
# caught.
|
||||
@@ -849,6 +861,12 @@ def commonpath(paths):
|
||||
raise ValueError("Paths don't have the same drive")
|
||||
|
||||
drive, root, path = splitroot(paths[0].replace(altsep, sep))
|
||||
if len({r for d, r, p in drivesplits}) != 1:
|
||||
if drive:
|
||||
raise ValueError("Can't mix absolute and relative paths")
|
||||
else:
|
||||
raise ValueError("Can't mix rooted and not-rooted paths")
|
||||
|
||||
common = path.split(sep)
|
||||
common = [c for c in common if c and c != curdir]
|
||||
|
||||
@@ -869,13 +887,15 @@ def commonpath(paths):
|
||||
|
||||
|
||||
try:
|
||||
# The isdir(), isfile(), islink() and exists() implementations in
|
||||
# genericpath use os.stat(). This is overkill on Windows. Use simpler
|
||||
# The isdir(), isfile(), islink(), exists() and lexists() implementations
|
||||
# in genericpath use os.stat(). This is overkill on Windows. Use simpler
|
||||
# builtin functions if they are available.
|
||||
from nt import _path_isdir as isdir
|
||||
from nt import _path_isfile as isfile
|
||||
from nt import _path_islink as islink
|
||||
from nt import _path_isjunction as isjunction
|
||||
from nt import _path_exists as exists
|
||||
from nt import _path_lexists as lexists
|
||||
except ImportError:
|
||||
# Use genericpath.* as imported above
|
||||
pass
|
||||
@@ -883,15 +903,12 @@ except ImportError:
|
||||
|
||||
try:
|
||||
from nt import _path_isdevdrive
|
||||
except ImportError:
|
||||
def isdevdrive(path):
|
||||
"""Determines whether the specified path is on a Windows Dev Drive."""
|
||||
# Never a Dev Drive
|
||||
return False
|
||||
else:
|
||||
def isdevdrive(path):
|
||||
"""Determines whether the specified path is on a Windows Dev Drive."""
|
||||
try:
|
||||
return _path_isdevdrive(abspath(path))
|
||||
except OSError:
|
||||
return False
|
||||
except ImportError:
|
||||
# Use genericpath.isdevdrive as imported above
|
||||
pass
|
||||
|
||||
11
Lib/numbers.py
vendored
11
Lib/numbers.py
vendored
@@ -290,18 +290,27 @@ Real.register(float)
|
||||
|
||||
|
||||
class Rational(Real):
|
||||
""".numerator and .denominator should be in lowest terms."""
|
||||
"""To Real, Rational adds numerator and denominator properties.
|
||||
|
||||
The numerator and denominator values should be in lowest terms,
|
||||
with a positive denominator.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def numerator(self):
|
||||
"""The numerator of a rational number in lowest terms."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def denominator(self):
|
||||
"""The denominator of a rational number in lowest terms.
|
||||
|
||||
This denominator should be positive.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
# Concrete implementation of Real's conversion to float.
|
||||
|
||||
449
Lib/opcode.py
vendored
449
Lib/opcode.py
vendored
@@ -4,404 +4,47 @@ opcode module - potentially shared between dis and other modules which
|
||||
operate on bytecodes (e.g. peephole optimizers).
|
||||
"""
|
||||
|
||||
__all__ = ["cmp_op", "hasarg", "hasconst", "hasname", "hasjrel", "hasjabs",
|
||||
"haslocal", "hascompare", "hasfree", "hasexc", "opname", "opmap",
|
||||
"HAVE_ARGUMENT", "EXTENDED_ARG"]
|
||||
|
||||
# It's a chicken-and-egg I'm afraid:
|
||||
# We're imported before _opcode's made.
|
||||
# With exception unheeded
|
||||
# (stack_effect is not needed)
|
||||
# Both our chickens and eggs are allayed.
|
||||
# --Larry Hastings, 2013/11/23
|
||||
__all__ = ["cmp_op", "stack_effect", "hascompare", "opname", "opmap",
|
||||
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasarg", "hasconst", "hasname",
|
||||
"hasjump", "hasjrel", "hasjabs", "hasfree", "haslocal", "hasexc"]
|
||||
|
||||
try:
|
||||
from _opcode import stack_effect
|
||||
__all__.append('stack_effect')
|
||||
except ImportError:
|
||||
pass
|
||||
import _opcode
|
||||
from _opcode import stack_effect
|
||||
|
||||
cmp_op = ('<', '<=', '==', '!=', '>', '>=')
|
||||
from _opcode_metadata import (_specializations, _specialized_opmap, opmap,
|
||||
HAVE_ARGUMENT, MIN_INSTRUMENTED_OPCODE)
|
||||
EXTENDED_ARG = opmap['EXTENDED_ARG']
|
||||
|
||||
hasarg = []
|
||||
hasconst = []
|
||||
hasname = []
|
||||
hasjrel = []
|
||||
hasjabs = []
|
||||
haslocal = []
|
||||
hascompare = []
|
||||
hasfree = []
|
||||
hasexc = []
|
||||
|
||||
def is_pseudo(op):
|
||||
return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
|
||||
|
||||
oplists = [hasarg, hasconst, hasname, hasjrel, hasjabs,
|
||||
haslocal, hascompare, hasfree, hasexc]
|
||||
|
||||
opmap = {}
|
||||
|
||||
## pseudo opcodes (used in the compiler) mapped to the values
|
||||
## they can become in the actual code.
|
||||
_pseudo_ops = {}
|
||||
|
||||
def def_op(name, op):
|
||||
opmap[name] = op
|
||||
|
||||
def name_op(name, op):
|
||||
def_op(name, op)
|
||||
hasname.append(op)
|
||||
|
||||
def jrel_op(name, op):
|
||||
def_op(name, op)
|
||||
hasjrel.append(op)
|
||||
|
||||
def jabs_op(name, op):
|
||||
def_op(name, op)
|
||||
hasjabs.append(op)
|
||||
|
||||
def pseudo_op(name, op, real_ops):
|
||||
def_op(name, op)
|
||||
_pseudo_ops[name] = real_ops
|
||||
# add the pseudo opcode to the lists its targets are in
|
||||
for oplist in oplists:
|
||||
res = [opmap[rop] in oplist for rop in real_ops]
|
||||
if any(res):
|
||||
assert all(res)
|
||||
oplist.append(op)
|
||||
|
||||
|
||||
# Instruction opcodes for compiled code
|
||||
# Blank lines correspond to available opcodes
|
||||
|
||||
def_op('CACHE', 0)
|
||||
def_op('POP_TOP', 1)
|
||||
def_op('PUSH_NULL', 2)
|
||||
|
||||
def_op('NOP', 9)
|
||||
def_op('UNARY_POSITIVE', 10)
|
||||
def_op('UNARY_NEGATIVE', 11)
|
||||
def_op('UNARY_NOT', 12)
|
||||
|
||||
def_op('UNARY_INVERT', 15)
|
||||
|
||||
def_op('BINARY_SUBSCR', 25)
|
||||
def_op('BINARY_SLICE', 26)
|
||||
def_op('STORE_SLICE', 27)
|
||||
|
||||
def_op('GET_LEN', 30)
|
||||
def_op('MATCH_MAPPING', 31)
|
||||
def_op('MATCH_SEQUENCE', 32)
|
||||
def_op('MATCH_KEYS', 33)
|
||||
|
||||
def_op('PUSH_EXC_INFO', 35)
|
||||
def_op('CHECK_EXC_MATCH', 36)
|
||||
def_op('CHECK_EG_MATCH', 37)
|
||||
|
||||
def_op('WITH_EXCEPT_START', 49)
|
||||
def_op('GET_AITER', 50)
|
||||
def_op('GET_ANEXT', 51)
|
||||
def_op('BEFORE_ASYNC_WITH', 52)
|
||||
def_op('BEFORE_WITH', 53)
|
||||
def_op('END_ASYNC_FOR', 54)
|
||||
def_op('CLEANUP_THROW', 55)
|
||||
|
||||
def_op('STORE_SUBSCR', 60)
|
||||
def_op('DELETE_SUBSCR', 61)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
# Delete below def_op after updating coroutines.py
|
||||
def_op('YIELD_FROM', 72)
|
||||
|
||||
def_op('GET_ITER', 68)
|
||||
def_op('GET_YIELD_FROM_ITER', 69)
|
||||
def_op('PRINT_EXPR', 70)
|
||||
def_op('LOAD_BUILD_CLASS', 71)
|
||||
|
||||
def_op('LOAD_ASSERTION_ERROR', 74)
|
||||
def_op('RETURN_GENERATOR', 75)
|
||||
|
||||
def_op('LIST_TO_TUPLE', 82)
|
||||
def_op('RETURN_VALUE', 83)
|
||||
def_op('IMPORT_STAR', 84)
|
||||
def_op('SETUP_ANNOTATIONS', 85)
|
||||
|
||||
def_op('ASYNC_GEN_WRAP', 87)
|
||||
def_op('PREP_RERAISE_STAR', 88)
|
||||
def_op('POP_EXCEPT', 89)
|
||||
|
||||
HAVE_ARGUMENT = 90 # real opcodes from here have an argument:
|
||||
|
||||
name_op('STORE_NAME', 90) # Index in name list
|
||||
name_op('DELETE_NAME', 91) # ""
|
||||
def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
|
||||
jrel_op('FOR_ITER', 93)
|
||||
def_op('UNPACK_EX', 94)
|
||||
name_op('STORE_ATTR', 95) # Index in name list
|
||||
name_op('DELETE_ATTR', 96) # ""
|
||||
name_op('STORE_GLOBAL', 97) # ""
|
||||
name_op('DELETE_GLOBAL', 98) # ""
|
||||
def_op('SWAP', 99)
|
||||
def_op('LOAD_CONST', 100) # Index in const list
|
||||
hasconst.append(100)
|
||||
name_op('LOAD_NAME', 101) # Index in name list
|
||||
def_op('BUILD_TUPLE', 102) # Number of tuple items
|
||||
def_op('BUILD_LIST', 103) # Number of list items
|
||||
def_op('BUILD_SET', 104) # Number of set items
|
||||
def_op('BUILD_MAP', 105) # Number of dict entries
|
||||
name_op('LOAD_ATTR', 106) # Index in name list
|
||||
def_op('COMPARE_OP', 107) # Comparison operator
|
||||
hascompare.append(107)
|
||||
name_op('IMPORT_NAME', 108) # Index in name list
|
||||
name_op('IMPORT_FROM', 109) # Index in name list
|
||||
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
|
||||
jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
|
||||
jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
|
||||
jrel_op('POP_JUMP_IF_FALSE', 114)
|
||||
jrel_op('POP_JUMP_IF_TRUE', 115)
|
||||
name_op('LOAD_GLOBAL', 116) # Index in name list
|
||||
def_op('IS_OP', 117)
|
||||
def_op('CONTAINS_OP', 118)
|
||||
def_op('RERAISE', 119)
|
||||
def_op('COPY', 120)
|
||||
def_op('BINARY_OP', 122)
|
||||
jrel_op('SEND', 123) # Number of bytes to skip
|
||||
def_op('LOAD_FAST', 124) # Local variable number, no null check
|
||||
haslocal.append(124)
|
||||
def_op('STORE_FAST', 125) # Local variable number
|
||||
haslocal.append(125)
|
||||
def_op('DELETE_FAST', 126) # Local variable number
|
||||
haslocal.append(126)
|
||||
def_op('LOAD_FAST_CHECK', 127) # Local variable number
|
||||
haslocal.append(127)
|
||||
jrel_op('POP_JUMP_IF_NOT_NONE', 128)
|
||||
jrel_op('POP_JUMP_IF_NONE', 129)
|
||||
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
||||
def_op('GET_AWAITABLE', 131)
|
||||
def_op('MAKE_FUNCTION', 132) # Flags
|
||||
def_op('BUILD_SLICE', 133) # Number of items
|
||||
jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards)
|
||||
def_op('MAKE_CELL', 135)
|
||||
hasfree.append(135)
|
||||
def_op('LOAD_CLOSURE', 136)
|
||||
hasfree.append(136)
|
||||
def_op('LOAD_DEREF', 137)
|
||||
hasfree.append(137)
|
||||
def_op('STORE_DEREF', 138)
|
||||
hasfree.append(138)
|
||||
def_op('DELETE_DEREF', 139)
|
||||
hasfree.append(139)
|
||||
jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards)
|
||||
|
||||
def_op('CALL_FUNCTION_EX', 142) # Flags
|
||||
|
||||
def_op('EXTENDED_ARG', 144)
|
||||
EXTENDED_ARG = 144
|
||||
def_op('LIST_APPEND', 145)
|
||||
def_op('SET_ADD', 146)
|
||||
def_op('MAP_ADD', 147)
|
||||
def_op('LOAD_CLASSDEREF', 148)
|
||||
hasfree.append(148)
|
||||
def_op('COPY_FREE_VARS', 149)
|
||||
def_op('YIELD_VALUE', 150)
|
||||
def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py
|
||||
def_op('MATCH_CLASS', 152)
|
||||
|
||||
def_op('FORMAT_VALUE', 155)
|
||||
def_op('BUILD_CONST_KEY_MAP', 156)
|
||||
def_op('BUILD_STRING', 157)
|
||||
|
||||
def_op('LIST_EXTEND', 162)
|
||||
def_op('SET_UPDATE', 163)
|
||||
def_op('DICT_MERGE', 164)
|
||||
def_op('DICT_UPDATE', 165)
|
||||
|
||||
def_op('CALL', 171)
|
||||
def_op('KW_NAMES', 172)
|
||||
hasconst.append(172)
|
||||
|
||||
|
||||
hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
|
||||
|
||||
MIN_PSEUDO_OPCODE = 256
|
||||
|
||||
pseudo_op('SETUP_FINALLY', 256, ['NOP'])
|
||||
hasexc.append(256)
|
||||
pseudo_op('SETUP_CLEANUP', 257, ['NOP'])
|
||||
hasexc.append(257)
|
||||
pseudo_op('SETUP_WITH', 258, ['NOP'])
|
||||
hasexc.append(258)
|
||||
pseudo_op('POP_BLOCK', 259, ['NOP'])
|
||||
|
||||
pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
|
||||
pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
|
||||
|
||||
pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR'])
|
||||
|
||||
MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
|
||||
|
||||
del def_op, name_op, jrel_op, jabs_op, pseudo_op
|
||||
|
||||
opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)]
|
||||
opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)]
|
||||
for op, i in opmap.items():
|
||||
opname[i] = op
|
||||
|
||||
cmp_op = ('<', '<=', '==', '!=', '>', '>=')
|
||||
|
||||
_nb_ops = [
|
||||
("NB_ADD", "+"),
|
||||
("NB_AND", "&"),
|
||||
("NB_FLOOR_DIVIDE", "//"),
|
||||
("NB_LSHIFT", "<<"),
|
||||
("NB_MATRIX_MULTIPLY", "@"),
|
||||
("NB_MULTIPLY", "*"),
|
||||
("NB_REMAINDER", "%"),
|
||||
("NB_OR", "|"),
|
||||
("NB_POWER", "**"),
|
||||
("NB_RSHIFT", ">>"),
|
||||
("NB_SUBTRACT", "-"),
|
||||
("NB_TRUE_DIVIDE", "/"),
|
||||
("NB_XOR", "^"),
|
||||
("NB_INPLACE_ADD", "+="),
|
||||
("NB_INPLACE_AND", "&="),
|
||||
("NB_INPLACE_FLOOR_DIVIDE", "//="),
|
||||
("NB_INPLACE_LSHIFT", "<<="),
|
||||
("NB_INPLACE_MATRIX_MULTIPLY", "@="),
|
||||
("NB_INPLACE_MULTIPLY", "*="),
|
||||
("NB_INPLACE_REMAINDER", "%="),
|
||||
("NB_INPLACE_OR", "|="),
|
||||
("NB_INPLACE_POWER", "**="),
|
||||
("NB_INPLACE_RSHIFT", ">>="),
|
||||
("NB_INPLACE_SUBTRACT", "-="),
|
||||
("NB_INPLACE_TRUE_DIVIDE", "/="),
|
||||
("NB_INPLACE_XOR", "^="),
|
||||
]
|
||||
# These lists are documented as part of the dis module's API
|
||||
hasarg = [op for op in opmap.values() if _opcode.has_arg(op)]
|
||||
hasconst = [op for op in opmap.values() if _opcode.has_const(op)]
|
||||
hasname = [op for op in opmap.values() if _opcode.has_name(op)]
|
||||
hasjump = [op for op in opmap.values() if _opcode.has_jump(op)]
|
||||
hasjrel = hasjump # for backward compatibility
|
||||
hasjabs = []
|
||||
hasfree = [op for op in opmap.values() if _opcode.has_free(op)]
|
||||
haslocal = [op for op in opmap.values() if _opcode.has_local(op)]
|
||||
hasexc = [op for op in opmap.values() if _opcode.has_exc(op)]
|
||||
|
||||
_specializations = {
|
||||
"BINARY_OP": [
|
||||
"BINARY_OP_ADAPTIVE",
|
||||
"BINARY_OP_ADD_FLOAT",
|
||||
"BINARY_OP_ADD_INT",
|
||||
"BINARY_OP_ADD_UNICODE",
|
||||
"BINARY_OP_INPLACE_ADD_UNICODE",
|
||||
"BINARY_OP_MULTIPLY_FLOAT",
|
||||
"BINARY_OP_MULTIPLY_INT",
|
||||
"BINARY_OP_SUBTRACT_FLOAT",
|
||||
"BINARY_OP_SUBTRACT_INT",
|
||||
],
|
||||
"BINARY_SUBSCR": [
|
||||
"BINARY_SUBSCR_ADAPTIVE",
|
||||
"BINARY_SUBSCR_DICT",
|
||||
"BINARY_SUBSCR_GETITEM",
|
||||
"BINARY_SUBSCR_LIST_INT",
|
||||
"BINARY_SUBSCR_TUPLE_INT",
|
||||
],
|
||||
"CALL": [
|
||||
"CALL_ADAPTIVE",
|
||||
"CALL_PY_EXACT_ARGS",
|
||||
"CALL_PY_WITH_DEFAULTS",
|
||||
"CALL_BOUND_METHOD_EXACT_ARGS",
|
||||
"CALL_BUILTIN_CLASS",
|
||||
"CALL_BUILTIN_FAST_WITH_KEYWORDS",
|
||||
"CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
|
||||
"CALL_NO_KW_BUILTIN_FAST",
|
||||
"CALL_NO_KW_BUILTIN_O",
|
||||
"CALL_NO_KW_ISINSTANCE",
|
||||
"CALL_NO_KW_LEN",
|
||||
"CALL_NO_KW_LIST_APPEND",
|
||||
"CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
|
||||
"CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
|
||||
"CALL_NO_KW_METHOD_DESCRIPTOR_O",
|
||||
"CALL_NO_KW_STR_1",
|
||||
"CALL_NO_KW_TUPLE_1",
|
||||
"CALL_NO_KW_TYPE_1",
|
||||
],
|
||||
"COMPARE_OP": [
|
||||
"COMPARE_OP_ADAPTIVE",
|
||||
"COMPARE_OP_FLOAT_JUMP",
|
||||
"COMPARE_OP_INT_JUMP",
|
||||
"COMPARE_OP_STR_JUMP",
|
||||
],
|
||||
"EXTENDED_ARG": [
|
||||
"EXTENDED_ARG_QUICK",
|
||||
],
|
||||
"FOR_ITER": [
|
||||
"FOR_ITER_ADAPTIVE",
|
||||
"FOR_ITER_LIST",
|
||||
"FOR_ITER_RANGE",
|
||||
],
|
||||
"JUMP_BACKWARD": [
|
||||
"JUMP_BACKWARD_QUICK",
|
||||
],
|
||||
"LOAD_ATTR": [
|
||||
"LOAD_ATTR_ADAPTIVE",
|
||||
# These potentially push [NULL, bound method] onto the stack.
|
||||
"LOAD_ATTR_CLASS",
|
||||
"LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
|
||||
"LOAD_ATTR_INSTANCE_VALUE",
|
||||
"LOAD_ATTR_MODULE",
|
||||
"LOAD_ATTR_PROPERTY",
|
||||
"LOAD_ATTR_SLOT",
|
||||
"LOAD_ATTR_WITH_HINT",
|
||||
# These will always push [unbound method, self] onto the stack.
|
||||
"LOAD_ATTR_METHOD_LAZY_DICT",
|
||||
"LOAD_ATTR_METHOD_NO_DICT",
|
||||
"LOAD_ATTR_METHOD_WITH_DICT",
|
||||
"LOAD_ATTR_METHOD_WITH_VALUES",
|
||||
],
|
||||
"LOAD_CONST": [
|
||||
"LOAD_CONST__LOAD_FAST",
|
||||
],
|
||||
"LOAD_FAST": [
|
||||
"LOAD_FAST__LOAD_CONST",
|
||||
"LOAD_FAST__LOAD_FAST",
|
||||
],
|
||||
"LOAD_GLOBAL": [
|
||||
"LOAD_GLOBAL_ADAPTIVE",
|
||||
"LOAD_GLOBAL_BUILTIN",
|
||||
"LOAD_GLOBAL_MODULE",
|
||||
],
|
||||
"RESUME": [
|
||||
"RESUME_QUICK",
|
||||
],
|
||||
"STORE_ATTR": [
|
||||
"STORE_ATTR_ADAPTIVE",
|
||||
"STORE_ATTR_INSTANCE_VALUE",
|
||||
"STORE_ATTR_SLOT",
|
||||
"STORE_ATTR_WITH_HINT",
|
||||
],
|
||||
"STORE_FAST": [
|
||||
"STORE_FAST__LOAD_FAST",
|
||||
"STORE_FAST__STORE_FAST",
|
||||
],
|
||||
"STORE_SUBSCR": [
|
||||
"STORE_SUBSCR_ADAPTIVE",
|
||||
"STORE_SUBSCR_DICT",
|
||||
"STORE_SUBSCR_LIST_INT",
|
||||
],
|
||||
"UNPACK_SEQUENCE": [
|
||||
"UNPACK_SEQUENCE_ADAPTIVE",
|
||||
"UNPACK_SEQUENCE_LIST",
|
||||
"UNPACK_SEQUENCE_TUPLE",
|
||||
"UNPACK_SEQUENCE_TWO_TUPLE",
|
||||
],
|
||||
}
|
||||
_specialized_instructions = [
|
||||
opcode for family in _specializations.values() for opcode in family
|
||||
]
|
||||
_specialization_stats = [
|
||||
"success",
|
||||
"failure",
|
||||
"hit",
|
||||
"deferred",
|
||||
"miss",
|
||||
"deopt",
|
||||
]
|
||||
|
||||
_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
|
||||
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()
|
||||
_nb_ops = _opcode.get_nb_ops()
|
||||
|
||||
hascompare = [opmap["COMPARE_OP"]]
|
||||
|
||||
_cache_format = {
|
||||
"LOAD_GLOBAL": {
|
||||
"counter": 1,
|
||||
"index": 1,
|
||||
"module_keys_version": 2,
|
||||
"module_keys_version": 1,
|
||||
"builtin_keys_version": 1,
|
||||
},
|
||||
"BINARY_OP": {
|
||||
@@ -412,16 +55,19 @@ _cache_format = {
|
||||
},
|
||||
"COMPARE_OP": {
|
||||
"counter": 1,
|
||||
"mask": 1,
|
||||
},
|
||||
"CONTAINS_OP": {
|
||||
"counter": 1,
|
||||
},
|
||||
"BINARY_SUBSCR": {
|
||||
"counter": 1,
|
||||
"type_version": 2,
|
||||
"func_version": 1,
|
||||
},
|
||||
"FOR_ITER": {
|
||||
"counter": 1,
|
||||
},
|
||||
"LOAD_SUPER_ATTR": {
|
||||
"counter": 1,
|
||||
},
|
||||
"LOAD_ATTR": {
|
||||
"counter": 1,
|
||||
"version": 2,
|
||||
@@ -436,13 +82,34 @@ _cache_format = {
|
||||
"CALL": {
|
||||
"counter": 1,
|
||||
"func_version": 2,
|
||||
"min_args": 1,
|
||||
},
|
||||
"STORE_SUBSCR": {
|
||||
"counter": 1,
|
||||
},
|
||||
"SEND": {
|
||||
"counter": 1,
|
||||
},
|
||||
"JUMP_BACKWARD": {
|
||||
"counter": 1,
|
||||
},
|
||||
"TO_BOOL": {
|
||||
"counter": 1,
|
||||
"version": 2,
|
||||
},
|
||||
"POP_JUMP_IF_TRUE": {
|
||||
"counter": 1,
|
||||
},
|
||||
"POP_JUMP_IF_FALSE": {
|
||||
"counter": 1,
|
||||
},
|
||||
"POP_JUMP_IF_NONE": {
|
||||
"counter": 1,
|
||||
},
|
||||
"POP_JUMP_IF_NOT_NONE": {
|
||||
"counter": 1,
|
||||
},
|
||||
}
|
||||
|
||||
_inline_cache_entries = [
|
||||
sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256)
|
||||
]
|
||||
_inline_cache_entries = {
|
||||
name : sum(value.values()) for (name, value) in _cache_format.items()
|
||||
}
|
||||
|
||||
138
Lib/os.py
vendored
138
Lib/os.py
vendored
@@ -110,6 +110,7 @@ if _exists("_have_functions"):
|
||||
_add("HAVE_FCHMODAT", "chmod")
|
||||
_add("HAVE_FCHOWNAT", "chown")
|
||||
_add("HAVE_FSTATAT", "stat")
|
||||
_add("HAVE_LSTAT", "lstat")
|
||||
_add("HAVE_FUTIMESAT", "utime")
|
||||
_add("HAVE_LINKAT", "link")
|
||||
_add("HAVE_MKDIRAT", "mkdir")
|
||||
@@ -131,6 +132,7 @@ if _exists("_have_functions"):
|
||||
_set = set()
|
||||
_add("HAVE_FCHDIR", "chdir")
|
||||
_add("HAVE_FCHMOD", "chmod")
|
||||
_add("MS_WINDOWS", "chmod")
|
||||
_add("HAVE_FCHOWN", "chown")
|
||||
_add("HAVE_FDOPENDIR", "listdir")
|
||||
_add("HAVE_FDOPENDIR", "scandir")
|
||||
@@ -171,6 +173,7 @@ if _exists("_have_functions"):
|
||||
_add("HAVE_FSTATAT", "stat")
|
||||
_add("HAVE_LCHFLAGS", "chflags")
|
||||
_add("HAVE_LCHMOD", "chmod")
|
||||
_add("MS_WINDOWS", "chmod")
|
||||
if _exists("lchown"): # mac os x10.3
|
||||
_add("HAVE_LCHOWN", "chown")
|
||||
_add("HAVE_LINKAT", "link")
|
||||
@@ -279,6 +282,10 @@ def renames(old, new):
|
||||
|
||||
__all__.extend(["makedirs", "removedirs", "renames"])
|
||||
|
||||
# Private sentinel that makes walk() classify all symlinks and junctions as
|
||||
# regular files.
|
||||
_walk_symlinks_as_files = object()
|
||||
|
||||
def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
"""Directory tree generator.
|
||||
|
||||
@@ -331,12 +338,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
|
||||
import os
|
||||
from os.path import join, getsize
|
||||
for root, dirs, files in os.walk('python/Lib/email'):
|
||||
for root, dirs, files in os.walk('python/Lib/xml'):
|
||||
print(root, "consumes ")
|
||||
print(sum(getsize(join(root, name)) for name in files), end=" ")
|
||||
print("bytes in", len(files), "non-directory files")
|
||||
if 'CVS' in dirs:
|
||||
dirs.remove('CVS') # don't visit CVS directories
|
||||
if '__pycache__' in dirs:
|
||||
dirs.remove('__pycache__') # don't visit __pycache__ directories
|
||||
|
||||
"""
|
||||
sys.audit("os.walk", top, topdown, onerror, followlinks)
|
||||
@@ -380,7 +387,10 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
break
|
||||
|
||||
try:
|
||||
is_dir = entry.is_dir()
|
||||
if followlinks is _walk_symlinks_as_files:
|
||||
is_dir = entry.is_dir(follow_symlinks=False) and not entry.is_junction()
|
||||
else:
|
||||
is_dir = entry.is_dir()
|
||||
except OSError:
|
||||
# If is_dir() raises an OSError, consider the entry not to
|
||||
# be a directory, same behaviour as os.path.isdir().
|
||||
@@ -459,34 +469,69 @@ if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
|
||||
Example:
|
||||
|
||||
import os
|
||||
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
|
||||
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
|
||||
print(root, "consumes", end="")
|
||||
print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
|
||||
end="")
|
||||
print("bytes in", len(files), "non-directory files")
|
||||
if 'CVS' in dirs:
|
||||
dirs.remove('CVS') # don't visit CVS directories
|
||||
if '__pycache__' in dirs:
|
||||
dirs.remove('__pycache__') # don't visit __pycache__ directories
|
||||
"""
|
||||
sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
|
||||
top = fspath(top)
|
||||
# Note: To guard against symlink races, we use the standard
|
||||
# lstat()/open()/fstat() trick.
|
||||
if not follow_symlinks:
|
||||
orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
|
||||
topfd = open(top, O_RDONLY | O_NONBLOCK, dir_fd=dir_fd)
|
||||
stack = [(_fwalk_walk, (True, dir_fd, top, top, None))]
|
||||
isbytes = isinstance(top, bytes)
|
||||
try:
|
||||
if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
|
||||
path.samestat(orig_st, stat(topfd)))):
|
||||
yield from _fwalk(topfd, top, isinstance(top, bytes),
|
||||
topdown, onerror, follow_symlinks)
|
||||
while stack:
|
||||
yield from _fwalk(stack, isbytes, topdown, onerror, follow_symlinks)
|
||||
finally:
|
||||
close(topfd)
|
||||
# Close any file descriptors still on the stack.
|
||||
while stack:
|
||||
action, value = stack.pop()
|
||||
if action == _fwalk_close:
|
||||
close(value)
|
||||
|
||||
def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks):
|
||||
# Each item in the _fwalk() stack is a pair (action, args).
|
||||
_fwalk_walk = 0 # args: (isroot, dirfd, toppath, topname, entry)
|
||||
_fwalk_yield = 1 # args: (toppath, dirnames, filenames, topfd)
|
||||
_fwalk_close = 2 # args: dirfd
|
||||
|
||||
def _fwalk(stack, isbytes, topdown, onerror, follow_symlinks):
|
||||
# Note: This uses O(depth of the directory tree) file descriptors: if
|
||||
# necessary, it can be adapted to only require O(1) FDs, see issue
|
||||
# #13734.
|
||||
|
||||
action, value = stack.pop()
|
||||
if action == _fwalk_close:
|
||||
close(value)
|
||||
return
|
||||
elif action == _fwalk_yield:
|
||||
yield value
|
||||
return
|
||||
assert action == _fwalk_walk
|
||||
isroot, dirfd, toppath, topname, entry = value
|
||||
try:
|
||||
if not follow_symlinks:
|
||||
# Note: To guard against symlink races, we use the standard
|
||||
# lstat()/open()/fstat() trick.
|
||||
if entry is None:
|
||||
orig_st = stat(topname, follow_symlinks=False, dir_fd=dirfd)
|
||||
else:
|
||||
orig_st = entry.stat(follow_symlinks=False)
|
||||
topfd = open(topname, O_RDONLY | O_NONBLOCK, dir_fd=dirfd)
|
||||
except OSError as err:
|
||||
if isroot:
|
||||
raise
|
||||
if onerror is not None:
|
||||
onerror(err)
|
||||
return
|
||||
stack.append((_fwalk_close, topfd))
|
||||
if not follow_symlinks:
|
||||
if isroot and not st.S_ISDIR(orig_st.st_mode):
|
||||
return
|
||||
if not path.samestat(orig_st, stat(topfd)):
|
||||
return
|
||||
|
||||
scandir_it = scandir(topfd)
|
||||
dirs = []
|
||||
nondirs = []
|
||||
@@ -512,31 +557,18 @@ if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
|
||||
|
||||
if topdown:
|
||||
yield toppath, dirs, nondirs, topfd
|
||||
else:
|
||||
stack.append((_fwalk_yield, (toppath, dirs, nondirs, topfd)))
|
||||
|
||||
for name in dirs if entries is None else zip(dirs, entries):
|
||||
try:
|
||||
if not follow_symlinks:
|
||||
if topdown:
|
||||
orig_st = stat(name, dir_fd=topfd, follow_symlinks=False)
|
||||
else:
|
||||
assert entries is not None
|
||||
name, entry = name
|
||||
orig_st = entry.stat(follow_symlinks=False)
|
||||
dirfd = open(name, O_RDONLY | O_NONBLOCK, dir_fd=topfd)
|
||||
except OSError as err:
|
||||
if onerror is not None:
|
||||
onerror(err)
|
||||
continue
|
||||
try:
|
||||
if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
|
||||
dirpath = path.join(toppath, name)
|
||||
yield from _fwalk(dirfd, dirpath, isbytes,
|
||||
topdown, onerror, follow_symlinks)
|
||||
finally:
|
||||
close(dirfd)
|
||||
|
||||
if not topdown:
|
||||
yield toppath, dirs, nondirs, topfd
|
||||
toppath = path.join(toppath, toppath[:0]) # Add trailing slash.
|
||||
if entries is None:
|
||||
stack.extend(
|
||||
(_fwalk_walk, (False, topfd, toppath + name, name, None))
|
||||
for name in dirs[::-1])
|
||||
else:
|
||||
stack.extend(
|
||||
(_fwalk_walk, (False, topfd, toppath + name, name, entry))
|
||||
for name, entry in zip(dirs[::-1], entries[::-1]))
|
||||
|
||||
__all__.append("fwalk")
|
||||
|
||||
@@ -1061,6 +1093,12 @@ def _fspath(path):
|
||||
else:
|
||||
raise TypeError("expected str, bytes or os.PathLike object, "
|
||||
"not " + path_type.__name__)
|
||||
except TypeError:
|
||||
if path_type.__fspath__ is None:
|
||||
raise TypeError("expected str, bytes or os.PathLike object, "
|
||||
"not " + path_type.__name__) from None
|
||||
else:
|
||||
raise
|
||||
if isinstance(path_repr, (str, bytes)):
|
||||
return path_repr
|
||||
else:
|
||||
@@ -1079,6 +1117,8 @@ class PathLike(abc.ABC):
|
||||
|
||||
"""Abstract base class for implementing the file system path protocol."""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
@abc.abstractmethod
|
||||
def __fspath__(self):
|
||||
"""Return the file system path representation of the object."""
|
||||
@@ -1128,3 +1168,17 @@ if name == 'nt':
|
||||
cookie,
|
||||
nt._remove_dll_directory
|
||||
)
|
||||
|
||||
|
||||
if _exists('sched_getaffinity') and sys._get_cpu_count_config() < 0:
|
||||
def process_cpu_count():
|
||||
"""
|
||||
Get the number of CPUs of the current process.
|
||||
|
||||
Return the number of logical CPUs usable by the calling thread of the
|
||||
current process. Return None if indeterminable.
|
||||
"""
|
||||
return len(sched_getaffinity(0))
|
||||
else:
|
||||
# Just an alias to cpu_count() (same docstring)
|
||||
process_cpu_count = cpu_count
|
||||
|
||||
148
Lib/pickle.py
vendored
148
Lib/pickle.py
vendored
@@ -314,16 +314,17 @@ class _Unframer:
|
||||
# Tools used for pickling.
|
||||
|
||||
def _getattribute(obj, name):
|
||||
top = obj
|
||||
for subpath in name.split('.'):
|
||||
if subpath == '<locals>':
|
||||
raise AttributeError("Can't get local attribute {!r} on {!r}"
|
||||
.format(name, obj))
|
||||
.format(name, top))
|
||||
try:
|
||||
parent = obj
|
||||
obj = getattr(obj, subpath)
|
||||
except AttributeError:
|
||||
raise AttributeError("Can't get attribute {!r} on {!r}"
|
||||
.format(name, obj)) from None
|
||||
.format(name, top)) from None
|
||||
return obj, parent
|
||||
|
||||
def whichmodule(obj, name):
|
||||
@@ -396,6 +397,8 @@ def decode_long(data):
|
||||
return int.from_bytes(data, byteorder='little', signed=True)
|
||||
|
||||
|
||||
_NoValue = object()
|
||||
|
||||
# Pickling machinery
|
||||
|
||||
class _Pickler:
|
||||
@@ -530,10 +533,11 @@ class _Pickler:
|
||||
self.framer.commit_frame()
|
||||
|
||||
# Check for persistent id (defined by a subclass)
|
||||
pid = self.persistent_id(obj)
|
||||
if pid is not None and save_persistent_id:
|
||||
self.save_pers(pid)
|
||||
return
|
||||
if save_persistent_id:
|
||||
pid = self.persistent_id(obj)
|
||||
if pid is not None:
|
||||
self.save_pers(pid)
|
||||
return
|
||||
|
||||
# Check the memo
|
||||
x = self.memo.get(id(obj))
|
||||
@@ -542,8 +546,8 @@ class _Pickler:
|
||||
return
|
||||
|
||||
rv = NotImplemented
|
||||
reduce = getattr(self, "reducer_override", None)
|
||||
if reduce is not None:
|
||||
reduce = getattr(self, "reducer_override", _NoValue)
|
||||
if reduce is not _NoValue:
|
||||
rv = reduce(obj)
|
||||
|
||||
if rv is NotImplemented:
|
||||
@@ -556,8 +560,8 @@ class _Pickler:
|
||||
|
||||
# Check private dispatch table if any, or else
|
||||
# copyreg.dispatch_table
|
||||
reduce = getattr(self, 'dispatch_table', dispatch_table).get(t)
|
||||
if reduce is not None:
|
||||
reduce = getattr(self, 'dispatch_table', dispatch_table).get(t, _NoValue)
|
||||
if reduce is not _NoValue:
|
||||
rv = reduce(obj)
|
||||
else:
|
||||
# Check for a class with a custom metaclass; treat as regular
|
||||
@@ -567,12 +571,12 @@ class _Pickler:
|
||||
return
|
||||
|
||||
# Check for a __reduce_ex__ method, fall back to __reduce__
|
||||
reduce = getattr(obj, "__reduce_ex__", None)
|
||||
if reduce is not None:
|
||||
reduce = getattr(obj, "__reduce_ex__", _NoValue)
|
||||
if reduce is not _NoValue:
|
||||
rv = reduce(self.proto)
|
||||
else:
|
||||
reduce = getattr(obj, "__reduce__", None)
|
||||
if reduce is not None:
|
||||
reduce = getattr(obj, "__reduce__", _NoValue)
|
||||
if reduce is not _NoValue:
|
||||
rv = reduce()
|
||||
else:
|
||||
raise PicklingError("Can't pickle %r object: %r" %
|
||||
@@ -780,14 +784,10 @@ class _Pickler:
|
||||
self.write(FLOAT + repr(obj).encode("ascii") + b'\n')
|
||||
dispatch[float] = save_float
|
||||
|
||||
def save_bytes(self, obj):
|
||||
if self.proto < 3:
|
||||
if not obj: # bytes object is empty
|
||||
self.save_reduce(bytes, (), obj=obj)
|
||||
else:
|
||||
self.save_reduce(codecs.encode,
|
||||
(str(obj, 'latin1'), 'latin1'), obj=obj)
|
||||
return
|
||||
def _save_bytes_no_memo(self, obj):
|
||||
# helper for writing bytes objects for protocol >= 3
|
||||
# without memoizing them
|
||||
assert self.proto >= 3
|
||||
n = len(obj)
|
||||
if n <= 0xff:
|
||||
self.write(SHORT_BINBYTES + pack("<B", n) + obj)
|
||||
@@ -797,9 +797,29 @@ class _Pickler:
|
||||
self._write_large_bytes(BINBYTES + pack("<I", n), obj)
|
||||
else:
|
||||
self.write(BINBYTES + pack("<I", n) + obj)
|
||||
|
||||
def save_bytes(self, obj):
|
||||
if self.proto < 3:
|
||||
if not obj: # bytes object is empty
|
||||
self.save_reduce(bytes, (), obj=obj)
|
||||
else:
|
||||
self.save_reduce(codecs.encode,
|
||||
(str(obj, 'latin1'), 'latin1'), obj=obj)
|
||||
return
|
||||
self._save_bytes_no_memo(obj)
|
||||
self.memoize(obj)
|
||||
dispatch[bytes] = save_bytes
|
||||
|
||||
def _save_bytearray_no_memo(self, obj):
|
||||
# helper for writing bytearray objects for protocol >= 5
|
||||
# without memoizing them
|
||||
assert self.proto >= 5
|
||||
n = len(obj)
|
||||
if n >= self.framer._FRAME_SIZE_TARGET:
|
||||
self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
|
||||
else:
|
||||
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
|
||||
|
||||
def save_bytearray(self, obj):
|
||||
if self.proto < 5:
|
||||
if not obj: # bytearray is empty
|
||||
@@ -807,18 +827,14 @@ class _Pickler:
|
||||
else:
|
||||
self.save_reduce(bytearray, (bytes(obj),), obj=obj)
|
||||
return
|
||||
n = len(obj)
|
||||
if n >= self.framer._FRAME_SIZE_TARGET:
|
||||
self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
|
||||
else:
|
||||
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
|
||||
self._save_bytearray_no_memo(obj)
|
||||
self.memoize(obj)
|
||||
dispatch[bytearray] = save_bytearray
|
||||
|
||||
if _HAVE_PICKLE_BUFFER:
|
||||
def save_picklebuffer(self, obj):
|
||||
if self.proto < 5:
|
||||
raise PicklingError("PickleBuffer can only pickled with "
|
||||
raise PicklingError("PickleBuffer can only be pickled with "
|
||||
"protocol >= 5")
|
||||
with obj.raw() as m:
|
||||
if not m.contiguous:
|
||||
@@ -830,10 +846,18 @@ class _Pickler:
|
||||
if in_band:
|
||||
# Write data in-band
|
||||
# XXX The C implementation avoids a copy here
|
||||
buf = m.tobytes()
|
||||
in_memo = id(buf) in self.memo
|
||||
if m.readonly:
|
||||
self.save_bytes(m.tobytes())
|
||||
if in_memo:
|
||||
self._save_bytes_no_memo(buf)
|
||||
else:
|
||||
self.save_bytes(buf)
|
||||
else:
|
||||
self.save_bytearray(m.tobytes())
|
||||
if in_memo:
|
||||
self._save_bytearray_no_memo(buf)
|
||||
else:
|
||||
self.save_bytearray(buf)
|
||||
else:
|
||||
# Write data out-of-band
|
||||
self.write(NEXT_BUFFER)
|
||||
@@ -1070,11 +1094,16 @@ class _Pickler:
|
||||
(obj, module_name, name))
|
||||
|
||||
if self.proto >= 2:
|
||||
code = _extension_registry.get((module_name, name))
|
||||
if code:
|
||||
assert code > 0
|
||||
code = _extension_registry.get((module_name, name), _NoValue)
|
||||
if code is not _NoValue:
|
||||
if code <= 0xff:
|
||||
write(EXT1 + pack("<B", code))
|
||||
data = pack("<B", code)
|
||||
if data == b'\0':
|
||||
# Should never happen in normal circumstances,
|
||||
# since the type and the value of the code are
|
||||
# checked in copyreg.add_extension().
|
||||
raise RuntimeError("extension code 0 is out of range")
|
||||
write(EXT1 + data)
|
||||
elif code <= 0xffff:
|
||||
write(EXT2 + pack("<H", code))
|
||||
else:
|
||||
@@ -1088,11 +1117,35 @@ class _Pickler:
|
||||
self.save(module_name)
|
||||
self.save(name)
|
||||
write(STACK_GLOBAL)
|
||||
elif parent is not module:
|
||||
self.save_reduce(getattr, (parent, lastname))
|
||||
elif self.proto >= 3:
|
||||
write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
|
||||
bytes(name, "utf-8") + b'\n')
|
||||
elif '.' in name:
|
||||
# In protocol < 4, objects with multi-part __qualname__
|
||||
# are represented as
|
||||
# getattr(getattr(..., attrname1), attrname2).
|
||||
dotted_path = name.split('.')
|
||||
name = dotted_path.pop(0)
|
||||
save = self.save
|
||||
for attrname in dotted_path:
|
||||
save(getattr)
|
||||
if self.proto < 2:
|
||||
write(MARK)
|
||||
self._save_toplevel_by_name(module_name, name)
|
||||
for attrname in dotted_path:
|
||||
save(attrname)
|
||||
if self.proto < 2:
|
||||
write(TUPLE)
|
||||
else:
|
||||
write(TUPLE2)
|
||||
write(REDUCE)
|
||||
else:
|
||||
self._save_toplevel_by_name(module_name, name)
|
||||
|
||||
self.memoize(obj)
|
||||
|
||||
def _save_toplevel_by_name(self, module_name, name):
|
||||
if self.proto >= 3:
|
||||
# Non-ASCII identifiers are supported only with protocols >= 3.
|
||||
self.write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
|
||||
bytes(name, "utf-8") + b'\n')
|
||||
else:
|
||||
if self.fix_imports:
|
||||
r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
|
||||
@@ -1102,14 +1155,12 @@ class _Pickler:
|
||||
elif module_name in r_import_mapping:
|
||||
module_name = r_import_mapping[module_name]
|
||||
try:
|
||||
write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
|
||||
bytes(name, "ascii") + b'\n')
|
||||
self.write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
|
||||
bytes(name, "ascii") + b'\n')
|
||||
except UnicodeEncodeError:
|
||||
raise PicklingError(
|
||||
"can't pickle global identifier '%s.%s' using "
|
||||
"pickle protocol %i" % (module, name, self.proto)) from None
|
||||
|
||||
self.memoize(obj)
|
||||
"pickle protocol %i" % (module_name, name, self.proto)) from None
|
||||
|
||||
def save_type(self, obj):
|
||||
if obj is type(None):
|
||||
@@ -1546,9 +1597,8 @@ class _Unpickler:
|
||||
dispatch[EXT4[0]] = load_ext4
|
||||
|
||||
def get_extension(self, code):
|
||||
nil = []
|
||||
obj = _extension_cache.get(code, nil)
|
||||
if obj is not nil:
|
||||
obj = _extension_cache.get(code, _NoValue)
|
||||
if obj is not _NoValue:
|
||||
self.append(obj)
|
||||
return
|
||||
key = _inverted_registry.get(code)
|
||||
@@ -1705,8 +1755,8 @@ class _Unpickler:
|
||||
stack = self.stack
|
||||
state = stack.pop()
|
||||
inst = stack[-1]
|
||||
setstate = getattr(inst, "__setstate__", None)
|
||||
if setstate is not None:
|
||||
setstate = getattr(inst, "__setstate__", _NoValue)
|
||||
if setstate is not _NoValue:
|
||||
setstate(state)
|
||||
return
|
||||
slotstate = None
|
||||
|
||||
11
Lib/pickletools.py
vendored
11
Lib/pickletools.py
vendored
@@ -312,7 +312,7 @@ uint8 = ArgumentDescriptor(
|
||||
doc="Eight-byte unsigned integer, little-endian.")
|
||||
|
||||
|
||||
def read_stringnl(f, decode=True, stripquotes=True):
|
||||
def read_stringnl(f, decode=True, stripquotes=True, *, encoding='latin-1'):
|
||||
r"""
|
||||
>>> import io
|
||||
>>> read_stringnl(io.BytesIO(b"'abcd'\nefg\n"))
|
||||
@@ -356,7 +356,7 @@ def read_stringnl(f, decode=True, stripquotes=True):
|
||||
raise ValueError("no string quotes around %r" % data)
|
||||
|
||||
if decode:
|
||||
data = codecs.escape_decode(data)[0].decode("ascii")
|
||||
data = codecs.escape_decode(data)[0].decode(encoding)
|
||||
return data
|
||||
|
||||
stringnl = ArgumentDescriptor(
|
||||
@@ -370,7 +370,7 @@ stringnl = ArgumentDescriptor(
|
||||
""")
|
||||
|
||||
def read_stringnl_noescape(f):
|
||||
return read_stringnl(f, stripquotes=False)
|
||||
return read_stringnl(f, stripquotes=False, encoding='utf-8')
|
||||
|
||||
stringnl_noescape = ArgumentDescriptor(
|
||||
name='stringnl_noescape',
|
||||
@@ -2513,7 +2513,10 @@ def dis(pickle, out=None, memo=None, indentlevel=4, annotate=0):
|
||||
# make a mild effort to align arguments
|
||||
line += ' ' * (10 - len(opcode.name))
|
||||
if arg is not None:
|
||||
line += ' ' + repr(arg)
|
||||
if opcode.name in ("STRING", "BINSTRING", "SHORT_BINSTRING"):
|
||||
line += ' ' + ascii(arg)
|
||||
else:
|
||||
line += ' ' + repr(arg)
|
||||
if markmsg:
|
||||
line += ' ' + markmsg
|
||||
if annotate:
|
||||
|
||||
286
Lib/posixpath.py
vendored
286
Lib/posixpath.py
vendored
@@ -22,6 +22,7 @@ defpath = '/bin:/usr/bin'
|
||||
altsep = None
|
||||
devnull = '/dev/null'
|
||||
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
@@ -35,7 +36,7 @@ __all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext"
|
||||
"samefile","sameopenfile","samestat",
|
||||
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
|
||||
"devnull","realpath","supports_unicode_filenames","relpath",
|
||||
"commonpath", "isjunction"]
|
||||
"commonpath", "isjunction","isdevdrive","ALLOW_MISSING"]
|
||||
|
||||
|
||||
def _get_sep(path):
|
||||
@@ -77,12 +78,11 @@ def join(a, *p):
|
||||
sep = _get_sep(a)
|
||||
path = a
|
||||
try:
|
||||
if not p:
|
||||
path[:0] + sep #23780: Ensure compatible data type even if p is null.
|
||||
for b in map(os.fspath, p):
|
||||
if b.startswith(sep):
|
||||
for b in p:
|
||||
b = os.fspath(b)
|
||||
if b.startswith(sep) or not path:
|
||||
path = b
|
||||
elif not path or path.endswith(sep):
|
||||
elif path.endswith(sep):
|
||||
path += b
|
||||
else:
|
||||
path += sep + b
|
||||
@@ -135,33 +135,30 @@ def splitdrive(p):
|
||||
return p[:0], p
|
||||
|
||||
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail. On Posix, drive is always
|
||||
empty; the root may be empty, a single slash, or two slashes. The tail
|
||||
contains anything after the root. For example:
|
||||
try:
|
||||
from posix import _path_splitroot_ex as splitroot
|
||||
except ImportError:
|
||||
def splitroot(p):
|
||||
"""Split a pathname into drive, root and tail.
|
||||
|
||||
splitroot('foo/bar') == ('', '', 'foo/bar')
|
||||
splitroot('/foo/bar') == ('', '/', 'foo/bar')
|
||||
splitroot('//foo/bar') == ('', '//', 'foo/bar')
|
||||
splitroot('///foo/bar') == ('', '/', '//foo/bar')
|
||||
"""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'/'
|
||||
empty = b''
|
||||
else:
|
||||
sep = '/'
|
||||
empty = ''
|
||||
if p[:1] != sep:
|
||||
# Relative path, e.g.: 'foo'
|
||||
return empty, empty, p
|
||||
elif p[1:2] != sep or p[2:3] == sep:
|
||||
# Absolute path, e.g.: '/foo', '///foo', '////foo', etc.
|
||||
return empty, sep, p[1:]
|
||||
else:
|
||||
# Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see
|
||||
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
return empty, p[:2], p[2:]
|
||||
The tail contains anything after the root."""
|
||||
p = os.fspath(p)
|
||||
if isinstance(p, bytes):
|
||||
sep = b'/'
|
||||
empty = b''
|
||||
else:
|
||||
sep = '/'
|
||||
empty = ''
|
||||
if p[:1] != sep:
|
||||
# Relative path, e.g.: 'foo'
|
||||
return empty, empty, p
|
||||
elif p[1:2] != sep or p[2:3] == sep:
|
||||
# Absolute path, e.g.: '/foo', '///foo', '////foo', etc.
|
||||
return empty, sep, p[1:]
|
||||
else:
|
||||
# Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see
|
||||
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
||||
return empty, p[:2], p[2:]
|
||||
|
||||
|
||||
# Return the tail (basename) part of a path, same as split(path)[1].
|
||||
@@ -187,26 +184,6 @@ def dirname(p):
|
||||
return head
|
||||
|
||||
|
||||
# Is a path a junction?
|
||||
|
||||
def isjunction(path):
|
||||
"""Test whether a path is a junction
|
||||
Junctions are not a part of posix semantics"""
|
||||
os.fspath(path)
|
||||
return False
|
||||
|
||||
|
||||
# Being true for dangling symbolic links is also useful.
|
||||
|
||||
def lexists(path):
|
||||
"""Test whether a path exists. Returns True for broken symbolic links"""
|
||||
try:
|
||||
os.lstat(path)
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# Is a path a mount point?
|
||||
# (Does this work for all UNIXes? Is it even guaranteed to work by Posix?)
|
||||
|
||||
@@ -227,21 +204,17 @@ def ismount(path):
|
||||
parent = join(path, b'..')
|
||||
else:
|
||||
parent = join(path, '..')
|
||||
parent = realpath(parent)
|
||||
try:
|
||||
s2 = os.lstat(parent)
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
except OSError:
|
||||
parent = realpath(parent)
|
||||
try:
|
||||
s2 = os.lstat(parent)
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
dev1 = s1.st_dev
|
||||
dev2 = s2.st_dev
|
||||
if dev1 != dev2:
|
||||
return True # path/.. on a different device as path
|
||||
ino1 = s1.st_ino
|
||||
ino2 = s2.st_ino
|
||||
if ino1 == ino2:
|
||||
return True # path/.. is the same i-node as path
|
||||
return False
|
||||
# path/.. on a different device as path or the same i-node as path
|
||||
return s1.st_dev != s2.st_dev or s1.st_ino == s2.st_ino
|
||||
|
||||
|
||||
# Expand paths beginning with '~' or '~user'.
|
||||
@@ -290,7 +263,7 @@ def expanduser(path):
|
||||
return path
|
||||
name = path[1:i]
|
||||
if isinstance(name, bytes):
|
||||
name = str(name, 'ASCII')
|
||||
name = os.fsdecode(name)
|
||||
try:
|
||||
pwent = pwd.getpwnam(name)
|
||||
except KeyError:
|
||||
@@ -303,11 +276,8 @@ def expanduser(path):
|
||||
return path
|
||||
if isinstance(path, bytes):
|
||||
userhome = os.fsencode(userhome)
|
||||
root = b'/'
|
||||
else:
|
||||
root = '/'
|
||||
userhome = userhome.rstrip(root)
|
||||
return (userhome + path[i:]) or root
|
||||
userhome = userhome.rstrip(sep)
|
||||
return (userhome + path[i:]) or sep
|
||||
|
||||
|
||||
# Expand paths containing shell variable substitutions.
|
||||
@@ -371,7 +341,7 @@ def expandvars(path):
|
||||
# if it contains symbolic links!
|
||||
|
||||
try:
|
||||
from posix import _path_normpath
|
||||
from posix import _path_normpath as normpath
|
||||
|
||||
except ImportError:
|
||||
def normpath(path):
|
||||
@@ -379,21 +349,19 @@ except ImportError:
|
||||
path = os.fspath(path)
|
||||
if isinstance(path, bytes):
|
||||
sep = b'/'
|
||||
empty = b''
|
||||
dot = b'.'
|
||||
dotdot = b'..'
|
||||
else:
|
||||
sep = '/'
|
||||
empty = ''
|
||||
dot = '.'
|
||||
dotdot = '..'
|
||||
if path == empty:
|
||||
if not path:
|
||||
return dot
|
||||
_, initial_slashes, path = splitroot(path)
|
||||
comps = path.split(sep)
|
||||
new_comps = []
|
||||
for comp in comps:
|
||||
if comp in (empty, dot):
|
||||
if not comp or comp == dot:
|
||||
continue
|
||||
if (comp != dotdot or (not initial_slashes and not new_comps) or
|
||||
(new_comps and new_comps[-1] == dotdot)):
|
||||
@@ -404,24 +372,16 @@ except ImportError:
|
||||
path = initial_slashes + sep.join(comps)
|
||||
return path or dot
|
||||
|
||||
else:
|
||||
def normpath(path):
|
||||
"""Normalize path, eliminating double slashes, etc."""
|
||||
path = os.fspath(path)
|
||||
if isinstance(path, bytes):
|
||||
return os.fsencode(_path_normpath(os.fsdecode(path))) or b"."
|
||||
return _path_normpath(path) or "."
|
||||
|
||||
|
||||
def abspath(path):
|
||||
"""Return an absolute path."""
|
||||
path = os.fspath(path)
|
||||
if not isabs(path):
|
||||
if isinstance(path, bytes):
|
||||
cwd = os.getcwdb()
|
||||
else:
|
||||
cwd = os.getcwd()
|
||||
path = join(cwd, path)
|
||||
if isinstance(path, bytes):
|
||||
if not path.startswith(b'/'):
|
||||
path = join(os.getcwdb(), path)
|
||||
else:
|
||||
if not path.startswith('/'):
|
||||
path = join(os.getcwd(), path)
|
||||
return normpath(path)
|
||||
|
||||
|
||||
@@ -432,72 +392,109 @@ def realpath(filename, *, strict=False):
|
||||
"""Return the canonical path of the specified filename, eliminating any
|
||||
symbolic links encountered in the path."""
|
||||
filename = os.fspath(filename)
|
||||
path, ok = _joinrealpath(filename[:0], filename, strict, {})
|
||||
return abspath(path)
|
||||
|
||||
# Join two paths, normalizing and eliminating any symbolic links
|
||||
# encountered in the second path.
|
||||
def _joinrealpath(path, rest, strict, seen):
|
||||
if isinstance(path, bytes):
|
||||
if isinstance(filename, bytes):
|
||||
sep = b'/'
|
||||
curdir = b'.'
|
||||
pardir = b'..'
|
||||
getcwd = os.getcwdb
|
||||
else:
|
||||
sep = '/'
|
||||
curdir = '.'
|
||||
pardir = '..'
|
||||
getcwd = os.getcwd
|
||||
if strict is ALLOW_MISSING:
|
||||
ignored_error = FileNotFoundError
|
||||
strict = True
|
||||
elif strict:
|
||||
ignored_error = ()
|
||||
else:
|
||||
ignored_error = OSError
|
||||
|
||||
if isabs(rest):
|
||||
rest = rest[1:]
|
||||
path = sep
|
||||
maxlinks = None
|
||||
|
||||
while rest:
|
||||
name, _, rest = rest.partition(sep)
|
||||
# The stack of unresolved path parts. When popped, a special value of None
|
||||
# indicates that a symlink target has been resolved, and that the original
|
||||
# symlink path can be retrieved by popping again. The [::-1] slice is a
|
||||
# very fast way of spelling list(reversed(...)).
|
||||
rest = filename.split(sep)[::-1]
|
||||
|
||||
# Number of unprocessed parts in 'rest'. This can differ from len(rest)
|
||||
# later, because 'rest' might contain markers for unresolved symlinks.
|
||||
part_count = len(rest)
|
||||
|
||||
# The resolved path, which is absolute throughout this function.
|
||||
# Note: getcwd() returns a normalized and symlink-free path.
|
||||
path = sep if filename.startswith(sep) else getcwd()
|
||||
|
||||
# Mapping from symlink paths to *fully resolved* symlink targets. If a
|
||||
# symlink is encountered but not yet resolved, the value is None. This is
|
||||
# used both to detect symlink loops and to speed up repeated traversals of
|
||||
# the same links.
|
||||
seen = {}
|
||||
|
||||
while part_count:
|
||||
name = rest.pop()
|
||||
if name is None:
|
||||
# resolved symlink target
|
||||
seen[rest.pop()] = path
|
||||
continue
|
||||
part_count -= 1
|
||||
if not name or name == curdir:
|
||||
# current dir
|
||||
continue
|
||||
if name == pardir:
|
||||
# parent dir
|
||||
if path:
|
||||
path, name = split(path)
|
||||
if name == pardir:
|
||||
path = join(path, pardir, pardir)
|
||||
else:
|
||||
path = pardir
|
||||
path = path[:path.rindex(sep)] or sep
|
||||
continue
|
||||
newpath = join(path, name)
|
||||
try:
|
||||
st = os.lstat(newpath)
|
||||
except OSError:
|
||||
if strict:
|
||||
raise
|
||||
is_link = False
|
||||
if path == sep:
|
||||
newpath = path + name
|
||||
else:
|
||||
is_link = stat.S_ISLNK(st.st_mode)
|
||||
if not is_link:
|
||||
path = newpath
|
||||
continue
|
||||
# Resolve the symbolic link
|
||||
if newpath in seen:
|
||||
# Already seen this path
|
||||
path = seen[newpath]
|
||||
if path is not None:
|
||||
# use cached value
|
||||
newpath = path + sep + name
|
||||
try:
|
||||
st_mode = os.lstat(newpath).st_mode
|
||||
if not stat.S_ISLNK(st_mode):
|
||||
if strict and part_count and not stat.S_ISDIR(st_mode):
|
||||
raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR),
|
||||
newpath)
|
||||
path = newpath
|
||||
continue
|
||||
# The symlink is not resolved, so we must have a symlink loop.
|
||||
if strict:
|
||||
# Raise OSError(errno.ELOOP)
|
||||
os.stat(newpath)
|
||||
else:
|
||||
# Return already resolved part + rest of the path unchanged.
|
||||
return join(newpath, rest), False
|
||||
seen[newpath] = None # not resolved symlink
|
||||
path, ok = _joinrealpath(path, os.readlink(newpath), strict, seen)
|
||||
if not ok:
|
||||
return join(path, rest), False
|
||||
seen[newpath] = path # resolved symlink
|
||||
if newpath in seen:
|
||||
# Already seen this path
|
||||
path = seen[newpath]
|
||||
if path is not None:
|
||||
# use cached value
|
||||
continue
|
||||
# The symlink is not resolved, so we must have a symlink loop.
|
||||
if strict:
|
||||
# Raise OSError(errno.ELOOP)
|
||||
os.stat(newpath)
|
||||
path = newpath
|
||||
continue
|
||||
target = os.readlink(newpath)
|
||||
except ignored_error:
|
||||
pass
|
||||
else:
|
||||
# Resolve the symbolic link
|
||||
if target.startswith(sep):
|
||||
# Symlink target is absolute; reset resolved path.
|
||||
path = sep
|
||||
if maxlinks is None:
|
||||
# Mark this symlink as seen but not fully resolved.
|
||||
seen[newpath] = None
|
||||
# Push the symlink path onto the stack, and signal its specialness
|
||||
# by also pushing None. When these entries are popped, we'll
|
||||
# record the fully-resolved symlink target in the 'seen' mapping.
|
||||
rest.append(newpath)
|
||||
rest.append(None)
|
||||
# Push the unresolved symlink target parts onto the stack.
|
||||
target_parts = target.split(sep)[::-1]
|
||||
rest.extend(target_parts)
|
||||
part_count += len(target_parts)
|
||||
continue
|
||||
# An error occurred and was ignored.
|
||||
path = newpath
|
||||
|
||||
return path, True
|
||||
return path
|
||||
|
||||
|
||||
supports_unicode_filenames = (sys.platform == 'darwin')
|
||||
@@ -505,10 +502,10 @@ supports_unicode_filenames = (sys.platform == 'darwin')
|
||||
def relpath(path, start=None):
|
||||
"""Return a relative version of a path"""
|
||||
|
||||
path = os.fspath(path)
|
||||
if not path:
|
||||
raise ValueError("no path specified")
|
||||
|
||||
path = os.fspath(path)
|
||||
if isinstance(path, bytes):
|
||||
curdir = b'.'
|
||||
sep = b'/'
|
||||
@@ -524,15 +521,17 @@ def relpath(path, start=None):
|
||||
start = os.fspath(start)
|
||||
|
||||
try:
|
||||
start_list = [x for x in abspath(start).split(sep) if x]
|
||||
path_list = [x for x in abspath(path).split(sep) if x]
|
||||
start_tail = abspath(start).lstrip(sep)
|
||||
path_tail = abspath(path).lstrip(sep)
|
||||
start_list = start_tail.split(sep) if start_tail else []
|
||||
path_list = path_tail.split(sep) if path_tail else []
|
||||
# Work out how much of the filepath is shared by start and path.
|
||||
i = len(commonprefix([start_list, path_list]))
|
||||
|
||||
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||
if not rel_list:
|
||||
return curdir
|
||||
return join(*rel_list)
|
||||
return sep.join(rel_list)
|
||||
except (TypeError, AttributeError, BytesWarning, DeprecationWarning):
|
||||
genericpath._check_arg_types('relpath', path, start)
|
||||
raise
|
||||
@@ -546,10 +545,11 @@ def relpath(path, start=None):
|
||||
def commonpath(paths):
|
||||
"""Given a sequence of path names, returns the longest common sub-path."""
|
||||
|
||||
paths = tuple(map(os.fspath, paths))
|
||||
|
||||
if not paths:
|
||||
raise ValueError('commonpath() arg is an empty sequence')
|
||||
|
||||
paths = tuple(map(os.fspath, paths))
|
||||
if isinstance(paths[0], bytes):
|
||||
sep = b'/'
|
||||
curdir = b'.'
|
||||
@@ -561,7 +561,7 @@ def commonpath(paths):
|
||||
split_paths = [path.split(sep) for path in paths]
|
||||
|
||||
try:
|
||||
isabs, = set(p[:1] == sep for p in paths)
|
||||
isabs, = {p.startswith(sep) for p in paths}
|
||||
except ValueError:
|
||||
raise ValueError("Can't mix absolute and relative paths") from None
|
||||
|
||||
|
||||
28
Lib/runpy.py
vendored
28
Lib/runpy.py
vendored
@@ -14,18 +14,20 @@ import sys
|
||||
import importlib.machinery # importlib first so we can test #15386 via -m
|
||||
import importlib.util
|
||||
import io
|
||||
import types
|
||||
import os
|
||||
|
||||
__all__ = [
|
||||
"run_module", "run_path",
|
||||
]
|
||||
|
||||
# avoid 'import types' just for ModuleType
|
||||
ModuleType = type(sys)
|
||||
|
||||
class _TempModule(object):
|
||||
"""Temporarily replace a module in sys.modules with an empty namespace"""
|
||||
def __init__(self, mod_name):
|
||||
self.mod_name = mod_name
|
||||
self.module = types.ModuleType(mod_name)
|
||||
self.module = ModuleType(mod_name)
|
||||
self._saved_module = []
|
||||
|
||||
def __enter__(self):
|
||||
@@ -245,17 +247,17 @@ def _get_main_module_details(error=ImportError):
|
||||
sys.modules[main_name] = saved_main
|
||||
|
||||
|
||||
def _get_code_from_file(run_name, fname):
|
||||
def _get_code_from_file(fname):
|
||||
# Check for a compiled file first
|
||||
from pkgutil import read_code
|
||||
decoded_path = os.path.abspath(os.fsdecode(fname))
|
||||
with io.open_code(decoded_path) as f:
|
||||
code_path = os.path.abspath(fname)
|
||||
with io.open_code(code_path) as f:
|
||||
code = read_code(f)
|
||||
if code is None:
|
||||
# That didn't work, so try it as normal source code
|
||||
with io.open_code(decoded_path) as f:
|
||||
with io.open_code(code_path) as f:
|
||||
code = compile(f.read(), fname, 'exec')
|
||||
return code, fname
|
||||
return code
|
||||
|
||||
def run_path(path_name, init_globals=None, run_name=None):
|
||||
"""Execute code located at the specified filesystem location.
|
||||
@@ -277,17 +279,13 @@ def run_path(path_name, init_globals=None, run_name=None):
|
||||
pkg_name = run_name.rpartition(".")[0]
|
||||
from pkgutil import get_importer
|
||||
importer = get_importer(path_name)
|
||||
# Trying to avoid importing imp so as to not consume the deprecation warning.
|
||||
is_NullImporter = False
|
||||
if type(importer).__module__ == 'imp':
|
||||
if type(importer).__name__ == 'NullImporter':
|
||||
is_NullImporter = True
|
||||
if isinstance(importer, type(None)) or is_NullImporter:
|
||||
path_name = os.fsdecode(path_name)
|
||||
if isinstance(importer, type(None)):
|
||||
# Not a valid sys.path entry, so run the code directly
|
||||
# execfile() doesn't help as we want to allow compiled files
|
||||
code, fname = _get_code_from_file(run_name, path_name)
|
||||
code = _get_code_from_file(path_name)
|
||||
return _run_module_code(code, init_globals, run_name,
|
||||
pkg_name=pkg_name, script_name=fname)
|
||||
pkg_name=pkg_name, script_name=path_name)
|
||||
else:
|
||||
# Finder is defined for path, so add it to
|
||||
# the start of sys.path
|
||||
|
||||
229
Lib/site.py
vendored
229
Lib/site.py
vendored
@@ -75,6 +75,7 @@ import builtins
|
||||
import _sitebuiltins
|
||||
import io
|
||||
import stat
|
||||
import errno
|
||||
|
||||
# Prefixes for site-packages; add additional prefixes like /usr/local here
|
||||
PREFIXES = [sys.prefix, sys.exec_prefix]
|
||||
@@ -179,35 +180,46 @@ def addpackage(sitedir, name, known_paths):
|
||||
return
|
||||
_trace(f"Processing .pth file: {fullname!r}")
|
||||
try:
|
||||
# locale encoding is not ideal especially on Windows. But we have used
|
||||
# it for a long time. setuptools uses the locale encoding too.
|
||||
f = io.TextIOWrapper(io.open_code(fullname), encoding="locale")
|
||||
with io.open_code(fullname) as f:
|
||||
pth_content = f.read()
|
||||
except OSError:
|
||||
return
|
||||
with f:
|
||||
for n, line in enumerate(f):
|
||||
if line.startswith("#"):
|
||||
|
||||
try:
|
||||
# Accept BOM markers in .pth files as we do in source files
|
||||
# (Windows PowerShell 5.1 makes it hard to emit UTF-8 files without a BOM)
|
||||
pth_content = pth_content.decode("utf-8-sig")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback to locale encoding for backward compatibility.
|
||||
# We will deprecate this fallback in the future.
|
||||
import locale
|
||||
pth_content = pth_content.decode(locale.getencoding())
|
||||
_trace(f"Cannot read {fullname!r} as UTF-8. "
|
||||
f"Using fallback encoding {locale.getencoding()!r}")
|
||||
|
||||
for n, line in enumerate(pth_content.splitlines(), 1):
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
if line.strip() == "":
|
||||
continue
|
||||
try:
|
||||
if line.startswith(("import ", "import\t")):
|
||||
exec(line)
|
||||
continue
|
||||
if line.strip() == "":
|
||||
continue
|
||||
try:
|
||||
if line.startswith(("import ", "import\t")):
|
||||
exec(line)
|
||||
continue
|
||||
line = line.rstrip()
|
||||
dir, dircase = makepath(sitedir, line)
|
||||
if not dircase in known_paths and os.path.exists(dir):
|
||||
sys.path.append(dir)
|
||||
known_paths.add(dircase)
|
||||
except Exception as exc:
|
||||
print("Error processing line {:d} of {}:\n".format(n+1, fullname),
|
||||
file=sys.stderr)
|
||||
import traceback
|
||||
for record in traceback.format_exception(exc):
|
||||
for line in record.splitlines():
|
||||
print(' '+line, file=sys.stderr)
|
||||
print("\nRemainder of file ignored", file=sys.stderr)
|
||||
break
|
||||
line = line.rstrip()
|
||||
dir, dircase = makepath(sitedir, line)
|
||||
if dircase not in known_paths and os.path.exists(dir):
|
||||
sys.path.append(dir)
|
||||
known_paths.add(dircase)
|
||||
except Exception as exc:
|
||||
print(f"Error processing line {n:d} of {fullname}:\n",
|
||||
file=sys.stderr)
|
||||
import traceback
|
||||
for record in traceback.format_exception(exc):
|
||||
for line in record.splitlines():
|
||||
print(' '+line, file=sys.stderr)
|
||||
print("\nRemainder of file ignored", file=sys.stderr)
|
||||
break
|
||||
if reset:
|
||||
known_paths = None
|
||||
return known_paths
|
||||
@@ -270,14 +282,18 @@ def check_enableusersite():
|
||||
#
|
||||
# See https://bugs.python.org/issue29585
|
||||
|
||||
# Copy of sysconfig._get_implementation()
|
||||
def _get_implementation():
|
||||
return 'RustPython' # XXX: RustPython; for site-packages
|
||||
|
||||
# Copy of sysconfig._getuserbase()
|
||||
def _getuserbase():
|
||||
env_base = os.environ.get("PYTHONUSERBASE", None)
|
||||
if env_base:
|
||||
return env_base
|
||||
|
||||
# Emscripten, VxWorks, and WASI have no home directories
|
||||
if sys.platform in {"emscripten", "vxworks", "wasi"}:
|
||||
# Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories
|
||||
if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}:
|
||||
return None
|
||||
|
||||
def joinuser(*args):
|
||||
@@ -285,8 +301,7 @@ def _getuserbase():
|
||||
|
||||
if os.name == "nt":
|
||||
base = os.environ.get("APPDATA") or "~"
|
||||
# XXX: RUSTPYTHON; please keep this change for site-packages
|
||||
return joinuser(base, "RustPython")
|
||||
return joinuser(base, _get_implementation())
|
||||
|
||||
if sys.platform == "darwin" and sys._framework:
|
||||
return joinuser("~", "Library", sys._framework,
|
||||
@@ -298,15 +313,22 @@ def _getuserbase():
|
||||
# Same to sysconfig.get_path('purelib', os.name+'_user')
|
||||
def _get_path(userbase):
|
||||
version = sys.version_info
|
||||
if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
|
||||
abi_thread = 't'
|
||||
else:
|
||||
abi_thread = ''
|
||||
|
||||
implementation = _get_implementation()
|
||||
implementation_lower = implementation.lower()
|
||||
if os.name == 'nt':
|
||||
ver_nodot = sys.winver.replace('.', '')
|
||||
return f'{userbase}\\RustPython{ver_nodot}\\site-packages'
|
||||
return f'{userbase}\\{implementation}{ver_nodot}\\site-packages'
|
||||
|
||||
if sys.platform == 'darwin' and sys._framework:
|
||||
return f'{userbase}/lib/rustpython/site-packages'
|
||||
return f'{userbase}/lib/{implementation_lower}/site-packages'
|
||||
|
||||
return f'{userbase}/lib/rustpython{version[0]}.{version[1]}/site-packages'
|
||||
# XXX: RUSTPYTHON
|
||||
return f'{userbase}/lib/rustpython{version[0]}.{version[1]}{abi_thread}/site-packages'
|
||||
|
||||
|
||||
def getuserbase():
|
||||
@@ -372,6 +394,12 @@ def getsitepackages(prefixes=None):
|
||||
continue
|
||||
seen.add(prefix)
|
||||
|
||||
implementation = _get_implementation().lower()
|
||||
ver = sys.version_info
|
||||
if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
|
||||
abi_thread = 't'
|
||||
else:
|
||||
abi_thread = ''
|
||||
if os.sep == '/':
|
||||
libdirs = [sys.platlibdir]
|
||||
if sys.platlibdir != "lib":
|
||||
@@ -379,8 +407,7 @@ def getsitepackages(prefixes=None):
|
||||
|
||||
for libdir in libdirs:
|
||||
path = os.path.join(prefix, libdir,
|
||||
# XXX: RUSTPYTHON; please keep this change for site-packages
|
||||
"rustpython%d.%d" % sys.version_info[:2],
|
||||
f"{implementation}{ver[0]}.{ver[1]}{abi_thread}",
|
||||
"site-packages")
|
||||
sitepackages.append(path)
|
||||
else:
|
||||
@@ -417,8 +444,9 @@ def setcopyright():
|
||||
"""Set 'copyright' and 'credits' in builtins"""
|
||||
builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
|
||||
builtins.credits = _sitebuiltins._Printer("credits", """\
|
||||
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
|
||||
for supporting Python development. See www.python.org for more information.""")
|
||||
Thanks to CWI, CNRI, BeOpen, Zope Corporation, the Python Software
|
||||
Foundation, and a cast of thousands for supporting Python
|
||||
development. See www.python.org for more information.""")
|
||||
files, dirs = [], []
|
||||
# Not all modules are required to have a __file__ attribute. See
|
||||
# PEP 420 for more details.
|
||||
@@ -437,27 +465,76 @@ def setcopyright():
|
||||
def sethelper():
|
||||
builtins.help = _sitebuiltins._Helper()
|
||||
|
||||
|
||||
def gethistoryfile():
|
||||
"""Check if the PYTHON_HISTORY environment variable is set and define
|
||||
it as the .python_history file. If PYTHON_HISTORY is not set, use the
|
||||
default .python_history file.
|
||||
"""
|
||||
if not sys.flags.ignore_environment:
|
||||
history = os.environ.get("PYTHON_HISTORY")
|
||||
if history:
|
||||
return history
|
||||
return os.path.join(os.path.expanduser('~'),
|
||||
'.python_history')
|
||||
|
||||
|
||||
def enablerlcompleter():
|
||||
"""Enable default readline configuration on interactive prompts, by
|
||||
registering a sys.__interactivehook__.
|
||||
"""
|
||||
sys.__interactivehook__ = register_readline
|
||||
|
||||
|
||||
def register_readline():
|
||||
"""Configure readline completion on interactive prompts.
|
||||
|
||||
If the readline module can be imported, the hook will set the Tab key
|
||||
as completion key and register ~/.python_history as history file.
|
||||
This can be overridden in the sitecustomize or usercustomize module,
|
||||
or in a PYTHONSTARTUP file.
|
||||
"""
|
||||
def register_readline():
|
||||
import atexit
|
||||
if not sys.flags.ignore_environment:
|
||||
PYTHON_BASIC_REPL = os.getenv("PYTHON_BASIC_REPL")
|
||||
else:
|
||||
PYTHON_BASIC_REPL = False
|
||||
|
||||
import atexit
|
||||
|
||||
try:
|
||||
try:
|
||||
import readline
|
||||
import rlcompleter
|
||||
except ImportError:
|
||||
return
|
||||
readline = None
|
||||
else:
|
||||
import rlcompleter # noqa: F401
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
try:
|
||||
if PYTHON_BASIC_REPL:
|
||||
CAN_USE_PYREPL = False
|
||||
else:
|
||||
original_path = sys.path
|
||||
sys.path = [p for p in original_path if p != '']
|
||||
try:
|
||||
import _pyrepl.readline
|
||||
if os.name == "nt":
|
||||
import _pyrepl.windows_console
|
||||
console_errors = (_pyrepl.windows_console._error,)
|
||||
else:
|
||||
import _pyrepl.unix_console
|
||||
console_errors = _pyrepl.unix_console._error
|
||||
from _pyrepl.main import CAN_USE_PYREPL
|
||||
finally:
|
||||
sys.path = original_path
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
if readline is not None:
|
||||
# Reading the initialization (config) file may not be enough to set a
|
||||
# completion key, so we set one first and then read the file.
|
||||
readline_doc = getattr(readline, '__doc__', '')
|
||||
if readline_doc is not None and 'libedit' in readline_doc:
|
||||
if readline.backend == 'editline':
|
||||
readline.parse_and_bind('bind ^I rl_complete')
|
||||
else:
|
||||
readline.parse_and_bind('tab: complete')
|
||||
@@ -471,30 +548,44 @@ def enablerlcompleter():
|
||||
# want to ignore the exception.
|
||||
pass
|
||||
|
||||
if readline.get_current_history_length() == 0:
|
||||
# If no history was loaded, default to .python_history.
|
||||
# The guard is necessary to avoid doubling history size at
|
||||
# each interpreter exit when readline was already configured
|
||||
# through a PYTHONSTARTUP hook, see:
|
||||
# http://bugs.python.org/issue5845#msg198636
|
||||
history = os.path.join(os.path.expanduser('~'),
|
||||
'.python_history')
|
||||
if readline is None or readline.get_current_history_length() == 0:
|
||||
# If no history was loaded, default to .python_history,
|
||||
# or PYTHON_HISTORY.
|
||||
# The guard is necessary to avoid doubling history size at
|
||||
# each interpreter exit when readline was already configured
|
||||
# through a PYTHONSTARTUP hook, see:
|
||||
# http://bugs.python.org/issue5845#msg198636
|
||||
history = gethistoryfile()
|
||||
|
||||
if CAN_USE_PYREPL:
|
||||
readline_module = _pyrepl.readline
|
||||
exceptions = (OSError, *console_errors)
|
||||
else:
|
||||
if readline is None:
|
||||
return
|
||||
readline_module = readline
|
||||
exceptions = OSError
|
||||
|
||||
try:
|
||||
readline_module.read_history_file(history)
|
||||
except exceptions:
|
||||
pass
|
||||
|
||||
def write_history():
|
||||
try:
|
||||
readline.read_history_file(history)
|
||||
except OSError:
|
||||
readline_module.write_history_file(history)
|
||||
except (FileNotFoundError, PermissionError):
|
||||
# home directory does not exist or is not writable
|
||||
# https://bugs.python.org/issue19891
|
||||
pass
|
||||
except OSError:
|
||||
if errno.EROFS:
|
||||
pass # gh-128066: read-only file system
|
||||
else:
|
||||
raise
|
||||
|
||||
def write_history():
|
||||
try:
|
||||
readline.write_history_file(history)
|
||||
except OSError:
|
||||
# bpo-19891, bpo-41193: Home directory does not exist
|
||||
# or is not writable, or the filesystem is read-only.
|
||||
pass
|
||||
atexit.register(write_history)
|
||||
|
||||
atexit.register(write_history)
|
||||
|
||||
sys.__interactivehook__ = register_readline
|
||||
|
||||
def venv(known_paths):
|
||||
global PREFIXES, ENABLE_USER_SITE
|
||||
@@ -679,17 +770,5 @@ def _script():
|
||||
print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
|
||||
sys.exit(10)
|
||||
|
||||
def gethistoryfile():
|
||||
"""Check if the PYTHON_HISTORY environment variable is set and define
|
||||
it as the .python_history file. If PYTHON_HISTORY is not set, use the
|
||||
default .python_history file.
|
||||
"""
|
||||
if not sys.flags.ignore_environment:
|
||||
history = os.environ.get("PYTHON_HISTORY")
|
||||
if history:
|
||||
return history
|
||||
return os.path.join(os.path.expanduser('~'),
|
||||
'.python_history')
|
||||
|
||||
if __name__ == '__main__':
|
||||
_script()
|
||||
|
||||
344
Lib/ssl.py
vendored
344
Lib/ssl.py
vendored
@@ -18,9 +18,10 @@ Functions:
|
||||
seconds past the Epoch (the time values
|
||||
returned from time.time())
|
||||
|
||||
fetch_server_certificate (HOST, PORT) -- fetch the certificate provided
|
||||
by the server running on HOST at port PORT. No
|
||||
validation of the certificate is performed.
|
||||
get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the
|
||||
certificate from the server at the specified
|
||||
address and return it as a PEM-encoded string
|
||||
|
||||
|
||||
Integer constants:
|
||||
|
||||
@@ -94,31 +95,31 @@ import sys
|
||||
import os
|
||||
from collections import namedtuple
|
||||
from enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlag
|
||||
from enum import _simple_enum
|
||||
|
||||
import _ssl # if we can't import it, let the error propagate
|
||||
|
||||
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
|
||||
from _ssl import _SSLContext#, MemoryBIO, SSLSession
|
||||
from _ssl import _SSLContext, MemoryBIO, SSLSession
|
||||
from _ssl import (
|
||||
SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
|
||||
SSLSyscallError, SSLEOFError, SSLCertVerificationError
|
||||
)
|
||||
from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
|
||||
from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
|
||||
from _ssl import RAND_status, RAND_add, RAND_bytes
|
||||
try:
|
||||
from _ssl import RAND_egd
|
||||
except ImportError:
|
||||
# LibreSSL does not provide RAND_egd
|
||||
# RAND_egd is not supported on some platforms
|
||||
pass
|
||||
|
||||
|
||||
from _ssl import (
|
||||
HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
|
||||
HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3
|
||||
HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3, HAS_PSK
|
||||
)
|
||||
from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
|
||||
|
||||
|
||||
_IntEnum._convert_(
|
||||
'_SSLMethod', __name__,
|
||||
lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
|
||||
@@ -155,7 +156,8 @@ _PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()
|
||||
_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)
|
||||
|
||||
|
||||
class TLSVersion(_IntEnum):
|
||||
@_simple_enum(_IntEnum)
|
||||
class TLSVersion:
|
||||
MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED
|
||||
SSLv3 = _ssl.PROTO_SSLv3
|
||||
TLSv1 = _ssl.PROTO_TLSv1
|
||||
@@ -165,7 +167,8 @@ class TLSVersion(_IntEnum):
|
||||
MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED
|
||||
|
||||
|
||||
class _TLSContentType(_IntEnum):
|
||||
@_simple_enum(_IntEnum)
|
||||
class _TLSContentType:
|
||||
"""Content types (record layer)
|
||||
|
||||
See RFC 8446, section B.1
|
||||
@@ -179,7 +182,8 @@ class _TLSContentType(_IntEnum):
|
||||
INNER_CONTENT_TYPE = 0x101
|
||||
|
||||
|
||||
class _TLSAlertType(_IntEnum):
|
||||
@_simple_enum(_IntEnum)
|
||||
class _TLSAlertType:
|
||||
"""Alert types for TLSContentType.ALERT messages
|
||||
|
||||
See RFC 8466, section B.2
|
||||
@@ -220,7 +224,8 @@ class _TLSAlertType(_IntEnum):
|
||||
NO_APPLICATION_PROTOCOL = 120
|
||||
|
||||
|
||||
class _TLSMessageType(_IntEnum):
|
||||
@_simple_enum(_IntEnum)
|
||||
class _TLSMessageType:
|
||||
"""Message types (handshake protocol)
|
||||
|
||||
See RFC 8446, section B.3
|
||||
@@ -250,10 +255,10 @@ class _TLSMessageType(_IntEnum):
|
||||
|
||||
|
||||
if sys.platform == "win32":
|
||||
from _ssl import enum_certificates #, enum_crls
|
||||
from _ssl import enum_certificates, enum_crls
|
||||
|
||||
from socket import socket, AF_INET, SOCK_STREAM, create_connection
|
||||
from socket import SOL_SOCKET, SO_TYPE
|
||||
from socket import socket, SOCK_STREAM, create_connection
|
||||
from socket import SOL_SOCKET, SO_TYPE, _GLOBAL_DEFAULT_TIMEOUT
|
||||
import socket as _socket
|
||||
import base64 # for DER-to-PEM translation
|
||||
import errno
|
||||
@@ -275,7 +280,7 @@ CertificateError = SSLCertVerificationError
|
||||
def _dnsname_match(dn, hostname):
|
||||
"""Matching according to RFC 6125, section 6.4.3
|
||||
|
||||
- Hostnames are compared lower case.
|
||||
- Hostnames are compared lower-case.
|
||||
- For IDNA, both dn and hostname must be encoded as IDN A-label (ACE).
|
||||
- Partial wildcards like 'www*.example.org', multiple wildcards, sole
|
||||
wildcard or wildcards in labels other then the left-most label are not
|
||||
@@ -363,68 +368,11 @@ def _ipaddress_match(cert_ipaddress, host_ip):
|
||||
(section 1.7.2 - "Out of Scope").
|
||||
"""
|
||||
# OpenSSL may add a trailing newline to a subjectAltName's IP address,
|
||||
# commonly woth IPv6 addresses. Strip off trailing \n.
|
||||
# commonly with IPv6 addresses. Strip off trailing \n.
|
||||
ip = _inet_paton(cert_ipaddress.rstrip())
|
||||
return ip == host_ip
|
||||
|
||||
|
||||
def match_hostname(cert, hostname):
|
||||
"""Verify that *cert* (in decoded format as returned by
|
||||
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
|
||||
rules are followed.
|
||||
|
||||
The function matches IP addresses rather than dNSNames if hostname is a
|
||||
valid ipaddress string. IPv4 addresses are supported on all platforms.
|
||||
IPv6 addresses are supported on platforms with IPv6 support (AF_INET6
|
||||
and inet_pton).
|
||||
|
||||
CertificateError is raised on failure. On success, the function
|
||||
returns nothing.
|
||||
"""
|
||||
if not cert:
|
||||
raise ValueError("empty or no certificate, match_hostname needs a "
|
||||
"SSL socket or SSL context with either "
|
||||
"CERT_OPTIONAL or CERT_REQUIRED")
|
||||
try:
|
||||
host_ip = _inet_paton(hostname)
|
||||
except ValueError:
|
||||
# Not an IP address (common case)
|
||||
host_ip = None
|
||||
dnsnames = []
|
||||
san = cert.get('subjectAltName', ())
|
||||
for key, value in san:
|
||||
if key == 'DNS':
|
||||
if host_ip is None and _dnsname_match(value, hostname):
|
||||
return
|
||||
dnsnames.append(value)
|
||||
elif key == 'IP Address':
|
||||
if host_ip is not None and _ipaddress_match(value, host_ip):
|
||||
return
|
||||
dnsnames.append(value)
|
||||
if not dnsnames:
|
||||
# The subject is only checked when there is no dNSName entry
|
||||
# in subjectAltName
|
||||
for sub in cert.get('subject', ()):
|
||||
for key, value in sub:
|
||||
# XXX according to RFC 2818, the most specific Common Name
|
||||
# must be used.
|
||||
if key == 'commonName':
|
||||
if _dnsname_match(value, hostname):
|
||||
return
|
||||
dnsnames.append(value)
|
||||
if len(dnsnames) > 1:
|
||||
raise CertificateError("hostname %r "
|
||||
"doesn't match either of %s"
|
||||
% (hostname, ', '.join(map(repr, dnsnames))))
|
||||
elif len(dnsnames) == 1:
|
||||
raise CertificateError("hostname %r "
|
||||
"doesn't match %r"
|
||||
% (hostname, dnsnames[0]))
|
||||
else:
|
||||
raise CertificateError("no appropriate commonName or "
|
||||
"subjectAltName fields were found")
|
||||
|
||||
|
||||
DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
|
||||
"cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
|
||||
"openssl_capath")
|
||||
@@ -479,7 +427,14 @@ class SSLContext(_SSLContext):
|
||||
sslsocket_class = None # SSLSocket is assigned later.
|
||||
sslobject_class = None # SSLObject is assigned later.
|
||||
|
||||
def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs):
|
||||
def __new__(cls, protocol=None, *args, **kwargs):
|
||||
if protocol is None:
|
||||
warnings.warn(
|
||||
"ssl.SSLContext() without protocol argument is deprecated.",
|
||||
category=DeprecationWarning,
|
||||
stacklevel=2
|
||||
)
|
||||
protocol = PROTOCOL_TLS
|
||||
self = _SSLContext.__new__(cls, protocol)
|
||||
return self
|
||||
|
||||
@@ -518,6 +473,11 @@ class SSLContext(_SSLContext):
|
||||
)
|
||||
|
||||
def set_npn_protocols(self, npn_protocols):
|
||||
warnings.warn(
|
||||
"ssl NPN is deprecated, use ALPN instead",
|
||||
DeprecationWarning,
|
||||
stacklevel=2
|
||||
)
|
||||
protos = bytearray()
|
||||
for protocol in npn_protocols:
|
||||
b = bytes(protocol, 'ascii')
|
||||
@@ -553,18 +513,17 @@ class SSLContext(_SSLContext):
|
||||
self._set_alpn_protocols(protos)
|
||||
|
||||
def _load_windows_store_certs(self, storename, purpose):
|
||||
certs = bytearray()
|
||||
try:
|
||||
for cert, encoding, trust in enum_certificates(storename):
|
||||
# CA certs are never PKCS#7 encoded
|
||||
if encoding == "x509_asn":
|
||||
if trust is True or purpose.oid in trust:
|
||||
certs.extend(cert)
|
||||
try:
|
||||
self.load_verify_locations(cadata=cert)
|
||||
except SSLError as exc:
|
||||
warnings.warn(f"Bad certificate in Windows certificate store: {exc!s}")
|
||||
except PermissionError:
|
||||
warnings.warn("unable to enumerate Windows certificate store")
|
||||
if certs:
|
||||
self.load_verify_locations(cadata=certs)
|
||||
return certs
|
||||
|
||||
def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
|
||||
if not isinstance(purpose, _ASN1Object):
|
||||
@@ -734,12 +693,25 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
||||
# SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
|
||||
# OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
|
||||
# by default.
|
||||
context = SSLContext(PROTOCOL_TLS)
|
||||
|
||||
if purpose == Purpose.SERVER_AUTH:
|
||||
# verify certs and host name in client mode
|
||||
context = SSLContext(PROTOCOL_TLS_CLIENT)
|
||||
context.verify_mode = CERT_REQUIRED
|
||||
context.check_hostname = True
|
||||
elif purpose == Purpose.CLIENT_AUTH:
|
||||
context = SSLContext(PROTOCOL_TLS_SERVER)
|
||||
else:
|
||||
raise ValueError(purpose)
|
||||
|
||||
# `VERIFY_X509_PARTIAL_CHAIN` makes OpenSSL's chain building behave more
|
||||
# like RFC 3280 and 5280, which specify that chain building stops with the
|
||||
# first trust anchor, even if that anchor is not self-signed.
|
||||
#
|
||||
# `VERIFY_X509_STRICT` makes OpenSSL more conservative about the
|
||||
# certificates it accepts, including "disabling workarounds for
|
||||
# some broken certificates."
|
||||
context.verify_flags |= (_ssl.VERIFY_X509_PARTIAL_CHAIN |
|
||||
_ssl.VERIFY_X509_STRICT)
|
||||
|
||||
if cafile or capath or cadata:
|
||||
context.load_verify_locations(cafile, capath, cadata)
|
||||
@@ -755,7 +727,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
||||
context.keylog_filename = keylogfile
|
||||
return context
|
||||
|
||||
def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE,
|
||||
def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE,
|
||||
check_hostname=False, purpose=Purpose.SERVER_AUTH,
|
||||
certfile=None, keyfile=None,
|
||||
cafile=None, capath=None, cadata=None):
|
||||
@@ -772,10 +744,18 @@ def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE,
|
||||
# SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
|
||||
# OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
|
||||
# by default.
|
||||
context = SSLContext(protocol)
|
||||
if purpose == Purpose.SERVER_AUTH:
|
||||
# verify certs and host name in client mode
|
||||
if protocol is None:
|
||||
protocol = PROTOCOL_TLS_CLIENT
|
||||
elif purpose == Purpose.CLIENT_AUTH:
|
||||
if protocol is None:
|
||||
protocol = PROTOCOL_TLS_SERVER
|
||||
else:
|
||||
raise ValueError(purpose)
|
||||
|
||||
if not check_hostname:
|
||||
context.check_hostname = False
|
||||
context = SSLContext(protocol)
|
||||
context.check_hostname = check_hostname
|
||||
if cert_reqs is not None:
|
||||
context.verify_mode = cert_reqs
|
||||
if check_hostname:
|
||||
@@ -905,19 +885,46 @@ class SSLObject:
|
||||
"""
|
||||
return self._sslobj.getpeercert(binary_form)
|
||||
|
||||
def get_verified_chain(self):
|
||||
"""Returns verified certificate chain provided by the other
|
||||
end of the SSL channel as a list of DER-encoded bytes.
|
||||
|
||||
If certificate verification was disabled method acts the same as
|
||||
``SSLSocket.get_unverified_chain``.
|
||||
"""
|
||||
chain = self._sslobj.get_verified_chain()
|
||||
|
||||
if chain is None:
|
||||
return []
|
||||
|
||||
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
|
||||
|
||||
def get_unverified_chain(self):
|
||||
"""Returns raw certificate chain provided by the other
|
||||
end of the SSL channel as a list of DER-encoded bytes.
|
||||
"""
|
||||
chain = self._sslobj.get_unverified_chain()
|
||||
|
||||
if chain is None:
|
||||
return []
|
||||
|
||||
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
|
||||
|
||||
def selected_npn_protocol(self):
|
||||
"""Return the currently selected NPN protocol as a string, or ``None``
|
||||
if a next protocol was not negotiated or if NPN is not supported by one
|
||||
of the peers."""
|
||||
if _ssl.HAS_NPN:
|
||||
return self._sslobj.selected_npn_protocol()
|
||||
warnings.warn(
|
||||
"ssl NPN is deprecated, use ALPN instead",
|
||||
DeprecationWarning,
|
||||
stacklevel=2
|
||||
)
|
||||
|
||||
def selected_alpn_protocol(self):
|
||||
"""Return the currently selected ALPN protocol as a string, or ``None``
|
||||
if a next protocol was not negotiated or if ALPN is not supported by one
|
||||
of the peers."""
|
||||
if _ssl.HAS_ALPN:
|
||||
return self._sslobj.selected_alpn_protocol()
|
||||
return self._sslobj.selected_alpn_protocol()
|
||||
|
||||
def cipher(self):
|
||||
"""Return the currently selected cipher as a 3-tuple ``(name,
|
||||
@@ -996,38 +1003,67 @@ class SSLSocket(socket):
|
||||
if context.check_hostname and not server_hostname:
|
||||
raise ValueError("check_hostname requires server_hostname")
|
||||
|
||||
sock_timeout = sock.gettimeout()
|
||||
kwargs = dict(
|
||||
family=sock.family, type=sock.type, proto=sock.proto,
|
||||
fileno=sock.fileno()
|
||||
)
|
||||
self = cls.__new__(cls, **kwargs)
|
||||
super(SSLSocket, self).__init__(**kwargs)
|
||||
self.settimeout(sock.gettimeout())
|
||||
sock.detach()
|
||||
|
||||
self._context = context
|
||||
self._session = session
|
||||
self._closed = False
|
||||
self._sslobj = None
|
||||
self.server_side = server_side
|
||||
self.server_hostname = context._encode_hostname(server_hostname)
|
||||
self.do_handshake_on_connect = do_handshake_on_connect
|
||||
self.suppress_ragged_eofs = suppress_ragged_eofs
|
||||
|
||||
# See if we are connected
|
||||
# Now SSLSocket is responsible for closing the file descriptor.
|
||||
try:
|
||||
self.getpeername()
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTCONN:
|
||||
raise
|
||||
connected = False
|
||||
else:
|
||||
connected = True
|
||||
self._context = context
|
||||
self._session = session
|
||||
self._closed = False
|
||||
self._sslobj = None
|
||||
self.server_side = server_side
|
||||
self.server_hostname = context._encode_hostname(server_hostname)
|
||||
self.do_handshake_on_connect = do_handshake_on_connect
|
||||
self.suppress_ragged_eofs = suppress_ragged_eofs
|
||||
|
||||
self._connected = connected
|
||||
if connected:
|
||||
# create the SSL object
|
||||
# See if we are connected
|
||||
try:
|
||||
self.getpeername()
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTCONN:
|
||||
raise
|
||||
connected = False
|
||||
blocking = self.getblocking()
|
||||
self.setblocking(False)
|
||||
try:
|
||||
# We are not connected so this is not supposed to block, but
|
||||
# testing revealed otherwise on macOS and Windows so we do
|
||||
# the non-blocking dance regardless. Our raise when any data
|
||||
# is found means consuming the data is harmless.
|
||||
notconn_pre_handshake_data = self.recv(1)
|
||||
except OSError as e:
|
||||
# EINVAL occurs for recv(1) on non-connected on unix sockets.
|
||||
if e.errno not in (errno.ENOTCONN, errno.EINVAL):
|
||||
raise
|
||||
notconn_pre_handshake_data = b''
|
||||
self.setblocking(blocking)
|
||||
if notconn_pre_handshake_data:
|
||||
# This prevents pending data sent to the socket before it was
|
||||
# closed from escaping to the caller who could otherwise
|
||||
# presume it came through a successful TLS connection.
|
||||
reason = "Closed before TLS handshake with data in recv buffer."
|
||||
notconn_pre_handshake_data_error = SSLError(e.errno, reason)
|
||||
# Add the SSLError attributes that _ssl.c always adds.
|
||||
notconn_pre_handshake_data_error.reason = reason
|
||||
notconn_pre_handshake_data_error.library = None
|
||||
try:
|
||||
raise notconn_pre_handshake_data_error
|
||||
finally:
|
||||
# Explicitly break the reference cycle.
|
||||
notconn_pre_handshake_data_error = None
|
||||
else:
|
||||
connected = True
|
||||
|
||||
self.settimeout(sock_timeout) # Must come after setblocking() calls.
|
||||
self._connected = connected
|
||||
if connected:
|
||||
# create the SSL object
|
||||
self._sslobj = self._context._wrap_socket(
|
||||
self, server_side, self.server_hostname,
|
||||
owner=self, session=self._session,
|
||||
@@ -1038,9 +1074,12 @@ class SSLSocket(socket):
|
||||
# non-blocking
|
||||
raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
|
||||
self.do_handshake()
|
||||
except (OSError, ValueError):
|
||||
except:
|
||||
try:
|
||||
self.close()
|
||||
raise
|
||||
except OSError:
|
||||
pass
|
||||
raise
|
||||
return self
|
||||
|
||||
@property
|
||||
@@ -1123,13 +1162,33 @@ class SSLSocket(socket):
|
||||
self._check_connected()
|
||||
return self._sslobj.getpeercert(binary_form)
|
||||
|
||||
@_sslcopydoc
|
||||
def get_verified_chain(self):
|
||||
chain = self._sslobj.get_verified_chain()
|
||||
|
||||
if chain is None:
|
||||
return []
|
||||
|
||||
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
|
||||
|
||||
@_sslcopydoc
|
||||
def get_unverified_chain(self):
|
||||
chain = self._sslobj.get_unverified_chain()
|
||||
|
||||
if chain is None:
|
||||
return []
|
||||
|
||||
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
|
||||
|
||||
@_sslcopydoc
|
||||
def selected_npn_protocol(self):
|
||||
self._checkClosed()
|
||||
if self._sslobj is None or not _ssl.HAS_NPN:
|
||||
return None
|
||||
else:
|
||||
return self._sslobj.selected_npn_protocol()
|
||||
warnings.warn(
|
||||
"ssl NPN is deprecated, use ALPN instead",
|
||||
DeprecationWarning,
|
||||
stacklevel=2
|
||||
)
|
||||
return None
|
||||
|
||||
@_sslcopydoc
|
||||
def selected_alpn_protocol(self):
|
||||
@@ -1229,10 +1288,14 @@ class SSLSocket(socket):
|
||||
|
||||
def recv_into(self, buffer, nbytes=None, flags=0):
|
||||
self._checkClosed()
|
||||
if buffer and (nbytes is None):
|
||||
nbytes = len(buffer)
|
||||
elif nbytes is None:
|
||||
nbytes = 1024
|
||||
if nbytes is None:
|
||||
if buffer is not None:
|
||||
with memoryview(buffer) as view:
|
||||
nbytes = view.nbytes
|
||||
if not nbytes:
|
||||
nbytes = 1024
|
||||
else:
|
||||
nbytes = 1024
|
||||
if self._sslobj is not None:
|
||||
if flags != 0:
|
||||
raise ValueError(
|
||||
@@ -1382,32 +1445,6 @@ SSLContext.sslsocket_class = SSLSocket
|
||||
SSLContext.sslobject_class = SSLObject
|
||||
|
||||
|
||||
def wrap_socket(sock, keyfile=None, certfile=None,
|
||||
server_side=False, cert_reqs=CERT_NONE,
|
||||
ssl_version=PROTOCOL_TLS, ca_certs=None,
|
||||
do_handshake_on_connect=True,
|
||||
suppress_ragged_eofs=True,
|
||||
ciphers=None):
|
||||
|
||||
if server_side and not certfile:
|
||||
raise ValueError("certfile must be specified for server-side "
|
||||
"operations")
|
||||
if keyfile and not certfile:
|
||||
raise ValueError("certfile must be specified")
|
||||
context = SSLContext(ssl_version)
|
||||
context.verify_mode = cert_reqs
|
||||
if ca_certs:
|
||||
context.load_verify_locations(ca_certs)
|
||||
if certfile:
|
||||
context.load_cert_chain(certfile, keyfile)
|
||||
if ciphers:
|
||||
context.set_ciphers(ciphers)
|
||||
return context.wrap_socket(
|
||||
sock=sock, server_side=server_side,
|
||||
do_handshake_on_connect=do_handshake_on_connect,
|
||||
suppress_ragged_eofs=suppress_ragged_eofs
|
||||
)
|
||||
|
||||
# some utility functions
|
||||
|
||||
def cert_time_to_seconds(cert_time):
|
||||
@@ -1466,11 +1503,14 @@ def PEM_cert_to_DER_cert(pem_cert_string):
|
||||
d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
|
||||
return base64.decodebytes(d.encode('ASCII', 'strict'))
|
||||
|
||||
def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):
|
||||
def get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT,
|
||||
ca_certs=None, timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
||||
"""Retrieve the certificate from the server at the specified address,
|
||||
and return it as a PEM-encoded string.
|
||||
If 'ca_certs' is specified, validate the server cert against it.
|
||||
If 'ssl_version' is specified, use it in the connection attempt."""
|
||||
If 'ssl_version' is specified, use it in the connection attempt.
|
||||
If 'timeout' is specified, use it in the connection attempt.
|
||||
"""
|
||||
|
||||
host, port = addr
|
||||
if ca_certs is not None:
|
||||
@@ -1480,8 +1520,8 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):
|
||||
context = _create_stdlib_context(ssl_version,
|
||||
cert_reqs=cert_reqs,
|
||||
cafile=ca_certs)
|
||||
with create_connection(addr) as sock:
|
||||
with context.wrap_socket(sock) as sslsock:
|
||||
with create_connection(addr, timeout=timeout) as sock:
|
||||
with context.wrap_socket(sock, server_hostname=host) as sslsock:
|
||||
dercert = sslsock.getpeercert(True)
|
||||
return DER_cert_to_PEM_cert(dercert)
|
||||
|
||||
|
||||
570
Lib/sysconfig.py → Lib/sysconfig/__init__.py
vendored
570
Lib/sysconfig.py → Lib/sysconfig/__init__.py
vendored
@@ -1,10 +1,9 @@
|
||||
# XXX: RUSTPYTHON; Trick to make sysconfig work as RustPython
|
||||
exec(r'''
|
||||
"""Access to Python's configuration information."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from os.path import pardir, realpath
|
||||
import threading
|
||||
from os.path import realpath
|
||||
|
||||
__all__ = [
|
||||
'get_config_h_filename',
|
||||
@@ -22,29 +21,30 @@ __all__ = [
|
||||
|
||||
# Keys for get_config_var() that are never converted to Python integers.
|
||||
_ALWAYS_STR = {
|
||||
'IPHONEOS_DEPLOYMENT_TARGET',
|
||||
'MACOSX_DEPLOYMENT_TARGET',
|
||||
}
|
||||
|
||||
_INSTALL_SCHEMES = {
|
||||
'posix_prefix': {
|
||||
'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}',
|
||||
'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}',
|
||||
'purelib': '{base}/lib/python{py_version_short}/site-packages',
|
||||
'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages',
|
||||
'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'purelib': '{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'include':
|
||||
'{installed_base}/include/python{py_version_short}{abiflags}',
|
||||
'{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}',
|
||||
'platinclude':
|
||||
'{installed_platbase}/include/python{py_version_short}{abiflags}',
|
||||
'{installed_platbase}/include/{implementation_lower}{py_version_short}{abiflags}',
|
||||
'scripts': '{base}/bin',
|
||||
'data': '{base}',
|
||||
},
|
||||
'posix_home': {
|
||||
'stdlib': '{installed_base}/lib/python',
|
||||
'platstdlib': '{base}/lib/python',
|
||||
'purelib': '{base}/lib/python',
|
||||
'platlib': '{base}/lib/python',
|
||||
'include': '{installed_base}/include/python',
|
||||
'platinclude': '{installed_base}/include/python',
|
||||
'stdlib': '{installed_base}/lib/{implementation_lower}',
|
||||
'platstdlib': '{base}/lib/{implementation_lower}',
|
||||
'purelib': '{base}/lib/{implementation_lower}',
|
||||
'platlib': '{base}/lib/{implementation_lower}',
|
||||
'include': '{installed_base}/include/{implementation_lower}',
|
||||
'platinclude': '{installed_base}/include/{implementation_lower}',
|
||||
'scripts': '{base}/bin',
|
||||
'data': '{base}',
|
||||
},
|
||||
@@ -58,6 +58,7 @@ _INSTALL_SCHEMES = {
|
||||
'scripts': '{base}/Scripts',
|
||||
'data': '{base}',
|
||||
},
|
||||
|
||||
# Downstream distributors can overwrite the default install scheme.
|
||||
# This is done to support downstream modifications where distributors change
|
||||
# the installation layout (eg. different site-packages directory).
|
||||
@@ -76,14 +77,14 @@ _INSTALL_SCHEMES = {
|
||||
# Downstream distributors who patch posix_prefix/nt scheme are encouraged to
|
||||
# leave the following schemes unchanged
|
||||
'posix_venv': {
|
||||
'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}',
|
||||
'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}',
|
||||
'purelib': '{base}/lib/python{py_version_short}/site-packages',
|
||||
'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages',
|
||||
'stdlib': '{installed_base}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'platstdlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'purelib': '{base}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'platlib': '{platbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'include':
|
||||
'{installed_base}/include/python{py_version_short}{abiflags}',
|
||||
'{installed_base}/include/{implementation_lower}{py_version_short}{abiflags}',
|
||||
'platinclude':
|
||||
'{installed_platbase}/include/python{py_version_short}{abiflags}',
|
||||
'{installed_platbase}/include/{implementation_lower}{py_version_short}{abiflags}',
|
||||
'scripts': '{base}/bin',
|
||||
'data': '{base}',
|
||||
},
|
||||
@@ -105,6 +106,8 @@ if os.name == 'nt':
|
||||
else:
|
||||
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
|
||||
|
||||
def _get_implementation():
|
||||
return 'RustPython' # XXX: For site-packages
|
||||
|
||||
# NOTE: site.py has copy of this function.
|
||||
# Sync it when modify this function.
|
||||
@@ -113,8 +116,8 @@ def _getuserbase():
|
||||
if env_base:
|
||||
return env_base
|
||||
|
||||
# Emscripten, VxWorks, and WASI have no home directories
|
||||
if sys.platform in {"emscripten", "vxworks", "wasi"}:
|
||||
# Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories
|
||||
if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}:
|
||||
return None
|
||||
|
||||
def joinuser(*args):
|
||||
@@ -122,7 +125,7 @@ def _getuserbase():
|
||||
|
||||
if os.name == "nt":
|
||||
base = os.environ.get("APPDATA") or "~"
|
||||
return joinuser(base, "Python")
|
||||
return joinuser(base, _get_implementation())
|
||||
|
||||
if sys.platform == "darwin" and sys._framework:
|
||||
return joinuser("~", "Library", sys._framework,
|
||||
@@ -136,29 +139,29 @@ if _HAS_USER_BASE:
|
||||
_INSTALL_SCHEMES |= {
|
||||
# NOTE: When modifying "purelib" scheme, update site._get_path() too.
|
||||
'nt_user': {
|
||||
'stdlib': '{userbase}/Python{py_version_nodot_plat}',
|
||||
'platstdlib': '{userbase}/Python{py_version_nodot_plat}',
|
||||
'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
|
||||
'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
|
||||
'include': '{userbase}/Python{py_version_nodot_plat}/Include',
|
||||
'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts',
|
||||
'stdlib': '{userbase}/{implementation}{py_version_nodot_plat}',
|
||||
'platstdlib': '{userbase}/{implementation}{py_version_nodot_plat}',
|
||||
'purelib': '{userbase}/{implementation}{py_version_nodot_plat}/site-packages',
|
||||
'platlib': '{userbase}/{implementation}{py_version_nodot_plat}/site-packages',
|
||||
'include': '{userbase}/{implementation}{py_version_nodot_plat}/Include',
|
||||
'scripts': '{userbase}/{implementation}{py_version_nodot_plat}/Scripts',
|
||||
'data': '{userbase}',
|
||||
},
|
||||
'posix_user': {
|
||||
'stdlib': '{userbase}/{platlibdir}/python{py_version_short}',
|
||||
'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}',
|
||||
'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
|
||||
'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
|
||||
'include': '{userbase}/include/python{py_version_short}',
|
||||
'stdlib': '{userbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'platstdlib': '{userbase}/{platlibdir}/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'purelib': '{userbase}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'platlib': '{userbase}/lib/{implementation_lower}{py_version_short}{abi_thread}/site-packages',
|
||||
'include': '{userbase}/include/{implementation_lower}{py_version_short}{abi_thread}',
|
||||
'scripts': '{userbase}/bin',
|
||||
'data': '{userbase}',
|
||||
},
|
||||
'osx_framework_user': {
|
||||
'stdlib': '{userbase}/lib/python',
|
||||
'platstdlib': '{userbase}/lib/python',
|
||||
'purelib': '{userbase}/lib/python/site-packages',
|
||||
'platlib': '{userbase}/lib/python/site-packages',
|
||||
'include': '{userbase}/include/python{py_version_short}',
|
||||
'stdlib': '{userbase}/lib/{implementation_lower}',
|
||||
'platstdlib': '{userbase}/lib/{implementation_lower}',
|
||||
'purelib': '{userbase}/lib/{implementation_lower}/site-packages',
|
||||
'platlib': '{userbase}/lib/{implementation_lower}/site-packages',
|
||||
'include': '{userbase}/include/{implementation_lower}{py_version_short}',
|
||||
'scripts': '{userbase}/bin',
|
||||
'data': '{userbase}',
|
||||
},
|
||||
@@ -170,19 +173,15 @@ _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
|
||||
_PY_VERSION = sys.version.split()[0]
|
||||
_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}'
|
||||
_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}'
|
||||
_PREFIX = os.path.normpath(sys.prefix)
|
||||
_BASE_PREFIX = os.path.normpath(sys.base_prefix)
|
||||
_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
|
||||
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
|
||||
# Mutex guarding initialization of _CONFIG_VARS.
|
||||
_CONFIG_VARS_LOCK = threading.RLock()
|
||||
_CONFIG_VARS = None
|
||||
# True iff _CONFIG_VARS has been fully initialized.
|
||||
_CONFIG_VARS_INITIALIZED = False
|
||||
_USER_BASE = None
|
||||
|
||||
# Regexes needed for parsing Makefile (and similar syntaxes,
|
||||
# like old-style Setup files).
|
||||
_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)"
|
||||
_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)"
|
||||
_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}"
|
||||
|
||||
|
||||
def _safe_realpath(path):
|
||||
try:
|
||||
@@ -221,8 +220,15 @@ if "_PYTHON_PROJECT_BASE" in os.environ:
|
||||
def is_python_build(check_home=None):
|
||||
if check_home is not None:
|
||||
import warnings
|
||||
warnings.warn("check_home argument is deprecated and ignored.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
warnings.warn(
|
||||
(
|
||||
'The check_home argument of sysconfig.is_python_build is '
|
||||
'deprecated and its value is ignored. '
|
||||
'It will be removed in Python 3.15.'
|
||||
),
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
for fn in ("Setup", "Setup.local"):
|
||||
if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):
|
||||
return True
|
||||
@@ -291,6 +297,7 @@ def _get_preferred_schemes():
|
||||
'home': 'posix_home',
|
||||
'user': 'osx_framework_user',
|
||||
}
|
||||
|
||||
return {
|
||||
'prefix': 'posix_prefix',
|
||||
'home': 'posix_home',
|
||||
@@ -314,134 +321,6 @@ def get_default_scheme():
|
||||
return get_preferred_scheme('prefix')
|
||||
|
||||
|
||||
def _parse_makefile(filename, vars=None, keep_unresolved=True):
|
||||
"""Parse a Makefile-style file.
|
||||
|
||||
A dictionary containing name/value pairs is returned. If an
|
||||
optional dictionary is passed in as the second argument, it is
|
||||
used instead of a new dictionary.
|
||||
"""
|
||||
import re
|
||||
|
||||
if vars is None:
|
||||
vars = {}
|
||||
done = {}
|
||||
notdone = {}
|
||||
|
||||
with open(filename, encoding=sys.getfilesystemencoding(),
|
||||
errors="surrogateescape") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('#') or line.strip() == '':
|
||||
continue
|
||||
m = re.match(_variable_rx, line)
|
||||
if m:
|
||||
n, v = m.group(1, 2)
|
||||
v = v.strip()
|
||||
# `$$' is a literal `$' in make
|
||||
tmpv = v.replace('$$', '')
|
||||
|
||||
if "$" in tmpv:
|
||||
notdone[n] = v
|
||||
else:
|
||||
try:
|
||||
if n in _ALWAYS_STR:
|
||||
raise ValueError
|
||||
|
||||
v = int(v)
|
||||
except ValueError:
|
||||
# insert literal `$'
|
||||
done[n] = v.replace('$$', '$')
|
||||
else:
|
||||
done[n] = v
|
||||
|
||||
# do variable interpolation here
|
||||
variables = list(notdone.keys())
|
||||
|
||||
# Variables with a 'PY_' prefix in the makefile. These need to
|
||||
# be made available without that prefix through sysconfig.
|
||||
# Special care is needed to ensure that variable expansion works, even
|
||||
# if the expansion uses the name without a prefix.
|
||||
renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
|
||||
|
||||
while len(variables) > 0:
|
||||
for name in tuple(variables):
|
||||
value = notdone[name]
|
||||
m1 = re.search(_findvar1_rx, value)
|
||||
m2 = re.search(_findvar2_rx, value)
|
||||
if m1 and m2:
|
||||
m = m1 if m1.start() < m2.start() else m2
|
||||
else:
|
||||
m = m1 if m1 else m2
|
||||
if m is not None:
|
||||
n = m.group(1)
|
||||
found = True
|
||||
if n in done:
|
||||
item = str(done[n])
|
||||
elif n in notdone:
|
||||
# get it on a subsequent round
|
||||
found = False
|
||||
elif n in os.environ:
|
||||
# do it like make: fall back to environment
|
||||
item = os.environ[n]
|
||||
|
||||
elif n in renamed_variables:
|
||||
if (name.startswith('PY_') and
|
||||
name[3:] in renamed_variables):
|
||||
item = ""
|
||||
|
||||
elif 'PY_' + n in notdone:
|
||||
found = False
|
||||
|
||||
else:
|
||||
item = str(done['PY_' + n])
|
||||
|
||||
else:
|
||||
done[n] = item = ""
|
||||
|
||||
if found:
|
||||
after = value[m.end():]
|
||||
value = value[:m.start()] + item + after
|
||||
if "$" in after:
|
||||
notdone[name] = value
|
||||
else:
|
||||
try:
|
||||
if name in _ALWAYS_STR:
|
||||
raise ValueError
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
done[name] = value.strip()
|
||||
else:
|
||||
done[name] = value
|
||||
variables.remove(name)
|
||||
|
||||
if name.startswith('PY_') \
|
||||
and name[3:] in renamed_variables:
|
||||
|
||||
name = name[3:]
|
||||
if name not in done:
|
||||
done[name] = value
|
||||
|
||||
else:
|
||||
# Adds unresolved variables to the done dict.
|
||||
# This is disabled when called from distutils.sysconfig
|
||||
if keep_unresolved:
|
||||
done[name] = value
|
||||
# bogus variable reference (e.g. "prefix=$/opt/python");
|
||||
# just drop it since we can't deal
|
||||
variables.remove(name)
|
||||
|
||||
# strip spurious spaces
|
||||
for k, v in done.items():
|
||||
if isinstance(v, str):
|
||||
done[k] = v.strip()
|
||||
|
||||
# save the results in the global dictionary
|
||||
vars.update(done)
|
||||
return vars
|
||||
|
||||
|
||||
def get_makefile_filename():
|
||||
"""Return the path of the Makefile."""
|
||||
if _PYTHON_BUILD:
|
||||
@@ -462,91 +341,44 @@ def _get_sysconfigdata_name():
|
||||
f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}',
|
||||
)
|
||||
|
||||
|
||||
def _generate_posix_vars():
|
||||
"""Generate the Python module containing build-time variables."""
|
||||
import pprint
|
||||
vars = {}
|
||||
# load the installed Makefile:
|
||||
makefile = get_makefile_filename()
|
||||
try:
|
||||
_parse_makefile(makefile, vars)
|
||||
except OSError as e:
|
||||
msg = f"invalid Python installation: unable to open {makefile}"
|
||||
if hasattr(e, "strerror"):
|
||||
msg = f"{msg} ({e.strerror})"
|
||||
raise OSError(msg)
|
||||
# load the installed pyconfig.h:
|
||||
config_h = get_config_h_filename()
|
||||
try:
|
||||
with open(config_h, encoding="utf-8") as f:
|
||||
parse_config_h(f, vars)
|
||||
except OSError as e:
|
||||
msg = f"invalid Python installation: unable to open {config_h}"
|
||||
if hasattr(e, "strerror"):
|
||||
msg = f"{msg} ({e.strerror})"
|
||||
raise OSError(msg)
|
||||
# On AIX, there are wrong paths to the linker scripts in the Makefile
|
||||
# -- these paths are relative to the Python source, but when installed
|
||||
# the scripts are in another directory.
|
||||
if _PYTHON_BUILD:
|
||||
vars['BLDSHARED'] = vars['LDSHARED']
|
||||
|
||||
# There's a chicken-and-egg situation on OS X with regards to the
|
||||
# _sysconfigdata module after the changes introduced by #15298:
|
||||
# get_config_vars() is called by get_platform() as part of the
|
||||
# `make pybuilddir.txt` target -- which is a precursor to the
|
||||
# _sysconfigdata.py module being constructed. Unfortunately,
|
||||
# get_config_vars() eventually calls _init_posix(), which attempts
|
||||
# to import _sysconfigdata, which we won't have built yet. In order
|
||||
# for _init_posix() to work, if we're on Darwin, just mock up the
|
||||
# _sysconfigdata module manually and populate it with the build vars.
|
||||
# This is more than sufficient for ensuring the subsequent call to
|
||||
# get_platform() succeeds.
|
||||
name = _get_sysconfigdata_name()
|
||||
if 'darwin' in sys.platform:
|
||||
import types
|
||||
module = types.ModuleType(name)
|
||||
module.build_time_vars = vars
|
||||
sys.modules[name] = module
|
||||
|
||||
pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}'
|
||||
if hasattr(sys, "gettotalrefcount"):
|
||||
pybuilddir += '-pydebug'
|
||||
os.makedirs(pybuilddir, exist_ok=True)
|
||||
destfile = os.path.join(pybuilddir, name + '.py')
|
||||
|
||||
with open(destfile, 'w', encoding='utf8') as f:
|
||||
f.write('# system configuration generated and used by'
|
||||
' the sysconfig module\n')
|
||||
f.write('build_time_vars = ')
|
||||
pprint.pprint(vars, stream=f)
|
||||
|
||||
# Create file used for sys.path fixup -- see Modules/getpath.c
|
||||
with open('pybuilddir.txt', 'w', encoding='utf8') as f:
|
||||
f.write(pybuilddir)
|
||||
|
||||
def _init_posix(vars):
|
||||
"""Initialize the module as appropriate for POSIX systems."""
|
||||
# _sysconfigdata is generated at build time, see _generate_posix_vars()
|
||||
name = _get_sysconfigdata_name()
|
||||
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
|
||||
|
||||
# For cross builds, the path to the target's sysconfigdata must be specified
|
||||
# so it can be imported. It cannot be in PYTHONPATH, as foreign modules in
|
||||
# sys.path can cause crashes when loaded by the host interpreter.
|
||||
# Rely on truthiness as a valueless env variable is still an empty string.
|
||||
# See OS X note in _generate_posix_vars re _sysconfigdata.
|
||||
if (path := os.environ.get('_PYTHON_SYSCONFIGDATA_PATH')):
|
||||
from importlib.machinery import FileFinder, SourceFileLoader, SOURCE_SUFFIXES
|
||||
from importlib.util import module_from_spec
|
||||
spec = FileFinder(path, (SourceFileLoader, SOURCE_SUFFIXES)).find_spec(name)
|
||||
_temp = module_from_spec(spec)
|
||||
spec.loader.exec_module(_temp)
|
||||
else:
|
||||
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
|
||||
build_time_vars = _temp.build_time_vars
|
||||
vars.update(build_time_vars)
|
||||
|
||||
def _init_non_posix(vars):
|
||||
"""Initialize the module as appropriate for NT"""
|
||||
# set basic install directories
|
||||
import _imp
|
||||
import _winapi
|
||||
import _sysconfig
|
||||
vars['LIBDEST'] = get_path('stdlib')
|
||||
vars['BINLIBDEST'] = get_path('platstdlib')
|
||||
vars['INCLUDEPY'] = get_path('include')
|
||||
try:
|
||||
# GH-99201: _imp.extension_suffixes may be empty when
|
||||
# HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX.
|
||||
vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
# Add EXT_SUFFIX, SOABI, and Py_GIL_DISABLED
|
||||
vars.update(_sysconfig.config_vars())
|
||||
|
||||
vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs'))
|
||||
if hasattr(sys, 'dllhandle'):
|
||||
dllhandle = _winapi.GetModuleFileName(sys.dllhandle)
|
||||
vars['LIBRARY'] = os.path.basename(_safe_realpath(dllhandle))
|
||||
vars['LDLIBRARY'] = vars['LIBRARY']
|
||||
vars['EXE'] = '.exe'
|
||||
vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
|
||||
vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
|
||||
@@ -595,7 +427,7 @@ def get_config_h_filename():
|
||||
"""Return the path of pyconfig.h."""
|
||||
if _PYTHON_BUILD:
|
||||
if os.name == "nt":
|
||||
inc_dir = os.path.join(_PROJECT_BASE, "PC")
|
||||
inc_dir = os.path.dirname(sys._base_executable)
|
||||
else:
|
||||
inc_dir = _PROJECT_BASE
|
||||
else:
|
||||
@@ -633,6 +465,78 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True):
|
||||
return get_paths(scheme, vars, expand)[name]
|
||||
|
||||
|
||||
def _init_config_vars():
|
||||
global _CONFIG_VARS
|
||||
_CONFIG_VARS = {}
|
||||
# Normalized versions of prefix and exec_prefix are handy to have;
|
||||
# in fact, these are the standard versions used most places in the
|
||||
# Distutils.
|
||||
_PREFIX = os.path.normpath(sys.prefix)
|
||||
_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
|
||||
_CONFIG_VARS['prefix'] = _PREFIX # FIXME: This gets overwriten by _init_posix.
|
||||
_CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX # FIXME: This gets overwriten by _init_posix.
|
||||
_CONFIG_VARS['py_version'] = _PY_VERSION
|
||||
_CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
|
||||
_CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT
|
||||
_CONFIG_VARS['installed_base'] = _BASE_PREFIX
|
||||
_CONFIG_VARS['base'] = _PREFIX
|
||||
_CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX
|
||||
_CONFIG_VARS['platbase'] = _EXEC_PREFIX
|
||||
_CONFIG_VARS['projectbase'] = _PROJECT_BASE
|
||||
_CONFIG_VARS['platlibdir'] = sys.platlibdir
|
||||
_CONFIG_VARS['implementation'] = _get_implementation()
|
||||
_CONFIG_VARS['implementation_lower'] = _get_implementation().lower()
|
||||
try:
|
||||
_CONFIG_VARS['abiflags'] = sys.abiflags
|
||||
except AttributeError:
|
||||
# sys.abiflags may not be defined on all platforms.
|
||||
_CONFIG_VARS['abiflags'] = ''
|
||||
try:
|
||||
_CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '')
|
||||
except AttributeError:
|
||||
_CONFIG_VARS['py_version_nodot_plat'] = ''
|
||||
|
||||
if os.name == 'nt':
|
||||
_init_non_posix(_CONFIG_VARS)
|
||||
_CONFIG_VARS['VPATH'] = sys._vpath
|
||||
if os.name == 'posix':
|
||||
_init_posix(_CONFIG_VARS)
|
||||
if _HAS_USER_BASE:
|
||||
# Setting 'userbase' is done below the call to the
|
||||
# init function to enable using 'get_config_var' in
|
||||
# the init-function.
|
||||
_CONFIG_VARS['userbase'] = _getuserbase()
|
||||
|
||||
# e.g., 't' for free-threaded or '' for default build
|
||||
_CONFIG_VARS['abi_thread'] = 't' if _CONFIG_VARS.get('Py_GIL_DISABLED') else ''
|
||||
|
||||
# Always convert srcdir to an absolute path
|
||||
srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
|
||||
if os.name == 'posix':
|
||||
if _PYTHON_BUILD:
|
||||
# If srcdir is a relative path (typically '.' or '..')
|
||||
# then it should be interpreted relative to the directory
|
||||
# containing Makefile.
|
||||
base = os.path.dirname(get_makefile_filename())
|
||||
srcdir = os.path.join(base, srcdir)
|
||||
else:
|
||||
# srcdir is not meaningful since the installation is
|
||||
# spread about the filesystem. We choose the
|
||||
# directory containing the Makefile since we know it
|
||||
# exists.
|
||||
srcdir = os.path.dirname(get_makefile_filename())
|
||||
_CONFIG_VARS['srcdir'] = _safe_realpath(srcdir)
|
||||
|
||||
# OS X platforms require special customization to handle
|
||||
# multi-architecture, multi-os-version installers
|
||||
if sys.platform == 'darwin':
|
||||
import _osx_support
|
||||
_osx_support.customize_config_vars(_CONFIG_VARS)
|
||||
|
||||
global _CONFIG_VARS_INITIALIZED
|
||||
_CONFIG_VARS_INITIALIZED = True
|
||||
|
||||
|
||||
def get_config_vars(*args):
|
||||
"""With no arguments, return a dictionary of all configuration
|
||||
variables relevant for the current platform.
|
||||
@@ -643,66 +547,26 @@ def get_config_vars(*args):
|
||||
With arguments, return a list of values that result from looking up
|
||||
each argument in the configuration variable dictionary.
|
||||
"""
|
||||
global _CONFIG_VARS
|
||||
if _CONFIG_VARS is None:
|
||||
_CONFIG_VARS = {}
|
||||
# Normalized versions of prefix and exec_prefix are handy to have;
|
||||
# in fact, these are the standard versions used most places in the
|
||||
# Distutils.
|
||||
_CONFIG_VARS['prefix'] = _PREFIX
|
||||
_CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
|
||||
_CONFIG_VARS['py_version'] = _PY_VERSION
|
||||
_CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
|
||||
_CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT
|
||||
_CONFIG_VARS['installed_base'] = _BASE_PREFIX
|
||||
_CONFIG_VARS['base'] = _PREFIX
|
||||
_CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX
|
||||
_CONFIG_VARS['platbase'] = _EXEC_PREFIX
|
||||
_CONFIG_VARS['projectbase'] = _PROJECT_BASE
|
||||
_CONFIG_VARS['platlibdir'] = sys.platlibdir
|
||||
try:
|
||||
_CONFIG_VARS['abiflags'] = sys.abiflags
|
||||
except AttributeError:
|
||||
# sys.abiflags may not be defined on all platforms.
|
||||
_CONFIG_VARS['abiflags'] = ''
|
||||
try:
|
||||
_CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '')
|
||||
except AttributeError:
|
||||
_CONFIG_VARS['py_version_nodot_plat'] = ''
|
||||
global _CONFIG_VARS_INITIALIZED
|
||||
|
||||
if os.name == 'nt':
|
||||
_init_non_posix(_CONFIG_VARS)
|
||||
_CONFIG_VARS['VPATH'] = sys._vpath
|
||||
if os.name == 'posix':
|
||||
_init_posix(_CONFIG_VARS)
|
||||
if _HAS_USER_BASE:
|
||||
# Setting 'userbase' is done below the call to the
|
||||
# init function to enable using 'get_config_var' in
|
||||
# the init-function.
|
||||
_CONFIG_VARS['userbase'] = _getuserbase()
|
||||
|
||||
# Always convert srcdir to an absolute path
|
||||
srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
|
||||
if os.name == 'posix':
|
||||
if _PYTHON_BUILD:
|
||||
# If srcdir is a relative path (typically '.' or '..')
|
||||
# then it should be interpreted relative to the directory
|
||||
# containing Makefile.
|
||||
base = os.path.dirname(get_makefile_filename())
|
||||
srcdir = os.path.join(base, srcdir)
|
||||
else:
|
||||
# srcdir is not meaningful since the installation is
|
||||
# spread about the filesystem. We choose the
|
||||
# directory containing the Makefile since we know it
|
||||
# exists.
|
||||
srcdir = os.path.dirname(get_makefile_filename())
|
||||
_CONFIG_VARS['srcdir'] = _safe_realpath(srcdir)
|
||||
|
||||
# OS X platforms require special customization to handle
|
||||
# multi-architecture, multi-os-version installers
|
||||
if sys.platform == 'darwin':
|
||||
import _osx_support
|
||||
_osx_support.customize_config_vars(_CONFIG_VARS)
|
||||
# Avoid claiming the lock once initialization is complete.
|
||||
if not _CONFIG_VARS_INITIALIZED:
|
||||
with _CONFIG_VARS_LOCK:
|
||||
# Test again with the lock held to avoid races. Note that
|
||||
# we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED,
|
||||
# to ensure that recursive calls to get_config_vars()
|
||||
# don't re-enter init_config_vars().
|
||||
if _CONFIG_VARS is None:
|
||||
_init_config_vars()
|
||||
else:
|
||||
# If the site module initialization happened after _CONFIG_VARS was
|
||||
# initialized, a virtual environment might have been activated, resulting in
|
||||
# variables like sys.prefix changing their value, so we need to re-init the
|
||||
# config vars (see GH-126789).
|
||||
if _CONFIG_VARS['base'] != os.path.normpath(sys.prefix):
|
||||
with _CONFIG_VARS_LOCK:
|
||||
_CONFIG_VARS_INITIALIZED = False
|
||||
_init_config_vars()
|
||||
|
||||
if args:
|
||||
vals = []
|
||||
@@ -732,17 +596,22 @@ def get_platform():
|
||||
isn't particularly important.
|
||||
|
||||
Examples of returned values:
|
||||
linux-i586
|
||||
linux-alpha (?)
|
||||
solaris-2.6-sun4u
|
||||
|
||||
Windows will return one of:
|
||||
win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
|
||||
win32 (all others - specifically, sys.platform is returned)
|
||||
|
||||
For other non-POSIX platforms, currently just returns 'sys.platform'.
|
||||
Windows:
|
||||
|
||||
"""
|
||||
- win-amd64 (64-bit Windows on AMD64, aka x86_64, Intel64, and EM64T)
|
||||
- win-arm64 (64-bit Windows on ARM64, aka AArch64)
|
||||
- win32 (all others - specifically, sys.platform is returned)
|
||||
|
||||
POSIX based OS:
|
||||
|
||||
- linux-x86_64
|
||||
- macosx-15.5-arm64
|
||||
- macosx-26.0-universal2 (macOS on Apple Silicon or Intel)
|
||||
- android-24-arm64_v8a
|
||||
|
||||
For other non-POSIX platforms, currently just returns :data:`sys.platform`."""
|
||||
if os.name == 'nt':
|
||||
if 'amd64' in sys.version.lower():
|
||||
return 'win-amd64'
|
||||
@@ -770,10 +639,22 @@ def get_platform():
|
||||
machine = machine.replace('/', '-')
|
||||
|
||||
if osname[:5] == "linux":
|
||||
# At least on Linux/Intel, 'machine' is the processor --
|
||||
# i386, etc.
|
||||
# XXX what about Alpha, SPARC, etc?
|
||||
return f"{osname}-{machine}"
|
||||
if sys.platform == "android":
|
||||
osname = "android"
|
||||
release = get_config_var("ANDROID_API_LEVEL")
|
||||
|
||||
# Wheel tags use the ABI names from Android's own tools.
|
||||
machine = {
|
||||
"x86_64": "x86_64",
|
||||
"i686": "x86",
|
||||
"aarch64": "arm64_v8a",
|
||||
"armv7l": "armeabi_v7a",
|
||||
}[machine]
|
||||
else:
|
||||
# At least on Linux/Intel, 'machine' is the processor --
|
||||
# i386, etc.
|
||||
# XXX what about Alpha, SPARC, etc?
|
||||
return f"{osname}-{machine}"
|
||||
elif osname[:5] == "sunos":
|
||||
if release[0] >= "5": # SunOS 5 == Solaris 2
|
||||
osname = "solaris"
|
||||
@@ -795,10 +676,15 @@ def get_platform():
|
||||
if m:
|
||||
release = m.group()
|
||||
elif osname[:6] == "darwin":
|
||||
import _osx_support
|
||||
osname, release, machine = _osx_support.get_platform_osx(
|
||||
get_config_vars(),
|
||||
osname, release, machine)
|
||||
if sys.platform == "ios":
|
||||
release = get_config_vars().get("IPHONEOS_DEPLOYMENT_TARGET", "13.0")
|
||||
osname = sys.platform
|
||||
machine = sys.implementation._multiarch
|
||||
else:
|
||||
import _osx_support
|
||||
osname, release, machine = _osx_support.get_platform_osx(
|
||||
get_config_vars(),
|
||||
osname, release, machine)
|
||||
|
||||
return f"{osname}-{release}-{machine}"
|
||||
|
||||
@@ -807,6 +693,10 @@ def get_python_version():
|
||||
return _PY_VERSION_SHORT
|
||||
|
||||
|
||||
def _get_python_version_abi():
|
||||
return _PY_VERSION_SHORT + get_config_var("abi_thread")
|
||||
|
||||
|
||||
def expand_makefile_vars(s, vars):
|
||||
"""Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
|
||||
'string' according to 'vars' (a dictionary mapping variable names to
|
||||
@@ -817,6 +707,9 @@ def expand_makefile_vars(s, vars):
|
||||
"""
|
||||
import re
|
||||
|
||||
_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)"
|
||||
_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}"
|
||||
|
||||
# This algorithm does multiple expansion, so if vars['foo'] contains
|
||||
# "${bar}", it will expand ${foo} to ${bar}, and then expand
|
||||
# ${bar}... and so forth. This is fine as long as 'vars' comes from
|
||||
@@ -831,28 +724,3 @@ def expand_makefile_vars(s, vars):
|
||||
else:
|
||||
break
|
||||
return s
|
||||
|
||||
|
||||
def _print_dict(title, data):
|
||||
for index, (key, value) in enumerate(sorted(data.items())):
|
||||
if index == 0:
|
||||
print(f'{title}: ')
|
||||
print(f'\t{key} = "{value}"')
|
||||
|
||||
|
||||
def _main():
|
||||
"""Display all information sysconfig detains."""
|
||||
if '--generate-posix-vars' in sys.argv:
|
||||
_generate_posix_vars()
|
||||
return
|
||||
print(f'Platform: "{get_platform()}"')
|
||||
print(f'Python version: "{get_python_version()}"')
|
||||
print(f'Current installation scheme: "{get_default_scheme()}"')
|
||||
print()
|
||||
_print_dict('Paths', get_paths())
|
||||
print()
|
||||
_print_dict('Variables', get_config_vars())
|
||||
|
||||
if __name__ == '__main__':
|
||||
_main()
|
||||
'''.replace("Python", "RustPython").replace("/python", "/rustpython"))
|
||||
248
Lib/sysconfig/__main__.py
vendored
Normal file
248
Lib/sysconfig/__main__.py
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
import os
|
||||
import sys
|
||||
from sysconfig import (
|
||||
_ALWAYS_STR,
|
||||
_PYTHON_BUILD,
|
||||
_get_sysconfigdata_name,
|
||||
get_config_h_filename,
|
||||
get_config_vars,
|
||||
get_default_scheme,
|
||||
get_makefile_filename,
|
||||
get_paths,
|
||||
get_platform,
|
||||
get_python_version,
|
||||
parse_config_h,
|
||||
)
|
||||
|
||||
|
||||
# Regexes needed for parsing Makefile (and similar syntaxes,
|
||||
# like old-style Setup files).
|
||||
_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)"
|
||||
_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)"
|
||||
_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}"
|
||||
|
||||
|
||||
def _parse_makefile(filename, vars=None, keep_unresolved=True):
|
||||
"""Parse a Makefile-style file.
|
||||
|
||||
A dictionary containing name/value pairs is returned. If an
|
||||
optional dictionary is passed in as the second argument, it is
|
||||
used instead of a new dictionary.
|
||||
"""
|
||||
import re
|
||||
|
||||
if vars is None:
|
||||
vars = {}
|
||||
done = {}
|
||||
notdone = {}
|
||||
|
||||
with open(filename, encoding=sys.getfilesystemencoding(),
|
||||
errors="surrogateescape") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('#') or line.strip() == '':
|
||||
continue
|
||||
m = re.match(_variable_rx, line)
|
||||
if m:
|
||||
n, v = m.group(1, 2)
|
||||
v = v.strip()
|
||||
# `$$' is a literal `$' in make
|
||||
tmpv = v.replace('$$', '')
|
||||
|
||||
if "$" in tmpv:
|
||||
notdone[n] = v
|
||||
else:
|
||||
try:
|
||||
if n in _ALWAYS_STR:
|
||||
raise ValueError
|
||||
|
||||
v = int(v)
|
||||
except ValueError:
|
||||
# insert literal `$'
|
||||
done[n] = v.replace('$$', '$')
|
||||
else:
|
||||
done[n] = v
|
||||
|
||||
# do variable interpolation here
|
||||
variables = list(notdone.keys())
|
||||
|
||||
# Variables with a 'PY_' prefix in the makefile. These need to
|
||||
# be made available without that prefix through sysconfig.
|
||||
# Special care is needed to ensure that variable expansion works, even
|
||||
# if the expansion uses the name without a prefix.
|
||||
renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
|
||||
|
||||
while len(variables) > 0:
|
||||
for name in tuple(variables):
|
||||
value = notdone[name]
|
||||
m1 = re.search(_findvar1_rx, value)
|
||||
m2 = re.search(_findvar2_rx, value)
|
||||
if m1 and m2:
|
||||
m = m1 if m1.start() < m2.start() else m2
|
||||
else:
|
||||
m = m1 if m1 else m2
|
||||
if m is not None:
|
||||
n = m.group(1)
|
||||
found = True
|
||||
if n in done:
|
||||
item = str(done[n])
|
||||
elif n in notdone:
|
||||
# get it on a subsequent round
|
||||
found = False
|
||||
elif n in os.environ:
|
||||
# do it like make: fall back to environment
|
||||
item = os.environ[n]
|
||||
|
||||
elif n in renamed_variables:
|
||||
if (name.startswith('PY_') and
|
||||
name[3:] in renamed_variables):
|
||||
item = ""
|
||||
|
||||
elif 'PY_' + n in notdone:
|
||||
found = False
|
||||
|
||||
else:
|
||||
item = str(done['PY_' + n])
|
||||
|
||||
else:
|
||||
done[n] = item = ""
|
||||
|
||||
if found:
|
||||
after = value[m.end():]
|
||||
value = value[:m.start()] + item + after
|
||||
if "$" in after:
|
||||
notdone[name] = value
|
||||
else:
|
||||
try:
|
||||
if name in _ALWAYS_STR:
|
||||
raise ValueError
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
done[name] = value.strip()
|
||||
else:
|
||||
done[name] = value
|
||||
variables.remove(name)
|
||||
|
||||
if name.startswith('PY_') \
|
||||
and name[3:] in renamed_variables:
|
||||
|
||||
name = name[3:]
|
||||
if name not in done:
|
||||
done[name] = value
|
||||
|
||||
else:
|
||||
# Adds unresolved variables to the done dict.
|
||||
# This is disabled when called from distutils.sysconfig
|
||||
if keep_unresolved:
|
||||
done[name] = value
|
||||
# bogus variable reference (e.g. "prefix=$/opt/python");
|
||||
# just drop it since we can't deal
|
||||
variables.remove(name)
|
||||
|
||||
# strip spurious spaces
|
||||
for k, v in done.items():
|
||||
if isinstance(v, str):
|
||||
done[k] = v.strip()
|
||||
|
||||
# save the results in the global dictionary
|
||||
vars.update(done)
|
||||
return vars
|
||||
|
||||
|
||||
def _print_config_dict(d, stream):
|
||||
print ("{", file=stream)
|
||||
for k, v in sorted(d.items()):
|
||||
print(f" {k!r}: {v!r},", file=stream)
|
||||
print ("}", file=stream)
|
||||
|
||||
|
||||
def _generate_posix_vars():
|
||||
"""Generate the Python module containing build-time variables."""
|
||||
vars = {}
|
||||
# load the installed Makefile:
|
||||
makefile = get_makefile_filename()
|
||||
try:
|
||||
_parse_makefile(makefile, vars)
|
||||
except OSError as e:
|
||||
msg = f"invalid Python installation: unable to open {makefile}"
|
||||
if hasattr(e, "strerror"):
|
||||
msg = f"{msg} ({e.strerror})"
|
||||
raise OSError(msg)
|
||||
# load the installed pyconfig.h:
|
||||
config_h = get_config_h_filename()
|
||||
try:
|
||||
with open(config_h, encoding="utf-8") as f:
|
||||
parse_config_h(f, vars)
|
||||
except OSError as e:
|
||||
msg = f"invalid Python installation: unable to open {config_h}"
|
||||
if hasattr(e, "strerror"):
|
||||
msg = f"{msg} ({e.strerror})"
|
||||
raise OSError(msg)
|
||||
# On AIX, there are wrong paths to the linker scripts in the Makefile
|
||||
# -- these paths are relative to the Python source, but when installed
|
||||
# the scripts are in another directory.
|
||||
if _PYTHON_BUILD:
|
||||
vars['BLDSHARED'] = vars['LDSHARED']
|
||||
|
||||
# There's a chicken-and-egg situation on OS X with regards to the
|
||||
# _sysconfigdata module after the changes introduced by #15298:
|
||||
# get_config_vars() is called by get_platform() as part of the
|
||||
# `make pybuilddir.txt` target -- which is a precursor to the
|
||||
# _sysconfigdata.py module being constructed. Unfortunately,
|
||||
# get_config_vars() eventually calls _init_posix(), which attempts
|
||||
# to import _sysconfigdata, which we won't have built yet. In order
|
||||
# for _init_posix() to work, if we're on Darwin, just mock up the
|
||||
# _sysconfigdata module manually and populate it with the build vars.
|
||||
# This is more than sufficient for ensuring the subsequent call to
|
||||
# get_platform() succeeds.
|
||||
name = _get_sysconfigdata_name()
|
||||
if 'darwin' in sys.platform:
|
||||
import types
|
||||
module = types.ModuleType(name)
|
||||
module.build_time_vars = vars
|
||||
sys.modules[name] = module
|
||||
|
||||
pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}'
|
||||
if hasattr(sys, "gettotalrefcount"):
|
||||
pybuilddir += '-pydebug'
|
||||
os.makedirs(pybuilddir, exist_ok=True)
|
||||
destfile = os.path.join(pybuilddir, name + '.py')
|
||||
|
||||
with open(destfile, 'w', encoding='utf8') as f:
|
||||
f.write('# system configuration generated and used by'
|
||||
' the sysconfig module\n')
|
||||
f.write('build_time_vars = ')
|
||||
_print_config_dict(vars, stream=f)
|
||||
|
||||
# Create file used for sys.path fixup -- see Modules/getpath.c
|
||||
with open('pybuilddir.txt', 'w', encoding='utf8') as f:
|
||||
f.write(pybuilddir)
|
||||
|
||||
|
||||
def _print_dict(title, data):
|
||||
for index, (key, value) in enumerate(sorted(data.items())):
|
||||
if index == 0:
|
||||
print(f'{title}: ')
|
||||
print(f'\t{key} = "{value}"')
|
||||
|
||||
|
||||
def _main():
|
||||
"""Display all information sysconfig detains."""
|
||||
if '--generate-posix-vars' in sys.argv:
|
||||
_generate_posix_vars()
|
||||
return
|
||||
print(f'Platform: "{get_platform()}"')
|
||||
print(f'Python version: "{get_python_version()}"')
|
||||
print(f'Current installation scheme: "{get_default_scheme()}"')
|
||||
print()
|
||||
_print_dict('Paths', get_paths())
|
||||
print()
|
||||
_print_dict('Variables', get_config_vars())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
_main()
|
||||
except BrokenPipeError:
|
||||
pass
|
||||
41
Lib/test/_test_multiprocessing.py
vendored
41
Lib/test/_test_multiprocessing.py
vendored
@@ -6451,6 +6451,35 @@ class _TestSpawnedSysPath(BaseTestCase):
|
||||
self.assertEqual(child_sys_path[1:], sys.path[1:])
|
||||
self.assertIsNone(import_error, msg=f"child could not import {self._mod_name}")
|
||||
|
||||
def test_std_streams_flushed_after_preload(self):
|
||||
# gh-135335: Check fork server flushes standard streams after
|
||||
# preloading modules
|
||||
if multiprocessing.get_start_method() != "forkserver":
|
||||
self.skipTest("forkserver specific test")
|
||||
|
||||
# Create a test module in the temporary directory on the child's path
|
||||
# TODO: This can all be simplified once gh-126631 is fixed and we can
|
||||
# use __main__ instead of a module.
|
||||
dirname = os.path.join(self._temp_dir, 'preloaded_module')
|
||||
init_name = os.path.join(dirname, '__init__.py')
|
||||
os.mkdir(dirname)
|
||||
with open(init_name, "w") as f:
|
||||
cmd = '''if 1:
|
||||
import sys
|
||||
print('stderr', end='', file=sys.stderr)
|
||||
print('stdout', end='', file=sys.stdout)
|
||||
'''
|
||||
f.write(cmd)
|
||||
|
||||
name = os.path.join(os.path.dirname(__file__), 'mp_preload_flush.py')
|
||||
env = {'PYTHONPATH': self._temp_dir}
|
||||
_, out, err = test.support.script_helper.assert_python_ok(name, **env)
|
||||
|
||||
# Check stderr first, as it is more likely to be useful to see in the
|
||||
# event of a failure.
|
||||
self.assertEqual(err.decode().rstrip(), 'stderr')
|
||||
self.assertEqual(out.decode().rstrip(), 'stdout')
|
||||
|
||||
|
||||
class MiscTestCase(unittest.TestCase):
|
||||
def test__all__(self):
|
||||
@@ -6516,6 +6545,18 @@ class MiscTestCase(unittest.TestCase):
|
||||
self.assertEqual(q.get_nowait(), "done")
|
||||
close_queue(q)
|
||||
|
||||
def test_preload_main(self):
|
||||
# gh-126631: Check that __main__ can be pre-loaded
|
||||
if multiprocessing.get_start_method() != "forkserver":
|
||||
self.skipTest("forkserver specific test")
|
||||
|
||||
name = os.path.join(os.path.dirname(__file__), 'mp_preload_main.py')
|
||||
_, out, err = test.support.script_helper.assert_python_ok(name)
|
||||
self.assertEqual(err, b'')
|
||||
|
||||
# The trailing empty string comes from split() on output ending with \n
|
||||
out = out.decode().split("\n")
|
||||
self.assertEqual(out, ['__main__', '__mp_main__', 'f', 'f', ''])
|
||||
|
||||
#
|
||||
# Mixins
|
||||
|
||||
167
Lib/test/certdata/allsans.pem
vendored
Normal file
167
Lib/test/certdata/allsans.pem
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQCczEVv5D2UDtn6
|
||||
DMmZ/uCWCLyL+K5xTZp/5j3cyISoaTuU1Ku3kD97eLgpHj4Fgk5ZJi21zsQqepCj
|
||||
jAhBk6tj6RYUcnMbb8MuxUkQMEDW+5LfSyp+HCaetlHosWdhEDqX4kpJ5ajBwNRt
|
||||
07mxQExtC4kcno0ut9rG5XzLN29XpCpRHlFFrntOgQAEoiz9/fc8qaTgb37RgGYP
|
||||
Qsxh7PcRDRe4ZGx1l06Irr8Y+2W50zWCfkwCS3DaLDOKIjSOfPHNqmfcfsTpzrj8
|
||||
330cdPklrMIuiBv+iGklCjkPZJiEhxvY2k6ERM4HAxxuPCivrH5MCeMNYvBVUcLr
|
||||
GROm7JRXRllI/XubwwoAaAb+y+dZtCZ9AnzHIb+nyKiJxWAjzjR+QPL6jHrVWBVA
|
||||
WTc83YP5FvxUXMfY3sVv9tNSCV3cpYOW5+iXcQzLuczXnOLRYk7p9wkb0/hk9KuK
|
||||
4BMA90eBhvFMCFgHJ1/xJg2nFmBHPo/xbcwPG/ma5T/McA8mAlECAwEAAQKCAYAB
|
||||
m29nxPNjod5Wm4xydWQYbZj/J0qkcyru/i1qpqyDbGa1sRNcg5A/A/8BPuPcWxhR
|
||||
/hvwVeD5XX2/i2cnQuv6D3DQP1cSNCxQPanwzknP2k7IVqUmG0RDErPWuoDIhCnR
|
||||
ljp0NPQsnj0fLhEkcbgG0xwx7KceUDigGsiTbatIvvBHGhQzrmTpqlVVdtMWvGRt
|
||||
HQEJYuMuIw6IwALHyy3CITv5wh/Bec5OhNoFF8iUZceR4ZkGWf8bYWIa25xlzH6K
|
||||
4rhOOh1G2ObHHTjhZq4mGXTHY1MEkAxXKWlR3DJc0Lh5E1UETSI6WBHWRb08iwQ5
|
||||
AkLOPyMpt08xHFWbJqywvlxenpri+gjY3xbXqGNhyDYWHZqlQmJVnzxoUOuuHi2R
|
||||
dO86IckUc4Thjbm7a6AilL9t8juNZvyeQUVgtVi25uPkm/cK6r5vo8y4UOUU41EN
|
||||
NOathlF69gh93il4t6zJW9jPV2WENv1H/vhKUWKW6cabX3vy4rANwy3q4V//GDEC
|
||||
gcEAuniGCHaEdSjV2sUHyt/yrCLbU6+eLTfNk6AQyXJk6Wrvj6g3gx90ewEq5i/C
|
||||
ukmSKDslr9pupq8Z/UNfYHZfJfpwEsYvIZ8DdFSd62/h66DhIoEn1v3Lwt+aexgX
|
||||
yGJHF0BG9JA2CU5Z5NGjlnQYqQBobO9uZMq62l15Ig1MAMHGL0ZYVvOqGZD7XvtC
|
||||
4UnclK5kjp51Vd5rydEQxyi5qkyLl9Q6T0FQXOphGIOd8ifYeUGe7YC72cFPevdx
|
||||
wDXZAoHBANdDVvCMrjmzdrS6td39/2nHTeerFPbsOe2LIQYzqjeEe6GWqd2NL9NZ
|
||||
bk3/cAuVgbWtdvSQQhhmSqOC7JZic4hbZb3lK6v/sr4F/Zu0CfAu80swWFMeS7vq
|
||||
eQeYzN4w4dKpJArvU3ll7N9AlZhdlYkbPf0WdeOIjZawdAOxNtNe0O+j+5MsXR59
|
||||
qkULatumhcKUnqxFCiVHzy21CVJtRzrtu6oGoSdFbmG82eSJ1rPXiuuDnCyzjyMW
|
||||
iClYRM4NOQKBwERnO/vUxihYT4LOLlqcpl/A9aYQUT0TMGWMHTxYq2343WJceeiu
|
||||
3ELXHc6NDKjbnjMF54BH57lbmHQQh+dR5PuAkCZC7z0tIM5G0Bty0nRmcs/+gwfZ
|
||||
2Cpnbjrjjq3iZ2O/H4hNcpUdWdqXkKP7eKReUvBLMLrmp369NVdpe0z3yGTFMFjN
|
||||
T8PLLHsePt14A+PCyX6L4E0cp3vEJpx4cwtmwvpyTuWN9xXuoKmmdoVDWqS4jr1f
|
||||
MQnjYO2h4ed5mQKBwGVttWli4DUP+r7tuwP+ynptDqg6VIaEiEcFZ2okre+63QYm
|
||||
l6NtAzvyx6a41XKf355bPdG+p2YXzNN+vTue6BE3/5iagxloQjCHYhgbnRMvDDRB
|
||||
c1y2ybihoqWRufZ30fARAoqkehCZliMbq2E/t1YDIBJAowuzLAP04LVcqxitdIV2
|
||||
HvQZ00aqr7AY0SDuNdiZbqp9XWpzi4td4iaUlxuNKP/UX9rBPGGROpoU2LWkujB+
|
||||
svfdI3TFCSNyE/mDAQKBwQCP++WZKxExrSFRk3W+TcHKHZb2pusfoPWE7WH6EnDW
|
||||
dkTZpa3PZaf0xgeglmNBv4Paxw2eMPsIhyNv62XY/6GbY6VJWRyx/s+NsazeP4ji
|
||||
xUOufnwTePjYw6x0pcl6BknZrHn8LCJU741h0yTum8cDdNfRKdc0AMy0gVXk4ZTG
|
||||
2cAtbEcWb3J+a5kYf6mp5yx3BNwtewkGZhc2VuQ9mQNbMmOOS/pHQQTRWcxsQwyt
|
||||
GPAhMKawjrL1KFmu7vIqDSw=
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:5f
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=allsans
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:9c:cc:45:6f:e4:3d:94:0e:d9:fa:0c:c9:99:fe:
|
||||
e0:96:08:bc:8b:f8:ae:71:4d:9a:7f:e6:3d:dc:c8:
|
||||
84:a8:69:3b:94:d4:ab:b7:90:3f:7b:78:b8:29:1e:
|
||||
3e:05:82:4e:59:26:2d:b5:ce:c4:2a:7a:90:a3:8c:
|
||||
08:41:93:ab:63:e9:16:14:72:73:1b:6f:c3:2e:c5:
|
||||
49:10:30:40:d6:fb:92:df:4b:2a:7e:1c:26:9e:b6:
|
||||
51:e8:b1:67:61:10:3a:97:e2:4a:49:e5:a8:c1:c0:
|
||||
d4:6d:d3:b9:b1:40:4c:6d:0b:89:1c:9e:8d:2e:b7:
|
||||
da:c6:e5:7c:cb:37:6f:57:a4:2a:51:1e:51:45:ae:
|
||||
7b:4e:81:00:04:a2:2c:fd:fd:f7:3c:a9:a4:e0:6f:
|
||||
7e:d1:80:66:0f:42:cc:61:ec:f7:11:0d:17:b8:64:
|
||||
6c:75:97:4e:88:ae:bf:18:fb:65:b9:d3:35:82:7e:
|
||||
4c:02:4b:70:da:2c:33:8a:22:34:8e:7c:f1:cd:aa:
|
||||
67:dc:7e:c4:e9:ce:b8:fc:df:7d:1c:74:f9:25:ac:
|
||||
c2:2e:88:1b:fe:88:69:25:0a:39:0f:64:98:84:87:
|
||||
1b:d8:da:4e:84:44:ce:07:03:1c:6e:3c:28:af:ac:
|
||||
7e:4c:09:e3:0d:62:f0:55:51:c2:eb:19:13:a6:ec:
|
||||
94:57:46:59:48:fd:7b:9b:c3:0a:00:68:06:fe:cb:
|
||||
e7:59:b4:26:7d:02:7c:c7:21:bf:a7:c8:a8:89:c5:
|
||||
60:23:ce:34:7e:40:f2:fa:8c:7a:d5:58:15:40:59:
|
||||
37:3c:dd:83:f9:16:fc:54:5c:c7:d8:de:c5:6f:f6:
|
||||
d3:52:09:5d:dc:a5:83:96:e7:e8:97:71:0c:cb:b9:
|
||||
cc:d7:9c:e2:d1:62:4e:e9:f7:09:1b:d3:f8:64:f4:
|
||||
ab:8a:e0:13:00:f7:47:81:86:f1:4c:08:58:07:27:
|
||||
5f:f1:26:0d:a7:16:60:47:3e:8f:f1:6d:cc:0f:1b:
|
||||
f9:9a:e5:3f:cc:70:0f:26:02:51
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:allsans, othername: 1.2.3.4::some other identifier, othername: 1.3.6.1.5.2.2::<unsupported>, email:user@example.org, DNS:www.example.org, DirName:/C=XY/L=Castle Anthrax/O=Python Software Foundation/CN=dirname example, URI:https://www.python.org/, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, Registered ID:1.2.3.4.5
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
31:5E:C0:5E:2F:47:FF:8B:92:F9:EE:3D:B1:87:D0:53:75:3B:B1:48
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
||||
serial:CB:2D:80:99:5A:69:52:5B
|
||||
Authority Information Access:
|
||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
||||
X509v3 CRL Distribution Points:
|
||||
Full Name:
|
||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
72:42:a6:fc:ee:3c:21:47:05:33:e8:8c:6b:27:07:4a:ed:e2:
|
||||
81:47:96:79:43:ff:0f:ef:5a:06:aa:4c:01:70:5b:21:c4:b7:
|
||||
5d:17:29:c8:10:02:c3:08:7b:8c:86:56:9e:e9:7c:6e:a8:b6:
|
||||
26:13:9e:1e:1f:93:66:85:67:63:9e:08:fb:55:39:56:82:f5:
|
||||
be:0c:38:1e:eb:c4:54:b2:a7:7b:18:55:bb:00:87:43:50:50:
|
||||
bb:e1:29:10:cf:3d:c9:07:c7:d2:5d:b6:45:68:1f:d6:de:00:
|
||||
96:3e:29:73:f6:22:70:21:a2:ba:68:28:94:ec:37:bc:a7:00:
|
||||
70:58:4e:d1:48:ae:ef:8d:11:a4:6e:10:2f:92:83:07:e2:76:
|
||||
ac:bf:4f:bb:d6:9f:47:9e:a4:02:03:16:f8:a8:0a:3d:67:17:
|
||||
31:44:0e:68:d0:d3:24:d5:e7:bf:67:30:8f:88:97:92:0a:1e:
|
||||
d7:74:df:7e:7b:4c:c6:d9:c3:84:92:2b:a0:89:11:08:4c:dd:
|
||||
32:49:df:36:23:d4:63:56:e4:f1:68:5a:6f:a0:c3:3c:e2:36:
|
||||
ee:f3:46:60:78:4d:76:a5:5a:4a:61:c6:f8:ae:18:68:c2:8d:
|
||||
0e:2f:76:50:bb:be:b9:56:f1:04:5c:ac:ad:d7:d6:a4:1e:45:
|
||||
45:52:f4:10:a2:0f:9b:e3:d9:73:17:b6:52:42:a6:5b:c9:e9:
|
||||
8d:60:74:68:d0:1f:7a:ce:01:8e:9e:55:cb:cf:64:c1:cc:9a:
|
||||
72:aa:b4:5f:b5:55:13:41:10:51:a0:2c:a5:5b:43:12:ca:cc:
|
||||
b7:c4:ac:f2:6f:72:fd:0d:50:6a:d6:81:c1:91:93:21:fe:de:
|
||||
9a:be:e5:3c:2a:98:95:a1:42:f8:f2:5c:75:c6:f1:fd:11:b1:
|
||||
22:26:33:5b:43:63:21:06:61:d2:cd:04:f3:30:c6:a8:3f:17:
|
||||
d3:05:a3:87:45:2e:52:1e:51:88:e3:59:4c:78:51:b0:7b:b4:
|
||||
58:d9:27:22:6e:8c
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHDTCCBXWgAwIBAgIJAMstgJlaaVJfMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMF0xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEDAOBgNVBAMMB2Fs
|
||||
bHNhbnMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCczEVv5D2UDtn6
|
||||
DMmZ/uCWCLyL+K5xTZp/5j3cyISoaTuU1Ku3kD97eLgpHj4Fgk5ZJi21zsQqepCj
|
||||
jAhBk6tj6RYUcnMbb8MuxUkQMEDW+5LfSyp+HCaetlHosWdhEDqX4kpJ5ajBwNRt
|
||||
07mxQExtC4kcno0ut9rG5XzLN29XpCpRHlFFrntOgQAEoiz9/fc8qaTgb37RgGYP
|
||||
Qsxh7PcRDRe4ZGx1l06Irr8Y+2W50zWCfkwCS3DaLDOKIjSOfPHNqmfcfsTpzrj8
|
||||
330cdPklrMIuiBv+iGklCjkPZJiEhxvY2k6ERM4HAxxuPCivrH5MCeMNYvBVUcLr
|
||||
GROm7JRXRllI/XubwwoAaAb+y+dZtCZ9AnzHIb+nyKiJxWAjzjR+QPL6jHrVWBVA
|
||||
WTc83YP5FvxUXMfY3sVv9tNSCV3cpYOW5+iXcQzLuczXnOLRYk7p9wkb0/hk9KuK
|
||||
4BMA90eBhvFMCFgHJ1/xJg2nFmBHPo/xbcwPG/ma5T/McA8mAlECAwEAAaOCAt4w
|
||||
ggLaMIIBMAYDVR0RBIIBJzCCASOCB2FsbHNhbnOgHgYDKgMEoBcMFXNvbWUgb3Ro
|
||||
ZXIgaWRlbnRpZmllcqA1BgYrBgEFAgKgKzApoBAbDktFUkJFUk9TLlJFQUxNoRUw
|
||||
E6ADAgEBoQwwChsIdXNlcm5hbWWBEHVzZXJAZXhhbXBsZS5vcmeCD3d3dy5leGFt
|
||||
cGxlLm9yZ6RnMGUxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJh
|
||||
eDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xGDAWBgNVBAMM
|
||||
D2Rpcm5hbWUgZXhhbXBsZYYXaHR0cHM6Ly93d3cucHl0aG9uLm9yZy+HBH8AAAGH
|
||||
EAAAAAAAAAAAAAAAAAAAAAGIBCoDBAUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
|
||||
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQx
|
||||
XsBeL0f/i5L57j2xh9BTdTuxSDB9BgNVHSMEdjB0gBTz7JSO8o4wxI5owr+OahnA
|
||||
wZ92ZaFRpE8wTTELMAkGA1UEBhMCWFkxJjAkBgNVBAoMHVB5dGhvbiBTb2Z0d2Fy
|
||||
ZSBGb3VuZGF0aW9uIENBMRYwFAYDVQQDDA1vdXItY2Etc2VydmVyggkAyy2AmVpp
|
||||
UlswgYMGCCsGAQUFBwEBBHcwdTA8BggrBgEFBQcwAoYwaHR0cDovL3Rlc3RjYS5w
|
||||
eXRob250ZXN0Lm5ldC90ZXN0Y2EvcHljYWNlcnQuY2VyMDUGCCsGAQUFBzABhilo
|
||||
dHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9vY3NwLzBDBgNVHR8E
|
||||
PDA6MDigNqA0hjJodHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9y
|
||||
ZXZvY2F0aW9uLmNybDANBgkqhkiG9w0BAQsFAAOCAYEAckKm/O48IUcFM+iMaycH
|
||||
Su3igUeWeUP/D+9aBqpMAXBbIcS3XRcpyBACwwh7jIZWnul8bqi2JhOeHh+TZoVn
|
||||
Y54I+1U5VoL1vgw4HuvEVLKnexhVuwCHQ1BQu+EpEM89yQfH0l22RWgf1t4Alj4p
|
||||
c/YicCGiumgolOw3vKcAcFhO0Uiu740RpG4QL5KDB+J2rL9Pu9afR56kAgMW+KgK
|
||||
PWcXMUQOaNDTJNXnv2cwj4iXkgoe13TffntMxtnDhJIroIkRCEzdMknfNiPUY1bk
|
||||
8Whab6DDPOI27vNGYHhNdqVaSmHG+K4YaMKNDi92ULu+uVbxBFysrdfWpB5FRVL0
|
||||
EKIPm+PZcxe2UkKmW8npjWB0aNAfes4Bjp5Vy89kwcyacqq0X7VVE0EQUaAspVtD
|
||||
EsrMt8Ss8m9y/Q1QataBwZGTIf7emr7lPCqYlaFC+PJcdcbx/RGxIiYzW0NjIQZh
|
||||
0s0E8zDGqD8X0wWjh0UuUh5RiONZTHhRsHu0WNknIm6M
|
||||
-----END CERTIFICATE-----
|
||||
36
Lib/test/certdata/badcert.pem
vendored
Normal file
36
Lib/test/certdata/badcert.pem
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L
|
||||
opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH
|
||||
fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB
|
||||
AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU
|
||||
D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA
|
||||
IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM
|
||||
oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0
|
||||
ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/
|
||||
loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j
|
||||
oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA
|
||||
z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq
|
||||
ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV
|
||||
q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
Just bad cert data
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L
|
||||
opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH
|
||||
fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB
|
||||
AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU
|
||||
D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA
|
||||
IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM
|
||||
oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0
|
||||
ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/
|
||||
loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j
|
||||
oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA
|
||||
z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq
|
||||
ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV
|
||||
q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
Just bad cert data
|
||||
-----END CERTIFICATE-----
|
||||
40
Lib/test/certdata/badkey.pem
vendored
Normal file
40
Lib/test/certdata/badkey.pem
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Bad Key, though the cert should be OK
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x
|
||||
IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT
|
||||
U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1
|
||||
NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl
|
||||
bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj
|
||||
aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh
|
||||
m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8
|
||||
M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn
|
||||
fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC
|
||||
AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb
|
||||
08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx
|
||||
CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/
|
||||
iHkC6gGdBJhogs4=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Bad Key, though the cert should be OK
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x
|
||||
IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT
|
||||
U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1
|
||||
NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl
|
||||
bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj
|
||||
aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh
|
||||
m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8
|
||||
M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn
|
||||
fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC
|
||||
AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb
|
||||
08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx
|
||||
CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/
|
||||
iHkC6gGdBJhogs4=
|
||||
-----END CERTIFICATE-----
|
||||
14
Lib/test/certdata/capath/4e1295a3.0
vendored
Normal file
14
Lib/test/certdata/capath/4e1295a3.0
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
|
||||
VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
|
||||
bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
|
||||
dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
|
||||
DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
|
||||
EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
|
||||
dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
|
||||
EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
|
||||
L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
|
||||
BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
|
||||
9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
|
||||
-----END CERTIFICATE-----
|
||||
41
Lib/test/certdata/capath/5ed36f99.0
vendored
Normal file
41
Lib/test/certdata/capath/5ed36f99.0
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
|
||||
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
|
||||
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
|
||||
Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
|
||||
BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
|
||||
MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
|
||||
ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||
CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
|
||||
8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
|
||||
zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
|
||||
fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
|
||||
w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
|
||||
G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
|
||||
epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
|
||||
laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
|
||||
QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
|
||||
fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
|
||||
YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
|
||||
ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
|
||||
gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
|
||||
MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
|
||||
IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
|
||||
dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
|
||||
czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
|
||||
dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
|
||||
aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
|
||||
AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
|
||||
b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
|
||||
ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
|
||||
nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
|
||||
18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
|
||||
gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
|
||||
Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
|
||||
sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
|
||||
SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
|
||||
CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
|
||||
GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
|
||||
zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
|
||||
omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
|
||||
-----END CERTIFICATE-----
|
||||
14
Lib/test/certdata/capath/6e88d7b8.0
vendored
Normal file
14
Lib/test/certdata/capath/6e88d7b8.0
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
|
||||
VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
|
||||
bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
|
||||
dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
|
||||
DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
|
||||
EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
|
||||
dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
|
||||
EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
|
||||
L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
|
||||
BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
|
||||
9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
|
||||
-----END CERTIFICATE-----
|
||||
41
Lib/test/certdata/capath/99d0fa06.0
vendored
Normal file
41
Lib/test/certdata/capath/99d0fa06.0
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
|
||||
IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
|
||||
IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
|
||||
Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
|
||||
BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
|
||||
MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
|
||||
ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||
CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
|
||||
8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
|
||||
zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
|
||||
fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
|
||||
w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
|
||||
G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
|
||||
epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
|
||||
laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
|
||||
QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
|
||||
fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
|
||||
YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
|
||||
ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
|
||||
gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
|
||||
MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
|
||||
IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
|
||||
dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
|
||||
czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
|
||||
dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
|
||||
aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
|
||||
AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
|
||||
b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
|
||||
ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
|
||||
nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
|
||||
18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
|
||||
gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
|
||||
Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
|
||||
sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
|
||||
SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
|
||||
CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
|
||||
GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
|
||||
zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
|
||||
omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
|
||||
-----END CERTIFICATE-----
|
||||
27
Lib/test/certdata/capath/b1930218.0
vendored
Normal file
27
Lib/test/certdata/capath/b1930218.0
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgDCCAuigAwIBAgIJAMstgJlaaVJbMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
|
||||
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjCCAaIwDQYJKoZI
|
||||
hvcNAQEBBQADggGPADCCAYoCggGBANCgm7G5O3nuMS+4URwBde0JWUysyL9qCvh6
|
||||
CPAl4yV7avjE2KqgYAclsM9zcQVSaL8Gk64QYZa8s2mBGn0Z/CCGj5poG+3N4mxh
|
||||
Z8dOVepDBiEb6bm+hF/C2uuJiOBCpkVJKtC5a4yTyUQ7yvw8lH/dcMWt2Es73B74
|
||||
VUu1J4b437CDz/cWN78TFzTUyVXtaxbJf60gTvAe2Ru/jbrNypbvHmnLUWZhSA3o
|
||||
eaNZYdQQjeANOwuFttWFEt2lB8VL+iP6VDn3lwvJREceVnc8PBMBC2131hS6RPRT
|
||||
NVbZPbk+NV/bM5pPWrk4RMkySf5m9h8al6rKTEr2uF5Af/sLHfhbodz4wC7QbUn1
|
||||
0kbUkFf+koE0ri04u6gXDOHlP+L3JgVUUPVksxxuRP9vqbQDlukOwojYclKQmcZB
|
||||
D0aQWbg+b9Linh02gpXTWIoS8+LYDSBRI/CQLZo+fSaGsqfX+ShgA+N3x4gEyf6J
|
||||
d3AQT8Ogijv0q0J74xSS2K4W1qHefQIDAQABo2MwYTAdBgNVHQ4EFgQU8+yUjvKO
|
||||
MMSOaMK/jmoZwMGfdmUwHwYDVR0jBBgwFoAU8+yUjvKOMMSOaMK/jmoZwMGfdmUw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
|
||||
ggGBAIsAVHKzjevzrzSf1mDq3oQ/jASPGaa+AmfEY8V040c3WYOUBvFFGegHL9ZO
|
||||
S0+oPccHByeS9H5zT4syGZRGeiXE2cQnsBFjOmCLheFzTzQ7a6Q0jEmOzc9PsmUn
|
||||
QRmw/IAxePJzapt9cTRQ/Hio2gW0nFs6mXprXe870+k7MwESZc9eB9gZr9VT6vAQ
|
||||
rMS2Jjw0LnTuZN0dNnWJRACwDf0vswHMGosCzWzogILKv4LXAJ3YNhXSBzf8bHMd
|
||||
2qgc6CCOMnr+bScW5Fhs6z7w/iRSKXG4lntTS0UgVUBehhvsyUaRku6sk2WRLpS2
|
||||
tqzoozSJpBoSDU1EpVLti5HuL6avpJUl+c7HW6cA05PKtDxdTfexPMxttEW+gu0Y
|
||||
kMiG0XVRUARM6E/S1lCqdede/6F7Jxkca0ksbE1rY8w7cwDzmSbQgofTqTactD25
|
||||
SGiokvAnjgzNFXZChIDJP6N+tN3X+Kx2umCXPFofTt5x7gk5EN0x1WhXXRrlQroO
|
||||
aOZF0w==
|
||||
-----END CERTIFICATE-----
|
||||
27
Lib/test/certdata/capath/ceff1710.0
vendored
Normal file
27
Lib/test/certdata/capath/ceff1710.0
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgDCCAuigAwIBAgIJAMstgJlaaVJbMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
|
||||
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjCCAaIwDQYJKoZI
|
||||
hvcNAQEBBQADggGPADCCAYoCggGBANCgm7G5O3nuMS+4URwBde0JWUysyL9qCvh6
|
||||
CPAl4yV7avjE2KqgYAclsM9zcQVSaL8Gk64QYZa8s2mBGn0Z/CCGj5poG+3N4mxh
|
||||
Z8dOVepDBiEb6bm+hF/C2uuJiOBCpkVJKtC5a4yTyUQ7yvw8lH/dcMWt2Es73B74
|
||||
VUu1J4b437CDz/cWN78TFzTUyVXtaxbJf60gTvAe2Ru/jbrNypbvHmnLUWZhSA3o
|
||||
eaNZYdQQjeANOwuFttWFEt2lB8VL+iP6VDn3lwvJREceVnc8PBMBC2131hS6RPRT
|
||||
NVbZPbk+NV/bM5pPWrk4RMkySf5m9h8al6rKTEr2uF5Af/sLHfhbodz4wC7QbUn1
|
||||
0kbUkFf+koE0ri04u6gXDOHlP+L3JgVUUPVksxxuRP9vqbQDlukOwojYclKQmcZB
|
||||
D0aQWbg+b9Linh02gpXTWIoS8+LYDSBRI/CQLZo+fSaGsqfX+ShgA+N3x4gEyf6J
|
||||
d3AQT8Ogijv0q0J74xSS2K4W1qHefQIDAQABo2MwYTAdBgNVHQ4EFgQU8+yUjvKO
|
||||
MMSOaMK/jmoZwMGfdmUwHwYDVR0jBBgwFoAU8+yUjvKOMMSOaMK/jmoZwMGfdmUw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
|
||||
ggGBAIsAVHKzjevzrzSf1mDq3oQ/jASPGaa+AmfEY8V040c3WYOUBvFFGegHL9ZO
|
||||
S0+oPccHByeS9H5zT4syGZRGeiXE2cQnsBFjOmCLheFzTzQ7a6Q0jEmOzc9PsmUn
|
||||
QRmw/IAxePJzapt9cTRQ/Hio2gW0nFs6mXprXe870+k7MwESZc9eB9gZr9VT6vAQ
|
||||
rMS2Jjw0LnTuZN0dNnWJRACwDf0vswHMGosCzWzogILKv4LXAJ3YNhXSBzf8bHMd
|
||||
2qgc6CCOMnr+bScW5Fhs6z7w/iRSKXG4lntTS0UgVUBehhvsyUaRku6sk2WRLpS2
|
||||
tqzoozSJpBoSDU1EpVLti5HuL6avpJUl+c7HW6cA05PKtDxdTfexPMxttEW+gu0Y
|
||||
kMiG0XVRUARM6E/S1lCqdede/6F7Jxkca0ksbE1rY8w7cwDzmSbQgofTqTactD25
|
||||
SGiokvAnjgzNFXZChIDJP6N+tN3X+Kx2umCXPFofTt5x7gk5EN0x1WhXXRrlQroO
|
||||
aOZF0w==
|
||||
-----END CERTIFICATE-----
|
||||
34
Lib/test/certdata/cert3.pem
vendored
Normal file
34
Lib/test/certdata/cert3.pem
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF8TCCBFmgAwIBAgIJAMstgJlaaVJcMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxv
|
||||
Y2FsaG9zdDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKAqKHEL7aDt
|
||||
3swl8hQF8VaK4zDGDRaF3E/IZTMwCN7FsQ4ejSiOe3E90f0phHCIpEpv2OebNenY
|
||||
IpOGoFgkh62r/cthmnhu8Mn+FUIv17iOq7WX7B30OSqEpnr1voLX93XYkAq8LlMh
|
||||
P79vsSCVhTwow3HZY7krEgl5WlfryOfj1i1TODSFPRCJePh66BsOTUvV/33GC+Qd
|
||||
pVZVDGLowU1Ycmr/FdRvwT+F39Dehp03UFcxaX0/joPhH5gYpBB1kWTAQmxuqKMW
|
||||
9ZZs6hrPtMXF/yfSrrXrzTdpct9paKR8RcufOcS8qju/ISK+1P/LXg2b5KJHedLo
|
||||
TTIO3yCZ4d1odyuZBP7JDrI05gMJx95gz6sG685Qc+52MzLSTwr/Qg+MOjQoBy0o
|
||||
8fRRVvIMEwoN0ZDb4uFEUuwZceUP1vTk/GGpNQt7ct4ropn6K4Zta3BUtovlLjZa
|
||||
IIBhc1KETUqjRDvC6ACKmlcJ/5pY/dbH1lOux+IMFsh+djmaV90b3QIDAQABo4IB
|
||||
wDCCAbwwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA4GA1UdDwEB/wQEAwIFoDAdBgNV
|
||||
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E
|
||||
FgQUP7HpT6C+MGY+ChjID0caTzRqD0IwfQYDVR0jBHYwdIAU8+yUjvKOMMSOaMK/
|
||||
jmoZwMGfdmWhUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAMst
|
||||
gJlaaVJbMIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0
|
||||
Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcw
|
||||
AYYpaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYD
|
||||
VR0fBDwwOjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0
|
||||
Y2EvcmV2b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGBAMo0usXQzycxMtYN
|
||||
JzC42xfftzmnu7E7hsQx/fur22MazJCruU6rNEkMXow+cKOnay+nmiV7AVoYlkh2
|
||||
+DZ4dPq8fWh/5cqmnXvccr2jJVEXaOjp1wKGLH0WfLXcRLIK4/fJM6NRNoO81HDN
|
||||
hJGfBrot0gUKZcPZVQmouAlpu5OGwrfCkHR8v/BdvA5jE4zr+g/x+uUScE0M64wu
|
||||
okJCAAQP/PkfQZxjePBmk7KPLuiTHFDLLX+2uldvUmLXOQsJgqumU03MBT4Z8NTA
|
||||
zqmtEM65ceSP8lo8Zbrcy+AEkCulFaZ92tyjtbe8oN4wTmTLFw06oFLSZzuiOgDV
|
||||
OaphdVKf/pvA6KBpr6izox0KQFIE5z3AAJZfKzMGDDD20xhy7jjQZNMAhjfsT+k4
|
||||
SeYB/6KafNxq08uoulj7w4Z4R/EGpkXnU96ZHYHmvGN0RnxwI1cpYHCazG8AjsK/
|
||||
anN9brBi5twTGrn+D8LRBqF5Yn+2MKkD0EdXJdtIENHP+32sPQ==
|
||||
-----END CERTIFICATE-----
|
||||
41
Lib/test/certdata/ffdh3072.pem
vendored
Normal file
41
Lib/test/certdata/ffdh3072.pem
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
DH Parameters: (3072 bit)
|
||||
prime:
|
||||
00:ff:ff:ff:ff:ff:ff:ff:ff:ad:f8:54:58:a2:bb:
|
||||
4a:9a:af:dc:56:20:27:3d:3c:f1:d8:b9:c5:83:ce:
|
||||
2d:36:95:a9:e1:36:41:14:64:33:fb:cc:93:9d:ce:
|
||||
24:9b:3e:f9:7d:2f:e3:63:63:0c:75:d8:f6:81:b2:
|
||||
02:ae:c4:61:7a:d3:df:1e:d5:d5:fd:65:61:24:33:
|
||||
f5:1f:5f:06:6e:d0:85:63:65:55:3d:ed:1a:f3:b5:
|
||||
57:13:5e:7f:57:c9:35:98:4f:0c:70:e0:e6:8b:77:
|
||||
e2:a6:89:da:f3:ef:e8:72:1d:f1:58:a1:36:ad:e7:
|
||||
35:30:ac:ca:4f:48:3a:79:7a:bc:0a:b1:82:b3:24:
|
||||
fb:61:d1:08:a9:4b:b2:c8:e3:fb:b9:6a:da:b7:60:
|
||||
d7:f4:68:1d:4f:42:a3:de:39:4d:f4:ae:56:ed:e7:
|
||||
63:72:bb:19:0b:07:a7:c8:ee:0a:6d:70:9e:02:fc:
|
||||
e1:cd:f7:e2:ec:c0:34:04:cd:28:34:2f:61:91:72:
|
||||
fe:9c:e9:85:83:ff:8e:4f:12:32:ee:f2:81:83:c3:
|
||||
fe:3b:1b:4c:6f:ad:73:3b:b5:fc:bc:2e:c2:20:05:
|
||||
c5:8e:f1:83:7d:16:83:b2:c6:f3:4a:26:c1:b2:ef:
|
||||
fa:88:6b:42:38:61:1f:cf:dc:de:35:5b:3b:65:19:
|
||||
03:5b:bc:34:f4:de:f9:9c:02:38:61:b4:6f:c9:d6:
|
||||
e6:c9:07:7a:d9:1d:26:91:f7:f7:ee:59:8c:b0:fa:
|
||||
c1:86:d9:1c:ae:fe:13:09:85:13:92:70:b4:13:0c:
|
||||
93:bc:43:79:44:f4:fd:44:52:e2:d7:4d:d3:64:f2:
|
||||
e2:1e:71:f5:4b:ff:5c:ae:82:ab:9c:9d:f6:9e:e8:
|
||||
6d:2b:c5:22:36:3a:0d:ab:c5:21:97:9b:0d:ea:da:
|
||||
1d:bf:9a:42:d5:c4:48:4e:0a:bc:d0:6b:fa:53:dd:
|
||||
ef:3c:1b:20:ee:3f:d5:9d:7c:25:e4:1d:2b:66:c6:
|
||||
2e:37:ff:ff:ff:ff:ff:ff:ff:ff
|
||||
generator: 2 (0x2)
|
||||
recommended-private-length: 276 bits
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBjAKCAYEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||
ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
|
||||
7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
|
||||
nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZsYu
|
||||
N///////////AgECAgIBFA==
|
||||
-----END DH PARAMETERS-----
|
||||
166
Lib/test/certdata/idnsans.pem
vendored
Normal file
166
Lib/test/certdata/idnsans.pem
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
81hAHFgeD4f+C8fLols/sA==
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:60
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=idnsans
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:a9:eb:3b:78:d1:60:77:2b:bc:a3:04:6b:a0:9d:
|
||||
1b:aa:23:70:29:7e:d4:e1:65:60:c8:a6:f5:b4:71:
|
||||
59:8d:d2:7a:90:c6:c3:ba:08:29:d2:e1:d4:bb:49:
|
||||
88:46:16:22:2a:5a:33:55:73:65:86:d2:0b:fb:9c:
|
||||
2e:43:16:0b:aa:6e:77:4d:66:4f:7f:4a:35:fc:10:
|
||||
ec:4a:cf:80:0d:8d:de:b5:5a:74:e4:0c:ee:53:6e:
|
||||
28:b2:77:e4:ee:10:1c:61:99:b1:05:eb:d6:c5:f5:
|
||||
db:5d:d5:28:28:f2:39:8c:ee:3f:9a:6b:a0:a5:62:
|
||||
1f:f8:f5:bc:7e:6e:52:43:17:be:84:19:2a:e6:07:
|
||||
5a:be:a1:b3:1e:65:44:61:3d:73:41:7a:88:aa:29:
|
||||
1f:37:c7:91:dc:2d:32:58:32:87:2f:6f:a9:bc:b8:
|
||||
00:70:b9:29:1a:d7:71:9b:dd:01:ae:d3:aa:79:95:
|
||||
d2:ba:4c:32:b7:f0:7b:28:3b:2e:8c:14:ee:45:d4:
|
||||
fa:e4:6a:41:bf:78:11:ce:8d:c0:4e:18:f7:cd:99:
|
||||
3c:16:3a:ab:f0:95:c4:16:ca:4a:f8:42:ca:56:4b:
|
||||
ec:93:cd:d9:20:67:e9:b1:6a:bf:f2:42:ea:bb:c2:
|
||||
e6:12:35:a1:1f:18:7e:72:a1:8b:55:58:88:0a:c3:
|
||||
06:51:0c:fa:a9:49:0b:95:7b:e2:7e:31:62:cf:43:
|
||||
a4:53:33:ea:d7:20:75:73:1e:d3:e4:d5:ff:03:ae:
|
||||
03:7e:85:27:a9:27:2f:ec:54:10:44:40:2c:e3:9f:
|
||||
20:7e:b1:c9:fb:e8:44:d6:72:1d:e2:c9:5a:0c:8f:
|
||||
7a:15:38:6b:34:6f:85:d3:0c:c9:94:c3:f0:e6:12:
|
||||
de:53:0d:a8:7b:4e:a1:37:1b:e7:e9:04:86:e0:31:
|
||||
28:f1:33:35:10:66:5d:bb:8b:39:8c:f6:74:02:25:
|
||||
10:28:b0:da:0d:c1:7a:a5:33:be:78:2b:d5:9c:63:
|
||||
a8:13:f2:49:1c:8f:50:9f:4e:63
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:idnsans, DNS:xn--knig-5qa.idn.pythontest.net, DNS:xn--knigsgsschen-lcb0w.idna2003.pythontest.net, DNS:xn--knigsgchen-b4a3dun.idna2008.pythontest.net, DNS:xn--nxasmq6b.idna2003.pythontest.net, DNS:xn--nxasmm1c.idna2008.pythontest.net
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
5B:93:42:58:B0:B4:18:CC:41:4C:15:EB:42:33:66:77:4C:71:2F:42
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
||||
serial:CB:2D:80:99:5A:69:52:5B
|
||||
Authority Information Access:
|
||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
||||
X509v3 CRL Distribution Points:
|
||||
Full Name:
|
||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
5f:d8:9b:dc:22:55:80:47:e1:9b:04:3e:46:53:9b:e5:a7:4a:
|
||||
8f:eb:53:01:39:d5:04:f6:cf:dc:48:84:8a:a9:c3:a5:35:22:
|
||||
2f:ab:74:77:ec:a6:fd:b1:e6:e6:74:82:38:54:0b:27:36:e6:
|
||||
ec:3d:fe:92:1a:b2:7a:35:0d:a3:e5:7c:ff:e5:5b:1a:28:4b:
|
||||
29:1f:99:1b:3e:11:e9:e2:e0:d7:da:06:4f:e3:7b:8c:ad:30:
|
||||
f4:39:24:e8:ad:2a:0e:71:74:ab:ed:62:e9:9f:85:7e:6a:b0:
|
||||
bb:53:b4:d7:6b:b8:da:54:15:5c:9a:41:cf:61:f1:ab:67:d6:
|
||||
27:5c:0c:a3:d7:41:e7:27:3e:58:89:d6:1f:3f:2a:52:cc:13:
|
||||
0b:4b:e6:d6:ba:a0:c7:fd:e3:17:a4:b8:da:cc:cb:88:70:21:
|
||||
3b:70:df:09:40:6c:e7:02:81:08:80:b0:36:77:fb:44:c5:cf:
|
||||
bf:19:54:7c:d1:4e:1f:a2:44:9e:d8:56:0e:bf:4b:0b:e0:84:
|
||||
6f:bc:f6:c6:7f:35:7a:17:ca:83:b3:82:c6:4e:d3:f3:d8:30:
|
||||
05:fd:6d:3c:8a:ab:63:55:6f:c5:18:ba:66:fe:e2:35:04:2b:
|
||||
ae:76:34:f0:56:18:e8:54:db:83:b2:1b:93:0a:25:81:81:f0:
|
||||
25:ca:0a:95:be:8e:2f:05:3f:6c:e7:de:d1:7c:b8:a3:71:7c:
|
||||
6f:8a:05:c3:69:eb:6f:e6:76:8c:11:e1:59:0b:12:53:07:42:
|
||||
84:e8:89:ee:ab:7d:28:81:48:e8:79:d5:cf:a2:05:a4:fd:72:
|
||||
2c:7d:b4:1c:08:90:4e:0d:10:05:d1:9a:c0:69:4c:0a:14:39:
|
||||
17:fb:4d:5b:f6:42:bb:46:27:23:0f:5e:57:5b:b8:ae:9b:a3:
|
||||
0e:23:59:41:63:41:a4:f1:69:df:b3:a3:5c:10:d5:63:30:74:
|
||||
a8:3c:0c:8e:1c:6b:10:e1:13:27:02:26:9b:fd:88:93:7e:91:
|
||||
9c:f9:c2:07:27:a4
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGvTCCBSWgAwIBAgIJAMstgJlaaVJgMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMF0xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEDAOBgNVBAMMB2lk
|
||||
bnNhbnMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCp6zt40WB3K7yj
|
||||
BGugnRuqI3ApftThZWDIpvW0cVmN0nqQxsO6CCnS4dS7SYhGFiIqWjNVc2WG0gv7
|
||||
nC5DFguqbndNZk9/SjX8EOxKz4ANjd61WnTkDO5Tbiiyd+TuEBxhmbEF69bF9dtd
|
||||
1Sgo8jmM7j+aa6ClYh/49bx+blJDF76EGSrmB1q+obMeZURhPXNBeoiqKR83x5Hc
|
||||
LTJYMocvb6m8uABwuSka13Gb3QGu06p5ldK6TDK38HsoOy6MFO5F1PrkakG/eBHO
|
||||
jcBOGPfNmTwWOqvwlcQWykr4QspWS+yTzdkgZ+mxar/yQuq7wuYSNaEfGH5yoYtV
|
||||
WIgKwwZRDPqpSQuVe+J+MWLPQ6RTM+rXIHVzHtPk1f8DrgN+hSepJy/sVBBEQCzj
|
||||
nyB+scn76ETWch3iyVoMj3oVOGs0b4XTDMmUw/DmEt5TDah7TqE3G+fpBIbgMSjx
|
||||
MzUQZl27izmM9nQCJRAosNoNwXqlM754K9WcY6gT8kkcj1CfTmMCAwEAAaOCAo4w
|
||||
ggKKMIHhBgNVHREEgdkwgdaCB2lkbnNhbnOCH3huLS1rbmlnLTVxYS5pZG4ucHl0
|
||||
aG9udGVzdC5uZXSCLnhuLS1rbmlnc2dzc2NoZW4tbGNiMHcuaWRuYTIwMDMucHl0
|
||||
aG9udGVzdC5uZXSCLnhuLS1rbmlnc2djaGVuLWI0YTNkdW4uaWRuYTIwMDgucHl0
|
||||
aG9udGVzdC5uZXSCJHhuLS1ueGFzbXE2Yi5pZG5hMjAwMy5weXRob250ZXN0Lm5l
|
||||
dIIkeG4tLW54YXNtbTFjLmlkbmEyMDA4LnB5dGhvbnRlc3QubmV0MA4GA1UdDwEB
|
||||
/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/
|
||||
BAIwADAdBgNVHQ4EFgQUW5NCWLC0GMxBTBXrQjNmd0xxL0IwfQYDVR0jBHYwdIAU
|
||||
8+yUjvKOMMSOaMK/jmoZwMGfdmWhUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQK
|
||||
DB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNh
|
||||
LXNlcnZlcoIJAMstgJlaaVJbMIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKG
|
||||
MGh0dHA6Ly90ZXN0Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNl
|
||||
cjA1BggrBgEFBQcwAYYpaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0
|
||||
Y2Evb2NzcC8wQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250
|
||||
ZXN0Lm5ldC90ZXN0Y2EvcmV2b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGB
|
||||
AF/Ym9wiVYBH4ZsEPkZTm+WnSo/rUwE51QT2z9xIhIqpw6U1Ii+rdHfspv2x5uZ0
|
||||
gjhUCyc25uw9/pIasno1DaPlfP/lWxooSykfmRs+Eeni4NfaBk/je4ytMPQ5JOit
|
||||
Kg5xdKvtYumfhX5qsLtTtNdruNpUFVyaQc9h8atn1idcDKPXQecnPliJ1h8/KlLM
|
||||
EwtL5ta6oMf94xekuNrMy4hwITtw3wlAbOcCgQiAsDZ3+0TFz78ZVHzRTh+iRJ7Y
|
||||
Vg6/SwvghG+89sZ/NXoXyoOzgsZO0/PYMAX9bTyKq2NVb8UYumb+4jUEK652NPBW
|
||||
GOhU24OyG5MKJYGB8CXKCpW+ji8FP2zn3tF8uKNxfG+KBcNp62/mdowR4VkLElMH
|
||||
QoToie6rfSiBSOh51c+iBaT9cix9tBwIkE4NEAXRmsBpTAoUORf7TVv2QrtGJyMP
|
||||
XldbuK6bow4jWUFjQaTxad+zo1wQ1WMwdKg8DI4caxDhEycCJpv9iJN+kZz5wgcn
|
||||
pA==
|
||||
-----END CERTIFICATE-----
|
||||
69
Lib/test/certdata/keycert.passwd.pem
vendored
Normal file
69
Lib/test/certdata/keycert.passwd.pem
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
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
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgzCCAuugAwIBAgIUU+FIM/dUbCklbdDwNPd2xemDAEwwDQYJKoZIhvcNAQEL
|
||||
BQAwXzELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYD
|
||||
VQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxo
|
||||
b3N0MB4XDTIzMTEyNTA0MjEzNloXDTQzMDEyNDA0MjEzNlowXzELMAkGA1UEBhMC
|
||||
WFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxob3N0MIIBojANBgkqhkiG
|
||||
9w0BAQEFAAOCAY8AMIIBigKCAYEAzXTIl1su11AGu6sDPsoxqcRGyAX0yjxIcswF
|
||||
vj+eW/fBs2GcBby95VEOKpJPKRYYB7fAEAjAKK59zFdsDX/ynxPZLqyLQocBkFVq
|
||||
tclhCRZu//KZND+uQuHSx3PjGkSvK/nrGjg5T0bkM4SFeb0YdLb+0aDTKGozUC82
|
||||
oBAilNcrFz1VXpEF0qUe9QeKQhyd0MaW5T1oSn+U3RAj2MXm3TGExyZeaicpIM5O
|
||||
HFlnwUxsYSDZo0jUj342MbPOZh8szZDWi042jdtSA3i8uMSplEf4O8ZPmX0JCtrz
|
||||
fVjRVdaKXIjrhMNWB8K44q6AeyhqJcVHtOmPYoHDm0qIjcrurt0LZaGhmCuKimNd
|
||||
njcPxW0VQmDIS/mO5+s24SK+Mpznm5q/clXEwyD8FbrtrzV5cHCE8eNkxjuQjkmi
|
||||
wW9uadK1s54tDwRWMl6DRWRyxoF0an885UQWmbsgEB5aRmEx2L0JeD0/q6Iw1Nta
|
||||
As8DG4AaWuYMrgZXz7XvyiMq3IxVAgMBAAGjNzA1MBQGA1UdEQQNMAuCCWxvY2Fs
|
||||
aG9zdDAdBgNVHQ4EFgQUl2wd7iWE1JTZUVq2yFBKGm9N36owDQYJKoZIhvcNAQEL
|
||||
BQADggGBAF0f5x6QXFbgdyLOyeAPD/1DDxNjM68fJSmNM/6vxHJeDFzK0Pja+iJo
|
||||
xv54YiS9F2tiKPpejk4ujvLQgvrYrTQvliIE+7fUT0dV74wZKPdLphftT9uEo1dH
|
||||
TeIld+549fqcfZCJfVPE2Ka4vfyMGij9hVfY5FoZL1Xpnq/ZGYyWZNAPbkG292p8
|
||||
KrfLZm/0fFYAhq8tG/6DX7+2btxeX4MP/49tzskcYWgOjlkknyhJ76aMG9BJ1D7F
|
||||
/TIEh5ihNwRTmyt023RBz/xWiN4xBLyIlpQ6d5ECKmFNFr0qnEui6UovfCHUF6lZ
|
||||
qcAQ5VFQQ2CayNlVmQ+UGmWIqANlacYWBt7Q6VqpGg24zTMec1/Pqd6X07ScSfrm
|
||||
MAtywrWrU7p1aEkN5lBa4n/XKZHGYMjor/YcMdF5yjdSrZr274YYO1pafmTFwRwH
|
||||
5o16c8WPc0aPvTFbkGIFT5ddxYstw+QwsBtLKE2lJ4Qfmxt0Ew/0L7xkbK1BaCOo
|
||||
EGD2IF7VDQ==
|
||||
-----END CERTIFICATE-----
|
||||
67
Lib/test/certdata/keycert.pem
vendored
Normal file
67
Lib/test/certdata/keycert.pem
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
kNdcwhtZZ3dpChUdf+w/LIc=
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgzCCAuugAwIBAgIUU+FIM/dUbCklbdDwNPd2xemDAEwwDQYJKoZIhvcNAQEL
|
||||
BQAwXzELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYD
|
||||
VQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxo
|
||||
b3N0MB4XDTIzMTEyNTA0MjEzNloXDTQzMDEyNDA0MjEzNlowXzELMAkGA1UEBhMC
|
||||
WFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxob3N0MIIBojANBgkqhkiG
|
||||
9w0BAQEFAAOCAY8AMIIBigKCAYEAzXTIl1su11AGu6sDPsoxqcRGyAX0yjxIcswF
|
||||
vj+eW/fBs2GcBby95VEOKpJPKRYYB7fAEAjAKK59zFdsDX/ynxPZLqyLQocBkFVq
|
||||
tclhCRZu//KZND+uQuHSx3PjGkSvK/nrGjg5T0bkM4SFeb0YdLb+0aDTKGozUC82
|
||||
oBAilNcrFz1VXpEF0qUe9QeKQhyd0MaW5T1oSn+U3RAj2MXm3TGExyZeaicpIM5O
|
||||
HFlnwUxsYSDZo0jUj342MbPOZh8szZDWi042jdtSA3i8uMSplEf4O8ZPmX0JCtrz
|
||||
fVjRVdaKXIjrhMNWB8K44q6AeyhqJcVHtOmPYoHDm0qIjcrurt0LZaGhmCuKimNd
|
||||
njcPxW0VQmDIS/mO5+s24SK+Mpznm5q/clXEwyD8FbrtrzV5cHCE8eNkxjuQjkmi
|
||||
wW9uadK1s54tDwRWMl6DRWRyxoF0an885UQWmbsgEB5aRmEx2L0JeD0/q6Iw1Nta
|
||||
As8DG4AaWuYMrgZXz7XvyiMq3IxVAgMBAAGjNzA1MBQGA1UdEQQNMAuCCWxvY2Fs
|
||||
aG9zdDAdBgNVHQ4EFgQUl2wd7iWE1JTZUVq2yFBKGm9N36owDQYJKoZIhvcNAQEL
|
||||
BQADggGBAF0f5x6QXFbgdyLOyeAPD/1DDxNjM68fJSmNM/6vxHJeDFzK0Pja+iJo
|
||||
xv54YiS9F2tiKPpejk4ujvLQgvrYrTQvliIE+7fUT0dV74wZKPdLphftT9uEo1dH
|
||||
TeIld+549fqcfZCJfVPE2Ka4vfyMGij9hVfY5FoZL1Xpnq/ZGYyWZNAPbkG292p8
|
||||
KrfLZm/0fFYAhq8tG/6DX7+2btxeX4MP/49tzskcYWgOjlkknyhJ76aMG9BJ1D7F
|
||||
/TIEh5ihNwRTmyt023RBz/xWiN4xBLyIlpQ6d5ECKmFNFr0qnEui6UovfCHUF6lZ
|
||||
qcAQ5VFQQ2CayNlVmQ+UGmWIqANlacYWBt7Q6VqpGg24zTMec1/Pqd6X07ScSfrm
|
||||
MAtywrWrU7p1aEkN5lBa4n/XKZHGYMjor/YcMdF5yjdSrZr274YYO1pafmTFwRwH
|
||||
5o16c8WPc0aPvTFbkGIFT5ddxYstw+QwsBtLKE2lJ4Qfmxt0Ew/0L7xkbK1BaCOo
|
||||
EGD2IF7VDQ==
|
||||
-----END CERTIFICATE-----
|
||||
67
Lib/test/certdata/keycert2.pem
vendored
Normal file
67
Lib/test/certdata/keycert2.pem
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
M4mhHOfwBicqYzzEYbOE9Vk9
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEjDCCAvSgAwIBAgIUQ2S3jJ5nve5k5956sgsrWY3vw9MwDQYJKoZIhvcNAQEL
|
||||
BQAwYjELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYD
|
||||
VQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEVMBMGA1UEAwwMZmFrZWhv
|
||||
c3RuYW1lMB4XDTIzMTEyNTA0MjEzN1oXDTQzMDEyNDA0MjEzN1owYjELMAkGA1UE
|
||||
BhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRob24g
|
||||
U29mdHdhcmUgRm91bmRhdGlvbjEVMBMGA1UEAwwMZmFrZWhvc3RuYW1lMIIBojAN
|
||||
BgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsgFF43M4FBJ+5pjsAzIv/vsA0cai
|
||||
QCdn+xfQA8U7jpvhLXaX2K+JgZ/FM/XtyPmYXhuct0GdXXQWAPWE33FC9KJ/FFyz
|
||||
jgVWQnrcbEF6EgLgzD1dCF3hILWWQ13u0k6ikkHmJOws/lbR3pWfI+6DjnMebCYK
|
||||
W2g/jhiZz6AHQfJfJ0H8agBuObFuD+oHyyqCS74inLQ3uab4IiQvLb8rYPyIREin
|
||||
nny2eIsdnTY49hjVGi/pIVOlBLjNZCR3D1Yz6GHPsvH6Kf6oUNIrYQYTtjryfmJj
|
||||
hXQhOu0sgsFN6fMyaTfl5MGx7bYJjYODkrOx+lexOdvwrEzUwErYQR17camjPr42
|
||||
xgEa89haXP5/i8EbezBiEdIFbZ7U4Jz9B6Hh7JIQCHg7Wj62esx3Zd2g8IAHnFXm
|
||||
0xAU+WD26M/l9ZVnTq0Q9iVt26l0kSDdxOKs+SDLjcd1b4aUkXhWc0ekCG8UKszv
|
||||
1afdyL8vIT2eljIH0mFrOwhrbuDT+/TyX3TLAgMBAAGjOjA4MBcGA1UdEQQQMA6C
|
||||
DGZha2Vob3N0bmFtZTAdBgNVHQ4EFgQU5wVOIuQD/Jxmam/97g91+igosWQwDQYJ
|
||||
KoZIhvcNAQELBQADggGBAFv5gW5x4ET5NXEw6vILlOtwxwplEbU/x6eUVR/AXtEz
|
||||
jtq9zIk2svX/JIzSLRQnjJmb/nCDCeNcFMkkgIiB64I3yMJT9n50fO4EhSGEaITZ
|
||||
vYAw0/U6QXw+B1VS1ijNA44X2zvC+aw1q9W+0SKtvnu7l16TQ654ey0Qh9hOF1HS
|
||||
AZQ46593T9gaZMeexz4CShoBZ80oFOJezfNhyT3FK6tzXNbkVoJDhlLvr/ep81GG
|
||||
mABUGtKQYYMhuSSp0TDvf7jnXxtQcZI5lQOxZp0fnWUcK4gMVJqFVicwY8NiOhAG
|
||||
6TlvXYP4COLAvGmqBB+xUhekIS0jVzaMyek+hKK0sT/OE+W/fR5V9YT5QlHFJCf5
|
||||
IUIfDCpBZrBpsOTwsUm8eL0krLiBjYf0HgH5oFBc7aF4w1kuUJjlsJ68bzO9mLEF
|
||||
HXDaOWbe00+7BMMDnyuEyLN8KaAGiN8x0NQRX+nTAjCdPs6E0NftcXtznWBID6tA
|
||||
j5m7qjsoGurj6TlDsBJb1A==
|
||||
-----END CERTIFICATE-----
|
||||
161
Lib/test/certdata/keycert3.pem
vendored
Normal file
161
Lib/test/certdata/keycert3.pem
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
gDq3K6+KpVREQFEhyOtIB2kk
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:5c
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:a0:2a:28:71:0b:ed:a0:ed:de:cc:25:f2:14:05:
|
||||
f1:56:8a:e3:30:c6:0d:16:85:dc:4f:c8:65:33:30:
|
||||
08:de:c5:b1:0e:1e:8d:28:8e:7b:71:3d:d1:fd:29:
|
||||
84:70:88:a4:4a:6f:d8:e7:9b:35:e9:d8:22:93:86:
|
||||
a0:58:24:87:ad:ab:fd:cb:61:9a:78:6e:f0:c9:fe:
|
||||
15:42:2f:d7:b8:8e:ab:b5:97:ec:1d:f4:39:2a:84:
|
||||
a6:7a:f5:be:82:d7:f7:75:d8:90:0a:bc:2e:53:21:
|
||||
3f:bf:6f:b1:20:95:85:3c:28:c3:71:d9:63:b9:2b:
|
||||
12:09:79:5a:57:eb:c8:e7:e3:d6:2d:53:38:34:85:
|
||||
3d:10:89:78:f8:7a:e8:1b:0e:4d:4b:d5:ff:7d:c6:
|
||||
0b:e4:1d:a5:56:55:0c:62:e8:c1:4d:58:72:6a:ff:
|
||||
15:d4:6f:c1:3f:85:df:d0:de:86:9d:37:50:57:31:
|
||||
69:7d:3f:8e:83:e1:1f:98:18:a4:10:75:91:64:c0:
|
||||
42:6c:6e:a8:a3:16:f5:96:6c:ea:1a:cf:b4:c5:c5:
|
||||
ff:27:d2:ae:b5:eb:cd:37:69:72:df:69:68:a4:7c:
|
||||
45:cb:9f:39:c4:bc:aa:3b:bf:21:22:be:d4:ff:cb:
|
||||
5e:0d:9b:e4:a2:47:79:d2:e8:4d:32:0e:df:20:99:
|
||||
e1:dd:68:77:2b:99:04:fe:c9:0e:b2:34:e6:03:09:
|
||||
c7:de:60:cf:ab:06:eb:ce:50:73:ee:76:33:32:d2:
|
||||
4f:0a:ff:42:0f:8c:3a:34:28:07:2d:28:f1:f4:51:
|
||||
56:f2:0c:13:0a:0d:d1:90:db:e2:e1:44:52:ec:19:
|
||||
71:e5:0f:d6:f4:e4:fc:61:a9:35:0b:7b:72:de:2b:
|
||||
a2:99:fa:2b:86:6d:6b:70:54:b6:8b:e5:2e:36:5a:
|
||||
20:80:61:73:52:84:4d:4a:a3:44:3b:c2:e8:00:8a:
|
||||
9a:57:09:ff:9a:58:fd:d6:c7:d6:53:ae:c7:e2:0c:
|
||||
16:c8:7e:76:39:9a:57:dd:1b:dd
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:localhost
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
3F:B1:E9:4F:A0:BE:30:66:3E:0A:18:C8:0F:47:1A:4F:34:6A:0F:42
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
||||
serial:CB:2D:80:99:5A:69:52:5B
|
||||
Authority Information Access:
|
||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
||||
X509v3 CRL Distribution Points:
|
||||
Full Name:
|
||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
ca:34:ba:c5:d0:cf:27:31:32:d6:0d:27:30:b8:db:17:df:b7:
|
||||
39:a7:bb:b1:3b:86:c4:31:fd:fb:ab:db:63:1a:cc:90:ab:b9:
|
||||
4e:ab:34:49:0c:5e:8c:3e:70:a3:a7:6b:2f:a7:9a:25:7b:01:
|
||||
5a:18:96:48:76:f8:36:78:74:fa:bc:7d:68:7f:e5:ca:a6:9d:
|
||||
7b:dc:72:bd:a3:25:51:17:68:e8:e9:d7:02:86:2c:7d:16:7c:
|
||||
b5:dc:44:b2:0a:e3:f7:c9:33:a3:51:36:83:bc:d4:70:cd:84:
|
||||
91:9f:06:ba:2d:d2:05:0a:65:c3:d9:55:09:a8:b8:09:69:bb:
|
||||
93:86:c2:b7:c2:90:74:7c:bf:f0:5d:bc:0e:63:13:8c:eb:fa:
|
||||
0f:f1:fa:e5:12:70:4d:0c:eb:8c:2e:a2:42:42:00:04:0f:fc:
|
||||
f9:1f:41:9c:63:78:f0:66:93:b2:8f:2e:e8:93:1c:50:cb:2d:
|
||||
7f:b6:ba:57:6f:52:62:d7:39:0b:09:82:ab:a6:53:4d:cc:05:
|
||||
3e:19:f0:d4:c0:ce:a9:ad:10:ce:b9:71:e4:8f:f2:5a:3c:65:
|
||||
ba:dc:cb:e0:04:90:2b:a5:15:a6:7d:da:dc:a3:b5:b7:bc:a0:
|
||||
de:30:4e:64:cb:17:0d:3a:a0:52:d2:67:3b:a2:3a:00:d5:39:
|
||||
aa:61:75:52:9f:fe:9b:c0:e8:a0:69:af:a8:b3:a3:1d:0a:40:
|
||||
52:04:e7:3d:c0:00:96:5f:2b:33:06:0c:30:f6:d3:18:72:ee:
|
||||
38:d0:64:d3:00:86:37:ec:4f:e9:38:49:e6:01:ff:a2:9a:7c:
|
||||
dc:6a:d3:cb:a8:ba:58:fb:c3:86:78:47:f1:06:a6:45:e7:53:
|
||||
de:99:1d:81:e6:bc:63:74:46:7c:70:23:57:29:60:70:9a:cc:
|
||||
6f:00:8e:c2:bf:6a:73:7d:6e:b0:62:e6:dc:13:1a:b9:fe:0f:
|
||||
c2:d1:06:a1:79:62:7f:b6:30:a9:03:d0:47:57:25:db:48:10:
|
||||
d1:cf:fb:7d:ac:3d
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF8TCCBFmgAwIBAgIJAMstgJlaaVJcMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxv
|
||||
Y2FsaG9zdDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKAqKHEL7aDt
|
||||
3swl8hQF8VaK4zDGDRaF3E/IZTMwCN7FsQ4ejSiOe3E90f0phHCIpEpv2OebNenY
|
||||
IpOGoFgkh62r/cthmnhu8Mn+FUIv17iOq7WX7B30OSqEpnr1voLX93XYkAq8LlMh
|
||||
P79vsSCVhTwow3HZY7krEgl5WlfryOfj1i1TODSFPRCJePh66BsOTUvV/33GC+Qd
|
||||
pVZVDGLowU1Ycmr/FdRvwT+F39Dehp03UFcxaX0/joPhH5gYpBB1kWTAQmxuqKMW
|
||||
9ZZs6hrPtMXF/yfSrrXrzTdpct9paKR8RcufOcS8qju/ISK+1P/LXg2b5KJHedLo
|
||||
TTIO3yCZ4d1odyuZBP7JDrI05gMJx95gz6sG685Qc+52MzLSTwr/Qg+MOjQoBy0o
|
||||
8fRRVvIMEwoN0ZDb4uFEUuwZceUP1vTk/GGpNQt7ct4ropn6K4Zta3BUtovlLjZa
|
||||
IIBhc1KETUqjRDvC6ACKmlcJ/5pY/dbH1lOux+IMFsh+djmaV90b3QIDAQABo4IB
|
||||
wDCCAbwwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA4GA1UdDwEB/wQEAwIFoDAdBgNV
|
||||
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E
|
||||
FgQUP7HpT6C+MGY+ChjID0caTzRqD0IwfQYDVR0jBHYwdIAU8+yUjvKOMMSOaMK/
|
||||
jmoZwMGfdmWhUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAMst
|
||||
gJlaaVJbMIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0
|
||||
Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcw
|
||||
AYYpaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYD
|
||||
VR0fBDwwOjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0
|
||||
Y2EvcmV2b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGBAMo0usXQzycxMtYN
|
||||
JzC42xfftzmnu7E7hsQx/fur22MazJCruU6rNEkMXow+cKOnay+nmiV7AVoYlkh2
|
||||
+DZ4dPq8fWh/5cqmnXvccr2jJVEXaOjp1wKGLH0WfLXcRLIK4/fJM6NRNoO81HDN
|
||||
hJGfBrot0gUKZcPZVQmouAlpu5OGwrfCkHR8v/BdvA5jE4zr+g/x+uUScE0M64wu
|
||||
okJCAAQP/PkfQZxjePBmk7KPLuiTHFDLLX+2uldvUmLXOQsJgqumU03MBT4Z8NTA
|
||||
zqmtEM65ceSP8lo8Zbrcy+AEkCulFaZ92tyjtbe8oN4wTmTLFw06oFLSZzuiOgDV
|
||||
OaphdVKf/pvA6KBpr6izox0KQFIE5z3AAJZfKzMGDDD20xhy7jjQZNMAhjfsT+k4
|
||||
SeYB/6KafNxq08uoulj7w4Z4R/EGpkXnU96ZHYHmvGN0RnxwI1cpYHCazG8AjsK/
|
||||
anN9brBi5twTGrn+D8LRBqF5Yn+2MKkD0EdXJdtIENHP+32sPQ==
|
||||
-----END CERTIFICATE-----
|
||||
161
Lib/test/certdata/keycert4.pem
vendored
Normal file
161
Lib/test/certdata/keycert4.pem
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
DbKC6hxxQbDaNOvXEAda8wU=
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:5d
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=fakehostname
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:c6:28:0d:73:64:38:de:34:f8:76:27:d5:87:55:
|
||||
75:cc:51:ff:21:e4:de:3f:6c:70:8c:dc:26:c8:69:
|
||||
9d:5d:4a:19:02:81:f9:85:5a:63:ad:ae:e1:22:86:
|
||||
06:df:45:86:92:59:90:30:0a:65:40:40:68:e6:82:
|
||||
f5:1f:80:e2:20:b0:57:cc:f3:23:be:cc:30:72:3e:
|
||||
1c:da:ed:7b:d6:3d:97:c4:7b:b9:8d:44:57:b9:66:
|
||||
56:27:b5:b7:8c:fe:fb:96:08:ce:15:cf:00:ea:fe:
|
||||
6a:85:4c:5c:4d:46:6c:08:9e:a1:3b:87:1d:16:9d:
|
||||
f0:a8:41:67:bd:37:8d:61:27:29:75:2b:43:a3:00:
|
||||
36:fe:4a:39:69:27:4f:d4:27:ad:e1:b0:1f:9d:a3:
|
||||
01:a3:69:a0:6f:27:c1:dd:b9:07:11:a8:d8:3c:b3:
|
||||
a1:5c:c8:92:7c:32:3b:2c:d6:e4:4c:14:ad:a3:f5:
|
||||
0a:e6:81:b0:3a:d5:7b:88:3c:2c:73:73:72:79:ee:
|
||||
65:bc:14:dd:8a:b1:1f:03:d8:73:a1:7b:d9:ec:4c:
|
||||
69:71:a7:e3:b9:0a:e7:5f:fd:10:56:07:8e:37:c5:
|
||||
ca:32:76:ec:11:5c:e1:53:74:40:14:e3:93:12:e2:
|
||||
d2:86:3f:68:73:7b:3b:b1:30:54:27:2c:a0:11:5d:
|
||||
55:b8:fe:01:71:66:4e:e4:53:c4:f0:79:95:12:e8:
|
||||
b0:18:3d:f6:09:9e:57:ed:79:be:b3:df:b2:c0:6e:
|
||||
da:03:bf:32:94:28:11:03:7f:f9:e6:a1:ae:c2:b8:
|
||||
ac:52:3c:2e:47:20:a8:4b:6e:35:3f:ea:4b:8f:82:
|
||||
54:95:11:f2:4f:25:6b:b6:6d:92:43:02:41:4b:f3:
|
||||
93:ad:de:03:ec:d7:41:17:da:53:14:cb:42:6d:de:
|
||||
d7:fe:4d:a4:23:12:f1:59:86:92:8d:f0:a0:1d:62:
|
||||
3d:de:56:03:9f:cc:80:5b:43:28:e8:b4:72:63:15:
|
||||
ef:49:92:ae:2a:ed:1a:08:fa:77
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:fakehostname
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
1C:70:14:B0:20:DD:08:76:A4:3B:56:59:FA:5F:34:F8:36:66:E8:56
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
||||
serial:CB:2D:80:99:5A:69:52:5B
|
||||
Authority Information Access:
|
||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
||||
X509v3 CRL Distribution Points:
|
||||
Full Name:
|
||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
75:14:e5:68:45:8d:ed:6c:f1:27:1e:0e:f3:35:ae:0e:60:c1:
|
||||
65:36:62:b8:07:78:e1:b9:8d:7a:50:70:af:06:c9:d4:ee:50:
|
||||
ef:d2:76:b2:a2:b6:cb:dc:a6:18:b5:3d:d2:f7:eb:0e:ec:b7:
|
||||
95:cd:2e:b1:36:6f:a8:9f:b8:4d:ff:ce:8a:c4:8e:62:37:32:
|
||||
80:3e:05:4a:4d:39:87:69:09:00:e8:40:64:d2:9d:f9:1f:9f:
|
||||
ab:67:1f:f9:c6:84:ba:7e:17:6c:8b:8d:08:ee:fb:8a:d7:cd:
|
||||
06:25:72:9f:4e:1a:c2:71:e1:1b:cf:a2:d7:1c:05:12:95:d6:
|
||||
49:4b:e9:95:95:89:cf:68:18:46:a3:ea:0d:9d:8e:ca:1c:28:
|
||||
55:49:6b:c0:4b:58:f5:42:b9:0a:ec:0e:6e:21:a4:ff:60:c0:
|
||||
1b:6e:40:72:d0:a5:c5:b5:db:4e:87:67:3a:31:70:cb:32:84:
|
||||
70:a9:e2:ff:e0:f2:db:cd:03:b4:85:45:d3:07:cc:0f:c7:49:
|
||||
d8:c2:17:eb:73:f7:4a:c0:d9:8c:59:ef:c0:0a:ce:13:0b:84:
|
||||
c9:aa:0d:11:14:b4:e5:74:aa:ec:18:de:5f:26:18:98:4a:76:
|
||||
f0:7f:cd:e6:c4:b5:58:03:03:f5:10:01:5d:8f:63:88:ba:65:
|
||||
d7:b4:7f:5a:1a:51:0e:ed:e5:68:fa:18:03:72:15:a1:ec:27:
|
||||
1f:ea:ac:24:46:18:6e:f1:97:db:4a:f4:d6:a1:91:a0:8c:b0:
|
||||
2f:be:87:3b:44:b0:8d:2a:89:85:5f:f2:d9:e3:2e:66:b2:88:
|
||||
98:04:2c:96:32:38:99:19:a9:83:fd:94:0c:dd:63:d4:1b:60:
|
||||
9d:43:98:35:ac:b4:23:38:de:7f:85:52:57:a0:37:df:a5:cf:
|
||||
be:54:2c:3c:50:27:2b:d4:54:a9:9d:a3:d4:a5:b3:c0:ea:3d:
|
||||
0e:e2:70:6b:fb:cb:a5:56:05:ec:64:72:f0:1a:db:64:01:cb:
|
||||
5d:27:c4:a1:c4:63
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF9zCCBF+gAwIBAgIJAMstgJlaaVJdMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMGIxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFTATBgNVBAMMDGZh
|
||||
a2Vob3N0bmFtZTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMYoDXNk
|
||||
ON40+HYn1YdVdcxR/yHk3j9scIzcJshpnV1KGQKB+YVaY62u4SKGBt9FhpJZkDAK
|
||||
ZUBAaOaC9R+A4iCwV8zzI77MMHI+HNrte9Y9l8R7uY1EV7lmVie1t4z++5YIzhXP
|
||||
AOr+aoVMXE1GbAieoTuHHRad8KhBZ703jWEnKXUrQ6MANv5KOWknT9QnreGwH52j
|
||||
AaNpoG8nwd25BxGo2DyzoVzIknwyOyzW5EwUraP1CuaBsDrVe4g8LHNzcnnuZbwU
|
||||
3YqxHwPYc6F72exMaXGn47kK51/9EFYHjjfFyjJ27BFc4VN0QBTjkxLi0oY/aHN7
|
||||
O7EwVCcsoBFdVbj+AXFmTuRTxPB5lRLosBg99gmeV+15vrPfssBu2gO/MpQoEQN/
|
||||
+eahrsK4rFI8LkcgqEtuNT/qS4+CVJUR8k8la7ZtkkMCQUvzk63eA+zXQRfaUxTL
|
||||
Qm3e1/5NpCMS8VmGko3woB1iPd5WA5/MgFtDKOi0cmMV70mSrirtGgj6dwIDAQAB
|
||||
o4IBwzCCAb8wFwYDVR0RBBAwDoIMZmFrZWhvc3RuYW1lMA4GA1UdDwEB/wQEAwIF
|
||||
oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAd
|
||||
BgNVHQ4EFgQUHHAUsCDdCHakO1ZZ+l80+DZm6FYwfQYDVR0jBHYwdIAU8+yUjvKO
|
||||
MMSOaMK/jmoZwMGfdmWhUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRo
|
||||
b24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZl
|
||||
coIJAMstgJlaaVJbMIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6
|
||||
Ly90ZXN0Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1Bggr
|
||||
BgEFBQcwAYYpaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2Nz
|
||||
cC8wQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5l
|
||||
dC90ZXN0Y2EvcmV2b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGBAHUU5WhF
|
||||
je1s8SceDvM1rg5gwWU2YrgHeOG5jXpQcK8GydTuUO/SdrKitsvcphi1PdL36w7s
|
||||
t5XNLrE2b6ifuE3/zorEjmI3MoA+BUpNOYdpCQDoQGTSnfkfn6tnH/nGhLp+F2yL
|
||||
jQju+4rXzQYlcp9OGsJx4RvPotccBRKV1klL6ZWVic9oGEaj6g2djsocKFVJa8BL
|
||||
WPVCuQrsDm4hpP9gwBtuQHLQpcW1206HZzoxcMsyhHCp4v/g8tvNA7SFRdMHzA/H
|
||||
SdjCF+tz90rA2YxZ78AKzhMLhMmqDREUtOV0quwY3l8mGJhKdvB/zebEtVgDA/UQ
|
||||
AV2PY4i6Zde0f1oaUQ7t5Wj6GANyFaHsJx/qrCRGGG7xl9tK9NahkaCMsC++hztE
|
||||
sI0qiYVf8tnjLmayiJgELJYyOJkZqYP9lAzdY9QbYJ1DmDWstCM43n+FUlegN9+l
|
||||
z75ULDxQJyvUVKmdo9Sls8DqPQ7icGv7y6VWBexkcvAa22QBy10nxKHEYw==
|
||||
-----END CERTIFICATE-----
|
||||
103
Lib/test/certdata/keycertecc.pem
vendored
Normal file
103
Lib/test/certdata/keycertecc.pem
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDRUbCeT3hMph4Y/ahL
|
||||
1sy9Qfy4DYotuAP06UetzG6syv+EoQ02kX3xvazqwiJDrEyhZANiAAQef97STEPn
|
||||
4Nk6C153VEx24MNkJUcmLe771u6lr3Q8Em3J/YPaA1i9Ys7KZA3WvoKBPoWaaikn
|
||||
4yLQbd/6YE6AAjMuaThlR1/cqH5QnmS3DXHUjmxnLjWy/dZl0CJG1qo=
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:5e
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost-ecc
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: id-ecPublicKey
|
||||
Public-Key: (384 bit)
|
||||
pub:
|
||||
04:1e:7f:de:d2:4c:43:e7:e0:d9:3a:0b:5e:77:54:
|
||||
4c:76:e0:c3:64:25:47:26:2d:ee:fb:d6:ee:a5:af:
|
||||
74:3c:12:6d:c9:fd:83:da:03:58:bd:62:ce:ca:64:
|
||||
0d:d6:be:82:81:3e:85:9a:6a:29:27:e3:22:d0:6d:
|
||||
df:fa:60:4e:80:02:33:2e:69:38:65:47:5f:dc:a8:
|
||||
7e:50:9e:64:b7:0d:71:d4:8e:6c:67:2e:35:b2:fd:
|
||||
d6:65:d0:22:46:d6:aa
|
||||
ASN1 OID: secp384r1
|
||||
NIST CURVE: P-384
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:localhost-ecc
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication, TLS Web Client Authentication
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
45:ED:32:14:6D:51:A2:3B:B0:80:55:E0:A6:9B:74:4C:A5:56:88:B1
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
||||
serial:CB:2D:80:99:5A:69:52:5B
|
||||
Authority Information Access:
|
||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
||||
X509v3 CRL Distribution Points:
|
||||
Full Name:
|
||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
07:e4:91:0b:d3:ed:4b:52:7f:50:68:c7:8d:80:48:9f:b7:4a:
|
||||
13:66:bf:9d:4c:2d:18:19:68:a0:da:3b:12:85:05:16:fa:8d:
|
||||
9c:58:c6:81:b3:96:ba:11:62:65:d3:76:f1:1c:ab:95:e4:d8:
|
||||
2a:e0:1f:7b:c5:20:2e:7c:8f:de:87:7a:2b:52:54:ca:d1:41:
|
||||
b0:5e:20:72:df:44:00:4a:69:1a:ef:10:63:52:13:ed:49:02:
|
||||
ee:dc:9d:f3:c8:ba:c4:01:81:5a:a9:1c:15:12:b6:21:de:44:
|
||||
a5:fd:7e:f9:22:d1:3e:ee:22:dd:31:55:32:4e:41:68:27:c5:
|
||||
95:1b:7e:6b:18:74:f9:22:d6:b7:b9:31:72:51:a0:5a:2c:ff:
|
||||
62:76:e9:a0:55:8d:78:33:52:4a:58:b2:f4:4b:0c:43:82:2f:
|
||||
a9:84:68:05:dd:11:47:70:24:fe:5c:92:fd:17:21:63:bb:fa:
|
||||
93:fa:54:54:05:72:48:ed:81:48:ab:95:fc:6d:a8:62:96:f9:
|
||||
3b:e2:71:18:05:3e:76:bb:df:95:17:7b:81:4b:1f:7f:e1:67:
|
||||
76:c4:07:cb:65:a7:f2:cf:e6:b4:fb:75:7c:ee:df:a1:f5:34:
|
||||
20:2b:48:fd:2e:49:ff:f3:a6:3b:00:49:6c:88:79:ed:9c:16:
|
||||
2a:04:72:e2:93:e4:7e:3f:2a:dd:30:47:9a:99:84:2a:b9:c4:
|
||||
40:31:a6:68:f3:20:d1:75:f1:1e:c8:18:64:5b:f8:4c:ce:9a:
|
||||
3c:57:2c:e3:63:64:29:0a:c2:b6:8e:20:01:55:9f:fe:10:ba:
|
||||
12:42:38:0a:9b:53:01:a5:b4:08:76:ec:e8:a6:fc:69:2c:f7:
|
||||
7f:5e:0f:44:07:55:e1:7c:2e:58:e5:d6:fc:6f:c2:4d:83:65:
|
||||
bd:f3:32:e3:14:48:22:8d:80:18:ea:44:f8:24:79:ff:ff:c6:
|
||||
04:c2:e9:90:34:40:d6:59:3f:59:1e:4a:9a:58:60:ce:ab:f9:
|
||||
76:0e:ef:f7:05:17
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEyzCCAzOgAwIBAgIJAMstgJlaaVJeMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaMGMxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNVBAMMDWxv
|
||||
Y2FsaG9zdC1lY2MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQef97STEPn4Nk6C153
|
||||
VEx24MNkJUcmLe771u6lr3Q8Em3J/YPaA1i9Ys7KZA3WvoKBPoWaaikn4yLQbd/6
|
||||
YE6AAjMuaThlR1/cqH5QnmS3DXHUjmxnLjWy/dZl0CJG1qqjggHEMIIBwDAYBgNV
|
||||
HREEETAPgg1sb2NhbGhvc3QtZWNjMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
|
||||
BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQURe0y
|
||||
FG1RojuwgFXgppt0TKVWiLEwfQYDVR0jBHYwdIAU8+yUjvKOMMSOaMK/jmoZwMGf
|
||||
dmWhUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
|
||||
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAMstgJlaaVJb
|
||||
MIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0Y2EucHl0
|
||||
aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcwAYYpaHR0
|
||||
cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYDVR0fBDww
|
||||
OjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2EvcmV2
|
||||
b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQELBQADggGBAAfkkQvT7UtSf1Box42ASJ+3
|
||||
ShNmv51MLRgZaKDaOxKFBRb6jZxYxoGzlroRYmXTdvEcq5Xk2CrgH3vFIC58j96H
|
||||
eitSVMrRQbBeIHLfRABKaRrvEGNSE+1JAu7cnfPIusQBgVqpHBUStiHeRKX9fvki
|
||||
0T7uIt0xVTJOQWgnxZUbfmsYdPki1re5MXJRoFos/2J26aBVjXgzUkpYsvRLDEOC
|
||||
L6mEaAXdEUdwJP5ckv0XIWO7+pP6VFQFckjtgUirlfxtqGKW+TvicRgFPna735UX
|
||||
e4FLH3/hZ3bEB8tlp/LP5rT7dXzu36H1NCArSP0uSf/zpjsASWyIee2cFioEcuKT
|
||||
5H4/Kt0wR5qZhCq5xEAxpmjzINF18R7IGGRb+EzOmjxXLONjZCkKwraOIAFVn/4Q
|
||||
uhJCOAqbUwGltAh27Oim/Gks939eD0QHVeF8Lljl1vxvwk2DZb3zMuMUSCKNgBjq
|
||||
RPgkef//xgTC6ZA0QNZZP1keSppYYM6r+XYO7/cFFw==
|
||||
-----END CERTIFICATE-----
|
||||
13
Lib/test/certdata/leaf-missing-aki.ca.pem
vendored
Normal file
13
Lib/test/certdata/leaf-missing-aki.ca.pem
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Taken from x509-limbo's `rfc5280::aki::leaf-missing-aki` testcase.
|
||||
# See: https://x509-limbo.com/testcases/rfc5280/#rfc5280akileaf-missing-aki
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBkDCCATWgAwIBAgIUGjIb/aYm9u9fBh2o4GAYRJwk5XIwCgYIKoZIzj0EAwIw
|
||||
GjEYMBYGA1UEAwwPeDUwOS1saW1iby1yb290MCAXDTcwMDEwMTAwMDAwMVoYDzI5
|
||||
NjkwNTAzMDAwMDAxWjAaMRgwFgYDVQQDDA94NTA5LWxpbWJvLXJvb3QwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAARUzBhjMOkO911U65Fvs4YmL1YPNj63P9Fa+g9U
|
||||
KrUqiIy8WjaDXdIe8g8Zj0TalpbU1gYCs3atteMxgIp6qxwHo1cwVTAPBgNVHRMB
|
||||
Af8EBTADAQH/MAsGA1UdDwQEAwICBDAWBgNVHREEDzANggtleGFtcGxlLmNvbTAd
|
||||
BgNVHQ4EFgQUcv1fyqgezMGzmo+lhmUkdUuAbIowCgYIKoZIzj0EAwIDSQAwRgIh
|
||||
AIOErPSRlWpnyMub9UgtPF/lSzdvnD4Q8KjLQppHx6oPAiEA373p4L/HvUbs0xg8
|
||||
6/pLyn0RT02toKKJcMV3ChohLtM=
|
||||
-----END CERTIFICATE-----
|
||||
18
Lib/test/certdata/leaf-missing-aki.keycert.pem
vendored
Normal file
18
Lib/test/certdata/leaf-missing-aki.keycert.pem
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Taken from x509-limbo's `rfc5280::aki::leaf-missing-aki` testcase.
|
||||
# See: https://x509-limbo.com/testcases/rfc5280/#rfc5280akileaf-missing-aki
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIF5Re+/FP3rg+7c1odKEQPXhb9V65kXnlZIWHDG9gKrLoAoGCCqGSM49
|
||||
AwEHoUQDQgAE1WAQMdC7ims7T9lpK9uzaCuKqHb/oNMbGjh1f10pOHv3Z+oAvsqF
|
||||
Sv3hGzreu69YLy01afA6sUCf1AA/95dKkg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBjjCCATWgAwIBAgIUVlBgclml+OXlrWzZfcgYCiNm96UwCgYIKoZIzj0EAwIw
|
||||
GjEYMBYGA1UEAwwPeDUwOS1saW1iby1yb290MCAXDTcwMDEwMTAwMDAwMVoYDzI5
|
||||
NjkwNTAzMDAwMDAxWjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTBZMBMGByqGSM49
|
||||
AgEGCCqGSM49AwEHA0IABNVgEDHQu4prO0/ZaSvbs2griqh2/6DTGxo4dX9dKTh7
|
||||
92fqAL7KhUr94Rs63ruvWC8tNWnwOrFAn9QAP/eXSpKjWzBZMB0GA1UdDgQWBBS3
|
||||
yYRQQwo3syjGVQ8Yw7/XRZHbpzALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB
|
||||
BQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDRwAwRAIg
|
||||
BVq7lw4Y5MPEyisPhowMWd4KnERupdM5qeImDO+dD7ICIE/ksd6Wz1b8rMAfllNV
|
||||
yiYst9lfwTd2SkFgdDNUDFud
|
||||
-----END CERTIFICATE-----
|
||||
315
Lib/test/certdata/make_ssl_certs.py
vendored
Normal file
315
Lib/test/certdata/make_ssl_certs.py
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
"""Make the custom certificate and private key files used by test_ssl
|
||||
and friends."""
|
||||
|
||||
import os
|
||||
import pprint
|
||||
import shutil
|
||||
import tempfile
|
||||
from subprocess import *
|
||||
|
||||
startdate = "20180829142316Z"
|
||||
enddate = "20371028142316Z"
|
||||
|
||||
req_template = """
|
||||
[ default ]
|
||||
base_url = http://testca.pythontest.net/testca
|
||||
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
|
||||
[req_distinguished_name]
|
||||
C = XY
|
||||
L = Castle Anthrax
|
||||
O = Python Software Foundation
|
||||
CN = {hostname}
|
||||
|
||||
[req_x509_extensions_nosan]
|
||||
|
||||
[req_x509_extensions_simple]
|
||||
subjectAltName = @san
|
||||
|
||||
[req_x509_extensions_full]
|
||||
subjectAltName = @san
|
||||
keyUsage = critical,keyEncipherment,digitalSignature
|
||||
extendedKeyUsage = serverAuth,clientAuth
|
||||
basicConstraints = critical,CA:false
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer:always
|
||||
authorityInfoAccess = @issuer_ocsp_info
|
||||
crlDistributionPoints = @crl_info
|
||||
|
||||
[ issuer_ocsp_info ]
|
||||
caIssuers;URI.0 = $base_url/pycacert.cer
|
||||
OCSP;URI.0 = $base_url/ocsp/
|
||||
|
||||
[ crl_info ]
|
||||
URI.0 = $base_url/revocation.crl
|
||||
|
||||
[san]
|
||||
DNS.1 = {hostname}
|
||||
{extra_san}
|
||||
|
||||
[dir_sect]
|
||||
C = XY
|
||||
L = Castle Anthrax
|
||||
O = Python Software Foundation
|
||||
CN = dirname example
|
||||
|
||||
[princ_name]
|
||||
realm = EXP:0, GeneralString:KERBEROS.REALM
|
||||
principal_name = EXP:1, SEQUENCE:principal_seq
|
||||
|
||||
[principal_seq]
|
||||
name_type = EXP:0, INTEGER:1
|
||||
name_string = EXP:1, SEQUENCE:principals
|
||||
|
||||
[principals]
|
||||
princ1 = GeneralString:username
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
dir = cadir
|
||||
database = $dir/index.txt
|
||||
crlnumber = $dir/crl.txt
|
||||
default_md = sha256
|
||||
startdate = {startdate}
|
||||
default_startdate = {startdate}
|
||||
enddate = {enddate}
|
||||
default_enddate = {enddate}
|
||||
default_days = 7000
|
||||
default_crl_days = 7000
|
||||
certificate = pycacert.pem
|
||||
private_key = pycakey.pem
|
||||
serial = $dir/serial
|
||||
RANDFILE = $dir/.rand
|
||||
policy = policy_match
|
||||
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
stateOrProvinceName = optional
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ policy_anything ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
|
||||
[ v3_ca ]
|
||||
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid:always,issuer
|
||||
basicConstraints = critical, CA:true
|
||||
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
|
||||
|
||||
"""
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def make_cert_key(hostname, sign=False, extra_san='',
|
||||
ext='req_x509_extensions_full', key='rsa:3072'):
|
||||
print("creating cert for " + hostname)
|
||||
tempnames = []
|
||||
for i in range(3):
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
tempnames.append(f.name)
|
||||
req_file, cert_file, key_file = tempnames
|
||||
try:
|
||||
req = req_template.format(
|
||||
hostname=hostname,
|
||||
extra_san=extra_san,
|
||||
startdate=startdate,
|
||||
enddate=enddate
|
||||
)
|
||||
with open(req_file, 'w') as f:
|
||||
f.write(req)
|
||||
args = ['req', '-new', '-nodes', '-days', '7000',
|
||||
'-newkey', key, '-keyout', key_file,
|
||||
'-extensions', ext,
|
||||
'-config', req_file]
|
||||
if sign:
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
tempnames.append(f.name)
|
||||
reqfile = f.name
|
||||
args += ['-out', reqfile ]
|
||||
|
||||
else:
|
||||
args += ['-x509', '-out', cert_file ]
|
||||
check_call(['openssl'] + args)
|
||||
|
||||
if sign:
|
||||
args = [
|
||||
'ca',
|
||||
'-config', req_file,
|
||||
'-extensions', ext,
|
||||
'-out', cert_file,
|
||||
'-outdir', 'cadir',
|
||||
'-policy', 'policy_anything',
|
||||
'-batch', '-infiles', reqfile
|
||||
]
|
||||
check_call(['openssl'] + args)
|
||||
|
||||
|
||||
with open(cert_file, 'r') as f:
|
||||
cert = f.read()
|
||||
with open(key_file, 'r') as f:
|
||||
key = f.read()
|
||||
return cert, key
|
||||
finally:
|
||||
for name in tempnames:
|
||||
os.remove(name)
|
||||
|
||||
TMP_CADIR = 'cadir'
|
||||
|
||||
def unmake_ca():
|
||||
shutil.rmtree(TMP_CADIR)
|
||||
|
||||
def make_ca():
|
||||
os.mkdir(TMP_CADIR)
|
||||
with open(os.path.join('cadir','index.txt'),'a+') as f:
|
||||
pass # empty file
|
||||
with open(os.path.join('cadir','crl.txt'),'a+') as f:
|
||||
f.write("00")
|
||||
with open(os.path.join('cadir','index.txt.attr'),'w+') as f:
|
||||
f.write('unique_subject = no')
|
||||
# random start value for serial numbers
|
||||
with open(os.path.join('cadir','serial'), 'w') as f:
|
||||
f.write('CB2D80995A69525B\n')
|
||||
|
||||
with tempfile.NamedTemporaryFile("w") as t:
|
||||
req = req_template.format(
|
||||
hostname='our-ca-server',
|
||||
extra_san='',
|
||||
startdate=startdate,
|
||||
enddate=enddate
|
||||
)
|
||||
t.write(req)
|
||||
t.flush()
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
args = ['req', '-config', t.name, '-new',
|
||||
'-nodes',
|
||||
'-newkey', 'rsa:3072',
|
||||
'-keyout', 'pycakey.pem',
|
||||
'-out', f.name,
|
||||
'-subj', '/C=XY/L=Castle Anthrax/O=Python Software Foundation CA/CN=our-ca-server']
|
||||
check_call(['openssl'] + args)
|
||||
args = ['ca', '-config', t.name,
|
||||
'-out', 'pycacert.pem', '-batch', '-outdir', TMP_CADIR,
|
||||
'-keyfile', 'pycakey.pem',
|
||||
'-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ]
|
||||
check_call(['openssl'] + args)
|
||||
args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
|
||||
check_call(['openssl'] + args)
|
||||
|
||||
# capath hashes depend on subject!
|
||||
check_call([
|
||||
'openssl', 'x509', '-in', 'pycacert.pem', '-out', 'capath/ceff1710.0'
|
||||
])
|
||||
shutil.copy('capath/ceff1710.0', 'capath/b1930218.0')
|
||||
|
||||
|
||||
def print_cert(path):
|
||||
import _ssl
|
||||
pprint.pprint(_ssl._test_decode_cert(path))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(here)
|
||||
cert, key = make_cert_key('localhost', ext='req_x509_extensions_simple')
|
||||
with open('ssl_cert.pem', 'w') as f:
|
||||
f.write(cert)
|
||||
with open('ssl_key.pem', 'w') as f:
|
||||
f.write(key)
|
||||
print("password protecting ssl_key.pem in ssl_key.passwd.pem")
|
||||
check_call(['openssl','pkey','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-aes256','-passout','pass:somepass'])
|
||||
check_call(['openssl','pkey','-in','ssl_key.pem','-out','keycert.passwd.pem','-aes256','-passout','pass:somepass'])
|
||||
|
||||
with open('keycert.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
with open('keycert.passwd.pem', 'a+') as f:
|
||||
f.write(cert)
|
||||
|
||||
# For certificate matching tests
|
||||
make_ca()
|
||||
cert, key = make_cert_key('fakehostname', ext='req_x509_extensions_simple')
|
||||
with open('keycert2.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
cert, key = make_cert_key('localhost', sign=True)
|
||||
with open('keycert3.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
check_call(['openssl', 'x509', '-outform', 'pem', '-in', 'keycert3.pem', '-out', 'cert3.pem'])
|
||||
|
||||
cert, key = make_cert_key('fakehostname', sign=True)
|
||||
with open('keycert4.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
cert, key = make_cert_key(
|
||||
'localhost-ecc', sign=True, key='param:secp384r1.pem'
|
||||
)
|
||||
with open('keycertecc.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
extra_san = [
|
||||
'otherName.1 = 1.2.3.4;UTF8:some other identifier',
|
||||
'otherName.2 = 1.3.6.1.5.2.2;SEQUENCE:princ_name',
|
||||
'email.1 = user@example.org',
|
||||
'DNS.2 = www.example.org',
|
||||
# GEN_X400
|
||||
'dirName.1 = dir_sect',
|
||||
# GEN_EDIPARTY
|
||||
'URI.1 = https://www.python.org/',
|
||||
'IP.1 = 127.0.0.1',
|
||||
'IP.2 = ::1',
|
||||
'RID.1 = 1.2.3.4.5',
|
||||
]
|
||||
|
||||
cert, key = make_cert_key('allsans', sign=True, extra_san='\n'.join(extra_san))
|
||||
with open('allsans.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
extra_san = [
|
||||
# könig (king)
|
||||
'DNS.2 = xn--knig-5qa.idn.pythontest.net',
|
||||
# königsgäßchen (king's alleyway)
|
||||
'DNS.3 = xn--knigsgsschen-lcb0w.idna2003.pythontest.net',
|
||||
'DNS.4 = xn--knigsgchen-b4a3dun.idna2008.pythontest.net',
|
||||
# βόλοσ (marble)
|
||||
'DNS.5 = xn--nxasmq6b.idna2003.pythontest.net',
|
||||
'DNS.6 = xn--nxasmm1c.idna2008.pythontest.net',
|
||||
]
|
||||
|
||||
# IDN SANS, signed
|
||||
cert, key = make_cert_key('idnsans', sign=True, extra_san='\n'.join(extra_san))
|
||||
with open('idnsans.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
cert, key = make_cert_key('nosan', sign=True, ext='req_x509_extensions_nosan')
|
||||
with open('nosan.pem', 'w') as f:
|
||||
f.write(key)
|
||||
f.write(cert)
|
||||
|
||||
unmake_ca()
|
||||
print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/utils.py")
|
||||
print_cert('keycert.pem')
|
||||
print_cert('keycert3.pem')
|
||||
31
Lib/test/certdata/nokia.pem
vendored
Normal file
31
Lib/test/certdata/nokia.pem
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Certificate for projects.developer.nokia.com:443 (see issue 13034)
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFLDCCBBSgAwIBAgIQLubqdkCgdc7lAF9NfHlUmjANBgkqhkiG9w0BAQUFADCB
|
||||
vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
|
||||
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
|
||||
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt
|
||||
VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X
|
||||
DTExMDkyMTAwMDAwMFoXDTEyMDkyMDIzNTk1OVowcTELMAkGA1UEBhMCRkkxDjAM
|
||||
BgNVBAgTBUVzcG9vMQ4wDAYDVQQHFAVFc3BvbzEOMAwGA1UEChQFTm9raWExCzAJ
|
||||
BgNVBAsUAkJJMSUwIwYDVQQDFBxwcm9qZWN0cy5kZXZlbG9wZXIubm9raWEuY29t
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCr92w1bpHYSYxUEx8N/8Iddda2
|
||||
lYi+aXNtQfV/l2Fw9Ykv3Ipw4nLeGTj18FFlAZgMdPRlgrzF/NNXGw/9l3/qKdow
|
||||
CypkQf8lLaxb9Ze1E/KKmkRJa48QTOqvo6GqKuTI6HCeGlG1RxDb8YSKcQWLiytn
|
||||
yj3Wp4MgRQO266xmMQIDAQABo4IB9jCCAfIwQQYDVR0RBDowOIIccHJvamVjdHMu
|
||||
ZGV2ZWxvcGVyLm5va2lhLmNvbYIYcHJvamVjdHMuZm9ydW0ubm9raWEuY29tMAkG
|
||||
A1UdEwQCMAAwCwYDVR0PBAQDAgWgMEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9T
|
||||
VlJJbnRsLUczLWNybC52ZXJpc2lnbi5jb20vU1ZSSW50bEczLmNybDBEBgNVHSAE
|
||||
PTA7MDkGC2CGSAGG+EUBBxcDMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZl
|
||||
cmlzaWduLmNvbS9ycGEwKAYDVR0lBCEwHwYJYIZIAYb4QgQBBggrBgEFBQcDAQYI
|
||||
KwYBBQUHAwIwcgYIKwYBBQUHAQEEZjBkMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
|
||||
cC52ZXJpc2lnbi5jb20wPAYIKwYBBQUHMAKGMGh0dHA6Ly9TVlJJbnRsLUczLWFp
|
||||
YS52ZXJpc2lnbi5jb20vU1ZSSW50bEczLmNlcjBuBggrBgEFBQcBDARiMGChXqBc
|
||||
MFowWDBWFglpbWFnZS9naWYwITAfMAcGBSsOAwIaBBRLa7kolgYMu9BSOJsprEsH
|
||||
iyEFGDAmFiRodHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvMS5naWYwDQYJ
|
||||
KoZIhvcNAQEFBQADggEBACQuPyIJqXwUyFRWw9x5yDXgMW4zYFopQYOw/ItRY522
|
||||
O5BsySTh56BWS6mQB07XVfxmYUGAvRQDA5QHpmY8jIlNwSmN3s8RKo+fAtiNRlcL
|
||||
x/mWSfuMs3D/S6ev3D6+dpEMZtjrhOdctsarMKp8n/hPbwhAbg5hVjpkW5n8vz2y
|
||||
0KxvvkA1AxpLwpVv7OlK17ttzIHw8bp9HTlHBU5s8bKz4a565V/a5HI0CSEv/+0y
|
||||
ko4/ghTnZc1CkmUngKKeFMSah/mT/xAh8XnE2l1AazFa8UKuYki1e+ArHaGZc4ix
|
||||
UYOtiRphwfuYQhRZ7qX9q2MMkCMI65XNK/SaFrAbbG0=
|
||||
-----END CERTIFICATE-----
|
||||
131
Lib/test/certdata/nosan.pem
vendored
Normal file
131
Lib/test/certdata/nosan.pem
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
hctFUL/gjIGg9PVqTWzVVKaI
|
||||
-----END PRIVATE KEY-----
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 1 (0x0)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:61
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=nosan
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:bd:f7:11:18:3d:3c:05:37:f8:e2:8b:49:66:d7:
|
||||
57:24:10:68:5c:c5:c8:92:b0:88:13:82:2a:2b:e7:
|
||||
80:8b:81:0c:bb:25:79:65:4d:89:80:58:54:d3:83:
|
||||
6c:cd:06:f0:cc:7b:11:88:d2:1f:b1:b5:9e:2a:d5:
|
||||
17:a7:82:18:2d:df:73:77:63:a0:93:de:ff:cb:ec:
|
||||
99:04:d5:a6:d0:6c:5b:de:29:6f:f2:76:5c:47:d3:
|
||||
e8:cb:96:c1:0d:49:68:f2:4b:00:bc:d3:e7:fd:2f:
|
||||
76:d7:4d:c0:fc:4f:81:6e:f5:4b:72:d9:18:35:6b:
|
||||
f1:32:7a:49:e0:e5:19:9f:92:62:cd:83:17:e7:5f:
|
||||
94:79:9d:68:61:d0:08:9a:ee:1d:c0:c7:6c:c2:00:
|
||||
b7:f1:a9:92:26:7f:1c:1a:bc:48:07:b1:6f:f2:66:
|
||||
2f:93:f9:ea:09:c1:ed:22:ed:ae:8b:69:4a:0b:aa:
|
||||
c3:d5:f5:98:5a:83:38:8d:0d:a6:a9:a4:f1:c7:e3:
|
||||
63:56:df:d5:a5:46:1c:75:52:3b:62:46:6d:89:8a:
|
||||
19:f3:c5:c7:ec:fb:dd:33:2d:74:a9:e6:9c:68:fd:
|
||||
c1:3d:21:ae:1d:f2:27:aa:dd:1c:5d:fd:78:23:94:
|
||||
5e:85:5d:71:49:8f:07:cb:df:a0:f0:7a:1c:bc:9b:
|
||||
73:ca:28:0b:8e:f9:fc:8c:80:f3:cf:31:06:fb:a1:
|
||||
a4:72:fc:c0:46:d0:d6:b2:46:b7:93:c3:22:88:2d:
|
||||
2d:b3:69:f2:16:fe:22:a9:80:80:9b:c6:b5:89:af:
|
||||
f1:f5:6f:74:ba:3c:12:98:50:4d:ae:42:cd:3f:64:
|
||||
f9:d1:8e:38:74:55:e3:67:b9:ee:c9:71:1a:0d:6d:
|
||||
ed:bb:23:67:79:e8:a5:01:b1:51:0f:76:89:23:53:
|
||||
9f:6f:35:88:ba:49:ef:95:89:95:ed:51:b3:35:bb:
|
||||
f2:34:92:f0:cc:a6:b0:22:a1:bc:2d:24:56:20:70:
|
||||
4f:3a:37:59:45:26:31:d2:c0:33
|
||||
Exponent: 65537 (0x10001)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
7e:dd:64:64:92:6c:b9:41:ce:f3:e3:f8:e6:9f:c8:5b:32:39:
|
||||
8c:03:5b:5e:7e:b3:23:ca:6c:d1:99:2f:53:af:9d:3c:84:cd:
|
||||
c6:ce:0a:ee:94:de:ff:a7:06:81:7e:e2:38:a5:05:39:58:22:
|
||||
dc:13:83:53:e7:f8:16:cb:93:dc:cf:4b:e6:1b:9f:9e:71:ef:
|
||||
ee:ba:ea:b6:68:5c:32:22:7e:54:4f:46:a6:0b:11:8f:ef:05:
|
||||
6e:d3:0b:d0:a8:be:95:23:a2:e4:e7:a8:a2:a4:7d:98:52:86:
|
||||
a4:15:fb:74:7a:9a:89:23:43:20:26:3a:56:9e:a3:6e:54:02:
|
||||
76:4e:25:9c:a1:8c:03:99:e5:eb:a6:61:b4:9c:2a:b1:ed:eb:
|
||||
94:f9:14:aa:a4:c3:f0:f7:7a:03:a3:b1:f8:c0:83:79:ab:8a:
|
||||
93:7f:0a:95:08:50:ff:55:19:ac:28:a2:c8:9f:a6:77:72:a3:
|
||||
da:37:a9:ff:f3:57:70:c8:65:d9:55:14:84:b4:b3:78:86:82:
|
||||
da:84:2c:48:19:51:ec:9d:20:b1:4d:18:fb:82:9f:7b:a7:80:
|
||||
22:69:25:83:4d:bf:ac:31:64:f5:39:11:f1:ed:53:fb:67:ab:
|
||||
91:86:c5:4d:87:e8:6b:fe:9a:84:fe:6a:92:6b:62:c1:ae:d2:
|
||||
f0:cb:06:6e:f3:50:f4:8d:6d:fa:7d:6a:1c:64:c3:98:91:da:
|
||||
c9:8c:a9:79:e5:48:4c:a2:de:42:28:e8:0e:9f:52:6a:a4:e0:
|
||||
c7:ac:11:9c:ba:5d:d6:84:93:56:28:f1:6d:83:aa:62:b2:b7:
|
||||
56:c6:64:d9:96:4e:97:ab:4e:8f:ba:f6:ab:b9:17:52:98:32:
|
||||
7f:b5:12:fa:39:d7:34:2a:f3:ed:40:90:6f:66:7b:b6:c1:9d:
|
||||
b9:53:d0:e3:e9:69:8c:cf:7a:fd:08:0a:62:47:d4:ce:72:f7:
|
||||
6f:80:b4:1d:18:7a:ba:a2:a9:45:49:ef:9c:0b:99:89:03:ab:
|
||||
5f:7a:9d:c5:77:b7
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEJDCCAowCCQDLLYCZWmlSYTANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJY
|
||||
WTEmMCQGA1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNV
|
||||
BAMMDW91ci1jYS1zZXJ2ZXIwHhcNMTgwODI5MTQyMzE2WhcNMzcxMDI4MTQyMzE2
|
||||
WjBbMQswCQYDVQQGEwJYWTEXMBUGA1UEBwwOQ2FzdGxlIEFudGhyYXgxIzAhBgNV
|
||||
BAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQ4wDAYDVQQDDAVub3NhbjCC
|
||||
AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAL33ERg9PAU3+OKLSWbXVyQQ
|
||||
aFzFyJKwiBOCKivngIuBDLsleWVNiYBYVNODbM0G8Mx7EYjSH7G1nirVF6eCGC3f
|
||||
c3djoJPe/8vsmQTVptBsW94pb/J2XEfT6MuWwQ1JaPJLALzT5/0vdtdNwPxPgW71
|
||||
S3LZGDVr8TJ6SeDlGZ+SYs2DF+dflHmdaGHQCJruHcDHbMIAt/GpkiZ/HBq8SAex
|
||||
b/JmL5P56gnB7SLtrotpSguqw9X1mFqDOI0Npqmk8cfjY1bf1aVGHHVSO2JGbYmK
|
||||
GfPFx+z73TMtdKnmnGj9wT0hrh3yJ6rdHF39eCOUXoVdcUmPB8vfoPB6HLybc8oo
|
||||
C475/IyA888xBvuhpHL8wEbQ1rJGt5PDIogtLbNp8hb+IqmAgJvGtYmv8fVvdLo8
|
||||
EphQTa5CzT9k+dGOOHRV42e57slxGg1t7bsjZ3nopQGxUQ92iSNTn281iLpJ75WJ
|
||||
le1RszW78jSS8MymsCKhvC0kViBwTzo3WUUmMdLAMwIDAQABMA0GCSqGSIb3DQEB
|
||||
CwUAA4IBgQB+3WRkkmy5Qc7z4/jmn8hbMjmMA1tefrMjymzRmS9Tr508hM3Gzgru
|
||||
lN7/pwaBfuI4pQU5WCLcE4NT5/gWy5Pcz0vmG5+ece/uuuq2aFwyIn5UT0amCxGP
|
||||
7wVu0wvQqL6VI6Lk56iipH2YUoakFft0epqJI0MgJjpWnqNuVAJ2TiWcoYwDmeXr
|
||||
pmG0nCqx7euU+RSqpMPw93oDo7H4wIN5q4qTfwqVCFD/VRmsKKLIn6Z3cqPaN6n/
|
||||
81dwyGXZVRSEtLN4hoLahCxIGVHsnSCxTRj7gp97p4AiaSWDTb+sMWT1ORHx7VP7
|
||||
Z6uRhsVNh+hr/pqE/mqSa2LBrtLwywZu81D0jW36fWocZMOYkdrJjKl55UhMot5C
|
||||
KOgOn1JqpODHrBGcul3WhJNWKPFtg6pisrdWxmTZlk6Xq06PuvaruRdSmDJ/tRL6
|
||||
Odc0KvPtQJBvZnu2wZ25U9Dj6WmMz3r9CApiR9TOcvdvgLQdGHq6oqlFSe+cC5mJ
|
||||
A6tfep3Fd7c=
|
||||
-----END CERTIFICATE-----
|
||||
90
Lib/test/certdata/nullbytecert.pem
vendored
Normal file
90
Lib/test/certdata/nullbytecert.pem
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 0 (0x0)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=US, ST=Oregon, L=Beaverton, O=Python Software Foundation, OU=Python Core Development, CN=null.python.org\x00example.org/emailAddress=python-dev@python.org
|
||||
Validity
|
||||
Not Before: Aug 7 13:11:52 2013 GMT
|
||||
Not After : Aug 7 13:12:52 2013 GMT
|
||||
Subject: C=US, ST=Oregon, L=Beaverton, O=Python Software Foundation, OU=Python Core Development, CN=null.python.org\x00example.org/emailAddress=python-dev@python.org
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:b5:ea:ed:c9:fb:46:7d:6f:3b:76:80:dd:3a:f3:
|
||||
03:94:0b:a7:a6:db:ec:1d:df:ff:23:74:08:9d:97:
|
||||
16:3f:a3:a4:7b:3e:1b:0e:96:59:25:03:a7:26:e2:
|
||||
88:a9:cf:79:cd:f7:04:56:b0:ab:79:32:6e:59:c1:
|
||||
32:30:54:eb:58:a8:cb:91:f0:42:a5:64:27:cb:d4:
|
||||
56:31:88:52:ad:cf:bd:7f:f0:06:64:1f:cc:27:b8:
|
||||
a3:8b:8c:f3:d8:29:1f:25:0b:f5:46:06:1b:ca:02:
|
||||
45:ad:7b:76:0a:9c:bf:bb:b9:ae:0d:16:ab:60:75:
|
||||
ae:06:3e:9c:7c:31:dc:92:2f:29:1a:e0:4b:0c:91:
|
||||
90:6c:e9:37:c5:90:d7:2a:d7:97:15:a3:80:8f:5d:
|
||||
7b:49:8f:54:30:d4:97:2c:1c:5b:37:b5:ab:69:30:
|
||||
68:43:d3:33:78:4b:02:60:f5:3c:44:80:a1:8f:e7:
|
||||
f0:0f:d1:5e:87:9e:46:cf:62:fc:f9:bf:0c:65:12:
|
||||
f1:93:c8:35:79:3f:c8:ec:ec:47:f5:ef:be:44:d5:
|
||||
ae:82:1e:2d:9a:9f:98:5a:67:65:e1:74:70:7c:cb:
|
||||
d3:c2:ce:0e:45:49:27:dc:e3:2d:d4:fb:48:0e:2f:
|
||||
9e:77:b8:14:46:c0:c4:36:ca:02:ae:6a:91:8c:da:
|
||||
2f:85
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Subject Key Identifier:
|
||||
88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C
|
||||
X509v3 Key Usage:
|
||||
Digital Signature, Non Repudiation, Key Encipherment
|
||||
X509v3 Subject Alternative Name:
|
||||
*************************************************************
|
||||
WARNING: The values for DNS, email and URI are WRONG. OpenSSL
|
||||
doesn't print the text after a NULL byte.
|
||||
*************************************************************
|
||||
DNS:altnull.python.org, email:null@python.org, URI:http://null.python.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
ac:4f:45:ef:7d:49:a8:21:70:8e:88:59:3e:d4:36:42:70:f5:
|
||||
a3:bd:8b:d7:a8:d0:58:f6:31:4a:b1:a4:a6:dd:6f:d9:e8:44:
|
||||
3c:b6:0a:71:d6:7f:b1:08:61:9d:60:ce:75:cf:77:0c:d2:37:
|
||||
86:02:8d:5e:5d:f9:0f:71:b4:16:a8:c1:3d:23:1c:f1:11:b3:
|
||||
56:6e:ca:d0:8d:34:94:e6:87:2a:99:f2:ae:ae:cc:c2:e8:86:
|
||||
de:08:a8:7f:c5:05:fa:6f:81:a7:82:e6:d0:53:9d:34:f4:ac:
|
||||
3e:40:fe:89:57:7a:29:a4:91:7e:0b:c6:51:31:e5:10:2f:a4:
|
||||
60:76:cd:95:51:1a:be:8b:a1:b0:fd:ad:52:bd:d7:1b:87:60:
|
||||
d2:31:c7:17:c4:18:4f:2d:08:25:a3:a7:4f:b7:92:ca:e2:f5:
|
||||
25:f1:54:75:81:9d:b3:3d:61:a2:f7:da:ed:e1:c6:6f:2c:60:
|
||||
1f:d8:6f:c5:92:05:ab:c9:09:62:49:a9:14:ad:55:11:cc:d6:
|
||||
4a:19:94:99:97:37:1d:81:5f:8b:cf:a3:a8:96:44:51:08:3d:
|
||||
0b:05:65:12:eb:b6:70:80:88:48:72:4f:c6:c2:da:cf:cd:8e:
|
||||
5b:ba:97:2f:60:b4:96:56:49:5e:3a:43:76:63:04:be:2a:f6:
|
||||
c1:ca:a9:94
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
|
||||
DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
|
||||
eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
|
||||
RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
|
||||
ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
|
||||
NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
|
||||
DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
|
||||
ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
|
||||
ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
|
||||
hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
|
||||
pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
|
||||
vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
|
||||
KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
|
||||
oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
|
||||
08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
|
||||
HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
|
||||
BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
|
||||
Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
|
||||
bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
|
||||
AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
|
||||
i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
|
||||
HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
|
||||
kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
|
||||
VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
|
||||
RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
|
||||
-----END CERTIFICATE-----
|
||||
0
Lib/test/certdata/nullcert.pem
vendored
Normal file
0
Lib/test/certdata/nullcert.pem
vendored
Normal file
102
Lib/test/certdata/pycacert.pem
vendored
Normal file
102
Lib/test/certdata/pycacert.pem
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
cb:2d:80:99:5a:69:52:5b
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Validity
|
||||
Not Before: Aug 29 14:23:16 2018 GMT
|
||||
Not After : Oct 28 14:23:16 2037 GMT
|
||||
Subject: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (3072 bit)
|
||||
Modulus:
|
||||
00:d0:a0:9b:b1:b9:3b:79:ee:31:2f:b8:51:1c:01:
|
||||
75:ed:09:59:4c:ac:c8:bf:6a:0a:f8:7a:08:f0:25:
|
||||
e3:25:7b:6a:f8:c4:d8:aa:a0:60:07:25:b0:cf:73:
|
||||
71:05:52:68:bf:06:93:ae:10:61:96:bc:b3:69:81:
|
||||
1a:7d:19:fc:20:86:8f:9a:68:1b:ed:cd:e2:6c:61:
|
||||
67:c7:4e:55:ea:43:06:21:1b:e9:b9:be:84:5f:c2:
|
||||
da:eb:89:88:e0:42:a6:45:49:2a:d0:b9:6b:8c:93:
|
||||
c9:44:3b:ca:fc:3c:94:7f:dd:70:c5:ad:d8:4b:3b:
|
||||
dc:1e:f8:55:4b:b5:27:86:f8:df:b0:83:cf:f7:16:
|
||||
37:bf:13:17:34:d4:c9:55:ed:6b:16:c9:7f:ad:20:
|
||||
4e:f0:1e:d9:1b:bf:8d:ba:cd:ca:96:ef:1e:69:cb:
|
||||
51:66:61:48:0d:e8:79:a3:59:61:d4:10:8d:e0:0d:
|
||||
3b:0b:85:b6:d5:85:12:dd:a5:07:c5:4b:fa:23:fa:
|
||||
54:39:f7:97:0b:c9:44:47:1e:56:77:3c:3c:13:01:
|
||||
0b:6d:77:d6:14:ba:44:f4:53:35:56:d9:3d:b9:3e:
|
||||
35:5f:db:33:9a:4f:5a:b9:38:44:c9:32:49:fe:66:
|
||||
f6:1f:1a:97:aa:ca:4c:4a:f6:b8:5e:40:7f:fb:0b:
|
||||
1d:f8:5b:a1:dc:f8:c0:2e:d0:6d:49:f5:d2:46:d4:
|
||||
90:57:fe:92:81:34:ae:2d:38:bb:a8:17:0c:e1:e5:
|
||||
3f:e2:f7:26:05:54:50:f5:64:b3:1c:6e:44:ff:6f:
|
||||
a9:b4:03:96:e9:0e:c2:88:d8:72:52:90:99:c6:41:
|
||||
0f:46:90:59:b8:3e:6f:d2:e2:9e:1d:36:82:95:d3:
|
||||
58:8a:12:f3:e2:d8:0d:20:51:23:f0:90:2d:9a:3e:
|
||||
7d:26:86:b2:a7:d7:f9:28:60:03:e3:77:c7:88:04:
|
||||
c9:fe:89:77:70:10:4f:c3:a0:8a:3b:f4:ab:42:7b:
|
||||
e3:14:92:d8:ae:16:d6:a1:de:7d
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
X509v3 Authority Key Identifier:
|
||||
F3:EC:94:8E:F2:8E:30:C4:8E:68:C2:BF:8E:6A:19:C0:C1:9F:76:65
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:TRUE
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Certificate Sign, CRL Sign
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
8b:00:54:72:b3:8d:eb:f3:af:34:9f:d6:60:ea:de:84:3f:8c:
|
||||
04:8f:19:a6:be:02:67:c4:63:c5:74:e3:47:37:59:83:94:06:
|
||||
f1:45:19:e8:07:2f:d6:4e:4b:4f:a8:3d:c7:07:07:27:92:f4:
|
||||
7e:73:4f:8b:32:19:94:46:7a:25:c4:d9:c4:27:b0:11:63:3a:
|
||||
60:8b:85:e1:73:4f:34:3b:6b:a4:34:8c:49:8e:cd:cf:4f:b2:
|
||||
65:27:41:19:b0:fc:80:31:78:f2:73:6a:9b:7d:71:34:50:fc:
|
||||
78:a8:da:05:b4:9c:5b:3a:99:7a:6b:5d:ef:3b:d3:e9:3b:33:
|
||||
01:12:65:cf:5e:07:d8:19:af:d5:53:ea:f0:10:ac:c4:b6:26:
|
||||
3c:34:2e:74:ee:64:dd:1d:36:75:89:44:00:b0:0d:fd:2f:b3:
|
||||
01:cc:1a:8b:02:cd:6c:e8:80:82:ca:bf:82:d7:00:9d:d8:36:
|
||||
15:d2:07:37:fc:6c:73:1d:da:a8:1c:e8:20:8e:32:7a:fe:6d:
|
||||
27:16:e4:58:6c:eb:3e:f0:fe:24:52:29:71:b8:96:7b:53:4b:
|
||||
45:20:55:40:5e:86:1b:ec:c9:46:91:92:ee:ac:93:65:91:2e:
|
||||
94:b6:b6:ac:e8:a3:34:89:a4:1a:12:0d:4d:44:a5:52:ed:8b:
|
||||
91:ee:2f:a6:af:a4:95:25:f9:ce:c7:5b:a7:00:d3:93:ca:b4:
|
||||
3c:5d:4d:f7:b1:3c:cc:6d:b4:45:be:82:ed:18:90:c8:86:d1:
|
||||
75:51:50:04:4c:e8:4f:d2:d6:50:aa:75:e7:5e:ff:a1:7b:27:
|
||||
19:1c:6b:49:2c:6c:4d:6b:63:cc:3b:73:00:f3:99:26:d0:82:
|
||||
87:d3:a9:36:9c:b4:3d:b9:48:68:a8:92:f0:27:8e:0c:cd:15:
|
||||
76:42:84:80:c9:3f:a3:7e:b4:dd:d7:f8:ac:76:ba:60:97:3c:
|
||||
5a:1f:4e:de:71:ee:09:39:10:dd:31:d5:68:57:5d:1a:e5:42:
|
||||
ba:0e:68:e6:45:d3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgDCCAuigAwIBAgIJAMstgJlaaVJbMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
|
||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODA4MjkxNDIzMTZaFw0zNzEwMjgx
|
||||
NDIzMTZaME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
|
||||
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjCCAaIwDQYJKoZI
|
||||
hvcNAQEBBQADggGPADCCAYoCggGBANCgm7G5O3nuMS+4URwBde0JWUysyL9qCvh6
|
||||
CPAl4yV7avjE2KqgYAclsM9zcQVSaL8Gk64QYZa8s2mBGn0Z/CCGj5poG+3N4mxh
|
||||
Z8dOVepDBiEb6bm+hF/C2uuJiOBCpkVJKtC5a4yTyUQ7yvw8lH/dcMWt2Es73B74
|
||||
VUu1J4b437CDz/cWN78TFzTUyVXtaxbJf60gTvAe2Ru/jbrNypbvHmnLUWZhSA3o
|
||||
eaNZYdQQjeANOwuFttWFEt2lB8VL+iP6VDn3lwvJREceVnc8PBMBC2131hS6RPRT
|
||||
NVbZPbk+NV/bM5pPWrk4RMkySf5m9h8al6rKTEr2uF5Af/sLHfhbodz4wC7QbUn1
|
||||
0kbUkFf+koE0ri04u6gXDOHlP+L3JgVUUPVksxxuRP9vqbQDlukOwojYclKQmcZB
|
||||
D0aQWbg+b9Linh02gpXTWIoS8+LYDSBRI/CQLZo+fSaGsqfX+ShgA+N3x4gEyf6J
|
||||
d3AQT8Ogijv0q0J74xSS2K4W1qHefQIDAQABo2MwYTAdBgNVHQ4EFgQU8+yUjvKO
|
||||
MMSOaMK/jmoZwMGfdmUwHwYDVR0jBBgwFoAU8+yUjvKOMMSOaMK/jmoZwMGfdmUw
|
||||
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
|
||||
ggGBAIsAVHKzjevzrzSf1mDq3oQ/jASPGaa+AmfEY8V040c3WYOUBvFFGegHL9ZO
|
||||
S0+oPccHByeS9H5zT4syGZRGeiXE2cQnsBFjOmCLheFzTzQ7a6Q0jEmOzc9PsmUn
|
||||
QRmw/IAxePJzapt9cTRQ/Hio2gW0nFs6mXprXe870+k7MwESZc9eB9gZr9VT6vAQ
|
||||
rMS2Jjw0LnTuZN0dNnWJRACwDf0vswHMGosCzWzogILKv4LXAJ3YNhXSBzf8bHMd
|
||||
2qgc6CCOMnr+bScW5Fhs6z7w/iRSKXG4lntTS0UgVUBehhvsyUaRku6sk2WRLpS2
|
||||
tqzoozSJpBoSDU1EpVLti5HuL6avpJUl+c7HW6cA05PKtDxdTfexPMxttEW+gu0Y
|
||||
kMiG0XVRUARM6E/S1lCqdede/6F7Jxkca0ksbE1rY8w7cwDzmSbQgofTqTactD25
|
||||
SGiokvAnjgzNFXZChIDJP6N+tN3X+Kx2umCXPFofTt5x7gk5EN0x1WhXXRrlQroO
|
||||
aOZF0w==
|
||||
-----END CERTIFICATE-----
|
||||
40
Lib/test/certdata/pycakey.pem
vendored
Normal file
40
Lib/test/certdata/pycakey.pem
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
E2bb0CdekSHf05HPiF9QpK1z
|
||||
-----END PRIVATE KEY-----
|
||||
14
Lib/test/certdata/revocation.crl
vendored
Normal file
14
Lib/test/certdata/revocation.crl
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICJjCBjwIBATANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQGEwJYWTEmMCQGA1UE
|
||||
CgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNVBAMMDW91ci1j
|
||||
YS1zZXJ2ZXIXDTIzMTEyNTA0MjEzNloXDTQzMDEyNDA0MjEzNlqgDjAMMAoGA1Ud
|
||||
FAQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBgQDMZ4XLQlzUrqBbszEq9I/nXK3jN8/p
|
||||
VZ2aScU2le0ySJqIthe0yXEYuoFu+I4ZULyNkCA79baStIl8/Lt48DOHfBVv8SVx
|
||||
ZqF7/fdUZBCLJV1kuhuSSknbtNmja5NI4/lcRRXrodRWDMcOmqlKbAC6RMQz/gMG
|
||||
vpewGPX1oj5AQnqqd9spKtHbeqeDiyyWYr9ZZFO/433lP7GdsoriTPggYJJMWJvs
|
||||
819buE0iGwWf+rTLB51VyGluhcz2pqimej6Ra2cdnYh5IztZlDFR99HywzWhVz/A
|
||||
2fwUA91GR7zATerweXVKNd59mcgF4PZWiXmQMwcE0qQOMqMmAqYPLim1mretZsAs
|
||||
t1X+nDM0Ak3sKumIjteQF7I6VpSsG4NCtq23G8KpNHnBZVOt0U065lQEvx0ZmB94
|
||||
1z7SzjfSZMVXYxBjSXljwuoc1keGpNT5xCmHyrOIxaHsmizzwNESW4dGVLu7/JfK
|
||||
w40uGbwH09w4Cfbwuo7w6sRWDWPnlW2mkoc=
|
||||
-----END X509 CRL-----
|
||||
7
Lib/test/certdata/secp384r1.pem
vendored
Normal file
7
Lib/test/certdata/secp384r1.pem
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
$ openssl genpkey -genparam -algorithm EC -pkeyopt ec_paramgen_curve:secp384r1 -pkeyopt ec_param_enc:named_curve -text
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BgUrgQQAIg==
|
||||
-----END EC PARAMETERS-----
|
||||
ECDSA-Parameters: (384 bit)
|
||||
ASN1 OID: secp384r1
|
||||
NIST CURVE: P-384
|
||||
34
Lib/test/certdata/selfsigned_pythontestdotnet.pem
vendored
Normal file
34
Lib/test/certdata/selfsigned_pythontestdotnet.pem
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF9zCCA9+gAwIBAgIUH98b4Fw/DyugC9cV7VK7ZODzHsIwDQYJKoZIhvcNAQEL
|
||||
BQAwgYoxCzAJBgNVBAYTAlhZMRcwFQYDVQQIDA5DYXN0bGUgQW50aHJheDEYMBYG
|
||||
A1UEBwwPQXJndW1lbnQgQ2xpbmljMSMwIQYDVQQKDBpQeXRob24gU29mdHdhcmUg
|
||||
Rm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0aG9udGVzdC5uZXQw
|
||||
HhcNMTkwNTA4MDEwMjQzWhcNMjcwNzI0MDEwMjQzWjCBijELMAkGA1UEBhMCWFkx
|
||||
FzAVBgNVBAgMDkNhc3RsZSBBbnRocmF4MRgwFgYDVQQHDA9Bcmd1bWVudCBDbGlu
|
||||
aWMxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQD
|
||||
DBpzZWxmLXNpZ25lZC5weXRob250ZXN0Lm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggIPADCCAgoCggIBAMKdJlyCThkahwoBb7pl5q64Pe9Fn5jrIvzsveHTc97TpjV2
|
||||
RLfICnXKrltPk/ohkVl6K5SUZQZwMVzFubkyxE0nZPHYHlpiKWQxbsYVkYv01rix
|
||||
IFdLvaxxbGYke2jwQao31s4o61AdlsfK1SdpHQUynBBMssqI3SB4XPmcA7e+wEEx
|
||||
jxjVish4ixA1vuIZOx8yibu+CFCf/geEjoBMF3QPdzULzlrCSw8k/45iZCSoNbvK
|
||||
DoL4TVV07PHOxpheDh8ZQmepGvU6pVqhb9m4lgmV0OGWHgozd5Ur9CbTVDmxIEz3
|
||||
TSoRtNJK7qtyZdGNqwjksQxgZTjM/d/Lm/BJG99AiOmYOjsl9gbQMZgvQmMAtUsI
|
||||
aMJnQuZ6R+KEpW/TR5qSKLWZSG45z/op+tzI2m+cE6HwTRVAWbcuJxcAA55MZjqU
|
||||
OOOu3BBYMjS5nf2sQ9uoXsVBFH7i0mQqoW1SLzr9opI8KsWwFxQmO2vBxWYaN+lH
|
||||
OmwBZBwyODIsmI1YGXmTp09NxRYz3Qe5GCgFzYowpMrcxUC24iduIdMwwhRM7rKg
|
||||
7GtIWMSrFfuI1XCLRmSlhDbhNN6fVg2f8Bo9PdH9ihiIyxSrc+FOUasUYCCJvlSZ
|
||||
8hFUlLvcmrZlWuazohm0lsXuMK1JflmQr/DA/uXxP9xzFfRy+RU3jDyxJbRHAgMB
|
||||
AAGjUzBRMB0GA1UdDgQWBBSQJyxiPMRK01i+0BsV9zUwDiBaHzAfBgNVHSMEGDAW
|
||||
gBSQJyxiPMRK01i+0BsV9zUwDiBaHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
|
||||
DQEBCwUAA4ICAQCR+7a7N/m+WLkxPPIA/CB4MOr2Uf8ixTv435Nyv6rXOun0+lTP
|
||||
ExSZ0uYQ+L0WylItI3cQHULldDueD+s8TGzxf5woaLKf6tqyr0NYhKs+UeNEzDnN
|
||||
9PHQIhX0SZw3XyXGUgPNBfRCg2ZDdtMMdOU4XlQN/IN/9hbYTrueyY7eXq9hmtI9
|
||||
1srftAMqr9SR1JP7aHI6DVgrEsZVMTDnfT8WmLSGLlY1HmGfdEn1Ip5sbo9uSkiH
|
||||
AEPgPfjYIvR5LqTOMn4KsrlZyBbFIDh9Sl99M1kZzgH6zUGVLCDg1y6Cms69fx/e
|
||||
W1HoIeVkY4b4TY7Bk7JsqyNhIuqu7ARaxkdaZWhYaA2YyknwANdFfNpfH+elCLIk
|
||||
BUt5S3f4i7DaUePTvKukCZiCq4Oyln7RcOn5If73wCeLB/ZM9Ei1HforyLWP1CN8
|
||||
XLfpHaoeoPSWIveI0XHUl65LsPN2UbMbul/F23hwl+h8+BLmyAS680Yhn4zEN6Ku
|
||||
B7Po90HoFa1Du3bmx4jsN73UkT/dwMTi6K072FbipnC1904oGlWmLwvAHvrtxxmL
|
||||
Pl3pvEaZIu8wa/PNF6Y7J7VIewikIJq6Ta6FrWeFfzMWOj2qA1ZZi6fUaDSNYvuV
|
||||
J5quYKCc/O+I/yDDf8wyBbZ/gvUXzUHTMYGG+bFrn1p7XDbYYeEJ6R/xEg==
|
||||
-----END CERTIFICATE-----
|
||||
27
Lib/test/certdata/ssl_cert.pem
vendored
Normal file
27
Lib/test/certdata/ssl_cert.pem
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEgzCCAuugAwIBAgIUU+FIM/dUbCklbdDwNPd2xemDAEwwDQYJKoZIhvcNAQEL
|
||||
BQAwXzELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYD
|
||||
VQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxo
|
||||
b3N0MB4XDTIzMTEyNTA0MjEzNloXDTQzMDEyNDA0MjEzNlowXzELMAkGA1UEBhMC
|
||||
WFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRob24gU29m
|
||||
dHdhcmUgRm91bmRhdGlvbjESMBAGA1UEAwwJbG9jYWxob3N0MIIBojANBgkqhkiG
|
||||
9w0BAQEFAAOCAY8AMIIBigKCAYEAzXTIl1su11AGu6sDPsoxqcRGyAX0yjxIcswF
|
||||
vj+eW/fBs2GcBby95VEOKpJPKRYYB7fAEAjAKK59zFdsDX/ynxPZLqyLQocBkFVq
|
||||
tclhCRZu//KZND+uQuHSx3PjGkSvK/nrGjg5T0bkM4SFeb0YdLb+0aDTKGozUC82
|
||||
oBAilNcrFz1VXpEF0qUe9QeKQhyd0MaW5T1oSn+U3RAj2MXm3TGExyZeaicpIM5O
|
||||
HFlnwUxsYSDZo0jUj342MbPOZh8szZDWi042jdtSA3i8uMSplEf4O8ZPmX0JCtrz
|
||||
fVjRVdaKXIjrhMNWB8K44q6AeyhqJcVHtOmPYoHDm0qIjcrurt0LZaGhmCuKimNd
|
||||
njcPxW0VQmDIS/mO5+s24SK+Mpznm5q/clXEwyD8FbrtrzV5cHCE8eNkxjuQjkmi
|
||||
wW9uadK1s54tDwRWMl6DRWRyxoF0an885UQWmbsgEB5aRmEx2L0JeD0/q6Iw1Nta
|
||||
As8DG4AaWuYMrgZXz7XvyiMq3IxVAgMBAAGjNzA1MBQGA1UdEQQNMAuCCWxvY2Fs
|
||||
aG9zdDAdBgNVHQ4EFgQUl2wd7iWE1JTZUVq2yFBKGm9N36owDQYJKoZIhvcNAQEL
|
||||
BQADggGBAF0f5x6QXFbgdyLOyeAPD/1DDxNjM68fJSmNM/6vxHJeDFzK0Pja+iJo
|
||||
xv54YiS9F2tiKPpejk4ujvLQgvrYrTQvliIE+7fUT0dV74wZKPdLphftT9uEo1dH
|
||||
TeIld+549fqcfZCJfVPE2Ka4vfyMGij9hVfY5FoZL1Xpnq/ZGYyWZNAPbkG292p8
|
||||
KrfLZm/0fFYAhq8tG/6DX7+2btxeX4MP/49tzskcYWgOjlkknyhJ76aMG9BJ1D7F
|
||||
/TIEh5ihNwRTmyt023RBz/xWiN4xBLyIlpQ6d5ECKmFNFr0qnEui6UovfCHUF6lZ
|
||||
qcAQ5VFQQ2CayNlVmQ+UGmWIqANlacYWBt7Q6VqpGg24zTMec1/Pqd6X07ScSfrm
|
||||
MAtywrWrU7p1aEkN5lBa4n/XKZHGYMjor/YcMdF5yjdSrZr274YYO1pafmTFwRwH
|
||||
5o16c8WPc0aPvTFbkGIFT5ddxYstw+QwsBtLKE2lJ4Qfmxt0Ew/0L7xkbK1BaCOo
|
||||
EGD2IF7VDQ==
|
||||
-----END CERTIFICATE-----
|
||||
42
Lib/test/certdata/ssl_key.passwd.pem
vendored
Normal file
42
Lib/test/certdata/ssl_key.passwd.pem
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
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
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
40
Lib/test/certdata/ssl_key.pem
vendored
Normal file
40
Lib/test/certdata/ssl_key.pem
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
kNdcwhtZZ3dpChUdf+w/LIc=
|
||||
-----END PRIVATE KEY-----
|
||||
22
Lib/test/certdata/talos-2019-0758.pem
vendored
Normal file
22
Lib/test/certdata/talos-2019-0758.pem
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDqDCCApKgAwIBAgIBAjALBgkqhkiG9w0BAQswHzELMAkGA1UEBhMCVUsxEDAO
|
||||
BgNVBAMTB2NvZHktY2EwHhcNMTgwNjE4MTgwMDU4WhcNMjgwNjE0MTgwMDU4WjA7
|
||||
MQswCQYDVQQGEwJVSzEsMCoGA1UEAxMjY29kZW5vbWljb24tdm0tMi50ZXN0Lmxh
|
||||
bC5jaXNjby5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC63fGB
|
||||
J80A9Av1GB0bptslKRIUtJm8EeEu34HkDWbL6AJY0P8WfDtlXjlPaLqFa6sqH6ES
|
||||
V48prSm1ZUbDSVL8R6BYVYpOlK8/48xk4pGTgRzv69gf5SGtQLwHy8UPBKgjSZoD
|
||||
5a5k5wJXGswhKFFNqyyxqCvWmMnJWxXTt2XDCiWc4g4YAWi4O4+6SeeHVAV9rV7C
|
||||
1wxqjzKovVe2uZOHjKEzJbbIU6JBPb6TRfMdRdYOw98n1VXDcKVgdX2DuuqjCzHP
|
||||
WhU4Tw050M9NaK3eXp4Mh69VuiKoBGOLSOcS8reqHIU46Reg0hqeL8LIL6OhFHIF
|
||||
j7HR6V1X6F+BfRS/AgMBAAGjgdYwgdMwCQYDVR0TBAIwADAdBgNVHQ4EFgQUOktp
|
||||
HQjxDXXUg8prleY9jeLKeQ4wTwYDVR0jBEgwRoAUx6zgPygZ0ZErF9sPC4+5e2Io
|
||||
UU+hI6QhMB8xCzAJBgNVBAYTAlVLMRAwDgYDVQQDEwdjb2R5LWNhggkA1QEAuwb7
|
||||
2s0wCQYDVR0SBAIwADAuBgNVHREEJzAlgiNjb2Rlbm9taWNvbi12bS0yLnRlc3Qu
|
||||
bGFsLmNpc2NvLmNvbTAOBgNVHQ8BAf8EBAMCBaAwCwYDVR0fBAQwAjAAMAsGCSqG
|
||||
SIb3DQEBCwOCAQEAvqantx2yBlM11RoFiCfi+AfSblXPdrIrHvccepV4pYc/yO6p
|
||||
t1f2dxHQb8rWH3i6cWag/EgIZx+HJQvo0rgPY1BFJsX1WnYf1/znZpkUBGbVmlJr
|
||||
t/dW1gSkNS6sPsM0Q+7HPgEv8CPDNK5eo7vU2seE0iWOkxSyVUuiCEY9ZVGaLVit
|
||||
p0C78nZ35Pdv4I+1cosmHl28+es1WI22rrnmdBpH8J1eY6WvUw2xuZHLeNVN0TzV
|
||||
Q3qq53AaCWuLOD1AjESWuUCxMZTK9DPS4JKXTK8RLyDeqOvJGjsSWp3kL0y3GaQ+
|
||||
10T1rfkKJub2+m9A9duin1fn6tHc2wSvB7m3DA==
|
||||
-----END CERTIFICATE-----
|
||||
2
Lib/test/data/README
vendored
Normal file
2
Lib/test/data/README
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
This empty directory serves as destination for temporary files
|
||||
created by some tests, in particular, the test_codecmaps_* tests.
|
||||
5
Lib/test/dtracedata/assert_usable.d
vendored
Normal file
5
Lib/test/dtracedata/assert_usable.d
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
BEGIN
|
||||
{
|
||||
printf("probe: success\n");
|
||||
exit(0);
|
||||
}
|
||||
5
Lib/test/dtracedata/assert_usable.stp
vendored
Normal file
5
Lib/test/dtracedata/assert_usable.stp
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
probe begin
|
||||
{
|
||||
println("probe: success")
|
||||
exit ()
|
||||
}
|
||||
31
Lib/test/dtracedata/call_stack.d
vendored
Normal file
31
Lib/test/dtracedata/call_stack.d
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
self int indent;
|
||||
|
||||
python$target:::function-entry
|
||||
/copyinstr(arg1) == "start"/
|
||||
{
|
||||
self->trace = 1;
|
||||
}
|
||||
|
||||
python$target:::function-entry
|
||||
/self->trace/
|
||||
{
|
||||
printf("%d\t%*s:", timestamp, 15, probename);
|
||||
printf("%*s", self->indent, "");
|
||||
printf("%s:%s:%d\n", basename(copyinstr(arg0)), copyinstr(arg1), arg2);
|
||||
self->indent++;
|
||||
}
|
||||
|
||||
python$target:::function-return
|
||||
/self->trace/
|
||||
{
|
||||
self->indent--;
|
||||
printf("%d\t%*s:", timestamp, 15, probename);
|
||||
printf("%*s", self->indent, "");
|
||||
printf("%s:%s:%d\n", basename(copyinstr(arg0)), copyinstr(arg1), arg2);
|
||||
}
|
||||
|
||||
python$target:::function-return
|
||||
/copyinstr(arg1) == "start"/
|
||||
{
|
||||
self->trace = 0;
|
||||
}
|
||||
18
Lib/test/dtracedata/call_stack.d.expected
vendored
Normal file
18
Lib/test/dtracedata/call_stack.d.expected
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
function-entry:call_stack.py:start:23
|
||||
function-entry: call_stack.py:function_1:1
|
||||
function-entry: call_stack.py:function_3:9
|
||||
function-return: call_stack.py:function_3:10
|
||||
function-return: call_stack.py:function_1:2
|
||||
function-entry: call_stack.py:function_2:5
|
||||
function-entry: call_stack.py:function_1:1
|
||||
function-entry: call_stack.py:function_3:9
|
||||
function-return: call_stack.py:function_3:10
|
||||
function-return: call_stack.py:function_1:2
|
||||
function-return: call_stack.py:function_2:6
|
||||
function-entry: call_stack.py:function_3:9
|
||||
function-return: call_stack.py:function_3:10
|
||||
function-entry: call_stack.py:function_4:13
|
||||
function-return: call_stack.py:function_4:14
|
||||
function-entry: call_stack.py:function_5:18
|
||||
function-return: call_stack.py:function_5:21
|
||||
function-return:call_stack.py:start:28
|
||||
30
Lib/test/dtracedata/call_stack.py
vendored
Normal file
30
Lib/test/dtracedata/call_stack.py
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
def function_1():
|
||||
function_3(1, 2)
|
||||
|
||||
# Check stacktrace
|
||||
def function_2():
|
||||
function_1()
|
||||
|
||||
# CALL_FUNCTION_VAR
|
||||
def function_3(dummy, dummy2):
|
||||
pass
|
||||
|
||||
# CALL_FUNCTION_KW
|
||||
def function_4(**dummy):
|
||||
return 1
|
||||
return 2 # unreachable
|
||||
|
||||
# CALL_FUNCTION_VAR_KW
|
||||
def function_5(dummy, dummy2, **dummy3):
|
||||
if False:
|
||||
return 7
|
||||
return 8
|
||||
|
||||
def start():
|
||||
function_1()
|
||||
function_2()
|
||||
function_3(1, 2)
|
||||
function_4(test=42)
|
||||
function_5(*(1, 2), **{"test": 42})
|
||||
|
||||
start()
|
||||
41
Lib/test/dtracedata/call_stack.stp
vendored
Normal file
41
Lib/test/dtracedata/call_stack.stp
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
global tracing
|
||||
|
||||
function basename:string(path:string)
|
||||
{
|
||||
last_token = token = tokenize(path, "/");
|
||||
while (token != "") {
|
||||
last_token = token;
|
||||
token = tokenize("", "/");
|
||||
}
|
||||
return last_token;
|
||||
}
|
||||
|
||||
probe process.mark("function__entry")
|
||||
{
|
||||
funcname = user_string($arg2);
|
||||
|
||||
if (funcname == "start") {
|
||||
tracing = 1;
|
||||
}
|
||||
}
|
||||
|
||||
probe process.mark("function__entry"), process.mark("function__return")
|
||||
{
|
||||
filename = user_string($arg1);
|
||||
funcname = user_string($arg2);
|
||||
lineno = $arg3;
|
||||
|
||||
if (tracing) {
|
||||
printf("%d\t%s:%s:%s:%d\n", gettimeofday_us(), $$name,
|
||||
basename(filename), funcname, lineno);
|
||||
}
|
||||
}
|
||||
|
||||
probe process.mark("function__return")
|
||||
{
|
||||
funcname = user_string($arg2);
|
||||
|
||||
if (funcname == "start") {
|
||||
tracing = 0;
|
||||
}
|
||||
}
|
||||
14
Lib/test/dtracedata/call_stack.stp.expected
vendored
Normal file
14
Lib/test/dtracedata/call_stack.stp.expected
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
function__entry:call_stack.py:start:23
|
||||
function__entry:call_stack.py:function_1:1
|
||||
function__return:call_stack.py:function_1:2
|
||||
function__entry:call_stack.py:function_2:5
|
||||
function__entry:call_stack.py:function_1:1
|
||||
function__return:call_stack.py:function_1:2
|
||||
function__return:call_stack.py:function_2:6
|
||||
function__entry:call_stack.py:function_3:9
|
||||
function__return:call_stack.py:function_3:10
|
||||
function__entry:call_stack.py:function_4:13
|
||||
function__return:call_stack.py:function_4:14
|
||||
function__entry:call_stack.py:function_5:18
|
||||
function__return:call_stack.py:function_5:21
|
||||
function__return:call_stack.py:start:28
|
||||
18
Lib/test/dtracedata/gc.d
vendored
Normal file
18
Lib/test/dtracedata/gc.d
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
python$target:::function-entry
|
||||
/copyinstr(arg1) == "start"/
|
||||
{
|
||||
self->trace = 1;
|
||||
}
|
||||
|
||||
python$target:::gc-start,
|
||||
python$target:::gc-done
|
||||
/self->trace/
|
||||
{
|
||||
printf("%d\t%s:%ld\n", timestamp, probename, arg0);
|
||||
}
|
||||
|
||||
python$target:::function-return
|
||||
/copyinstr(arg1) == "start"/
|
||||
{
|
||||
self->trace = 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user