pax_global_header 0000666 0000000 0000000 00000000064 15265463462 0014527 g ustar 00root root 0000000 0000000 52 comment=d650a487f5bfb392179d2e4a738cf550a3773fcb
netromdk-vermin-d650a48/ 0000775 0000000 0000000 00000000000 15265463462 0015205 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/.editorconfig 0000664 0000000 0000000 00000000464 15265463462 0017666 0 ustar 00root root 0000000 0000000 # This is the top-most .editorconfig file; do not search in parent directories.
root = true
# General settings.
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
# Exceptions follow beneath:
[Makefile]
indent_style = tab
netromdk-vermin-d650a48/.github/ 0000775 0000000 0000000 00000000000 15265463462 0016545 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/.github/CODEOWNERS 0000664 0000000 0000000 00000000022 15265463462 0020132 0 ustar 00root root 0000000 0000000 * @netromdk
netromdk-vermin-d650a48/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 15265463462 0020730 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/.github/ISSUE_TEMPLATE/Bug_report.md 0000664 0000000 0000000 00000000735 15265463462 0023367 0 ustar 00root root 0000000 0000000 ---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Environment (please complete the following information):**
- Vermin version or Git commit [e.g. 0.4.0]
**Additional context**
Add any other context about the problem here.
netromdk-vermin-d650a48/.github/ISSUE_TEMPLATE/Feature_request.md 0000664 0000000 0000000 00000001101 15265463462 0024406 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
netromdk-vermin-d650a48/.github/ISSUE_TEMPLATE/Vulnerability_report.md 0000664 0000000 0000000 00000000753 15265463462 0025503 0 ustar 00root root 0000000 0000000 ---
name: Vulnerability report
about: Create a vulnerability report to help us improve security
---
**Describe the vulnerability**
A clear and concise description of the vulnerability, and which files, features, or dependencies are
impacted.
**Proof of concept exploit**
How to exploit the vulnerability.
**Environment (please complete the following information):**
- Vermin version or Git commit [e.g. 0.4.0]
**Additional context**
Add any other context about the vulnerability here.
netromdk-vermin-d650a48/.github/dependabot.yml 0000664 0000000 0000000 00000000506 15265463462 0021376 0 ustar 00root root 0000000 0000000 version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "sunday"
# Maintain dependencies for pip
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "sunday"
netromdk-vermin-d650a48/.github/workflows/ 0000775 0000000 0000000 00000000000 15265463462 0020602 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/.github/workflows/analyze.yml 0000664 0000000 0000000 00000001635 15265463462 0022775 0 ustar 00root root 0000000 0000000 name: Analyze
# On all pushes to PRs or pushes to specific branches. Not on ALL pushes in general because it will
# double if pushing to a PR.
on:
pull_request:
push:
branches:
- 'master'
- 'dev'
permissions:
contents: read
jobs:
analyze:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.14']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: ${{ matrix.python-version }}
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
path: ~/.cache/pip
key: ${{ runner.os}}-pip-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: |
${{ runner.os}}-pip-
- name: Analyze
run: ./misc/actions/analyze.sh
netromdk-vermin-d650a48/.github/workflows/codeql-analysis.yml 0000664 0000000 0000000 00000002073 15265463462 0024417 0 ustar 00root root 0000000 0000000 name: "CodeQL"
# On all PRs to master branches and every sunday at 2:34. Not when pushing to master because PRs are
# required and otherwise it'll run two times: once for the PR and again when the accepted PR is
# merged to master.
on:
pull_request:
branches: [ master ]
schedule:
- cron: '34 2 * * 6'
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Initialize CodeQL
uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412
netromdk-vermin-d650a48/.github/workflows/security-check.yml 0000664 0000000 0000000 00000001765 15265463462 0024260 0 ustar 00root root 0000000 0000000 name: Security Check
# On all pushes to PRs or pushes to specific branches. Not on ALL pushes in general because it will
# double if pushing to a PR.
on:
pull_request:
push:
branches:
- 'master'
- 'dev'
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
strategy:
matrix:
# NOTE: Keep at 3.13 until Bandit updates with 3.14 support!
python-version: ['3.13']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: ${{ matrix.python-version }}
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
path: ~/.cache/pip
key: ${{ runner.os}}-pip-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: |
${{ runner.os}}-pip-
- name: Security Check
run: ./misc/actions/security-check.sh
netromdk-vermin-d650a48/.github/workflows/semgrep.yml 0000664 0000000 0000000 00000001241 15265463462 0022765 0 ustar 00root root 0000000 0000000 name: Semgrep
on:
workflow_dispatch: {}
pull_request: {}
push:
branches:
- master
- dev
paths:
- .github/workflows/semgrep.yml
# Run every sunday at 3:12.
schedule:
- cron: '12 3 * * 6'
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
container:
image: returntocorp/semgrep
if: (github.actor != 'dependabot[bot]')
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
# It takes some time to scan "vermin/rules.py". More than the default 30s timeout.
- run: semgrep ci --timeout 120 --verbose
netromdk-vermin-d650a48/.github/workflows/snyk-schedule.yml 0000664 0000000 0000000 00000003427 15265463462 0024111 0 ustar 00root root 0000000 0000000 name: Snyk Schedule
# Run every sunday at 2:14.
on:
schedule:
- cron: '14 2 * * 6'
permissions:
contents: read
jobs:
security:
runs-on: ubuntu-latest
strategy:
matrix:
requirements: [analysis, coverage]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: '3.10'
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: 18
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
path: ~/.cache/pip
key: snyk-pip-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: snyk-pip-
- name: Upgrade Pip
run: pip3 install --upgrade pip
- name: Install requirements
env:
reqs: ${{ matrix.requirements }}
run: python3 -m pip install -r misc/.$reqs-requirements.txt
- name: Install Snyk
run: npm install -g snyk
- name: Run Snyk
continue-on-error: true # To make sure that SARIF upload gets called
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
FORCE_COLOR: 2
SNYK_INTEGRATION_NAME: GITHUB_ACTIONS
SNYK_INTEGRATION_VERSION: python
reqs: ${{ matrix.requirements }}
run: snyk test --project-name=vermin --package-manager=pip --file=misc/.$reqs-requirements.txt --command=python3 --sarif-file-output=snyk-$reqs.sarif --show-vulnerable-paths=all --print-deps
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938
with:
sarif_file: snyk-${{matrix.requirements}}.sarif
netromdk-vermin-d650a48/.github/workflows/snyk.yml 0000664 0000000 0000000 00000002662 15265463462 0022317 0 ustar 00root root 0000000 0000000 name: Snyk
# On all pushes/PRs.
on:
push:
pull_request:
permissions:
contents: read
jobs:
security:
runs-on: ubuntu-latest
strategy:
matrix:
requirements: [analysis, coverage]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: '3.10'
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: 18
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
with:
path: ~/.cache/pip
key: snyk-pip-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: snyk-pip-
- name: Upgrade Pip
run: pip3 install --upgrade pip
- name: Install requirements
env:
reqs: ${{ matrix.requirements }}
run: python3 -m pip install -r misc/.$reqs-requirements.txt
- name: Install Snyk
run: npm install -g snyk
- name: Run Snyk
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
FORCE_COLOR: 2
SNYK_INTEGRATION_NAME: GITHUB_ACTIONS
SNYK_INTEGRATION_VERSION: python
reqs: ${{ matrix.requirements }}
run: snyk test --project-name=vermin --package-manager=pip --file=misc/.$reqs-requirements.txt --command=python3 --show-vulnerable-paths=all --print-deps
netromdk-vermin-d650a48/.github/workflows/test.yml 0000664 0000000 0000000 00000011617 15265463462 0022312 0 ustar 00root root 0000000 0000000 name: Test
# On all pushes to PRs or pushes to specific branches. Not on ALL pushes in general because it will
# double if pushing to a PR.
on:
pull_request:
push:
branches:
- 'master'
- 'dev'
permissions:
contents: read
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Start Linux jobs last since they are fastest to start and complete, and start 3.15 first,
# since it pairs wiht macOS+Windows jobs, and 3.5 and 3.6 last since they only run tests and
# don't use venv. 3.4 is not supported on GitHub anymore and 3.5 and 3.6 for x64 isn't
# produced for ubuntu 22.04.
python-version: ['3.15', '3.14', '3.13', '3.12', '3.11', '3.10', 3.9, 3.8, 3.7, 3.6, 3.5]
os: [windows-latest, macos-latest, ubuntu-latest]
# Choose test script depending on OS.
include:
- os: ubuntu-latest
test_script_name: ./misc/actions/test.sh
- os: macos-latest
test_script_name: ./misc/actions/test.sh
- os: windows-latest
test_script_name: ./misc/actions/test.ps1
exclude:
# Only test on macOS and Windows with Python 3.15.
- os: macos-latest
python-version: 3.5
- os: macos-latest
python-version: 3.6
- os: macos-latest
python-version: 3.7
- os: macos-latest
python-version: 3.8
- os: macos-latest
python-version: 3.9
- os: macos-latest
python-version: '3.10'
- os: macos-latest
python-version: '3.11'
- os: macos-latest
python-version: '3.12'
- os: macos-latest
python-version: '3.13'
- os: macos-latest
python-version: '3.14'
- os: windows-latest
python-version: 3.5
- os: windows-latest
python-version: 3.6
- os: windows-latest
python-version: 3.7
- os: windows-latest
python-version: 3.8
- os: windows-latest
python-version: 3.9
- os: windows-latest
python-version: '3.10'
- os: windows-latest
python-version: '3.11'
- os: windows-latest
python-version: '3.12'
- os: windows-latest
python-version: '3.13'
- os: windows-latest
python-version: '3.14'
# Ignore 3.5, 3.6, and 3.7 on Linux because it isn't compiled for x64 on Ubuntu 22.04.
- os: ubuntu-latest
python-version: 3.5
- os: ubuntu-latest
python-version: 3.6
- os: ubuntu-latest
python-version: 3.7
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: ${{ matrix.python-version }}
# The caches need to have the python version included since the
# "misc/.coverage-requirements.txt" does not have version-pinning.
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
if: startsWith(matrix.os, 'ubuntu-latest')
with:
path: ~/.cache/pip
key: ${{ matrix.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: |
${{ matrix.os }}-pip-${{ matrix.python-version }}-
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
if: startsWith(matrix.os, 'macos-latest')
with:
path: ~/Library/Caches/pip
key: ${{ matrix.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: |
${{ matrix.os }}-pip-${{ matrix.python-version }}-
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9
if: startsWith(matrix.os, 'windows-latest')
with:
path: ~\AppData\Local\pip\Cache
key: ${{ matrix.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/.*-requirements.txt') }}
restore-keys: |
${{ matrix.os }}-pip-${{ matrix.python-version }}-
- name: Test and coverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
COVERALLS_FLAG_NAME: ${{ matrix.os }}-${{ matrix.python-version }}
COVERALLS_PARALLEL: true
run: ${{ matrix.test_script_name }}
# When all parallel tests are done and uploaded, the coveralls session can be signalled as
# finished.
finish:
permissions:
checks: write # for coverallsapp/github-action to create new checks
needs: test
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@8d6379e14d29928660c4ba802d8e85393440b329
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
netromdk-vermin-d650a48/.gitignore 0000664 0000000 0000000 00000002403 15265463462 0017174 0 ustar 00root root 0000000 0000000 # Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# Sublime Text
*.sublime-*
# Mac stuff
.DS_Store
examples
# IntelliJ
.idea/
# Rendered manpages
docs/man/*.1
docs/man/*.5
netromdk-vermin-d650a48/.pre-commit-hooks.yaml 0000664 0000000 0000000 00000001371 15265463462 0021346 0 ustar 00root root 0000000 0000000 - id: vermin
name: Check minimum Python version
description: Checks the minimum needed Python version to run your package. Only runs on staged files (your target must be `x.y-` rather than `x.y` for it to work properly). If using non-default args, including `--violations` is recommended.
entry: vermin
args: ["--violations"]
require_serial: true
language: python
types: [python]
- id: vermin-all
name: Check minimum Python version
description: Checks the minimum needed Python version to run your package. Runs on all Python files in the repo. If using non-default args, including `--violations` is recommended.
entry: vermin
args: ["--violations", "."]
pass_filenames: false
require_serial: true
language: python
types: [python]
netromdk-vermin-d650a48/.semgrepignore 0000664 0000000 0000000 00000000103 15265463462 0020046 0 ustar 00root root 0000000 0000000 .semgrep
.semgrep_logs/
.venv/
.hypothesis/
build/
dist/
examples/
netromdk-vermin-d650a48/CONTRIBUTING.md 0000664 0000000 0000000 00000004120 15265463462 0017433 0 ustar 00root root 0000000 0000000 # Contributing
Contributions are very welcome, especially adding and updating detection rules of modules,
functions, classes etc. to cover as many Python versions as possible.
Note that code must remain valid and Vermin be able to run via Python v3+ but still include
detection of v2.x functionality.
## Dependencies
Install development and analysis dependencies via `make setup`. It will setup a `virtualenv` in
`.venv` and install necessary dependencies.
Dependencies can also be directly installed via:
```shell
% python3 -m pip install --upgrade pip virtualenv
% virtualenv -p python3 .venv
% source .venv/bin/activate # or whatever suits the platform.
% pip install -r misc/.analysis-requirements.txt
```
**Note:** Until the release of Vermin 1.6, it is recommended to use Python 3.10 or lower when
running analysis checks. This is because Pylint requires an update but doing so makes it
incompatible with certain versions of Python 2.x. In Vermin 1.6, support for Python 2.7 will be
removed and dependencies will be updated such that Python 3.11 can be used for analysis checks.
Unittests can be run without installing any dependencies: `make test`
## Detection Rules
Rules for detecting minimum versions are defined in "vermin/rules.py".
## Backports
Some features are sometimes backported into packages, in repositories such as
[PyPi](https://pypi.org), that are widely used but aren't in the standard language.
Backports are defined in "vermin/backports.py" with associated rules in "vermin/rules.py".
Adding versioned backports is only applicable when the minimum versions of the most current,
published version change. Unversioned backports must be the newest among versioned and unversioned,
and must be sorted after the versioned counterparts in the tuples of `BACKPORTS`. The version part
can be any string.
## Pull Requests
Make sure to keep the code vanilla Python and run `make test check-all` first to improve turnaround
time.
It is required to add new unittests to cover related changes if appropriate.
Unittests are defined in test suites located in the "tests/" folder.
netromdk-vermin-d650a48/LICENSE.txt 0000664 0000000 0000000 00000002062 15265463462 0017030 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2018 Morten Kristensen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
netromdk-vermin-d650a48/MANIFEST.in 0000664 0000000 0000000 00000000061 15265463462 0016740 0 ustar 00root root 0000000 0000000 include runtests.py
recursive-include tests *.py
netromdk-vermin-d650a48/Makefile 0000664 0000000 0000000 00000005316 15265463462 0016652 0 ustar 00root root 0000000 0000000 VERMIN_FILES=vermin vermin.py
TEST_FILES=tests runtests.py
OTHER_FILES=count.py
MODULES=vermin tests
TOP_LEVEL_FILES=${MODULES} vermin.py runtests.py ${OTHER_FILES}
SEMGREP_CMD=semgrep ci --metrics off --timeout 60 --verbose
MANPAGES=docs/man/vermin.1 docs/man/vermin.ini.5
RSTMAN ?= rst2man
test-self:
./vermin.py --violations -q -t=3 ${VERMIN_FILES}
test-tests:
./vermin.py --violations -q -t=3.2- ${TEST_FILES}
test: test-self test-tests
./runtests.py
count:
./count.py
@echo "Tests: `grep -ri 'def test_' tests | wc -l | xargs`"
@echo "Vermin SLOC: `sloccount vermin/ vermin.py 2>/dev/null | grep 'python:' | xargs`"
@echo "Tests SLOC: `sloccount tests/ runtests.py 2>/dev/null | grep 'python:' | xargs`"
setup-venv: clean-venv
virtualenv -p python3 .venv
setup-coverage: clean
pip install -r misc/.coverage-requirements.txt
setup-analysis: clean
pip install -r misc/.analysis-requirements.txt
setup-docs: clean
pip install -r misc/.docs-requirements.txt
setup: setup-venv setup-analysis setup-docs
install-deps:
python -m pip install --upgrade pip virtualenv
install-deps-user:
python -m pip install --user --upgrade pip virtualenv
clean:
find . -iname __pycache__ | xargs rm -fr
find . -iname '*.pyc' | xargs rm -f
clean-venv:
rm -fr .venv
clean-pypi:
rm -fr build dist *.egg-info vermin/*.egg-info
dist-clean: clean clean-venv clean-pypi
pypi-dist: clean-pypi
python -m pip install --upgrade build wheel twine
python -m build
update-coverage-requirements: setup-venv setup-coverage
pip freeze > misc/.coverage-requirements.txt
update-analysis-requirements: setup-venv setup-analysis
pip freeze > misc/.analysis-requirements.txt
check-style:
flake8 --count --show-source ${TOP_LEVEL_FILES}
static-analysis:
vulture --min-confidence 70 --sort-by-size ${TOP_LEVEL_FILES}
check-unused:
vulture --sort-by-size ${VERMIN_FILES}
security-check:
bandit -r -s B101 ${MODULES}
semgrep:
${SEMGREP_CMD}
semgrep-dry-run:
${SEMGREP_CMD} --dry-run
lint:
pylint -j 0 --disable=C0103,C0114,C0115,C0116,C0209,C0302,W0201,W0311,W0621,W0703,R0801,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0916,R0917,R1702,E1101,E1136\
${TOP_LEVEL_FILES}
check-pypi:
pyroma --min=10 .
check: check-style check-pypi static-analysis lint
# NOTE: `check` doesn't check all because bandit doesn't run on py37+ yet.
check-all: check security-check
test-coverage:
coverage run --source=vermin,tests runtests.py
coverage run --append --source=vermin ./vermin.py -v -t=3 vermin.py vermin
coverage-report:
coverage report -m
define docs_rule
$(1): $(1).rst
$(RSTMAN) $(1).rst $(1)
endef
$(foreach manpage,$(MANPAGES),$(eval $(call docs_rule,$(manpage))))
docs: $(MANPAGES)
clean-docs:
rm -f $(MANPAGES)
.PHONY: docs clean-docs
netromdk-vermin-d650a48/README.rst 0000664 0000000 0000000 00000045154 15265463462 0016705 0 ustar 00root root 0000000 0000000 |Test Status| |Analyze Status| |CodeQL Status| |Coverage| |PyPI version| |Commits since last| |Downloads| |CII best practices|
.. |PyPI version| image:: https://badge.fury.io/py/vermin.svg
:target: https://pypi.python.org/pypi/vermin/
.. |Test Status| image:: https://github.com/netromdk/vermin/workflows/Test/badge.svg?branch=master
:target: https://github.com/netromdk/vermin/actions
.. |Analyze Status| image:: https://github.com/netromdk/vermin/workflows/Analyze/badge.svg?branch=master
:target: https://github.com/netromdk/vermin/actions
.. |CodeQL Status| image:: https://github.com/netromdk/vermin/workflows/CodeQL/badge.svg?branch=master
:target: https://github.com/netromdk/vermin/security/code-scanning
.. |Snyk Status| image:: https://github.com/netromdk/vermin/workflows/Snyk%20Schedule/badge.svg?branch=master
:target: https://github.com/netromdk/vermin/actions
.. |Coverage| image:: https://coveralls.io/repos/github/netromdk/vermin/badge.svg?branch=master
:target: https://coveralls.io/github/netromdk/vermin?branch=master
.. |Commits since last| image:: https://img.shields.io/github/commits-since/netromdk/vermin/latest.svg
.. |Downloads| image:: https://static.pepy.tech/personalized-badge/vermin?period=total&units=international_system&left_color=gray&right_color=blue&left_text=Downloads
:target: https://pepy.tech/project/vermin
.. |CII best practices| image:: https://bestpractices.coreinfrastructure.org/projects/6451/badge
:target: https://bestpractices.coreinfrastructure.org/projects/6451
Vermin
******
Concurrently detect the minimum Python versions needed to run code. Additionally, since the code is
vanilla Python, and it doesn't have any external dependencies, it can be run with v3+ but still
includes detection of v2.x functionality.
It functions by parsing Python code into an abstract syntax tree (AST), which it traverses and
matches against internal dictionaries with **4312** rules, covering v2.0-2.7 and v3.0-3.15, divided
into **194** modules, **2995** classes/functions/constants members of modules, **991** kwargs of
functions, **4** strftime directives, **3** bytes format directives, **6** array typecodes, **3**
codecs error handler names, **19** codecs encodings, **78** builtin generic annotation types, **9**
builtin dict union (``|``) types, **8** builtin dict union merge (``|=``) types, and **2** user
function decorators.
Backports of the standard library, like ``typing``, can be enabled for better results. Get full list
of backports via ``--help``.
The project is fairly well-tested with **4605** unit and integration tests that are executed on
Linux, macOS, and Windows.
It is recommended to use the most recent Python version to run Vermin on projects since Python's own
language parser is used to detect language features, like f-strings since Python 3.6 etc.
As it parses each file, it reports Python syntax errors and warnings with full context, making it
easy to fix them in addition to the minimum versions detected.
Table of Contents
=================
* `Usage <#usage>`__
* `Features <#features>`__
* `Caveats <#caveats>`__
* `Configuration File <#configuration-file>`__
* `Examples <#examples>`__
* `Linting (showing only target versions violations) <#linting-showing-only-target-versions-violations>`__
* `API (experimental) <#api-experimental>`__
* `Analysis Exclusions <#analysis-exclusions>`__
* `Parsable Output <#parsable-output>`__
* `GitHub Output <#github-output>`__
* `Contributing <#contributing>`__
Usage
=====
It is fairly straightforward to use Vermin.
Running it from the repository either directly or through specific interpreter::
% ./vermin.py /path/to/your/project # (1) executing via `/usr/bin/env python`
% python3 vermin.py /path/to/your/project # (2) specifically `python3`
Or if installed via `PyPi `__::
% pip install vermin
% vermin /path/to/your/project
`Homebrew `__ (`pkg `__)::
% brew install vermin
`Spack `__ (`pkg `__)::
% git clone https://github.com/spack/spack.git
% . spack/share/spack/setup-env.sh # depending on shell
% spack install py-vermin
% spack load py-vermin
`Arch Linux (AUR) `__::
% yay -S python-vermin
When using continuous integration (CI) tools, like `Travis CI `_, Vermin can
be used to check that the minimum required versions didn't change. The following is an excerpt::
install:
- ./setup_virtual_env.sh
- pip install vermin
script:
- vermin -t=2.7 -t=3 project_package otherfile.py
Vermin can also be used as a `pre-commit `__ hook:
.. code-block:: yaml
repos:
- repo: https://github.com/netromdk/vermin
rev: GIT_SHA_OR_TAG # ex: 'e88bda9' or 'v1.3.4'
hooks:
- id: vermin
# specify your target version here, OR in a Vermin config file as usual:
args: ['-t=3.8-', '--violations']
# (if your target is specified in a Vermin config, you may omit the 'args' entry entirely)
When using the hook, a target version must be specified via a Vermin config file in your package,
or via the ``args`` option in your ``.pre-commit-config.yaml`` config. If you're passing the target
via ``args``, it's recommended to also include ``--violations`` (shown above).
If you're using the ``vermin-all`` hook, you can specify any target as you usually would. However,
if you're using the ``vermin`` hook, your target must be in the form of ``x.y-`` (as opposed to
``x.y``), otherwise you will run into issues when your staged changes meet a minimum version that
is lower than your target.
See the `pre-commit docs `__ for further general information
on how to get hooks set up on your project.
Features
========
Features detected include v2/v3 ``print expr`` and ``print(expr)``, ``long``, f-strings,
self-documenting f-strings (``f'{a=}'``), PEP 701 f-strings (3.12+), ``await`` in f-strings,
coroutines (``async`` and ``await``), asynchronous generators (``await`` and ``yield`` in same
function), asynchronous comprehensions, ``await`` in comprehensions, asynchronous ``for``-loops,
boolean constants, named expressions, keyword-only parameters, positional-only parameters,
``nonlocal``, ``yield from``, exception context cause (``raise .. from ..``), ``except*``, ``set``
literals, ``set`` comprehensions, ``dict`` comprehensions, unpacking in comprehension value
expressions (``[*x for x in range(10)]``), infix matrix multiplication, ``"..".format(..)``,
imports (``import X``, ``from X import Y``, ``from X import *``), function calls wrt. name and
kwargs, ``strftime`` + ``strptime`` directives used, function and variable annotations (also
``Final`` and ``Literal``), ``continue`` in ``finally`` block, modular inverse ``pow()``, array
typecodes, codecs error handler names, encodings, ``%`` formatting and directives for bytes and
bytearray, ``with`` statement, asynchronous ``with`` statement, multiple context expressions in a
``with`` statement, multiple context expressions in a ``with`` statement grouped with parenthesis,
unpacking assignment, generalized unpacking, ellipsis literal (``...``) out of slices, dictionary
union (``{..} | {..}``), dictionary union merge (``a = {..}; a |= {..}``), builtin generic type
annotations (``list[str]``), function decorators, class decorators, relaxed decorators,
``metaclass`` class keyword, pattern matching with ``match``, union types written as ``X | Y``, type
alias statements (``type X = SomeType``), type alias statements with lambdas/comprehensions in class
scopes, generic classes (``class C[T]: ...``), template string literals (``t'{var}'``), lazy imports
(``lazy import``, ``lazy from ... import``), special module attributes like ``__lazy_modules__``, and
slice type subscription (``slice[1:2:3]``). It tries to detect and ignore user-defined functions,
classes, arguments, and variables with names that clash with library-defined symbols.
Caveats
=======
For frequently asked questions, check out the `FAQ discussions
`__.
Self-documenting f-strings (``f'{a=}'``) cannot be distinguished from plain f-strings such as
``f'a={a}'`` by the AST alone, because the parser optimizes some information away (`#39
`__). Vermin therefore also verifies against the
source code. This detection is enabled by default, but can be disabled with ``--no-feature``. Note
that this also disables all other features.
PEP 701 f-string features require Python 3.12+. Vermin detects these using AST analysis combined
with source code heuristics, enabled by default, which requires Vermin to parse the syntax on Python
3.12+ (`#264 `__). Use ``--no-feature`` to disable
this detection.
Detecting union types (``X | Y`` `PEP 604 `__) can be
tricky because Vermin doesn't know all underlying details of constants and types since it parses and
traverses the AST. For this reason, heuristics are employed and this can sometimes yield incorrect
results (`#103 `__). To enable (unstable) union types
detection, use ``--feature union-types``.
Function and variable annotations aren't evaluated at definition time when ``from __future__ import
annotations`` is used (`PEP 563 `__). This is why
``--no-eval-annotations`` is on by default (since v1.1.1, `#66
`__). If annotations are being evaluated at runtime,
like using ``typing.get_type_hints`` or evaluating ``__annotations__`` of an object,
``--eval-annotations`` should be used for best results.
Configuration File
==================
Vermin automatically tries to detect a config file, starting in the current working directory where
it is run, following parent folders until either the root or project boundary files/folders are
reached. However, if ``--config-file`` is specified, no config is auto-detected and loaded.
Config file names being looked for: ``vermin.ini``, ``vermin.conf``, ``.vermin``, ``setup.cfg``
Project boundary files/folders: ``.git``, ``.svn``, ``.hg``, ``.bzr``, ``_darcs``, ``.fslckout``,
``.p4root``, ``.pijul``
A sample config file can be found `here `__.
Note that Vermin config can be in the same INI file as other configs, like the commonly used
``setup.cfg``:
.. code-block:: ini
[vermin]
verbose = 1
processes = 4
[flake8]
ignore = E111,F821
Examples
========
.. code-block:: console
% ./vermin.py vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
% ./vermin.py -t=3.3 vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
Target versions not met: 3.3
% echo $?
1
% ./vermin.py --versions vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
Version range: 2.0, 2.6, 2.7, 3.0
% ./vermin.py -v examples
Detecting python files..
Analyzing 6 files using 8 processes..
/path/to/examples/formatv2.py
2.7, 3.2 /path/to/examples/argparse.py
2.7, 3.0 /path/to/examples/formatv3.py
2.0, 3.0 /path/to/examples/printv3.py
!2, 3.4 /path/to/examples/abc.py
/path/to/examples/unknown.py
Minimum required versions: 3.4
Incompatible versions: 2.x
% ./vermin.py -vv /path/to/examples/abc.py
Detecting python files..
Analyzing using 8 processes..
!2, 3.4 /path/to/examples/abc.py
'abc' requires 2.6, 3.0
'abc.ABC' requires !2, 3.4
Minimum required versions: 3.4
Incompatible versions: 2.x
% ./vermin.py -vvv /path/to/examples/abc.py
Detecting python files..
Analyzing using 8 processes..
!2, 3.4 /path/to/examples/abc.py
L1 C7: 'abc' requires 2.6, 3.0
L2: 'abc.ABC' requires !2, 3.4
Minimum required versions: 3.4
Incompatible versions: 2.x
% ./vermin.py -f parsable /path/to/examples/abc.py
/path/to/examples/abc.py:1:7:2.6:3.0:'abc' module
/path/to/examples/abc.py:2::!2:3.4:'abc.ABC' member
/path/to/examples/abc.py:::!2:3.4:
:::!2:3.4:
See `Parsable Output <#parsable-output>`__ for more information about parsable output format.
Linting: Showing only target versions violations
================================================
Vermin shows lots of useful minimum version results when run normally, but it can also be used as a
linter to show only rules violating specified target versions by using ``--violations`` (or
``--lint``) and one or two ``--target`` values. Verbosity level 2 is automatically set when showing
only violations, but can be increased if necessary. The final versions verdict is still calculated
and printed at the end and the program exit code signifies whether the specified targets were met
(``0``) or violated (``1``). However, if no rules are triggered the exit code will be ``0`` due to
inconclusivity.
.. code-block:: console
% cat test.py
import argparse # 2.7, 3.2
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
% ./vermin.py -t=2.4- -t=3 --violations test.py ; echo $?
Detecting python files..
Analyzing using 8 processes..
2.7, 3.2 test.py
'all' member requires 2.5, 3.0
'argparse' module requires 2.7, 3.2
Minimum required versions: 2.7, 3.2
Target versions not met: 2.4-, 3.0
1
The two first lines violate the targets but the third line matches and is therefore not shown.
API (experimental)
==================
Information such as minimum versions, used functionality constructs etc. can also be accessed
programmatically via the ``vermin`` Python module, though it's an experimental feature. It is still
recommended to use the command-line interface.
.. code-block:: python
>>> import vermin as V
>>> V.version_strings(V.detect("a = long(1)"))
'2.0, !3'
>>> config = V.Config()
>>> config.add_exclusion("long")
>>> V.version_strings(V.detect("a = long(1)", config))
'~2, ~3'
>>> config.set_verbose(3)
>>> v = V.visit("""from argparse import ArgumentParser
... ap = ArgumentParser(allow_abbrev=True)
... """, config)
>>> print(v.output_text(), end="")
L1 C5: 'argparse' module requires 2.7, 3.2
L2: 'argparse.ArgumentParser(allow_abbrev)' requires !2, 3.5
>>> V.version_strings(v.minimum_versions())
'!2, 3.5'
Analysis Exclusions
===================
Analysis exclusion can be necessary in certain cases. The argument ``--exclude `` (multiple
can be specified) can be used to exclude modules, members, kwargs, codecs error handler names, or
codecs encodings by name from being analysed via . Consider the following code block that checks if
``PROTOCOL_TLS`` is an attribute of ``ssl``:
.. code-block:: python
import ssl
tls_version = ssl.PROTOCOL_TLSv1
if hasattr(ssl, "PROTOCOL_TLS"):
tls_version = ssl.PROTOCOL_TLS
It will state that "'ssl.PROTOCOL_TLS' requires 2.7, 3.6" but to exclude that from the results, use
``--exclude 'ssl.PROTOCOL_TLS'``. Afterwards, only "'ssl' requires 2.6, 3.0" will be shown and the
final minimum required versions are v2.6 and v3.0 instead of v2.7 and v3.6.
Code can even be excluded on a more fine grained level using the ``# novermin`` or ``# novm``
comments at line level. The following yields the same behavior as the previous code block, but only
for that particular ``if`` and its body:
.. code-block:: python
import ssl
tls_version = ssl.PROTOCOL_TLSv1
if hasattr(ssl, "PROTOCOL_TLS"): # novermin
tls_version = ssl.PROTOCOL_TLS
In scenarios where multiple tools are employed that use comments for various features, exclusions
can be defined by having ``#`` for each comment "segment":
.. code-block:: python
if hasattr(ssl, "PROTOCOL_TLS"): # noqa # novermin # pylint: disable=no-member
tls_version = ssl.PROTOCOL_TLS
Note that if a code base does not have any occurrences of ``# novermin`` or ``# novm``, speedups up
to 30-40%+ can be achieved by using the ``--no-parse-comments`` argument or ``parse_comments = no``
config setting.
Parsable Output
===============
For scenarios where the results of Vermin output is required, it is recommended to use the parsable
output format (``--format parsable``) instead of the default output. With this format enabled, each
line will be on the form:
.. code-block::
:::::
The ```` and ```` are only shown when the verbosity level is high enough, otherwise
they are empty.
Each feature detected per processed file will have the ```` defined on an individual
line. The last line of the processed file will have a special line with the corresponding ````
and no ````, constituting the minimum versions of that file:
.. code-block::
:::::
The very last line is the final minimum versions results of the entire scan and therefore has no
```` and ````:
.. code-block::
:::::
Inspection of example output
----------------------------
.. code-block:: console
% ./vermin.py -f parsable /path/to/project
/path/to/project/abc.py:1:7:2.6:3.0:'abc' module
/path/to/project/abc.py:2::!2:3.4:'abc.ABC' member
/path/to/project/abc.py:::!2:3.4:
/path/to/project/except_star.py:::~2:~3:
/path/to/project/annotations.py:::2.0:3.0:print(expr)
/path/to/project/annotations.py:1::!2:3.0:annotations
/path/to/project/annotations.py:::!2:3.0:
:::!2:3.4:
``abc.py`` requires ``!2`` and ``3.4`` via:
.. code-block::
/path/to/project/abc.py:::!2:3.4:
``except_star.py`` requires ``~2`` and ``~3`` via:
.. code-block::
/path/to/project/except_star.py:::~2:~3:
And ``annotations.py`` requires ``!2`` and ``3.0`` via:
.. code-block::
/path/to/project/annotations.py:::!2:3.0:
That means that the final result is ``!2`` and ``3.4``, which is shown by the last line:
.. code-block::
:::!2:3.4:
GitHub Output
=============
The GitHub output format has the same output as `parsable <#parsable-output>`__, but the lines are
formatted as GitHub Actions annotations. This let's you see minimum version violations as annotated
errors directly from a GitHub pipeline.
For annotations to appear in a pull request:
- Vermin must be called from a GitHub Actions workflow triggered by a PR
- Vermin must be called with current working directory as the root of the repository
- Only violations found in files changed in the PR will show up
Contributing
============
Contributions are very welcome, especially adding and updating detection rules of modules,
functions, classes etc. to cover as many Python versions as possible. See `CONTRIBUTING.md
`__ for more information.
netromdk-vermin-d650a48/SECURITY.md 0000664 0000000 0000000 00000000604 15265463462 0016776 0 ustar 00root root 0000000 0000000 # Security Policy
## Supported Versions
Security fixes and updates are applied to the `master` branch but they are not backported to older
releases.
## Reporting a Vulnerability
Report any vulnerability as an
[issue](https://github.com/netromdk/vermin/issues/new?template=Vulnerability_report.md) including
context information and which files, features, or dependencies are impacted.
netromdk-vermin-d650a48/count.py 0000775 0000000 0000000 00000002776 15265463462 0016726 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
from vermin import Config, MOD_REQS, MOD_MEM_REQS, KWARGS_REQS, STRFTIME_REQS, BYTES_REQS, \
ARRAY_TYPECODE_REQS, CODECS_ERROR_HANDLERS, CODECS_ENCODINGS, BUILTIN_GENERIC_ANNOTATION_TYPES, \
DICT_UNION_SUPPORTED_TYPES, DICT_UNION_MERGE_SUPPORTED_TYPES, DECORATOR_USER_FUNCTIONS
config = Config()
(mods, mems, kwargs, dirs, bdirs, typecodes, codecshandlers, codecsencs, builtinanntypes,
dictuniontypes, dictunionmergetypes, decouserfuncs) =\
(len(MOD_REQS(config)), len(MOD_MEM_REQS(config)), len(KWARGS_REQS(config)), len(STRFTIME_REQS),
len(BYTES_REQS), len(ARRAY_TYPECODE_REQS), len(CODECS_ERROR_HANDLERS), len(CODECS_ENCODINGS),
len(BUILTIN_GENERIC_ANNOTATION_TYPES), len(DICT_UNION_SUPPORTED_TYPES),
len(DICT_UNION_MERGE_SUPPORTED_TYPES), len(DECORATOR_USER_FUNCTIONS))
print("Rules:\n{:>4} modules\n{:>4} members\n{:>4} kwargs\n{:>4} strftime directives\n{:>4} bytes "
"format directives\n{:>4} array typecodes\n{:>4} codecs error handlers\n{:>4} codecs "
"encodings\n{:>4} builtin generic annotation types\n{:>4} builtin dict union types\n{:>4} "
"builtin dict union merge types\n{:>4} user function decorators\n{:>4} total".
format(mods, mems, kwargs, dirs, bdirs, typecodes, codecshandlers, codecsencs,
builtinanntypes, dictuniontypes, dictunionmergetypes, decouserfuncs,
mods + mems + kwargs + dirs + bdirs + typecodes + codecshandlers + codecsencs +
builtinanntypes + dictuniontypes + dictunionmergetypes + decouserfuncs))
netromdk-vermin-d650a48/docs/ 0000775 0000000 0000000 00000000000 15265463462 0016135 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/docs/man/ 0000775 0000000 0000000 00000000000 15265463462 0016710 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/docs/man/vermin.1.rst 0000664 0000000 0000000 00000030423 15265463462 0021103 0 ustar 00root root 0000000 0000000 ======
vermin
======
-------------------------------------------------------------------
Concurrently detect the minimum Python versions needed to run code.
-------------------------------------------------------------------
:Manual section: 1
.. contents::
Synopsis
========
``vermin`` [OPTIONS] *PATH* ...
Description
===========
Vermin parses Python code into an abstract syntax tree (AST) and matches that
against an internal library of rules in order to determine the minimum Python
version that the code can be run with.
Heuristics are employed to determine which files to analyze:
* 'py', 'py3', 'pyw', 'pyj', 'pyi' are always scanned, unless otherwise excluded.
* 'pyc', 'pyd', 'pxd', 'pyx', 'pyo', and various other files are ignored.
* Magic lines with 'python' are accepted, like: ``#!/usr/bin/env python``.
* Files that cannot be opened for reading as text devices are ignored.
However, vermin will always attempt to parse any file paths directly specified on
the command line, even without accepted extensions or heuristics, unless otherwise
excluded.
Results interpretation
~2
No known reason it won't work with Python 2
!2
It is known that it won't work with Python 2.
2.5, !3
Works with Python 2.5+ but it is known it won't work with Python 3.
~2, 3.4
No known reason it won't work with Python 2, works with Python 3.4+.
Incompatible versions notices mean that several files were detected incompatible
with Python 2 and Python 3 simultaneously. In such cases the results might be
inconclusive.
A config file is automatically detected from the current working directory
where vermin is run, following parent folders until either the root or project
boundary files/folders are reached. However, if ``--config-file`` is specified, no
configuration is auto-detected and loaded.
Config file names being looked for:
* vermin.ini
* vermin.conf
* .vermin
* setup.cfg
Project boundary files/folders:
* .bzr
* .fslckout
* .git
* .hg
* .p4root
* .pijul
* .svn
* _darcs
Options
=======
-q, --quiet
Enable quiet mode. If used together with ``--violations``, quiet mode is preserved while
showing only violations: no descriptive text, tips, or verdicts.
--no-quiet
Disable quiet mode.
-v..
Verbosity level 1 to 4. ``-v``, ``-vv``, ``-vvv``, and ``-vvvv`` shows increasingly more information.
-v
will show the individual versions required per file.
-vv
will also show which modules, functions etc. that constitutes the requirements.
-vvv
will also show line/column numbers.
-vvvv
will also show user-defined symbols being ignored
-t=VERSION, --target=VERSION
Target version that files must abide by. Can be specified once or twice.
A '-' can be appended to match target version or smaller, like '``-t=3.5-``'.
If not met Vermin will exit with code 1. Vermin will only compare target
versions with the same major version, so if you do not care about Python
2, you can just specify one target for Python 3. However, if used in
conjunction with ``--violations``, and no rules are triggered, it will exit
with code 0.
--no-target (default)
Don't expect certain target version(s).
-p=NUMBER, --processes=NUMBER
Use NUMBER concurrent processes to detect and analyze files. Defaults to all cores.
-i, --ignore
Ignore incompatible versions and warnings. However, if no compatible versions
are found then incompatible versions will be shown in the end to not have an
absence of results.
--no-ignore (default)
Don't ignore incompatible versions and warnings.
-d, --dump
Dump AST node visits.
--no-dump (default)
Don't dump AST node visits.
-h, --help
Show the help information and exits.
-V, --version
Show the version number and exits.
-c FILE, --config-file FILE
Loads the specified config file unless ``--no-config-file`` is specified. Any
additional arguments supplied are applied on top of that config. See vermin.ini(5)
section for more information.
--no-config-file
Disable automatic configuration file detection and disallow the ``--config-file`` argument.
--hidden
Analyze 'hidden' files and folders starting with '``.``'s.
--no-hidden (default)
Don't analyze hidden files and folders unless specified directly.
--versions
In the end, print all unique versions required by the analyzed code.
--show-tips (default)
Show helpful tips at the end, like those relating to backports or usage of
unevaluated generic/literal annotations.
--no-tips
Don't show tips.
--lint, --violations
Show only results that violate versions described by ``--target`` arguments,
which are required to be specified. Verbosity mode is automatically set to
at least 2 in order to show violations in output text, but can be increased
if necessary.
If no rules are triggered while used in conjunction with ``--target``, an exit
code 0 will still be yielded due to inconclusivity.
Can be used together with ``--quiet`` such that only the violations are shown:
no descriptive text, tips, or verdicts.
--no-lint, --no-violations (default)
Show regular results.
--pessimistic
Enable pessimistic mode: syntax errors are interpreted as the major Python version
in use being incompatible.
--no-pessimistic (default)
Disable pessimistic mode.
--eval-annotations
Instructs parser that annotations will be manually evaluated in code, which
changes minimum versions in certain cases. Otherwise, function and variable
annotations are not evaluated at definition time. Apply this argument if
code uses ``typing.get_type_hints`` or ``eval(obj.__annotations__)`` or
otherwise forces evaluation of annotations.
--no-eval-annotations (default)
Disable annotations evaluation.
--parse-comments (default)
Parse for comments to influence exclusion of code for analysis via "``# novm``"
and "``# novermin``".
--no-parse-comments
Don't parse for comments. Not parsing comments can sometimes yield a speedup
of 30-40%+.
--scan-symlink-folders
Scan symlinks to folders to include in analysis.
--no-symlink-folders (default)
Don't scan symlinks to folders to include in analysis. Symlinks to non-folders
or top-level folders will always be scanned.
-f FORMAT, --format FORMAT
Format to show results and output in. Supported formats:
default
Default formatting.
colored
Same as default, but prints with ANSI styling.
parsable
Each result is on form 'file:line:column:py2:py3:feature'. The
last line has no path or line/column numbers and contains the minimum py2 and
py3 versions. Minimum verbosity level is set to 3 but can be increased.
Tips, hints, incompatible versions, and `--versions` are disabled. File paths
containing ':' are ignored.
github
Same as parsable format, but each result is formatted as a GitHub
Actions annotation. Minimum version messages are annotated as errors, and all
other verbose messages as notices. The intent is that it be used for linting
in a GitHub Actions pipeline.
[--exclude NAME] ...
Exclude full names, like 'email.parser.FeedParser', from analysis. Useful to
ignore conditional logic that can trigger incompatible results. This option may
be specified multiple times.
[--exclude-file FILE] ...
Exclude full names, like 'email.parser.FeedParser', from analysis but read from
the specified file instead. Each line of the file constitutes an exclusion with
the same format as with `--exclude`.
--no-exclude (default)
Use no excludes. Clears any excludes specified before this.
[--exclude-regex PATTERN] ...
Exclude files from analysis by matching a regex pattern against their entire
path as expanded from the Vermin command line. Patterns are matched using
`re.search()`, so '^' or '$' anchors should be applied as needed.
--no-exclude-regex (default)
Use no exclude patterns. Clears any exclude patterns specified before this.
--make-paths-absolute (default)
Convert any relative paths from the command line into absolute paths. This
affects the path printed to the terminal if a file fails a check, and requires
``--exclude-regex`` patterns to match absolute paths.
--no-make-paths-absolute
Do not convert relative paths from the command line into absolute paths.
[--backport NAME] ...
Some features are sometimes backported into packages, in repositories such as PyPi,
that are widely used but aren't in the standard language. If such a backport is
specified as being used, the results will reflect that instead. Versioned
backports are only used when minimum versions change. Unversioned backports must
be the newest among versioned and unversioned. Supported backports:
*argparse*
https://pypi.org/project/argparse/ (2.3, 3.1)
*asyncio*
https://pypi.org/project/asyncio/ (!2, 3.3)
*configparser*
https://pypi.org/project/configparser/ (2.6, 3.2)
*contextvars*
https://pypi.org/project/contextvars/ (!2, 3.5)
*dataclasses*
https://pypi.org/project/dataclasses/ (!2, 3.6)
*enum*
https://pypi.org/project/enum34/ (2.4, 3.3)
*importlib*
https://pypi.org/project/importlib/ (2.3, 3.0)
*ipaddress*
https://pypi.org/project/ipaddress/ (2.6, 3.2)
*mock*
https://pypi.org/project/mock/ (!2, 3.6)
*statistics*
https://pypi.org/project/statistics/ (2.6, 3.4)
*typing*
https://pypi.org/project/typing/ (2.7, 3.2)
*typing_extensions==4.0*
https://pypi.org/project/typing-extensions/4.0.0/ (!2, 3.6)
*typing_extensions==4.3*
https://pypi.org/project/typing-extensions/4.3.0/ (!2, 3.7)
*typing_extensions*
https://pypi.org/project/typing-extensions/ (!2, 3.7)
*zoneinfo*
https://pypi.org/project/backports.zoneinfo/ (!2, 3.6)
--no-backport (default)
Use no backports. Clears any backports specified before this.
[--feature NAME] ...
Some features are enabled by default. Others must be explicitly enabled:
fstring-self-doc
Detect self-documenting fstrings. Enabled by default.
fstring-pep701
Detect PEP 701 f-string features (3.12+): same-quote nesting and
multi-line expressions. Requires running on Python 3.12+. Enabled by default.
union-types
[Unstable] Detect union types `X | Y`. Can in some cases wrongly report
union types due to having to employ heuristics.
--no-feature
Use no features. Disables all features, including those that are enabled by
default.
Examples
========
Check the minimum compatible versions:
.. code-block:: console
% ./vermin.py vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
Check if the target version is supported:
.. code-block:: console
% ./vermin.py -t=3.3 vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
Target versions not met: 3.3
% echo $?
1
List the unique versions required by the code:
.. code-block:: console
% ./vermin.py --versions vermin
Minimum required versions: 3.0
Incompatible versions: 2.x
Version range: 2.0, 2.6, 2.7, 3.0
Show the versions required for each file:
.. code-block:: console
% ./vermin.py -v examples
Detecting python files..
Analyzing 6 files using 8 processes..
/path/to/examples/formatv2.py
2.7, 3.2 /path/to/examples/argparse.py
2.7, 3.0 /path/to/examples/formatv3.py
2.0, 3.0 /path/to/examples/printv3.py
!2, 3.4 /path/to/examples/abc.py
/path/to/examples/unknown.py
Minimum required versions: 3.4
Incompatible versions: 2.x
Show which code elements constitute the requirements:
.. code-block:: console
% ./vermin.py -vv /path/to/examples/abc.py
Detecting python files..
Analyzing using 8 processes..
!2, 3.4 /path/to/examples/abc.py
'abc' requires 2.6, 3.0
'abc.ABC' requires !2, 3.4
Minimum required versions: 3.4
Incompatible versions: 2.x
Show the line and column numbers of the requirements:
.. code-block:: console
% ./vermin.py -vvv /path/to/examples/abc.py
Detecting python files..
Analyzing using 8 processes..
!2, 3.4 /path/to/examples/abc.py
L1 C7: 'abc' requires 2.6, 3.0
L2: 'abc.ABC' requires !2, 3.4
Minimum required versions: 3.4
Incompatible versions: 2.x
Output the results in a machine-readable format:
.. code-block:: console
% ./vermin.py -f parsable /path/to/examples/abc.py
/path/to/examples/abc.py:1:7:2.6:3.0:'abc' module
/path/to/examples/abc.py:2::!2:3.4:'abc.ABC' member
/path/to/examples/abc.py:::!2:3.4:
:::!2:3.4:
See also
========
vermin.ini(5), sample.vermin.ini
netromdk-vermin-d650a48/docs/man/vermin.ini.5.rst 0000664 0000000 0000000 00000011741 15265463462 0021667 0 ustar 00root root 0000000 0000000 ==========
vermin.ini
==========
-----------------------------
Configuration file for vermin
-----------------------------
:Manual section: 5
.. contents::
Description
===========
``vermin.ini`` is an INI-formatted configuration file. Options applicable to vermin
are in the ``[vermin]`` section so that it may be included in other configuration files
such as ``setup.cfg``. For example:
.. code-block:: ini
[vermin]
verbose = 1
processes = 4
[flake8]
ignore = E111,F821
Options
=======
The default values are marked with asterisks (`*`).
quiet = ***no*** | yes
Enable quiet mode. If used together with ``--violations``, quiet mode is preserved while
showing only violations: no descriptive text, tips, or verdicts.
verbose = ***0***
Verbosity level 1 to 4 showing increasingly more information. Turned off at level 0.
print_visits = ***no*** | yes
Dump AST node visits.
targets = VERSION
Target version that files must abide by. Can be specified once or twice.
A '-' can be appended to match target version or smaller, like '``-t=3.5-``'.
If not met Vermin will exit with code 1. Vermin will only compare target
versions with the same major version, so if you do not care about Python
2, you can just specify one target for Python 3. However, if used in
conjunction with ``--violations``, and no rules are triggered, it will exit
with code 0.
processes = ***0***
Use N concurrent processes to detect and analyze files. Defaults to 0, meaning
all cores available.
ignore_incomp = ***no*** | yes
Ignore incompatible versions and warnings. However, if no compatible versions
are found then incompatible versions will be shown in the end to not have an
absence of results.
analyze_hidden = ***no*** | yes
Analyze 'hidden' files and folders starting with '``.``'s.
show_tips = ***yes*** | no
Show helpful tips at the end, like those relating to backports or usage of
unevaluated generic/literal annotations.
pessimistic = ***no*** | yes
Enable pessimistic mode: syntax errors are interpreted as the major Python version
in use being incompatible.
exclusions = NAME
Exclude full names, like 'email.parser.FeedParser', from analysis. Useful to
ignore conditional logic that can trigger incompatible results
exclusion_regex = REGEX
Exclude files from analysis by matching a regex pattern against their entire
path as expanded from the Vermin command line. Patterns are matched using
`re.search()`, so '^' or '$' anchors should be applied as needed.
make_paths_absolute = ***yes*** | no
Convert any relative paths from the command line into absolute paths. This
affects the path printed to the terminal if a file fails a check, and requires
``--exclude-regex`` patterns to match absolute paths.
backports = NAME
Some features are sometimes backported into packages, in repositories such as PyPi,
that are widely used but aren't in the standard language. If such a backport is
specified as being used, the results will reflect that instead. Versioned
backports are only used when minimum versions change. Unversioned backports must
be the newest among versioned and unversioned.
See ``--help`` or vermin(1) for a full list of supported backports.
features = NAME
Some features are enabled by default. Others must be explicitly enabled.
See ``--help`` or vermin(1) for a full list of supported features.
format = ***default***
Format to show results and output in. Supported formats:
See ``--help`` or vermin(1) for a full list of supported formats.
eval_annotations = ***no*** | yes
Instructs parser that annotations will be manually evaluated in code, which
changes minimum versions in certain cases. Otherwise, function and variable
annotations are not evaluated at definition time. Apply this argument if
code uses ``typing.get_type_hints`` or ``eval(obj.__annotations__)`` or
otherwise forces evaluation of annotations.
only_show_violations = ***no*** | yes
Show only results that violate versions described by ``--target`` arguments,
which are required to be specified. Verbosity mode is automatically set to
at least 2 in order to show violations in output text, but can be increased
if necessary.
parse_comments = ***yes*** | no
Parse for comments to influence exclusion of code for analysis via "``# novm``"
and "``# novermin``".
scan_symlink_folders = ***no*** | yes
Scan symlinks to folders to include in analysis.
Examples
========
Specify targets to Python 2.7 and Python 3.9 or less:
.. code-block:: ini
targets = 2.7
3.9-
Exclude multiple full names:
.. code-block:: ini
exclusions =
email.parser.FeedParser
argparse.ArgumentParser(allow_abbrev)
Include multiple backports:
.. code-block:: ini
backports =
typing
argparse
Enable an unstable feature:
.. code-block:: ini
features =
fstring-self-doc
Exclude a directory using regex:
.. code-block:: ini
exclusion_regex =
^a/b$
# Required for the above regex
make_paths_absolute = no
See also
========
vermin(1), sample.vermin.ini
netromdk-vermin-d650a48/misc/ 0000775 0000000 0000000 00000000000 15265463462 0016140 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/misc/.analysis-requirements.txt 0000664 0000000 0000000 00000000763 15265463462 0023331 0 ustar 00root root 0000000 0000000 astroid==3.3.11
bandit==1.9.1
build==1.3.0
certifi==2025.10.5
charset-normalizer==3.4.3
dill==0.4.0
docutils==0.22.2
flake8==7.3.0
idna==3.10
isort==6.1.0
markdown-it-py==4.0.0
mccabe==0.7.0
mdurl==0.1.2
packaging==25.0
platformdirs==4.5.0
pycodestyle==2.14.0
pyflakes==3.4.0
Pygments==2.19.2
pylint==3.3.9
pyproject_hooks==1.2.0
pyroma==5.0
PyYAML==6.0.3
requests==2.32.5
rich==14.2.0
setuptools==80.9.0
stevedore==5.5.0
tomlkit==0.13.3
trove-classifiers==2025.9.11.17
urllib3==2.5.0
vulture==2.14
netromdk-vermin-d650a48/misc/.coverage-requirements.txt 0000664 0000000 0000000 00000000023 15265463462 0023266 0 ustar 00root root 0000000 0000000 coverage
coveralls
netromdk-vermin-d650a48/misc/.docs-requirements.txt 0000664 0000000 0000000 00000000011 15265463462 0022420 0 ustar 00root root 0000000 0000000 docutils
netromdk-vermin-d650a48/misc/actions/ 0000775 0000000 0000000 00000000000 15265463462 0017600 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/misc/actions/analyze.sh 0000775 0000000 0000000 00000000503 15265463462 0021600 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -x
setup() {
make install-deps setup-venv
source .venv/bin/activate
make setup-analysis
}
# Even if .venv is found, make sure required executables are found, otherwise setup anyway.
if [[ ! -d .venv ]] || [[ ! -f .venv/bin/flake8 ]]; then
setup
else
source .venv/bin/activate
fi
make check-all
netromdk-vermin-d650a48/misc/actions/security-check.sh 0000775 0000000 0000000 00000000510 15265463462 0023055 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -x
setup() {
make install-deps setup-venv
source .venv/bin/activate
make setup-analysis
}
# Even if .venv is found, make sure required executables are found, otherwise setup anyway.
if [[ ! -d .venv ]] || [[ ! -f .venv/bin/bandit ]]; then
setup
else
source .venv/bin/activate
fi
make security-check
netromdk-vermin-d650a48/misc/actions/test.ps1 0000664 0000000 0000000 00000002540 15265463462 0021205 0 ustar 00root root 0000000 0000000 $PYTHON_VERSION = python -c "import sys;v=sys.version_info;print('{}.{}'.format(v[0],v[1]))"
if ( $PYTHON_VERSION -eq "3.4" -or $PYTHON_VERSION -eq "3.5" -or $PYTHON_VERSION -eq "3.6") {
make test
}
else {
# Set policy that allows the execution of scripts and tests.
Set-ExecutionPolicy Unrestricted -Force
# Setup virtual env and install deps if virtual env doesn't already exist.
if (-not (Test-Path -LiteralPath ".venv")) {
make install-deps-user setup-venv
. .venv\Scripts\activate.ps1
make setup-coverage
}
else {
. .venv\Scripts\activate.ps1
}
# Run tests+program and record coverage.
coverage run --source=vermin,tests runtests.py
if (!$?) {
$Host.SetShouldExit(1) # This is necessary in order to fail the GitHub job.
exit 1
}
coverage run --append --source=vermin ./vermin.py -v -t=3 vermin.py vermin
if (!$?) {
$Host.SetShouldExit(1)
exit 1
}
# Output debug info to be able to troubleshoot in cases when the Coveralls command beneath fails.
coveralls debug --service=github-actions
# Report coverage. Note that it requires COVERALLS_REPO_TOKEN to be set!
for ($i = 0; $i -lt 5; $i++) {
$result = coveralls --service=github-actions
$exitCode = $LASTEXITCODE
Write-Host "Coveralls exit code: $exitCode"
if ($exitCode -eq 0) {
break
}
Start-Sleep -Seconds 10
}
}
netromdk-vermin-d650a48/misc/actions/test.sh 0000775 0000000 0000000 00000001654 15265463462 0021124 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -x
PYTHON_VERSION=$(python -c "import sys;v=sys.version_info;print('{}.{}'.format(v[0],v[1]))")
if [[ $PYTHON_VERSION = 3.4 ||
$PYTHON_VERSION = 3.5 ||
$PYTHON_VERSION = 3.6 ]];
then
make test
else
setup() {
make install-deps setup-venv
source .venv/bin/activate
make setup-coverage
}
# Even if .venv is found, make sure required executables are found, otherwise setup anyway.
if [[ ! -d .venv ]] || [[ ! -f .venv/bin/coveralls ]]; then
setup
else
source .venv/bin/activate
fi
make test-coverage
# Output debug info to be able to troubleshoot in cases when the Coveralls command beneath fails.
coveralls debug --service=github-actions
# Note that it requires COVERALLS_REPO_TOKEN to be set!
for i in {1..5}; do
coveralls --service=github-actions
CODE=$?
echo "Coveralls exit code: $CODE"
if [ $CODE -eq 0 ]; then break; fi
sleep 10
done
fi
netromdk-vermin-d650a48/profile.sh 0000775 0000000 0000000 00000001044 15265463462 0017203 0 ustar 00root root 0000000 0000000 #!/bin/sh
# Profile code triggered via input files but only with one process to simplify results for human
# parsing.
PROF_FILE=/tmp/out.prof
FLD=$(dirname $0)
VERMIN=${FLD}/vermin.py
if [ $# -eq 0 ]; then
echo "usage: $0 "
exit 1
fi
if ! hash pyprof2calltree 2>/dev/null; then
echo "Required program not found: pyprof2calltree"
echo "$ pip3 install pyprof2calltree && rehash"
exit 1
fi
set -x
time python3 -m cProfile -o "${PROF_FILE}" "${VERMIN}" -q -p=1 $@ && \
pyprof2calltree -k -i "${PROF_FILE}"
netromdk-vermin-d650a48/pyproject.toml 0000664 0000000 0000000 00000002074 15265463462 0020124 0 ustar 00root root 0000000 0000000 [build-system]
requires = ["setuptools>=80", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "vermin"
version = "1.9.2"
description = "Concurrently detect the minimum Python versions needed to run code"
readme = { file = "README.rst", content-type = "text/x-rst" }
requires-python = ">=3.0"
license = "MIT"
license-files = ["LICENSE.txt"]
authors = [
{ name = "Morten Kristensen", email = "me@mortens.dev" }
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3.0",
"Topic :: Utilities",
"Topic :: Software Development"
]
keywords = ["version", "detection", "analysis", "ast", "development"]
dependencies = []
optional-dependencies = {}
[tool.setuptools.packages.find]
where = ["."]
exclude = ["tests"]
[project.scripts]
vermin = "vermin:main"
[project.urls]
"Homepage" = "https://github.com/netromdk/vermin"
"Source" = "https://github.com/netromdk/vermin"
"Bug Reports" = "https://github.com/netromdk/vermin/issues"
netromdk-vermin-d650a48/runtests.py 0000775 0000000 0000000 00000003400 15265463462 0017446 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
import os
import sys
import unittest
from time import time
ROOT_MODULE = "tests."
# Isolate tests to be run "suite[.Class.test_method]". Class and method are optional.
ISOLATE = os.getenv("VERMIN_TEST_ISOLATE")
if ISOLATE is not None:
ISOLATE = ROOT_MODULE + ISOLATE.strip()
SUITES = (
"general",
"utility",
"config",
"arguments",
"lang",
"fstring_detector",
"module",
"builtin_classes",
"class",
"exception",
"builtin_functions",
"builtin_constants",
"builtin_exceptions",
"function",
"constants",
"decorators",
"kwargs",
"strftime_directive",
"annotation",
"maybe_annotations",
"array_typecodes",
"codecs_error_handlers",
"codecs_encodings",
"exclusions",
"comment_exclusions",
"backports",
"bytes_directive",
"violations",
)
def runsuite(suite):
# skip suite if doesn't match isolation filter
suite = ROOT_MODULE + suite
if ISOLATE:
if ISOLATE != suite and not ISOLATE.startswith(suite + "."):
print("Skipping test suite: {}".format(suite))
return 0
print("Isolated test(s): {}".format(ISOLATE))
print("Running test suite: {}".format(suite))
# Buffer output such that only on test errors will stdout/stderr be shown.
if ISOLATE:
res = unittest.main(None, argv=[sys.argv[0], ISOLATE], exit=False, buffer=True).result
else:
res = unittest.main(suite, exit=False, buffer=True).result
if len(res.failures) > 0 or len(res.errors) > 0:
sys.exit(-1)
return res.testsRun
def execute():
total_tests = 0
for suite in SUITES:
total_tests += runsuite(suite)
return total_tests
if __name__ == '__main__':
start, total_tests = time(), execute()
secs = time() - start
print("Ran {} tests ({} suites) in {:.3f}s".format(total_tests, len(SUITES), secs))
netromdk-vermin-d650a48/sample.vermin.ini 0000664 0000000 0000000 00000012227 15265463462 0020472 0 ustar 00root root 0000000 0000000 # Sample Vermin Configuration
#
# It contains all config options with default values commented out.
# The file is typically renamed as "vermin.ini" when copied into a project.
[vermin]
### Quiet mode ###
# If used together with --violations, quiet mode is preserved while showing only violations: no
# descriptive text, tips, or verdicts.
#
#quiet = no
### Verbosity ###
# Verbosity level 1 to 4. -v, -vv, -vvv, and -vvvv shows increasingly more information. Turned off
# at level 0.
#
#verbose = 0
### Dump AST node visits ###
# Only for debugging.
#
#print_visits = no
### Matching target versions ###
# Target version that files must abide by. Can be specified once or twice.
# A '-' can be appended to match target version or smaller, like '3.5-'.
# If not met Vermin will exit with code 1.
# Note that the amount of target versions must match the amount of minimum required versions
# detected.
#
# Examples:
#targets = 2.6-
#targets = 2.3
# 3,4
#targets = 2,7
# 3,9-
### Concurrent processing ###
# Use N concurrent processes to detect and analyze files. Defaults to 0, meaning all cores
# available.
#
#processes = 0
### Ignore incompatible versions and warnings ###
# However, if no compatible versions are found then incompatible versions will be shown in the end
# to not have an absence of results.
#
#ignore_incomp = no
### Hidden analysis ###
# Analyze 'hidden' files and folders starting with '.' (ignored by default when not specified
# directly).
#
#analyze_hidden = no
### Tips ###
# Possibly show helpful tips at the end, like those relating to backports or usage of unevaluated
# generic/literal annotations.
#
#show_tips = yes
### Pessimistic mode ###
# Syntax errors are interpreted as the major Python version in use being incompatible.
#
#pessimistic = no
### Exclusions ###
# Exclude full names, like 'email.parser.FeedParser', from analysis. Useful to ignore conditional
# logic that can trigger incompatible results.
#
# Exclude 'foo.bar.baz' module/member: foo.bar.baz
# Exclude 'foo' kwarg: somemodule.func(foo)
# Exclude 'bar' codecs error handler: ceh=bar
# Exclude 'baz' codecs encoding: ce=baz
#
# Example exclusions:
#exclusions =
# email.parser.FeedParser
# argparse.ArgumentParser(allow_abbrev)
#
#
# Exclude specific file paths from being crawled by matching against a regular expression. Useful to
# ignore files that are not executed under the same python interpreter, such as .pyi files.
#
# Exclude any '.pyi' file: \.pyi$
#
# (Note: the below examples require `make_paths_absolute = no`, or prefixing the patterns with the
# regex-escaped path to the current directory.)
#
# Exclude the directory 'a/b/': ^a/b$
# Exclude '.pyi' files under 'a/b/': ^a/b/.+\.pyi$
# Exclude '.pyi' files in exactly 'a/b/': ^a/b/[^/]+\.pyi$
#
# Example regex exclusions:
#exclusion_regex =
# \.pyi$
### Absolute Path Resolution
# Convert any relative paths from the command line into absolute paths. This affects the path
# printed to the terminal if a file fails a check, and and requires exclusion_regex patterns to
# match absolute paths.
#
#make_paths_absolute = yes
### Backports ###
# Some features are sometimes backported into packages, in repositories such as PyPi, that are
# widely used but aren't in the standard language. If such a backport is specified as being used,
# the results will reflect that instead.
#
# Get full list via `--help`.
#
# Example backports:
#backports =
# typing
# argparse
### Features ###
# fstring-self-doc and fstring-pep701 are enabled by default. Other features must be enabled
# explicitly. Use `--no-feature` to disable all features.
#
# Get full list via `--help`.
#
# Example features:
#features =
# fstring-self-doc
### Format ###
# Format to show results and output in.
#
# Get full list via `--help`.
#
#format = default
### Annotations evaluation ###
# Instructs parser that annotations will be manually evaluated in code, which changes minimum
# versions in certain cases. Otherwise, function and variable annotations are not evaluated at
# definition time. Apply this argument if code uses `typing.get_type_hints` or
# `eval(obj.__annotations__)` or otherwise forces evaluation of annotations.
#
#eval_annotations = no
### Violations ###
# Show only results that violate versions described by targets, which are required to be
# specified. Verbosity mode is automatically set to at least 2 in order to show violations in output
# text, but can be increased if necessary.
#
# If no rules are triggered while used in conjunction with targets, an exit code 0 will still be
# yielded due to inconclusivity.
#
# Can be used together with quiet mode such that only the violations are shown: no descriptive text,
# tips, or verdicts.
#
#only_show_violations = no
### Parse comments ###
# Whether or not to parse comments, searching for "# novm" and "# novermin" to exclude anslysis of
# specific lines. If these comments aren't used in a particular code base, not parsing them can
# sometimes yield a speedup of 30-40%+.
#
#parse_comments = yes
### Scan symlink folders ###
# Scan symlinks to folders to include in analysis. Symlinks to non-folders or top-level folders will
# always be scanned.
#
#scan_symlink_folders = no
netromdk-vermin-d650a48/setup.cfg 0000664 0000000 0000000 00000000171 15265463462 0017025 0 ustar 00root root 0000000 0000000 [flake8]
ignore = E111,E114,E121,E126,E127,E302,E305,W504,F821
max-line-length = 100
exclude = .git,.venv,examples,build
netromdk-vermin-d650a48/tests/ 0000775 0000000 0000000 00000000000 15265463462 0016347 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/tests/__init__.py 0000664 0000000 0000000 00000000000 15265463462 0020446 0 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/tests/annotation.py 0000664 0000000 0000000 00000004405 15265463462 0021076 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminModuleTests(VerminTest):
def test_return_annotation(self):
self.assertOnlyIn((3, 0), self.detect("def foo() -> str:\n\treturn ''"))
def test_arg_annotation(self):
self.assertOnlyIn((3, 0), self.detect("def foo(bar: int):\n\tpass"))
@VerminTest.skipUnlessVersion(3, 6)
def test_var_annotation(self):
self.assertOnlyIn((3, 6), self.detect("a: int = 5"))
@VerminTest.skipUnlessVersion(3, 6)
def test_Final_annotation(self):
self.config.set_eval_annotations(True)
self.assertOnlyIn((3, 8), self.detect("a: Final = 5"))
self.assertOnlyIn((3, 8), self.detect("a: Final[int] = 5"))
self.assertOnlyIn((3, 8), self.detect("a: typing.Final[int] = 5"))
@VerminTest.skipUnlessVersion(3, 6)
def test_Literal_annotation(self):
self.config.set_eval_annotations(True)
visitor = self.visit("a: Literal = 5")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("a: Literal[int] = 5")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("def only_four(x: Literal[4]):\n\treturn x")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("def foo(x: typing.Literal[4]):\n\treturn x")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
# Detect literal annotations after first annotation.
visitor = self.visit("def foo(x: L[1], y: Literal[4]):\n\treturn y")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("def foo(x: L[1], y: L[1], z: Literal[4]):\n\treturn z")
self.assertTrue(visitor.literal_annotations())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 6)
def test_maybe_Literal_annotation(self):
self.config.set_eval_annotations(False)
visitor = self.visit("def only_four(x: Literal[4]):\n\treturn x")
self.assertFalse(visitor.literal_annotations())
self.assertTrue(visitor.maybe_annotations())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
netromdk-vermin-d650a48/tests/arguments.py 0000664 0000000 0000000 00000055211 15265463462 0020732 0 ustar 00root root 0000000 0000000 import os
from tempfile import mkdtemp
from shutil import rmtree
from vermin import Backports, Features, DEFAULT_PROCESSES, CONFIG_FILE_NAMES
import vermin.formats
from .testutils import VerminTest, ScopedTemporaryFile
class VerminArgumentsTests(VerminTest):
def test_not_enough_args(self):
self.assertContainsDict({"code": 1, "usage": True, "full": False}, self.parse_args([]))
def test_help(self):
self.assertContainsDict({"code": 0, "usage": True, "full": True}, self.parse_args(["-h"]))
self.assertContainsDict({"code": 0, "usage": True, "full": True}, self.parse_args(["--help"]))
def test_files(self):
self.assertContainsDict({"code": 0, "paths": ["file.py", "file2.py", "folder/folder2"]},
self.parse_args(["file.py", "file2.py", "folder/folder2"]))
def test_mix_options_and_files(self):
self.assertContainsDict({"code": 0, "paths": ["file.py"]},
self.parse_args(["-q", "-t=2.7", "file.py"]))
self.assertTrue(self.config.show_tips())
self.assertEqual([(True, (2, 7))], self.config.targets())
def test_quiet(self):
self.assertFalse(self.config.quiet())
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["-q"]))
self.assertTrue(self.config.quiet())
self.config.set_quiet(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--quiet"]))
self.assertTrue(self.config.quiet())
def test_no_quiet(self):
self.config.set_quiet(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-quiet"]))
self.assertFalse(self.config.quiet())
def test_verbose(self):
self.assertEqual(0, self.config.verbose())
for n in range(1, 10):
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["-" + n * "v"]))
self.assertEqual(n, self.config.verbose())
def test_cant_mix_quiet_and_verbose(self):
self.assertContainsDict({"code": 1}, self.parse_args(["-q", "-v"]))
# Quiet and verbosity can be mixed only with violations mode.
def test_quiet_and_violations(self):
self.assertContainsDict({"code": 0}, self.parse_args(["-q", "--violations", "-t=3"]))
self.assertContainsDict({"code": 0}, self.parse_args(["-q", "--lint", "-t=3"]))
@VerminTest.parameterized_args([
# The boolean value means match target version exactly or not (equal or smaller).
(["-t=2.8"],
{"code": 0, "paths": []}, [(True, (2, 8))]),
(["--target=2.8"],
{"code": 0, "paths": []}, [(True, (2, 8))]),
(["-t=2,8"],
{"code": 0, "paths": []}, [(True, (2, 8))]),
(["--target=2,8"],
{"code": 0, "paths": []}, [(True, (2, 8))]),
(["-t=2.8-"],
{"code": 0, "paths": []}, [(False, (2, 8))]),
(["--target=2.8-"],
{"code": 0, "paths": []}, [(False, (2, 8))]),
(["-t=2,8-"],
{"code": 0, "paths": []}, [(False, (2, 8))]),
(["--target=2,8-"],
{"code": 0, "paths": []}, [(False, (2, 8))]),
(["-t=3-", "-t=2.8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
(["--target=3-", "--target=2.8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
(["-t=3-", "--target=2.8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
(["-t=3-", "-t=2,8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
(["--target=3-", "--target=2,8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
(["-t=3-", "--target=2,8"],
{"code": 0, "paths": []}, [(True, (2, 8)), (False, (3, 0))]),
# Too many targets (>2). It still adds up to two targets.
(["-t=3.1", "-t=2.8", "-t=3"], {"code": 1}, [(True, (2, 8)), (True, (3, 1))]),
(["--target=3.1", "--target=2.8", "--target=3"], {"code": 1}, [(True, (2, 8)), (True, (3, 1))]),
(["--target=3.1", "-t=2.8", "--target=3"], {"code": 1}, [(True, (2, 8)), (True, (3, 1))]),
# Invalid values.
(["-t=a"], {"code": 1}, []), # NaN
(["--target=a"], {"code": 1}, []),
(["-t=-1"], {"code": 1}, []), # < 2
(["--target=-1"], {"code": 1}, []),
(["-t=1.8"], {"code": 1}, []), # < 2
(["--target=1.8"], {"code": 1}, []),
(["-t=4"], {"code": 1}, []), # >= 4
(["--target=4"], {"code": 1}, []),
(["-t=4,5"], {"code": 1}, []), # > 4
(["--target=4,5"], {"code": 1}, []),
(["-t=2+"], {"code": 1}, []), # Only - allowed.
(["--target=2+"], {"code": 1}, []),
(["-t=2,0.1"], {"code": 1}, []), # 3 vals disallowed.
(["--target=2,0.1"], {"code": 1}, []),
(["-t=2.0,1"], {"code": 1}, []), # 3 vals disallowed.
(["--target=2.0,1"], {"code": 1}, []),
])
def test_targets(self, args, parsed_args, expected):
self.config.reset()
self.assertParseArgs(args, parsed_args)
self.assertEqual(self.config.targets(), expected)
def test_no_target(self):
self.assertTrue(self.config.add_target((True, (2, 7))))
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-target"]))
self.assertEmpty(self.config.targets())
self.assertTrue(self.config.add_target((True, (3, 4))))
self.assertTrue(self.config.add_target((True, (2, 2))))
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-target"]))
self.assertEmpty(self.config.targets())
def test_ignore_incomp(self):
self.assertFalse(self.config.ignore_incomp())
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["-i"]))
self.assertTrue(self.config.ignore_incomp())
self.config.set_ignore_incomp(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--ignore"]))
self.assertTrue(self.config.ignore_incomp())
def test_no_ignore(self):
self.config.set_ignore_incomp(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-ignore"]))
self.assertFalse(self.config.ignore_incomp())
@VerminTest.parameterized_args([
(["-q"], {"code": 0, "paths": []}, DEFAULT_PROCESSES),
# Valid values.
(["-p=1"], {"code": 0, "paths": []}, 1),
(["--processes=1"], {"code": 0, "paths": []}, 1),
(["-p=9"], {"code": 0, "paths": []}, 9),
(["--processes=9"], {"code": 0, "paths": []}, 9),
# Invalid values.
(["-p=hello"], {"code": 1}, DEFAULT_PROCESSES),
(["--processes=hello"], {"code": 1}, DEFAULT_PROCESSES),
(["-p=-1"], {"code": 1}, DEFAULT_PROCESSES),
(["--processes=-1"], {"code": 1}, DEFAULT_PROCESSES),
(["-p=0"], {"code": 1}, DEFAULT_PROCESSES),
(["--processes=0"], {"code": 1}, DEFAULT_PROCESSES),
])
def test_processes(self, args, parsed_args, expected):
self.config.reset()
self.assertParseArgs(args, parsed_args)
self.assertEqual(self.config.processes(), expected)
def test_dump(self):
self.assertFalse(self.config.print_visits())
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["-d"]))
self.assertTrue(self.config.print_visits())
self.config.reset()
self.assertFalse(self.config.print_visits())
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--dump"]))
self.assertTrue(self.config.print_visits())
def test_no_dump(self):
self.config.set_print_visits(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-dump"]))
self.assertFalse(self.config.print_visits())
def test_hidden(self):
self.assertContainsDict({"code": 0}, self.parse_args(["--hidden"]))
self.assertTrue(self.config.analyze_hidden())
def test_no_hidden(self):
self.config.set_analyze_hidden(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-hidden"]))
self.assertFalse(self.config.analyze_hidden())
def test_versions(self):
self.assertContainsDict({"versions": True}, self.parse_args(["--versions"]))
def test_exclude(self):
self.assertContainsDict({"code": 1}, self.parse_args(["--exclude"])) # Needs part.
self.assertEmpty(self.config.exclusions())
self.assertContainsDict({"code": 0}, self.parse_args(["--exclude", "bbb", "--exclude", "aaa"]))
self.assertEqual(["aaa", "bbb"], self.config.exclusions()) # Expect it sorted.
self.assertFalse(self.config.is_excluded("iamnotthere"))
self.assertTrue(self.config.is_excluded("aaa"))
self.assertTrue(self.config.is_excluded("bbb"))
self.config.reset()
args = ["--exclude", "foo.bar(baz)",
"--exclude", "ceh=surrogateescape",
"--exclude", "ce=utf-8"]
self.assertContainsDict({"code": 0}, self.parse_args(args))
self.assertTrue(self.config.is_excluded_kwarg("foo.bar", "baz"))
self.assertTrue(self.config.is_excluded_codecs_error_handler("surrogateescape"))
self.assertTrue(self.config.is_excluded_codecs_encoding("utf-8"))
self.assertContainsDict({"code": 0}, self.parse_args(["--no-exclude"]))
self.assertEmpty(self.config.exclusions())
def test_exclude_file(self):
self.assertContainsDict({"code": 1}, self.parse_args(["--exclude-file"])) # Needs part.
self.assertEmpty(self.config.exclusions())
fp = ScopedTemporaryFile()
fp.write(b"""bbb
aaa
""")
fp.close()
self.assertContainsDict({"code": 0}, self.parse_args(["--exclude-file", fp.path()]))
self.assertEqual(["aaa", "bbb"], self.config.exclusions()) # Expect it sorted.
self.assertContainsDict({"code": 0}, self.parse_args(["--no-exclude"]))
self.assertEmpty(self.config.exclusions())
# Nonexistent file is ignored.
fn = "nonexistentfile"
self.assertFalse(os.path.exists(fn))
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--exclude-file", fn]))
self.assertEmpty(self.config.exclusions())
def test_exclude_regex(self):
self.assertContainsDict({"code": 1}, self.parse_args(["--exclude-regex"])) # Needs part.
self.assertEmpty(self.config.exclusion_regex())
args = ["--exclude-regex", r"\.pyi$",
"--exclude-regex", "^a/b$"]
self.assertContainsDict({"code": 0}, self.parse_args(args))
expected = [r"\.pyi$", "^a/b$"]
self.assertEqual(expected, self.config.exclusion_regex()) # Expect it sorted.
self.assertFalse(self.config.is_excluded_by_regex("a/b.py"))
self.assertTrue(self.config.is_excluded_by_regex("asdf.pyi"))
self.assertTrue(self.config.is_excluded_by_regex("a/m.pyi"))
self.assertTrue(self.config.is_excluded_by_regex("a/b"))
# Regex patterns are applied at each level of directory traversal. If 'a/' is provided on the
# command line, then the regex 'a/b' will match the recursive traversal when it encounters the
# directory 'a/b', and avoid recursing into that directory. This makes it more efficient to use
# when possible, but more difficult to test in isolation. test_exclude_regex_relative() in
# general.py tests that 'a/b' excludes e.g. 'a/b/c.py'.
self.assertFalse(self.config.is_excluded_by_regex("a/b/c.py"))
self.config.reset()
self.assertEmpty(self.config.exclusion_regex())
args = ["--exclude-regex", "^a/b/.+$",
"--exclude-regex", r"^a/.+/.+\.pyi$"]
self.assertContainsDict({"code": 0}, self.parse_args(args))
self.assertTrue(self.config.is_excluded_by_regex("a/b/c.py"))
self.assertTrue(self.config.is_excluded_by_regex("a/b/c/d.py"))
# '.+/.+\.pyi' does not match .pyi files in the top-level directory.
self.assertFalse(self.config.is_excluded_by_regex("a/m.pyi"))
self.assertTrue(self.config.is_excluded_by_regex("a/d/m.pyi"))
self.assertFalse(self.config.is_excluded_by_regex("m.pyi"))
self.config.reset()
# Use '[^/]+' instead of '.+' to force only matching files in the top-level.
self.assertContainsDict({"code": 0}, self.parse_args(["--exclude-regex", r"^a/b/[^/]+\.pyi$"]))
self.assertTrue(self.config.is_excluded_by_regex("a/b/c.pyi"))
self.assertFalse(self.config.is_excluded_by_regex("a/b/c.py"))
self.assertFalse(self.config.is_excluded_by_regex("a/b/c/d.pyi"))
self.assertContainsDict({"code": 0}, self.parse_args(["--no-exclude-regex"]))
self.assertEmpty(self.config.exclusion_regex())
def test_make_paths_absolute(self):
self.assertTrue(self.config.make_paths_absolute())
self.assertContainsDict({"code": 0}, self.parse_args(["--no-make-paths-absolute"]))
self.assertFalse(self.config.make_paths_absolute())
self.assertContainsDict({"code": 0}, self.parse_args(["--make-paths-absolute"]))
self.assertTrue(self.config.make_paths_absolute())
def test_backport(self):
# Needs part.
self.assertContainsDict({"code": 1}, self.parse_args(["--backport"]))
self.assertEmpty(self.config.backports())
# Unknown module.
self.assertContainsDict({"code": 1}, self.parse_args(["--backport", "foobarbaz"]))
self.assertEmpty(self.config.backports())
# Known modules.
for mod in Backports.modules():
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--backport", mod]))
self.assertEqualItems([mod], self.config.backports())
self.assertContainsDict({"code": 0}, self.parse_args(["--no-backport"]))
self.assertEmpty(self.config.backports())
def test_show_tips(self):
self.config.set_show_tips(False)
self.assertContainsDict({"code": 0}, self.parse_args(["--show-tips"]))
self.assertTrue(self.config.show_tips())
def test_no_tips(self):
self.assertContainsDict({"code": 0}, self.parse_args(["--no-tips"]))
self.assertFalse(self.config.show_tips())
def test_feature(self):
# Default features are enabled.
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--verbose"]))
self.assertEqualItems(Features.defaults(), self.config.features())
# `--feature` is additive on top of the default features.
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--feature", "union-types"]))
feats = Features.defaults() | {"union-types"}
self.assertEqualItems(feats, self.config.features())
# Needs part.
self.config.reset()
self.assertContainsDict({"code": 1}, self.parse_args(["--feature"]))
self.assertEqualItems(Features.defaults(), self.config.features())
# Unknown feature.
self.config.reset()
self.assertContainsDict({"code": 1}, self.parse_args(["--feature", "foobarbaz"]))
self.assertEqualItems(Features.defaults(), self.config.features())
# Known features can be enabled individually after clearing all defaults.
for feature in Features.features():
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--no-feature", "--feature", feature]))
self.assertEqualItems([feature], self.config.features())
self.assertContainsDict({"code": 0}, self.parse_args(["--no-feature"]))
self.assertEmpty(self.config.features())
def test_format(self):
self.assertEqual("default", self.config.format().name())
# Needs part.
self.assertContainsDict({"code": 1}, self.parse_args(["--format"]))
self.assertEqual("default", self.config.format().name())
# Unknown format.
self.assertContainsDict({"code": 1}, self.parse_args(["--format", "foobarbaz"]))
self.assertEqual("default", self.config.format().name())
# Known formats.
for fmt in vermin.formats.names():
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["--format", fmt]))
self.assertEqual(fmt, self.config.format().name())
for fmt in ("parsable", "github"):
# Parsable verbose level 3, no tips, ignore incompatible versions, no `--versions`.
for args in (["--format", fmt], ["--format", fmt, "--verbose"],
["--format", fmt, "--versions"]):
self.config.reset()
self.assertContainsDict({"code": 0, "versions": False}, self.parse_args(args))
self.assertEqual(3, self.config.verbose())
self.assertTrue(self.config.ignore_incomp())
self.assertFalse(self.config.show_tips())
# Verbosity can be higher for parsable
self.config.reset()
self.assertContainsDict({"code": 0, "versions": False},
self.parse_args(["--format", fmt, "-vvvv"]))
self.assertEqual(4, self.config.verbose())
self.assertTrue(self.config.ignore_incomp())
self.assertFalse(self.config.show_tips())
def test_pessimistic(self):
self.assertFalse(self.config.pessimistic())
self.assertContainsDict({"code": 0}, self.parse_args(["--pessimistic"]))
self.assertTrue(self.config.pessimistic())
def test_no_pessimistic(self):
self.config.set_pessimistic(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-pessimistic"]))
self.assertFalse(self.config.pessimistic())
def test_config_file(self):
fp = ScopedTemporaryFile()
fp.write(b"""[vermin]
verbose = 3
pessimistic = on
""")
fp.close()
self.assertContainsDict({"code": 0}, self.parse_args(["--config-file", fp.path()]))
self.assertEqual(3, self.config.verbose())
self.assertTrue(self.config.pessimistic())
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["-c", fp.path()]))
self.assertEqual(3, self.config.verbose())
self.assertTrue(self.config.pessimistic())
# Unspecified config file.
self.assertContainsDict({"code": 1}, self.parse_args(["--config-file"]))
self.assertContainsDict({"code": 1}, self.parse_args(["-c"]))
# Nonexistent config file.
self.assertContainsDict({"code": 1}, self.parse_args(["--config-file", "doesnotexist"]))
self.assertContainsDict({"code": 1}, self.parse_args(["-c", "doesnotexist"]))
# Cannot be mixed with --no-config-file.
self.assertContainsDict({"code": 1},
self.parse_args(["--no-config-file", "--config-file", fp.path()]))
self.assertContainsDict({"code": 1},
self.parse_args(["--config-file", fp.path(), "--no-config-file"]))
self.assertContainsDict({"code": 1}, self.parse_args(["--no-config-file", "-c", fp.path()]))
self.assertContainsDict({"code": 1}, self.parse_args(["-c", fp.path(), "--no-config-file"]))
# Other arguments must override any loaded config file, which means the config file must be
# loaded first no matter the order of arguments passed on CLI.
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["-v", "-c", fp.path()]))
self.assertEqual(1, self.config.verbose())
self.assertTrue(self.config.pessimistic())
self.config.reset()
self.assertContainsDict({"code": 0}, self.parse_args(["-c", fp.path(), "-v"]))
self.assertEqual(1, self.config.verbose())
self.assertTrue(self.config.pessimistic())
# Can't use quiet and verbose modes together, even across CLI arguments and config file
# settings.
self.config.reset()
self.assertContainsDict({"code": 1}, self.parse_args(["-c", fp.path(), "-q"]))
self.config.reset()
self.assertContainsDict({"code": 1}, self.parse_args(["-q", "-c", fp.path()]))
def test_no_config_file(self):
tmp_fld = mkdtemp()
path = os.path.join(tmp_fld, CONFIG_FILE_NAMES[0])
with open(path, mode="w+", encoding="utf-8") as fp:
fp.write("""[vermin]
pessimistic = yes
""")
self.assertFalse(self.config.pessimistic())
# Don't use auto-detected config if --no-config-file is specified.
self.assertContainsDict({"code": 0},
self.parse_args(["--no-config-file"], os.path.dirname(path)))
self.assertFalse(self.config.pessimistic())
rmtree(tmp_fld)
def test_eval_annotations(self):
self.config.set_eval_annotations(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--eval-annotations"]))
self.assertTrue(self.config.eval_annotations())
def test_no_eval_annotations(self):
self.config.set_eval_annotations(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-eval-annotations"]))
self.assertFalse(self.config.eval_annotations())
def test_violations(self):
for cmd in ["--violations", "--lint"]:
self.config.reset()
self.config.set_only_show_violations(False)
# Targets are required to be specified.
self.assertContainsDict({"code": 1}, self.parse_args([cmd]))
# One target.
self.config.set_only_show_violations(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args([cmd, "-t=2.5"]))
self.assertTrue(self.config.only_show_violations())
self.assertEqual(2, self.config.verbose()) # Auto verbose 2.
# Two targets.
self.config.set_verbose(0)
self.config.clear_targets()
self.config.set_only_show_violations(False)
self.assertContainsDict({"code": 0, "paths": []},
self.parse_args([cmd, "-t=2.5", "-t=3.1"]))
self.assertTrue(self.config.only_show_violations())
self.assertEqual(2, self.config.verbose()) # Auto verbose 2.
# Force verbosity 2+.
self.config.set_verbose(0)
self.config.clear_targets()
self.config.set_only_show_violations(False)
self.assertContainsDict({"code": 0, "paths": []},
self.parse_args([cmd, "-t=2.5", "-v"]))
self.assertTrue(self.config.only_show_violations())
self.assertEqual(2, self.config.verbose())
# Allow larger verbosity.
self.config.set_verbose(0)
self.config.clear_targets()
self.config.set_only_show_violations(False)
self.assertContainsDict({"code": 0, "paths": []},
self.parse_args([cmd, "-t=2.5", "-vvv"]))
self.assertTrue(self.config.only_show_violations())
self.assertEqual(3, self.config.verbose())
def test_no_violations(self):
self.config.set_only_show_violations(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-violations"]))
self.assertFalse(self.config.only_show_violations())
self.config.set_only_show_violations(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-lint"]))
self.assertFalse(self.config.only_show_violations())
def test_parse_comments(self):
self.config.set_parse_comments(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--parse-comments"]))
self.assertTrue(self.config.parse_comments())
def test_no_parse_comments(self):
self.config.set_parse_comments(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-parse-comments"]))
self.assertFalse(self.config.parse_comments())
def test_scan_symlink_folders(self):
self.config.set_scan_symlink_folders(False)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--scan-symlink-folders"]))
self.assertTrue(self.config.scan_symlink_folders())
def test_no_symlink_folders(self):
self.config.set_scan_symlink_folders(True)
self.assertContainsDict({"code": 0, "paths": []}, self.parse_args(["--no-symlink-folders"]))
self.assertFalse(self.config.scan_symlink_folders())
netromdk-vermin-d650a48/tests/array_typecodes.py 0000664 0000000 0000000 00000004502 15265463462 0022117 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminArrayTypecodeTests(VerminTest):
@VerminTest.parameterized_args([
("from array import array\narray('q')", (3, 3)),
("import array\narray.array('q')", (3, 3)),
("from array import array\narray('q', [1, 2])", (3, 3)),
("from array import array as a\na('q', [1, 2])", (3, 3)),
])
def test_typecode_q(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("from array import array\narray('Q')", (3, 3)),
("import array\narray.array('Q')", (3, 3)),
("from array import array\narray('Q', [1, 2])", (3, 3)),
("from array import array as a\na('Q', [1, 2])", (3, 3)),
])
def test_typecode_Q(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("from array import array\narray('w')", (3, 13)),
("import array\narray.array('w')", (3, 13)),
("from array import array\narray('w', [1, 2])", (3, 13)),
("from array import array as a\na('w', [1, 2])", (3, 13)),
])
def test_typecode_w(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("from array import array\narray('e')", (3, 15)),
("import array\narray.array('e')", (3, 15)),
("from array import array\narray('e', [1, 2])", (3, 15)),
("from array import array as a\na('e', [1, 2])", (3, 15)),
])
def test_typecode_e(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("from array import array\narray('Zf')", (3, 15)),
("import array\narray.array('Zf')", (3, 15)),
("from array import array\narray('Zf', [1 + 2j, 3 - 4j])", (3, 15)),
("from array import array as a\na('Zf', [1 + 2j, 3 - 4j])", (3, 15)),
])
def test_typecode_Zf(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("from array import array\narray('Zd')", (3, 15)),
("import array\narray.array('Zd')", (3, 15)),
("from array import array\narray('Zd', [1 + 2j, 3 - 4j])", (3, 15)),
("from array import array as a\na('Zd', [1 + 2j, 3 - 4j])", (3, 15)),
])
def test_typecode_Zd(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
netromdk-vermin-d650a48/tests/backports.py 0000664 0000000 0000000 00000006314 15265463462 0020715 0 ustar 00root root 0000000 0000000 from vermin import Backports
from .testutils import VerminTest
class VerminBackportsTests(VerminTest):
def test_modules(self):
self.assertEqualItems((
"argparse",
"asyncio",
"configparser",
"contextvars",
"dataclasses",
"enum",
"importlib",
"ipaddress",
"mock",
"statistics",
"typing",
"typing_extensions==4.0",
"typing_extensions==4.3",
"typing_extensions",
"zoneinfo",
), Backports.modules())
def test_is_backport(self):
for mod in Backports.modules():
self.assertTrue(Backports.is_backport(mod))
def test_str(self):
self.assertEqual(""" argparse - https://pypi.org/project/argparse/ (2.3, 3.1)
asyncio - https://pypi.org/project/asyncio/ (!2, 3.3)
configparser - https://pypi.org/project/configparser/ (2.6, 3.2)
contextvars - https://pypi.org/project/contextvars/ (!2, 3.5)
dataclasses - https://pypi.org/project/dataclasses/ (!2, 3.6)
enum - https://pypi.org/project/enum34/ (2.4, 3.3)
importlib - https://pypi.org/project/importlib/ (2.3, 3.0)
ipaddress - https://pypi.org/project/ipaddress/ (2.6, 3.2)
mock - https://pypi.org/project/mock/ (!2, 3.6)
statistics - https://pypi.org/project/statistics/ (2.6, 3.4)
typing - https://pypi.org/project/typing/ (2.7, 3.2)
typing_extensions==4.0 - https://pypi.org/project/typing-extensions/4.0.0/ (!2, 3.6)
typing_extensions==4.3 - https://pypi.org/project/typing-extensions/4.3.0/ (!2, 3.7)
typing_extensions - https://pypi.org/project/typing-extensions/ (!2, 3.7)
zoneinfo - https://pypi.org/project/backports.zoneinfo/ (!2, 3.6)""",
Backports.str(3))
def test_version_filter(self):
self.assertEqual("somemodule", Backports.version_filter("somemodule==1.2"))
self.assertEqual("some_module", Backports.version_filter("some_module==1.2"))
self.assertEqual("some.module", Backports.version_filter("some.module==1.2"))
self.assertEqual("somemodule", Backports.version_filter("somemodule==string"))
self.assertEqual("somemodule", Backports.version_filter("somemodule"))
def test_unversioned_filter(self):
self.assertEqualItems([
"argparse",
"asyncio",
"configparser",
"contextvars",
"dataclasses",
"enum",
"importlib",
"ipaddress",
"mock",
"statistics",
"typing",
"typing_extensions",
"zoneinfo",
], Backports.unversioned_filter(Backports.modules()))
def test_expand_versions(self):
self.assertEqual([
("typing_extensions",
["https://pypi.org/project/typing-extensions/"],
(None, (3, 7))),
("typing_extensions==4.3",
["https://pypi.org/project/typing-extensions/4.3.0/"],
(None, (3, 7))),
("typing_extensions==4.0",
["https://pypi.org/project/typing-extensions/4.0.0/"],
(None, (3, 6))),
], Backports.expand_versions("typing_extensions"))
self.assertEqual([
("enum",
["https://pypi.org/project/enum34/"],
((2, 4), (3, 3))),
], Backports.expand_versions("enum"))
netromdk-vermin-d650a48/tests/builtin_classes.py 0000664 0000000 0000000 00000002400 15265463462 0022100 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminBuiltinClassesMemberTests(VerminTest):
def test_bool(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("bool()"))
def test_bytearray(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("bytearray()"))
def test_frozenset(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("frozenset()"))
def test_object(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("object()"))
def test_reversed(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("reversed()"))
def test_set(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("set()"))
def test_dict(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("dict()"))
def test_memoryview(self):
self.assertOnlyIn(((2, 7), (3, 0)), self.detect("memoryview()"))
def test_long(self):
self.assertOnlyIn((2, 0), self.detect("long()"))
def test_ExceptionGroup(self):
self.assertOnlyIn((3, 11), self.detect("ExceptionGroup()"))
def test_BaseExceptionGroup(self):
self.assertOnlyIn((3, 11), self.detect("BaseExceptionGroup()"))
def test_frozendict(self):
self.assertOnlyIn((3, 15), self.detect("frozendict()"))
def test_sentinel(self):
self.assertOnlyIn((3, 15), self.detect("sentinel()"))
netromdk-vermin-d650a48/tests/builtin_constants.py 0000664 0000000 0000000 00000003072 15265463462 0022465 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminBuiltinConstantsTests(VerminTest):
def test_obj_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').obj"))
def test_nbytes_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').nbytes"))
def test_contiguous_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').contiguous"))
def test_c_contiguous_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').c_contiguous"))
def test_f_contiguous_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').f_contiguous"))
def test_mapping_of_dict_view(self):
self.assertOnlyIn((3, 10), self.detect("{}.items().mapping"))
self.assertOnlyIn((3, 10), self.detect("{}.keys().mapping"))
self.assertOnlyIn((3, 10), self.detect("{}.values().mapping"))
self.assertOnlyIn((3, 10), self.detect("dict().items().mapping"))
self.assertOnlyIn((3, 10), self.detect("dict().keys().mapping"))
self.assertOnlyIn((3, 10), self.detect("dict().values().mapping"))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
d.items().mapping
"""))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
d.keys().mapping
"""))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
d.values().mapping
"""))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
i = d.items()
i.mapping
"""))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
i = d.keys()
i.mapping
"""))
self.assertOnlyIn((3, 10), self.detect("""
d = {}
i = d.values()
i.mapping
"""))
netromdk-vermin-d650a48/tests/builtin_exceptions.py 0000664 0000000 0000000 00000011546 15265463462 0022637 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminBuiltinExceptionsMemberTests(VerminTest):
def test_BaseException(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("BaseException()"))
self.assertOnlyIn((2, 5), self.detect("from exceptions import BaseException"))
def test_BytesWarning(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("BytesWarning()"))
self.assertOnlyIn((2, 6), self.detect("from exceptions import BytesWarning"))
def test_UnicodeWarning(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("UnicodeWarning()"))
self.assertOnlyIn((2, 5), self.detect("from exceptions import UnicodeWarning"))
def test_UnicodeError(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("UnicodeError()"))
self.assertOnlyIn((2, 0), self.detect("from exceptions import UnicodeError"))
def test_GeneratorExit(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("GeneratorExit()"))
self.assertOnlyIn((2, 5), self.detect("from exceptions import GeneratorExit"))
def test_ImportWarning(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("ImportWarning()"))
self.assertOnlyIn((2, 5), self.detect("from exceptions import ImportWarning"))
def test_StopIteration(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("StopIteration()"))
self.assertOnlyIn((2, 2), self.detect("from exceptions import StopIteration"))
def test_UnboundLocalError(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("UnboundLocalError()"))
self.assertOnlyIn((2, 0), self.detect("from exceptions import UnboundLocalError"))
def test_UnicodeDecodeError(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("UnicodeDecodeError()"))
self.assertOnlyIn((2, 3), self.detect("from exceptions import UnicodeDecodeError"))
def test_UnicodeEncodeError(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("UnicodeEncodeError()"))
self.assertOnlyIn((2, 3), self.detect("from exceptions import UnicodeEncodeError"))
def test_UnicodeTranslateError(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("UnicodeTranslateError()"))
self.assertOnlyIn((2, 3), self.detect("from exceptions import UnicodeTranslateError"))
def test_WindowsError(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("WindowsError()"))
self.assertOnlyIn((2, 0), self.detect("from exceptions import WindowsError"))
def test_ReferenceError(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("ReferenceError()"))
self.assertOnlyIn((2, 2), self.detect("from exceptions import ReferenceError"))
def test_ExceptionGroup(self):
self.assertOnlyIn((3, 11), self.detect("ExceptionGroup()"))
def test_BaseExceptionGroup(self):
self.assertOnlyIn((3, 11), self.detect("BaseExceptionGroup()"))
def test_BlockingIOError(self):
self.assertOnlyIn((3, 3), self.detect("BlockingIOError()"))
def test_BrokenPipeError(self):
self.assertOnlyIn((3, 3), self.detect("BrokenPipeError()"))
def test_ChildProcessError(self):
self.assertOnlyIn((3, 3), self.detect("ChildProcessError()"))
def test_ConnectionAbortedError(self):
self.assertOnlyIn((3, 3), self.detect("ConnectionAbortedError()"))
def test_ConnectionError(self):
self.assertOnlyIn((3, 3), self.detect("ConnectionError()"))
def test_ConnectionRefusedError(self):
self.assertOnlyIn((3, 3), self.detect("ConnectionRefusedError()"))
def test_ConnectionResetError(self):
self.assertOnlyIn((3, 3), self.detect("ConnectionResetError()"))
def test_EncodingWarning(self):
self.assertOnlyIn((3, 10), self.detect("EncodingWarning()"))
def test_FileExistsError(self):
self.assertOnlyIn((3, 3), self.detect("FileExistsError()"))
def test_FileNotFoundError(self):
self.assertOnlyIn((3, 3), self.detect("FileNotFoundError()"))
def test_InterruptedError(self):
self.assertOnlyIn((3, 3), self.detect("InterruptedError()"))
def test_IsADirectoryError(self):
self.assertOnlyIn((3, 3), self.detect("IsADirectoryError()"))
def test_ModuleNotFoundError(self):
self.assertOnlyIn((3, 6), self.detect("ModuleNotFoundError()"))
def test_NotADirectoryError(self):
self.assertOnlyIn((3, 3), self.detect("NotADirectoryError()"))
def test_PermissionError(self):
self.assertOnlyIn((3, 3), self.detect("PermissionError()"))
def test_ProcessLookupError(self):
self.assertOnlyIn((3, 3), self.detect("ProcessLookupError()"))
def test_PythonFinalizationError(self):
self.assertOnlyIn((3, 13), self.detect("PythonFinalizationError()"))
def test_RecursionError(self):
self.assertOnlyIn((3, 5), self.detect("RecursionError()"))
def test_ResourceWarning(self):
self.assertOnlyIn((3, 2), self.detect("ResourceWarning()"))
def test_StopAsyncIteration(self):
self.assertOnlyIn((3, 5), self.detect("StopAsyncIteration()"))
def test_TimeoutError(self):
self.assertOnlyIn((3, 3), self.detect("TimeoutError()"))
netromdk-vermin-d650a48/tests/builtin_functions.py 0000664 0000000 0000000 00000037173 15265463462 0022472 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminBuiltinFunctionsMemberTests(VerminTest):
def test_all(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("all()"))
def test_any(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("any()"))
def test_basestring(self):
self.assertOnlyIn((2, 3), self.detect("basestring()"))
def test_bin(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("bin()"))
def test_callable(self):
self.assertOnlyIn(((2, 0), (3, 2)), self.detect("callable()"))
def test_classmethod(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("classmethod()"))
def test_enumerate(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("enumerate()"))
def test_file(self):
self.assertOnlyIn((2, 0), self.detect("file()"))
def test_format(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("format()"))
def test_help(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("help()"))
def test_iter(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("iter()"))
def test_next(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("next()"))
def test_property(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("property()"))
def test_sorted(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("sorted()"))
def test_staticmethod(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("staticmethod()"))
def test_sum(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("sum()"))
def test_super(self):
# Calling without arguments requires v3 (`SourceVisitor.super_no_args()`).
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("super(SomeType)"))
def test_type(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("type()"))
def test_unichr(self):
self.assertOnlyIn((2, 0), self.detect("unichr()"))
def test_unicode(self):
self.assertOnlyIn((2, 0), self.detect("unicode()"))
def test_breakpoint(self):
self.assertOnlyIn((3, 7), self.detect("breakpoint()"))
self.assertOnlyIn((3, 7), self.detect("x=[]\nx[breakpoint()]"))
@VerminTest.parameterized_args([
("d={}\nd.has_key('a')", (2, 2)),
("{}.has_key('a')", (2, 2)),
("d=dict()\nd.has_key('a')", (2, 2)),
("dict().has_key('a')", (2, 2)),
])
def test_has_key_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.iteritems()", (2, 2)),
("{}.iteritems()", (2, 2)),
("d=dict()\nd.iteritems()", (2, 2)),
("dict().iteritems()", (2, 2)),
])
def test_iteritems_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.iterkeys()", (2, 2)),
("{}.iterkeys()", (2, 2)),
("d=dict()\nd.iterkeys()", (2, 2)),
("dict().iterkeys()", (2, 2)),
])
def test_iterkeys_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.itervalues()", (2, 2)),
("{}.itervalues()", (2, 2)),
("d=dict()\nd.itervalues()", (2, 2)),
("dict().itervalues()", (2, 2)),
])
def test_itervalues_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.viewitems()", (2, 7)),
("{}.viewitems()", (2, 7)),
("d=dict()\nd.viewitems()", (2, 7)),
("dict().viewitems()", (2, 7)),
])
def test_viewitems_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.viewkeys()", (2, 7)),
("{}.viewkeys()", (2, 7)),
("d=dict()\nd.viewkeys()", (2, 7)),
("dict().viewkeys()", (2, 7)),
])
def test_viewkeys_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.viewvalues()", (2, 7)),
("{}.viewvalues()", (2, 7)),
("d=dict()\nd.viewvalues()", (2, 7)),
("dict().viewvalues()", (2, 7)),
])
def test_viewvalues_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={}\nd.fromkeys()", ((2, 3), (3, 0))),
("{}.fromkeys()", ((2, 3), (3, 0))),
("d=dict()\nd.fromkeys()", ((2, 3), (3, 0))),
("dict().fromkeys()", ((2, 3), (3, 0))),
])
def test_fromkeys_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("d={1: 2}\nd.pop(1)", ((2, 3), (3, 0))),
("{1: 2}.pop(1)", ((2, 3), (3, 0))),
("d=dict({1: 2})\nd.pop(1)", ((2, 3), (3, 0))),
("dict({1: 2}).pop(1)", ((2, 3), (3, 0))),
])
def test_pop_of_dict(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
# set literals require 2.7, 3.0
("s={1,2}\ns.isdisjoint({3,4})", ((2, 7), (3, 0))),
("{1,2}.isdisjoint({3,4})", ((2, 7), (3, 0))),
("s=set()\ns.isdisjoint(set([3,4]))", ((2, 6), (3, 0))),
("set().isdisjoint(set([3,4]))", ((2, 6), (3, 0))),
])
def test_isdisjoint_of_set(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=frozenset()\ns.isdisjoint(set([3,4]))", ((2, 6), (3, 0))),
("frozenset().isdisjoint(set([3,4]))", ((2, 6), (3, 0))),
])
def test_isdisjoint_of_frozenset(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("l=[]\nl.clear()", (3, 0)),
("[].clear()", (3, 0)),
("l=list()\nl.clear()", (3, 0)),
("list().clear()", (3, 0)),
])
def test_clear_of_list(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("l=[]\nl.copy()", (3, 0)),
("[].copy()", (3, 0)),
("l=list()\nl.copy()", (3, 0)),
("list().copy()", (3, 0)),
])
def test_copy_of_list(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.decode()", (2, 2)),
("\"\".decode()", (2, 2)),
("s=str()\ns.decode()", (2, 2)),
("str().decode()", (2, 2)),
])
def test_decode_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.encode()", ((2, 0), (3, 0))),
("\"\".encode()", ((2, 0), (3, 0))),
("s=str()\ns.encode()", ((2, 0), (3, 0))),
("str().encode()", ((2, 0), (3, 0))),
])
def test_encode_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.casefold()", (3, 3)),
("\"\".casefold()", (3, 3)),
("s=str()\ns.casefold()", (3, 3)),
("str().casefold()", (3, 3)),
])
def test_casefold_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.format()", ((2, 6), (3, 0))),
("\"\".format()", ((2, 6), (3, 0))),
("s=str()\ns.format()", ((2, 6), (3, 0))),
("str().format()", ((2, 6), (3, 0))),
])
def test_format_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.format_map()", (3, 2)),
("\"\".format_map()", (3, 2)),
("s=str()\ns.format_map()", (3, 2)),
("str().format_map()", (3, 2)),
])
def test_format_map_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.isascii()", (3, 7)),
("\"\".isascii()", (3, 7)),
("s=str()\ns.isascii()", (3, 7)),
("str().isascii()", (3, 7)),
])
def test_isascii_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.isidentifier()", (3, 0)),
("\"\".isidentifier()", (3, 0)),
("s=str()\ns.isidentifier()", (3, 0)),
("str().isidentifier()", (3, 0)),
])
def test_isidentifier_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.isprintable()", (3, 0)),
("\"\".isprintable()", (3, 0)),
("s=str()\ns.isprintable()", (3, 0)),
("str().isprintable()", (3, 0)),
])
def test_isprintable_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.isdecimal()", (3, 0)),
("\"\".isdecimal()", (3, 0)),
("s=str()\ns.isdecimal()", (3, 0)),
("str().isdecimal()", (3, 0)),
])
def test_isdecimal_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.isnumeric()", (3, 0)),
("\"\".isnumeric()", (3, 0)),
("s=str()\ns.isnumeric()", (3, 0)),
("str().isnumeric()", (3, 0)),
])
def test_isnumeric_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.maketrans()", (3, 0)),
("\"\".maketrans()", (3, 0)),
("s=str()\ns.maketrans()", (3, 0)),
("str().maketrans()", (3, 0)),
])
def test_maketrans_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.removeprefix()", (3, 9)),
("\"\".removeprefix()", (3, 9)),
("s=str()\ns.removeprefix()", (3, 9)),
("str().removeprefix()", (3, 9)),
])
def test_removeprefix_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.removesuffix()", (3, 9)),
("\"\".removesuffix()", (3, 9)),
("s=str()\ns.removesuffix()", (3, 9)),
("str().removesuffix()", (3, 9)),
])
def test_removesuffix_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.partition('a')", ((2, 5), (3, 0))),
("\"\".partition('a')", ((2, 5), (3, 0))),
("s=str()\ns.partition('a')", ((2, 5), (3, 0))),
("str().partition('a')", ((2, 5), (3, 0))),
])
def test_partition_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.rpartition('a')", ((2, 5), (3, 0))),
("\"\".rpartition('a')", ((2, 5), (3, 0))),
("s=str()\ns.rpartition('a')", ((2, 5), (3, 0))),
("str().rpartition('a')", ((2, 5), (3, 0))),
])
def test_rpartition_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.rsplit('a')", ((2, 4), (3, 0))),
("\"\".rsplit('a')", ((2, 4), (3, 0))),
("s=str()\ns.rsplit('a')", ((2, 4), (3, 0))),
("str().rsplit('a')", ((2, 4), (3, 0))),
])
def test_rsplit_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("s=\"\"\ns.zfill(2)", ((2, 2), (3, 0))),
("\"\".zfill(2)", ((2, 2), (3, 0))),
("s=str()\ns.zfill(2)", ((2, 2), (3, 0))),
("str().zfill(2)", ((2, 2), (3, 0))),
])
def test_zfill_of_str(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
def test_as_integer_ratio_of_int(self):
self.assertOnlyIn((3, 8), self.detect("(42).as_integer_ratio()"))
self.assertOnlyIn((3, 8), self.detect("n=42\nn.as_integer_ratio()"))
def test_bit_length_of_int(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("(42).bit_length()"))
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("n=42\nn.bit_length()"))
def test_bit_count_of_int(self):
self.assertOnlyIn((3, 10), self.detect("(42).bit_count()"))
self.assertOnlyIn((3, 10), self.detect("n=42\nn.bit_count()"))
def test_is_integer_of_int(self):
self.assertOnlyIn((3, 12), self.detect("(42).is_integer()"))
self.assertOnlyIn((3, 12), self.detect("n=42\nn.is_integer()"))
def test_to_bytes_of_int(self):
self.assertOnlyIn((3, 2), self.detect("(42).to_bytes()"))
self.assertOnlyIn((3, 2), self.detect("n=42\nn.to_bytes()"))
def test_from_bytes_of_int(self):
self.assertOnlyIn((3, 2), self.detect("int.from_bytes([42])"))
def test_as_integer_ratio_of_float(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("(42.0).as_integer_ratio()"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("n=42.0\nn.as_integer_ratio()"))
def test_next_of_file(self):
self.assertOnlyIn((2, 3), self.detect("file('name').next()"))
def test_xreadlines_of_file(self):
self.assertOnlyIn((2, 1), self.detect("file('name').xreadlines()"))
def test_is_integer_of_float(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("(42.0).is_integer()"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("n=42.0\nn.is_integer()"))
def test_hex_of_float(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("(42.0).hex()"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("n=42.0\nn.hex()"))
def test_fromhex_of_float(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("(42.0).fromhex()"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("n=42.0\nn.fromhex()"))
def test_hex_of_bytes(self):
self.assertOnlyIn((3, 5), self.detect("b'\x10'.hex()"))
self.assertOnlyIn((3, 5), self.detect("b=b'\x10'\nb.hex()"))
def test_isascii_of_bytes(self):
self.assertOnlyIn((3, 7), self.detect("b'\x10'.isascii()"))
self.assertOnlyIn((3, 7), self.detect("b=b'\x10'\nb.isascii()"))
def test_maketrans_of_bytes(self):
self.assertOnlyIn((3, 1), self.detect("bytes.maketrans(b'a', b'b')"))
def test_removeprefix_of_bytes(self):
self.assertOnlyIn((3, 9), self.detect("bytes.removeprefix(b'a')"))
def test_removesuffix_of_bytes(self):
self.assertOnlyIn((3, 9), self.detect("bytes.removesuffix(b'a')"))
def test_hex_of_bytearray(self):
self.assertOnlyIn((3, 5), self.detect("bytearray(b'\x10').hex()"))
self.assertOnlyIn((3, 5), self.detect("b=bytearray(b'\x10')\nb.hex()"))
def test_isascii_of_bytearray(self):
self.assertOnlyIn((3, 7), self.detect("bytearray(b'\x10').isascii()"))
self.assertOnlyIn((3, 7), self.detect("b=bytearray(b'\x10')\nb.isascii()"))
def test_maketrans_of_bytearray(self):
self.assertOnlyIn((3, 1), self.detect("bytearray.maketrans(b'a', b'b')"))
def test_removeprefix_of_bytearray(self):
self.assertOnlyIn((3, 9), self.detect("bytearray.removeprefix(b'a')"))
def test_removesuffix_of_bytearray(self):
self.assertOnlyIn((3, 9), self.detect("bytearray.removesuffix(b'a')"))
def test_hex_of_memoryview(self):
self.assertOnlyIn((3, 5), self.detect("memoryview(b'1').hex()"))
def test_release_of_memoryview(self):
self.assertOnlyIn((3, 2), self.detect("memoryview(b'1').release()"))
def test_cast_of_memoryview(self):
self.assertOnlyIn((3, 3), self.detect("memoryview(b'1').cast()"))
def test_toreadonly_of_memoryview(self):
self.assertOnlyIn((3, 8), self.detect("memoryview(b'1').toreadonly()"))
def test_deleter_of_property(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("property.deleter()"))
def test_getter_of_property(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("property.getter()"))
def test_setter_of_property(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("property.setter()"))
def test_indices_of_slice(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("slice.indices()"))
def test_aiter(self):
self.assertOnlyIn((3, 10), self.detect("aiter()"))
def test_anext(self):
self.assertOnlyIn((3, 10), self.detect("anext()"))
def test_zip(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("zip()"))
netromdk-vermin-d650a48/tests/bytes_directive.py 0000664 0000000 0000000 00000000522 15265463462 0022104 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminBytesDirectiveTests(VerminTest):
def test_b_directive(self):
self.assertOnlyIn((3, 5), self.detect("b'%b'"))
def test_a_directive(self):
self.assertOnlyIn((3, 5), self.detect("b'%a'"))
def test_r_directive(self):
self.assertOnlyIn(((2, 7), (3, 5)), self.detect("b'%r'"))
netromdk-vermin-d650a48/tests/class.py 0000664 0000000 0000000 00000076300 15265463462 0020034 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminClassMemberTests(VerminTest):
def test_ConfigParser_of_ConfigParser(self):
self.assertOnlyIn((2, 3), self.detect("from ConfigParser import ConfigParser"))
def test_RawConfigParser_of_ConfigParser(self):
self.assertOnlyIn((2, 3), self.detect("from ConfigParser import RawConfigParser"))
def test_SafeConfigParser_of_ConfigParser(self):
self.assertOnlyIn((2, 3), self.detect("from ConfigParser import SafeConfigParser"))
def test_ExtendedInterpolation_of_configparser(self):
self.assertOnlyIn((3, 2), self.detect("from configparser import ExtendedInterpolation"))
def test_LifoQueue_of_Queue(self):
self.assertOnlyIn((2, 6), self.detect("from Queue import LifoQueue"))
def test_PriorityQueue_of_Queue(self):
self.assertOnlyIn((2, 6), self.detect("from Queue import PriorityQueue"))
def test_ABC_of_abc(self):
self.assertOnlyIn((3, 4), self.detect("from abc import ABC"))
def test_Format_of_annotationlib(self):
self.assertOnlyIn((3, 14), self.detect("from annotationlib import Format"))
def test_BooleanOptionalAction_of_argparse(self):
self.assertOnlyIn((3, 9), self.detect("from argparse import BooleanOptionalAction"))
def test_Constant_of_ast(self):
self.assertOnlyIn((3, 6), self.detect("from ast import Constant"))
def test_Barrier_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("from asyncio import Barrier"))
def test_BufferedProtocol_of_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("from asyncio import BufferedProtocol"))
def test_MultiLoopChildWatcher_of_asyncio(self):
self.assertOnlyIn((3, 8), self.detect("from asyncio import MultiLoopChildWatcher"))
def test_ThreadedChildWatcher_of_asyncio(self):
self.assertOnlyIn((3, 8), self.detect("from asyncio import ThreadedChildWatcher"))
def test_PidfdChildWatcher_of_asyncio(self):
self.assertOnlyIn((3, 9), self.detect("from asyncio import PidfdChildWatcher"))
def test_Runner_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("from asyncio import Runner"))
def test_TaskGroup_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("from asyncio import TaskGroup"))
def test_Calendar_of_calendar(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from calendar import Calendar"))
def test_Day_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import Day"))
def test_HTMLCalendar_of_calendar(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from calendar import HTMLCalendar"))
def test_LocaleHTMLCalendar_of_calendar(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from calendar import LocaleHTMLCalendar"))
def test_LocaleTextCalendar_of_calendar(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from calendar import LocaleTextCalendar"))
def test_Month_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import Month"))
def test_TextCalendar_of_calendar(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from calendar import TextCalendar"))
def test_IncrementalEncoder_of_codecs(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from codecs import IncrementalEncoder"))
def test_NNTP_SSL_of_nntplib(self):
self.assertOnlyIn((3, 2), self.detect("from nntplib import NNTP_SSL"))
def test_DirEntry_of_os(self):
self.assertOnlyIn((3, 5), self.detect("from os import DirEntry"))
def test_PathLike_of_os(self):
self.assertOnlyIn((3, 6), self.detect("from os import PathLike"))
def test_sched_param_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import sched_param"))
def test_terminal_size_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import terminal_size"))
def test_PickleBuffer_of_pickle(self):
self.assertOnlyIn((3, 8), self.detect("from pickle import PickleBuffer"))
def test_Popen4_of_popen2(self):
self.assertOnlyIn((2, 0), self.detect("from popen2 import Popen4"))
def test_POP3_SSL_of_poplib(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from poplib import POP3_SSL"))
def test_Stats_of_pstats(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from pstats import Stats"))
def test_PycInvalidationMode_of_py_compile(self):
self.assertOnlyIn((3, 7), self.detect("from py_compile import PycInvalidationMode"))
def test_SimpleQueue_of_queue(self):
self.assertOnlyIn((3, 7), self.detect("from queue import SimpleQueue"))
def test_SystemRandom_of_random(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from random import SystemRandom"))
def test_DevpollSelector_of_selectors(self):
self.assertOnlyIn((3, 5), self.detect("from selectors import DevpollSelector"))
def test_Handlers_of_signals(self):
self.assertOnlyIn((3, 5), self.detect("from signals import Handlers"))
def test_Sigmasks_of_signals(self):
self.assertOnlyIn((3, 5), self.detect("from signals import Sigmasks"))
def test_Signals_of_signals(self):
self.assertOnlyIn((3, 5), self.detect("from signals import Signals"))
def test_StartupState_from_site(self):
self.assertOnlyIn((3, 15), self.detect("from site import StartupState"))
def test_Barrier_of_multiprocessing(self):
self.assertOnlyIn((3, 3), self.detect("from multiprocessing import Barrier"))
def test_IsolatedAsyncioTestCase_of_unittest(self):
self.assertOnlyIn((3, 8), self.detect("from unittest import IsolatedAsyncioTestCase"))
def test_TextTestResult_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from unittest import TextTestResult"))
def test_AsyncMock_of_unittest_mock(self):
self.assertOnlyIn((3, 8), self.detect("from unittest.mock import AsyncMock"))
self.assertTrue(self.config.add_backport("mock"))
self.assertOnlyIn(((3, 6)), self.detect("from unittest.mock import AsyncMock"))
def test_DefragResult_of_urllib_parse(self):
self.assertOnlyIn((3, 2), self.detect("from urllib.parse import DefragResult"))
def test_DefragResultBytes_of_urllib_parse(self):
self.assertOnlyIn((3, 2), self.detect("from urllib.parse import DefragResultBytes"))
def test_ParseResultBytes_of_urllib_parse(self):
self.assertOnlyIn((3, 2), self.detect("from urllib.parse import ParseResultBytes"))
def test_SplitResultBytes_of_urllib_parse(self):
self.assertOnlyIn((3, 2), self.detect("from urllib.parse import SplitResultBytes"))
def test_DataHandler_of_urllib_request(self):
self.assertOnlyIn((3, 4), self.detect("from urllib.request import DataHandler"))
def test_HTTPPasswordMgrWithPriorAuth_of_urllib_request(self):
self.assertOnlyIn((3, 5), self.detect(
"from urllib.request import HTTPPasswordMgrWithPriorAuth"))
def test_HTTPCookieProcessor_of_urllib2(self):
self.assertOnlyIn((2, 4), self.detect("from urllib2 import HTTPCookieProcessor"))
def test_HTTPErrorProcessor_of_urllib2(self):
self.assertOnlyIn((2, 4), self.detect("from urllib2 import HTTPErrorProcessor"))
def test_SafeUUID_of_uuid(self):
self.assertOnlyIn((3, 7), self.detect("from uuid import SafeUUID"))
def test_timezone_of_datetime(self):
self.assertOnlyIn((3, 2), self.detect("from datetime import timezone"))
def test_Collection_of_typing(self):
self.assertOnlyIn((3, 6), self.detect("from typing import Collection"))
def test_ContextManager_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import ContextManager"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from typing import ContextManager"))
def test_Coroutine_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import Coroutine"))
def test_Counter_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import Counter"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from typing import Counter"))
def test_Deque_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import Deque"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from typing import Deque"))
def test_ForwardRef_of_typing(self):
self.assertOnlyIn((3, 7), self.detect("from typing import ForwardRef"))
def test_NamedTuple_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import NamedTuple"))
def test_OrderedDict_of_typing(self):
self.assertOnlyIn((3, 7), self.detect("from typing import OrderedDict"))
def test_AsyncContextManager_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import AsyncContextManager"))
def test_ChainMap_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import ChainMap"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn((3, 3), self.detect("from typing import ChainMap"))
def test_AsyncGenerator_of_typing(self):
self.assertOnlyIn((3, 6), self.detect("from typing import AsyncGenerator"))
def test_Protocol_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import Protocol"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import Protocol"))
def test_SupportsBytes_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import SupportsBytes"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn((3, 2), self.detect("from typing import SupportsBytes"))
def test_SupportsIndex_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import SupportsIndex"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from typing import SupportsIndex"))
def test_SupportsRound_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import SupportsRound"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn((3, 2), self.detect("from typing import SupportsRound"))
def test_Awaitable_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import Awaitable"))
def test_AsyncIterable_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import AsyncIterable"))
def test_AsyncIterator_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import AsyncIterator"))
def test_CapsuleType_of_types(self):
self.assertOnlyIn((3, 13), self.detect("from types import CapsuleType"))
def test_GenericAlias_of_types(self):
self.assertOnlyIn((3, 9), self.detect("from types import GenericAlias"))
def test_MappingProxyType_of_types(self):
self.assertOnlyIn((3, 3), self.detect("from types import MappingProxyType"))
def test_SimpleNamespace_of_types(self):
self.assertOnlyIn((3, 3), self.detect("from types import SimpleNamespace"))
def test_DomainFilter_of_tracemalloc(self):
self.assertOnlyIn((3, 6), self.detect("from tracemalloc import DomainFilter"))
def test_Counter_of_collections(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from collections import Counter"))
def test_deque_of_collections(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from collections import deque"))
def test_defaultdict_of_collections(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from collections import defaultdict"))
def test_namedtuple_of_collections(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from collections import namedtuple"))
def test_InterpreterPoolExecutor_of_concurrent_futures(self):
self.assertOnlyIn((3, 14), self.detect("""
from concurrent.futures import InterpreterPoolExecutor
"""))
def test_OrderedDict_of_collections(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from collections import OrderedDict"))
def test_UserDict_of_collections(self):
self.assertOnlyIn((3, 0), self.detect("from collections import UserDict"))
def test_UserList_of_collections(self):
self.assertOnlyIn((3, 0), self.detect("from collections import UserList"))
def test_UserString_of_collections(self):
self.assertOnlyIn((3, 0), self.detect("from collections import UserString"))
def test_ChainMap_of_collections(self):
self.assertOnlyIn((3, 3), self.detect("from collections import ChainMap"))
def test_Collection_of_collections_abc(self):
self.assertOnlyIn((3, 6), self.detect("from collections.abc import Collection"))
def test_Reversible_of_collections_abc(self):
self.assertOnlyIn((3, 6), self.detect("from collections.abc import Reversible"))
def test_Generator_of_collections_abc(self):
self.assertOnlyIn((3, 5), self.detect("from collections.abc import Generator"))
def test_Coroutine_of_collections_abc(self):
self.assertOnlyIn((3, 5), self.detect("from collections.abc import Coroutine"))
def test_AsyncIterable_of_collections_abc(self):
self.assertOnlyIn((3, 5), self.detect("from collections.abc import AsyncIterable"))
def test_AsyncIterator_of_collections_abc(self):
self.assertOnlyIn((3, 5), self.detect("from collections.abc import AsyncIterator"))
def test_AsyncGenerator_of_collections_abc(self):
self.assertOnlyIn((3, 6), self.detect("from collections.abc import AsyncGenerator"))
def test_Buffer_of_collections_abc(self):
self.assertOnlyIn((3, 12), self.detect("from collections.abc import Buffer"))
def test_AbstractContextManager_of_contextlib(self):
self.assertOnlyIn((3, 6), self.detect("from contextlib import AbstractContextManager"))
def test_AbstractAsyncContextManager_of_contextlib(self):
self.assertOnlyIn((3, 7), self.detect("from contextlib import AbstractAsyncContextManager"))
def test_ContextDecorator_of_contextlib(self):
self.assertOnlyIn((3, 2), self.detect("from contextlib import ContextDecorator"))
def test_ExitStack_of_contextlib(self):
self.assertOnlyIn((3, 3), self.detect("from contextlib import ExitStack"))
def test_AsyncExitStack_of_contextlib(self):
self.assertOnlyIn((3, 7), self.detect("from contextlib import AsyncExitStack"))
def test_AsyncContextDecorator_of_contextlib(self):
self.assertOnlyIn((3, 10), self.detect("from contextlib import AsyncContextDecorator"))
def test_unix_dialect_of_csv(self):
self.assertOnlyIn((3, 2), self.detect("from csv import unix_dialect"))
def test_c_double_complex_of_ctypes(self):
self.assertOnlyIn((3, 14), self.detect("from ctypes import c_double_complex"))
def test_c_float_complex_of_ctypes(self):
self.assertOnlyIn((3, 14), self.detect("from ctypes import c_float_complex"))
def test_c_longdouble_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from ctypes import c_longdouble"))
def test_c_longdouble_complex_of_ctypes(self):
self.assertOnlyIn((3, 14), self.detect("from ctypes import c_longdouble_complex"))
def test_c_bool_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from ctypes import c_bool"))
def test_c_ssize_t_of_ctypes(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ctypes import c_ssize_t"))
def test_BigEndianUnion_of_ctypes(self):
self.assertOnlyIn((3, 11), self.detect("from ctypes import BigEndianUnion"))
def test_LittleEndianUnion_of_ctypes(self):
self.assertOnlyIn((3, 11), self.detect("from ctypes import LittleEndianUnion"))
def test_HtmlDiff_of_difflib(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from difflib import HtmlDiff"))
def test_Signature_of_inspect(self):
self.assertOnlyIn((3, 3), self.detect("from inspect import Signature"))
def test_Reader_of_io(self):
self.assertOnlyIn((3, 14), self.detect("from io import Reader"))
def test_Writer_of_io(self):
self.assertOnlyIn((3, 14), self.detect("from io import Writer"))
def test_Parameter_of_inspect(self):
self.assertOnlyIn((3, 3), self.detect("from inspect import Parameter"))
def test_BoundArguments_of_inspect(self):
self.assertOnlyIn((3, 3), self.detect("from inspect import BoundArguments"))
def test_BufferFlags_of_inspect(self):
self.assertOnlyIn((3, 12), self.detect("from inspect import BufferFlags"))
def test_LoggerAdapter_of_logging(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from logging import LoggerAdapter"))
def test_NullHandler_of_logging(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from logging import NullHandler"))
def test_StreamHandler_of_logging(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from logging import StreamHandler"))
def test_QueueHandler_of_logging_handlers(self):
self.assertOnlyIn((3, 2), self.detect("from logging.handlers import QueueHandler"))
def test_QueueListener_of_logging_handlers(self):
self.assertOnlyIn((3, 2), self.detect("from logging.handlers import QueueListener"))
def test_WatchedFileHandler_of_logging_handlers(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from logging.handlers import WatchedFileHandler"))
def test_ModuleInfo_of_pkgutil(self):
self.assertOnlyIn((3, 6), self.detect("from pkgutil import ModuleInfo"))
def test_CGIXMLRPCRequestHandler_of_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 3), self.detect("from SimpleXMLRPCServer import CGIXMLRPCRequestHandler"))
def test_MemoryBIO_of_ssl(self):
self.assertOnlyIn((3, 5), self.detect("from ssl import MemoryBIO"))
def test_Options_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import Options"))
def test_SSLContext_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import SSLContext"))
def test_SSLSession_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import SSLSession"))
def test_SSLObject_of_ssl(self):
self.assertOnlyIn((3, 5), self.detect("from ssl import SSLObject"))
def test_AlertDescription_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import AlertDescription"))
def test_SSLErrorNumber_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import SSLErrorNumber"))
def test_TLSVersion_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import TLSVersion"))
def test_VerifyFlags_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import VerifyFlags"))
def test_VerifyMode_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import VerifyMode"))
def test_Formatter_of_string(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from string import Formatter"))
def test_Template_of_string(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from string import Template"))
def test_Interpolation_of_string_templatelib(self):
self.assertOnlyIn((3, 14), self.detect("from string.templatelib import Interpolation"))
def test_Template_of_string_templatelib(self):
self.assertOnlyIn((3, 14), self.detect("from string.templatelib import Template"))
def test_Struct_of_struct(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from struct import Struct"))
def test_CompletedProcess_of_subprocess(self):
self.assertOnlyIn((3, 5), self.detect("from subprocess import CompletedProcess"))
def test_EnvironmentVarGuard_of_test_support(self):
self.assertOnlyIn((2, 6), self.detect("from test.support import EnvironmentVarGuard"))
def test_TransientResource_of_test_support(self):
self.assertOnlyIn((2, 6), self.detect("from test.support import TransientResource"))
def test_WarningsRecorder_of_test_support(self):
self.assertOnlyIn((2, 6), self.detect("from test.support import WarningsRecorder"))
def test_EnvironmentVarGuard_of_test_support_os_helper(self):
self.assertOnlyIn((3, 10),
self.detect("from test.support.os_helper import EnvironmentVarGuard"))
def test_TransientResource_of_test_support_socket_helper(self):
self.assertOnlyIn((3, 9),
self.detect("from test.support.socket_helper import TransientResource"))
def test_WarningsRecorder_of_test_support_warnings_helper(self):
self.assertOnlyIn((3, 10),
self.detect("from test.support.warnings_helper import WarningsRecorder"))
def test_Barrier_of_threading(self):
self.assertOnlyIn((3, 2), self.detect("from threading import Barrier"))
def test_local_of_threading(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from threading import local"))
def test_ttk_of_tkinter(self):
self.assertOnlyIn((3, 1), self.detect("from tkinter import ttk"))
def test_struct_time_of_time(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from time import struct_time"))
def test_FrameSummary_of_traceback(self):
self.assertOnlyIn((3, 5), self.detect("from traceback import FrameSummary"))
def test_StackSummary_of_traceback(self):
self.assertOnlyIn((3, 5), self.detect("from traceback import StackSummary"))
def test_TracebackException_of_traceback(self):
self.assertOnlyIn((3, 5), self.detect("from traceback import TracebackException"))
def test_catch_warnings_of_warnings(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from warnings import catch_warnings"))
def test_WeakSet_of_weakref(self):
self.assertOnlyIn(((2, 7), (3, 0)), self.detect("from weakref import WeakSet"))
def test_WeakMethod_of_weakref(self):
self.assertOnlyIn((3, 4), self.detect("from weakref import WeakMethod"))
def test_finalize_of_weakref(self):
self.assertOnlyIn((3, 4), self.detect("from weakref import finalize"))
def test_IISCGIHandler_of_wsgiref_handlers(self):
self.assertOnlyIn((3, 2), self.detect("from wsgiref.handlers import IISCGIHandler"))
def test_C14NWriterTarget_of_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8), self.detect("from xml.etree.ElementTree import C14NWriterTarget"))
def test_XMLPullParser_of_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 4), self.detect("from xml.etree.ElementTree import XMLPullParser"))
def test_LexicalHandler_of_xml_sax_handler(self):
self.assertOnlyIn((3, 10), self.detect("from xml.sax.handler import LexicalHandler"))
def test_MultiCall_of_xmlrpclib(self):
self.assertOnlyIn((2, 4), self.detect("from xmlrpclib import MultiCall"))
def test_MIMENonMultipart_of_email_mime_nonmultipart(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.mime.nonmultipart import MIMENonMultipart"))
def test_MIMEMultipart_of_email_mime_multipart(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect(
"from email.mime.multipart import MIMEMultipart"))
def test_MIMEApplication_of_email_mime_application(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from email.mime.application import MIMEApplication"))
def test_FeedParser_of_email_parser(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from email.parser import FeedParser"))
def test_BytesFeedParser_of_email_parser(self):
self.assertOnlyIn((3, 2), self.detect("from email.parser import BytesFeedParser"))
def test_BytesParser_of_email_parser(self):
self.assertOnlyIn((3, 2), self.detect("from email.parser import BytesParser"))
def test_BytesHeaderParser_of_email_parser(self):
self.assertOnlyIn((3, 3), self.detect("from email.parser import BytesHeaderParser"))
def test_EmailPolicy_of_email_policy(self):
self.assertOnlyIn((3, 3), self.detect("from email.policy import EmailPolicy"))
def test_DecodedGenerator_of_email_generator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from email.generator import DecodedGenerator"))
def test_BytesGenerator_of_email_generator(self):
self.assertOnlyIn((3, 2), self.detect("from email.generator import BytesGenerator"))
def test_EnumCheck_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import EnumCheck"))
def test_EnumDict_of_enum(self):
self.assertOnlyIn((3, 13), self.detect("from enum import EnumDict"))
def test_EnumType_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import EnumType"))
def test_Flag_of_enum(self):
self.assertOnlyIn((3, 6), self.detect("from enum import Flag"))
def test_FlagBoundary_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import FlagBoundary"))
def test_IntFlag_of_enum(self):
self.assertOnlyIn((3, 6), self.detect("from enum import IntFlag"))
def test_ReprEnum_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import ReprEnum"))
def test_StrEnum_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import StrEnum"))
def test_auto_of_enum(self):
self.assertOnlyIn((3, 6), self.detect("from enum import auto"))
def test_FTP_TLS_of_ftplib(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ftplib import FTP_TLS"))
def test_partialmethod_of_functools(self):
self.assertOnlyIn((3, 4), self.detect("from functools import partialmethod"))
def test_HTTPMethod_of_http(self):
self.assertOnlyIn((3, 11), self.detect("from http import HTTPMethod"))
def test_HTTPStatus_of_http(self):
self.assertOnlyIn((3, 5), self.detect("from http import HTTPStatus"))
def test_ThreadingHTTPServer_of_http_server(self):
self.assertOnlyIn((3, 7), self.detect("from http.server import ThreadingHTTPServer"))
def test_ThreadingHTTPSServer_of_http_server(self):
self.assertOnlyIn((3, 14), self.detect("from http.server import ThreadingHTTPSServer"))
def test_HTTPSServer_of_http_server(self):
self.assertOnlyIn((3, 14), self.detect("from http.server import HTTPSServer"))
def test_HTTPConnection_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import HTTPConnection"))
def test_HTTPResponse_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import HTTPResponse"))
def test_HTTPSConnection_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import HTTPSConnection"))
def test_IMAP4_stream_of_imaplib(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from imaplib import IMAP4_stream"))
def test_NullImporter_of_imp(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from imp import NullImporter"))
def test_FileLoader_of_importlib_abc(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.abc import FileLoader"))
def test_MetaPathFinder_of_importlib_abc(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.abc import MetaPathFinder"))
def test_PathEntryFinder_of_importlib_abc(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.abc import PathEntryFinder"))
def test_ResourceReader_of_importlib_abc(self):
self.assertOnlyIn((3, 7), self.detect("from importlib.abc import ResourceReader"))
def test_Traversable_of_importlib_abc(self):
self.assertOnlyIn((3, 9), self.detect("from importlib.abc import Traversable"))
def test_TraversableReader_of_importlib_abc(self):
self.assertOnlyIn((3, 9), self.detect("from importlib.abc import TraversableReader"))
def test_TraversableResources_of_importlib_abc(self):
self.assertOnlyIn((3, 9), self.detect("from importlib.abc import TraversableResources"))
def test_WindowsRegistryFinder_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.machinery import WindowsRegistryFinder"))
def test_FileFinder_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.machinery import FileFinder"))
def test_SourceFileLoader_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.machinery import SourceFileLoader"))
def test_SourcelessFileLoader_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.machinery import SourcelessFileLoader"))
def test_ExtensionFileLoader_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect("from importlib.machinery import ExtensionFileLoader"))
def test_ModuleSpec_of_importlib_machinery(self):
self.assertOnlyIn((3, 4), self.detect("from importlib.machinery import ModuleSpec"))
def test_NamespaceLoader_of_importlib_machinery(self):
self.assertOnlyIn((3, 11), self.detect("from importlib.machinery import NamespaceLoader"))
def test_EntryPoints_of_importlib_metadata(self):
self.assertOnlyIn((3, 10), self.detect("from importlib.metadata import EntryPoints"))
def test_MetadataNotFound_of_importlib_metadata(self):
self.assertOnlyIn((3, 15), self.detect("from importlib.metadata import MetadataNotFound"))
def test_LazyLoader_of_importlib_util(self):
self.assertOnlyIn((3, 5), self.detect("from importlib.util import LazyLoader"))
def test_Bytecode_of_dis(self):
self.assertOnlyIn((3, 4), self.detect("from dis import Bytecode"))
def test_Instruction_of_dis(self):
self.assertOnlyIn((3, 4), self.detect("from dis import Instruction"))
def test_Positions_of_dis(self):
self.assertOnlyIn((3, 11), self.detect("from dis import Positions"))
def test_DocTest_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import DocTest"))
def test_DocTestFinder_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import DocTestFinder"))
def test_DocTestParser_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import DocTestParser"))
def test_DocTestRunner_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import DocTestRunner"))
def test_Example_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import Example"))
def test_OutputChecker_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import OutputChecker"))
def test_UID_of_plistlib(self):
self.assertOnlyIn((3, 8), self.detect("from plistlib import UID"))
def test_NormalDist_of_statistics(self):
self.assertOnlyIn((3, 8), self.detect("from statistics import NormalDist"))
def test_NoDefault_of_typing(self):
self.assertOnlyIn((3, 13), self.detect("from typing import NoDefault"))
def test_ReadOnly_of_typing(self):
self.assertOnlyIn((3, 13), self.detect("from typing import ReadOnly"))
def test_TypeIs_of_typing(self):
self.assertOnlyIn((3, 13), self.detect("from typing import TypeIs"))
def test_TypedDict_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import TypedDict"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import TypedDict"))
def test_ParamSpec_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import ParamSpec"))
def test_TypeAliasType_of_typing(self):
self.assertOnlyIn((3, 12), self.detect("from typing import TypeAliasType"))
def test_SMTP_SSL_of_smtplib(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from smtplib import SMTP_SSL"))
def test_Blob_of_sqlite3(self):
self.assertOnlyIn((3, 11), self.detect("from sqlite3 import Blob"))
def test_LMTP_of_smtplib(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from smtplib import LMTP"))
def test_Path_of_zipfile(self):
self.assertOnlyIn((3, 8), self.detect("from zipfile import Path"))
def test_zipimporter_of_zipimport(self):
self.assertOnlyIn(((2, 7), (3, 0)), self.detect("from zipimport import zipimporter"))
def test_FunctionProfile_of_pstats(self):
self.assertOnlyIn((3, 9), self.detect("from pstats import FunctionProfile"))
def test_StatsProfile_of_pstats(self):
self.assertOnlyIn((3, 9), self.detect("from pstats import StatsProfile"))
netromdk-vermin-d650a48/tests/codecs_encodings.py 0000664 0000000 0000000 00000016542 15265463462 0022222 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminCodecsEncodingTests(VerminTest):
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'cp273')", (3, 4)),
("import codecs\ncodecs.encode('test', '273')", (3, 4)),
("import codecs\ncodecs.encode('test', 'ibm273')", (3, 4)),
("import codecs\ncodecs.encode('test', 'csibm273')", (3, 4)),
])
def test_encoding_german(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'cp1125')", (3, 4)),
("import codecs\ncodecs.encode('test', '1125')", (3, 4)),
("import codecs\ncodecs.encode('test', 'ibm1125')", (3, 4)),
("import codecs\ncodecs.encode('test', 'cp866u')", (3, 4)),
("import codecs\ncodecs.encode('test', 'ruscii')", (3, 4)),
])
def test_encoding_ukrainian(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
def test_encoding_windows_cp_utf8(self):
self.assertOnlyIn((3, 3), self.detect("import codecs\ncodecs.encode('test', 'cp65001')"))
def test_encoding_tajik(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.encode('test', 'koi8_t')"))
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'kz1048')", (3, 5)),
("import codecs\ncodecs.encode('test', 'kz_1048')", (3, 5)),
("import codecs\ncodecs.encode('test', 'strk1048_2002')", (3, 5)),
("import codecs\ncodecs.encode('test', 'kz-1048')", (3, 5)),
("import codecs\ncodecs.encode('test', 'strk1048-2002')", (3, 5)),
("import codecs\ncodecs.encode('test', 'rk1048')", (3, 5)),
])
def test_encoding_kazakh(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
def test_encoding_windows_owm(self):
self.assertOnlyIn((3, 6), self.detect("import codecs\ncodecs.encode('test', 'oem')"))
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'base64_codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'base64-codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'base64')", (3, 4)),
("import codecs\ncodecs.encode('test', 'base_64')", (3, 4)),
("import codecs\ncodecs.encode('test', 'base-64')", (3, 4)),
])
def test_encoding_base64(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'bz2_codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'bz2-codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'bz2')", (3, 4)),
])
def test_encoding_bz2(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'hex_codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'hex-codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'hex')", (3, 4)),
])
def test_encoding_hex(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'quopri_codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'quopri-codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'quopri')", (3, 4)),
("import codecs\ncodecs.encode('test', 'quotedprintable')", (3, 4)),
("""import codecs
codecs.encode('test', 'quoted_printable')
""", (3, 4)),
("""import codecs
codecs.encode('test', 'quoted-printable')
""", (3, 4)),
])
def test_encoding_quopri(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'uu_codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'uu-codec')", (3, 2)),
("import codecs\ncodecs.encode('test', 'uu')", (3, 4)),
])
def test_encoding_uu(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'zip')", (3, 4)),
("import codecs\ncodecs.encode('test', 'zlib')", (3, 4)),
])
def test_encoding_zip(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("import codecs\ncodecs.encode('test', 'rot_13')", (3, 2)),
("import codecs\ncodecs.encode('test', 'rot-13')", (3, 2)),
("import codecs\ncodecs.encode('test', 'rot13')", (3, 4)),
])
def test_encoding_rot13(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
def test_function_encode(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.encode('test', 'koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("""import codecs
codecs.encode('test', encoding='koi8_t')
"""))
def test_function_decode(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.decode('test', 'koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("""import codecs
codecs.decode('test', encoding='koi8_t')
"""))
def test_function_lookup(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.lookup('koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.lookup(encoding='koi8_t')"))
def test_function_getencoder(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getencoder('koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getencoder(encoding='koi8_t')"))
def test_function_getdecoder(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getdecoder('koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getdecoder(encoding='koi8_t')"))
def test_function_getincrementalencoder(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getincrementalencoder('koi8_t')"))
self.assertOnlyIn((3, 5),
self.detect("import codecs\ncodecs.getincrementalencoder(encoding='koi8_t')"))
def test_function_getincrementaldecoder(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getincrementaldecoder('koi8_t')"))
self.assertOnlyIn((3, 5),
self.detect("import codecs\ncodecs.getincrementaldecoder(encoding='koi8_t')"))
def test_function_getreader(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getreader('koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getreader(encoding='koi8_t')"))
def test_function_getwriter(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getwriter('koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.getwriter(encoding='koi8_t')"))
def test_function_open(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.open('f.txt', 'r', 'koi8_t')"))
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.open('f.txt', encoding='koi8_t')"))
@VerminTest.parameterized_args([
("import codecs\ncodecs.EncodedFile('f.txt', 'koi8_t')", (3, 5)),
("""import codecs
codecs.EncodedFile('f.txt', data_encoding='koi8_t')
""", (3, 5)),
("""import codecs
codecs.EncodedFile('f.txt', 'utf-8', file_encoding='koi8_t')
""", (3, 5)),
("""from codecs import EncodedFile as EF
EF('f.txt', data_encoding='koi8_t', file_encoding='utf-8')
""", (3, 5)),
])
def test_function_EncodedFile(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
netromdk-vermin-d650a48/tests/codecs_error_handlers.py 0000664 0000000 0000000 00000010036 15265463462 0023252 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminCodecsErrorHandlerTests(VerminTest):
@VerminTest.parameterized_args([
("""import codecs
codecs.encode('test', 'utf-8', 'surrogateescape')
""", (3, 1)),
("""import codecs
codecs.encode('test', 'utf-8', errors='surrogateescape')
""", (3, 1)),
("""from codecs import encode
encode('test', 'utf-8', 'surrogateescape')
""", (3, 1)),
])
def test_handler_surrogateescape(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("""import codecs
codecs.decode('test', 'utf-8', 'surrogatepass')
""", (3, 1)),
("""import codecs
codecs.decode('test', 'utf-8', errors='surrogatepass')
""", (3, 1)),
("""from codecs import decode
decode('test', 'utf-8', 'surrogatepass')
""", (3, 1)),
])
def test_handler_surrogatepass(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_args([
("""import codecs
codecs.EncodedFile('test', 'utf-8', 'utf-8', 'namereplace')
""", (3, 5)),
("""import codecs
codecs.EncodedFile('test', 'utf-8', errors='namereplace')
""", (3, 5)),
("""from codecs import EncodedFile
EncodedFile('test', 'utf-8', 'utf-8', 'namereplace')
""", (3, 5)),
])
def test_handler_namereplace(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
def test_function_encode(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import encode\n"
"encode('test', 'utf-8', 'namereplace')"))
def test_function_decode(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import decode\n"
"decode('test', 'utf-8', 'namereplace')"))
def test_function_open(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import open\n"
"open('test', errors='namereplace')"))
def test_function_EncodedFile(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import EncodedFile\n"
"EncodedFile('test', 'utf-8', errors='namereplace')"))
def test_function_iterencode(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import iterencode\n"
"iterencode([], 'utf-8', 'namereplace')"))
def test_function_iterdecode(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import iterdecode\n"
"iterdecode([], 'utf-8', 'namereplace')"))
def test_function_IncrementalEncoder(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import IncrementalEncoder\n"
"IncrementalEncoder('namereplace')"))
def test_function_IncrementalDecoder(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import IncrementalDecoder\n"
"IncrementalDecoder('namereplace')"))
def test_function_StreamWriter(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import StreamWriter\n"
"from sys import stdout\n"
"StreamWriter(stdout, 'namereplace')"))
def test_function_StreamReader(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import StreamReader\n"
"from sys import stdin\n"
"StreamReader(stdin, 'namereplace')"))
def test_function_StreamReaderWriter(self):
self.assertOnlyIn((3, 5),
self.detect("from codecs import StreamReaderWriter as SRW\n"
"SRW(open('hello.txt'), None, None, 'namereplace')"))
def test_function_StreamRecoder(self):
self.assertOnlyIn((3, 5), self.detect(
"from codecs import StreamRecoder as SR, encode, decode\n"
"SR(open('hello.txt'), encode, decode, None, None, 'namereplace')"))
netromdk-vermin-d650a48/tests/comment_exclusions.py 0000664 0000000 0000000 00000044213 15265463462 0022643 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest, current_version
class VerminCommentsExclusionsTests(VerminTest):
def test_import(self):
visitor = self.visit("# novm\nimport email.parser.FeedParser")
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Comment "novm" or "novermin" on its own refers to the next line.
self.assertIn(2, visitor.no_lines())
visitor = self.visit("# novermin\nimport email.parser.FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Testing at end of line w/o spacing.
visitor = self.visit("import email.parser.FeedParser # novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser #novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser # novermin")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser#novermin")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Testing multiple comment segments.
visitor = self.visit("import email.parser.FeedParser # noqa # novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser # novm # noqa")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser # noqa # novermin # nolint")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser "
"# type: ignore[attr-defined] # novm # pylint: disable=no-member")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# novermin in a non-first segment.
visitor = self.visit("import email.parser.FeedParser # noqa # novermin")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Testing multiple comment segments on its own refers to the next line.
visitor = self.visit("# noqa # novm # nolint\nimport email.parser.FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("# noqa # novermin # nolint\nimport email.parser.FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("# type: ignore[attr-defined] # novm # pylint: disable=no-member\n"
"import email.parser.FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Detect comments on line that are indented, i.e. col != 0 but the comment is alone on the line.
visitor = self.visit("if 1:\n # novermin\n import email.parser.FeedParser")
self.assertIn(3, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("if 1:\n\t# novermin\n\timport email.parser.FeedParser")
self.assertIn(3, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("if 1:\n\tif 1:\n\t\t# novermin\n\t\timport email.parser.FeedParser")
self.assertIn(4, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_from_import(self):
visitor = self.visit("# novm\nfrom email.parser import FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("# novermin\nfrom email.parser import FeedParser")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("from email.parser import FeedParser # novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("from email.parser import FeedParser # novermin")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_function(self):
visitor = self.visit("# novm\ndef foo():\n\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("def foo(): # novm\n\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_async_function(self):
visitor = self.visit("# novm\nasync def foo():\n\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("async def foo(): #novm\n\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_class(self):
visitor = self.visit("# novm\nclass foo():\n\tdef __init__(self):\n\t\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("class foo(): # novm\n\tdef __init__(self):\n\t\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_if(self):
visitor = self.visit("# novm\nif True:\n\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("if True: # novm\n\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_for(self):
visitor = self.visit("# novm\nfor a in [1,2,3]:\n\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("for a in [1,2,3]: # novm\n\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 6)
def test_async_for(self):
visitor = self.visit("""async def foo():
# novm
async for a in [1,2,3]:
all([])
""")
self.assertIn(3, visitor.no_lines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("""async def foo():
async for a in [1,2,3]: # novm
all([])
""")
self.assertIn(2, visitor.no_lines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
def test_while(self):
visitor = self.visit("# novm\nwhile True:\n\tall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("while True: # novm\n\tall([])")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_boolop(self):
visitor = self.visit("# novm\nFalse or all([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("False or all([]) # novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_call(self):
visitor = self.visit("# novm\nall([])")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("all([]) # novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_assign(self):
visitor = self.visit("""import ssl
tls_version = ssl.PROTOCOL_TLSv1
if hasattr(ssl, "PROTOCOL_TLS"):
tls_version = ssl.PROTOCOL_TLS # novermin
""")
self.assertIn(4, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_augassign(self):
visitor = self.visit("""import ssl
tls_version = ssl.PROTOCOL_TLSv1
if hasattr(ssl, "PROTOCOL_TLS"):
tls_version += ssl.PROTOCOL_TLS # novermin
""")
self.assertIn(4, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 6)
def test_annassign(self):
visitor = self.visit("""a : int = 1 # novermin
""")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_coroutines_await(self):
self.config.set_verbose(2)
visitor = self.visit("""async def func():
await something() # novermin
""")
self.assertIn(2, visitor.no_lines())
# Since both `async def` and `await` require 3.5, and `await` must be in an `async def`, the
# verbose (2) output text is inspected.
self.assertTrue(visitor.coroutines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
self.assertNotIn("await", visitor.output_text())
@VerminTest.skipUnlessVersion(3, 8)
def test_namedexpr(self):
visitor = self.visit("""import ssl
(a := ssl.PROTOCOL_TLS) # novermin
""")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 3)
def test_yield_from(self):
visitor = self.visit("""def foo(x):
yield from range(x) # novermin
""")
self.assertIn(2, visitor.no_lines())
self.assertFalse(visitor.yield_from())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_yield(self):
visitor = self.visit("""import ssl
yield ssl.PROTOCOL_TLS # novermin
""")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_raise(self):
visitor = self.visit("""import ssl
raise ssl.PROTOCOL_TLS # novermin
""")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_excepthandler(self):
visitor = self.visit("""import ssl
try:
pass
except TypeError: # novermin
ssl.PROTOCOL_TLS
""")
self.assertIn(4, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_with(self):
visitor = self.visit("""import ssl
with 1 as a: # novermin
ssl.PROTOCOL_TLS
""")
self.assertIn(2, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_async_with(self):
visitor = self.visit("""import ssl
async def foo():
async with 1 as a: # novermin
ssl.PROTOCOL_TLS
""")
self.assertIn(3, visitor.no_lines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
def test_subscript(self):
visitor = self.visit("""import ssl
l = [1, 2, 3]
l[1:ssl.PROTOCOL_TLS.value] # novermin
""")
self.assertIn(3, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_newline_before_novm(self):
# Earlier, it wasn't checking for both `NL` and `NEWLINE` tokens to denote newlines, only the
# later.
visitor = self.visit("""import ssl
l = [1, 2, 3]
for a in l:
# novm
l[1:ssl.PROTOCOL_TLS.value]
""")
self.assertIn(6, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_function_decorator(self):
visitor = self.visit("""@staticmethod # novm
def foo(): pass
""")
self.assertFalse(visitor.function_decorators())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""@staticmethod #novm
@staticmethod #novm
def foo(): pass
""")
self.assertFalse(visitor.function_decorators())
self.assertEqual({1, 2}, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# When not all function decorators are excluded, the function decorator version requirement is
# still in effect.
visitor = self.visit("""@staticmethod
@staticmethod #novm
def foo(): pass
""")
self.assertTrue(visitor.function_decorators())
self.assertEqual({2}, visitor.no_lines())
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
visitor = self.visit("""@staticmethod #novm
@staticmethod
def foo(): pass
""")
self.assertEqual({1}, visitor.no_lines())
# The line numbers were not as precise before 3.8, so excluding the first decorator would
# exclude the whole function, too.
if current_version() < (3, 8):
self.assertFalse(visitor.function_decorators())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
else:
self.assertTrue(visitor.function_decorators())
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
def test_class_decorator(self):
visitor = self.visit("""@somedeco # novm
class Foo: pass
""")
self.assertFalse(visitor.class_decorators())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""@somedeco #novm
@somedeco #novm
class Foo: pass
""")
self.assertFalse(visitor.class_decorators())
self.assertEqual({1, 2}, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# When not all class decorators are excluded, the class decorator version requirement is still
# in effect.
visitor = self.visit("""@somedeco
@somedeco #novm
class Foo: pass
""")
self.assertTrue(visitor.class_decorators())
self.assertEqual({2}, visitor.no_lines())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
visitor = self.visit("""@somedeco #novm
@somedeco
class Foo: pass
""")
self.assertEqual({1}, visitor.no_lines())
# The line numbers were not as precise before 3.8, so excluding the first decorator would
# exclude the whole class, too.
if current_version() < (3, 8):
self.assertFalse(visitor.class_decorators())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
else:
self.assertTrue(visitor.class_decorators())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
def test_multiline(self):
visitor = self.visit('''foo = """
{}
""".format('bar') #novm
''')
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('''foo = """{}""".format('bar') #novm
''')
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('''foo = """{}
""".format('bar') #novm
''')
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""foo = '''
{}
'''.format('bar') #novm
""")
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""foo = '''{}'''.format('bar') #novm
""")
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""foo = '''{}
'''.format('bar') #novm
""")
self.assertFalse(visitor.format27())
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('''#novm
foo = """
{}
""".format('bar')
''')
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('''#novm
foo = """{}""".format('bar')
''')
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('''#novm
foo = """{}
""".format('bar')
''')
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""#novm
foo = '''
{}
'''.format('bar')
""")
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""#novm
foo = '''{}'''.format('bar')
""")
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("""#novm
foo = '''{}
'''.format('bar')
""")
self.assertFalse(visitor.format27())
self.assertIn(2, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_not_parsing_comments(self):
self.config.set_parse_comments(False)
visitor = self.visit("# novm\nimport email.parser.FeedParser")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
visitor = self.visit("import email.parser.FeedParser # novm")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 10)
def test_pattern_matching(self):
visitor = self.visit("""
def http_error(status):
match status: #novm
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
""")
self.assertIn(3, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_ifexp(self):
visitor = self.visit("1 if True else 2 #novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_nonlocal(self):
visitor = self.visit("""
def foo():
a = 1
def bar():
nonlocal a #novm
""")
self.assertIn(5, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 12)
def test_type_alias_statement(self):
visitor = self.visit("type X = int #novm")
self.assertIn(1, visitor.no_lines())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
netromdk-vermin-d650a48/tests/config.py 0000664 0000000 0000000 00000043171 15265463462 0020174 0 ustar 00root root 0000000 0000000 import os
from tempfile import mkdtemp
from shutil import rmtree
from vermin import Backports, Features, Config, DEFAULT_PROCESSES, CONFIG_FILE_NAMES, \
PROJECT_BOUNDARIES
import vermin.formats
from .testutils import VerminTest, ScopedTemporaryFile, touch
class VerminConfigTests(VerminTest):
def test_defaults(self):
self.assertFalse(self.config.quiet())
self.assertEqual(0, self.config.verbose())
self.assertFalse(self.config.print_visits())
self.assertEqual(DEFAULT_PROCESSES, self.config.processes())
self.assertFalse(self.config.ignore_incomp())
self.assertFalse(self.config.pessimistic())
self.assertTrue(self.config.show_tips())
self.assertFalse(self.config.analyze_hidden())
self.assertEmpty(self.config.exclusions())
self.assertEmpty(self.config.backports())
self.assertEqualItems(Features.defaults(), self.config.features())
self.assertEmpty(self.config.targets())
self.assertEqual("default", self.config.format().name())
self.assertFalse(self.config.eval_annotations())
self.assertFalse(self.config.only_show_violations())
self.assertTrue(self.config.parse_comments())
self.assertFalse(self.config.scan_symlink_folders())
def test_override_from(self):
other = Config()
other.set_quiet(True)
other.set_verbose(3)
other.set_print_visits(True)
other.set_processes(DEFAULT_PROCESSES + 1)
other.set_ignore_incomp(True)
other.set_pessimistic(True)
other.set_show_tips(False)
other.set_analyze_hidden(True)
other.add_exclusion("foo.bar.baz")
other.add_exclusion_regex("foo/")
self.assertTrue(other.add_backport("typing"))
self.assertTrue(other.enable_feature("fstring-self-doc"))
self.assertTrue(other.add_target("2.3"))
other.set_format(vermin.formats.ParsableFormat())
other.set_eval_annotations(True)
other.set_only_show_violations(True)
other.set_parse_comments(False)
other.set_scan_symlink_folders(True)
self.config.override_from(other)
self.assertEqual(other.quiet(), self.config.quiet())
self.assertEqual(other.verbose(), self.config.verbose())
self.assertEqual(other.print_visits(), self.config.print_visits())
self.assertEqual(other.processes(), self.config.processes())
self.assertEqual(other.ignore_incomp(), self.config.ignore_incomp())
self.assertEqual(other.pessimistic(), self.config.pessimistic())
self.assertEqual(other.show_tips(), self.config.show_tips())
self.assertEqual(other.analyze_hidden(), self.config.analyze_hidden())
self.assertEqual(other.exclusions(), self.config.exclusions())
self.assertEqual(other.exclusion_regex(), self.config.exclusion_regex())
self.assertEqual(other.backports(), self.config.backports())
self.assertEqual(other.features(), self.config.features())
self.assertEqual(other.targets(), self.config.targets())
self.assertEqual(other.format(), self.config.format())
self.assertEqual(other.eval_annotations(), self.config.eval_annotations())
self.assertEqual(other.only_show_violations(), self.config.only_show_violations())
self.assertEqual(other.parse_comments(), self.config.parse_comments())
self.assertEqual(other.scan_symlink_folders(), self.config.scan_symlink_folders())
def test_repr(self):
self.assertEqual(str(self.config), """{}(
quiet = {}
verbose = {}
print_visits = {}
processes = {}
ignore_incomp = {}
pessimistic = {}
show_tips = {}
analyze_hidden = {}
exclusions = {}
exclusion_regex = {}
make_paths_absolute = {}
backports = {}
features = {}
targets = {}
eval_annotations = {}
only_show_violations = {}
parse_comments = {}
scan_symlink_folders = {}
format = {}
)""".format(self.config.__class__.__name__, self.config.quiet(), self.config.verbose(),
self.config.print_visits(), self.config.processes(), self.config.ignore_incomp(),
self.config.pessimistic(), self.config.show_tips(), self.config.analyze_hidden(),
self.config.exclusions(), self.config.exclusion_regex(),
self.config.make_paths_absolute(), list(self.config.backports()),
list(self.config.features()), self.config.targets(), self.config.eval_annotations(),
self.config.only_show_violations(), self.config.parse_comments(),
self.config.scan_symlink_folders(), self.config.format().name()))
@VerminTest.parameterized_args([
[""],
["""
"""],
["""[vermin
"""],
["""vermin]
"""],
["""[ vermin ]
"""],
])
def test_parse_invalid_section(self, data):
self.assertIsNone(Config.parse_data(data))
@VerminTest.parameterized_args([
# Testing all possible, case-insensitive supported boolean values: 0, 1, on, off, no, yes, true,
# false. Does not need to be repeated for each following boolean test.
["""[vermin]
quiet =
""", False],
["""[vermin]
#quiet = True
""", False],
["""[vermin]
quiet = 1
""", True],
["""[vermin]
quiet = on
""", True],
["""[vermin]
quiet = yes
""", True],
["""[vermin]
quiet = true
""", True],
["""[vermin]
quiet = True
""", True],
["""[vermin]
quiet = 0
""", False],
["""[vermin]
quiet = off
""", False],
["""[vermin]
quiet = no
""", False],
["""[vermin]
quiet = false
""", False],
["""[vermin]
quiet = False
""", False],
])
def test_parse_quiet(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.quiet(), expected)
@VerminTest.parameterized_args([
["""[vermin]
verbose =
""", 0],
["""[vermin]
#verbose = 1
""", 0],
["""[vermin]
verbose = 0
""", 0],
["""[vermin]
verbose = 1
""", 1],
["""[vermin]
verbose = 2
""", 2],
])
def test_parse_verbose(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.verbose(), expected)
def test_parse_invalid_verbose(self):
self.assertIsNone(Config.parse_data("""[vermin]
verbose = -1
"""))
@VerminTest.parameterized_args([
["""[vermin]
print_visits =
""", False],
["""[vermin]
#print_visits = True
""", False],
["""[vermin]
print_visits = True
""", True],
["""[vermin]
print_visits = False
""", False],
["""[vermin]
print_visits = yes
""", True],
["""[vermin]
print_visits = no
""", False],
])
def test_parse_print_visits(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.print_visits(), expected)
@VerminTest.parameterized_args([
["""[vermin]
processes =
""", DEFAULT_PROCESSES],
["""[vermin]
#processes = 1
""", DEFAULT_PROCESSES],
["""[vermin]
processes = 0
""", DEFAULT_PROCESSES],
["""[vermin]
processes = 10
""", 10],
["""[vermin]
processes = 2
""", 2],
])
def test_parse_processes(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.processes(), expected)
def test_parse_invalid_processes(self):
self.assertIsNone(Config.parse_data("""[vermin]
processes = -1
"""))
@VerminTest.parameterized_args([
["""[vermin]
ignore_incomp =
""", False],
["""[vermin]
#ignore_incomp = True
""", False],
["""[vermin]
ignore_incomp = True
""", True],
["""[vermin]
ignore_incomp = False
""", False],
["""[vermin]
ignore_incomp = yes
""", True],
["""[vermin]
ignore_incomp = no
""", False],
])
def test_parse_ignore_incomp(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.ignore_incomp(), expected)
@VerminTest.parameterized_args([
["""[vermin]
pessimistic =
""", False],
["""[vermin]
#pessimistic = True
""", False],
["""[vermin]
pessimistic = True
""", True],
["""[vermin]
pessimistic = False
""", False],
["""[vermin]
pessimistic = yes
""", True],
["""[vermin]
pessimistic = no
""", False],
])
def test_parse_pessimistic(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.pessimistic(), expected)
@VerminTest.parameterized_args([
["""[vermin]
show_tips =
""", True],
["""[vermin]
#show_tips = False
""", True],
["""[vermin]
show_tips = False
""", False],
["""[vermin]
show_tips = True
""", True],
["""[vermin]
show_tips = no
""", False],
["""[vermin]
show_tips = yes
""", True],
])
def test_parse_show_tips(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.show_tips(), expected)
@VerminTest.parameterized_args([
["""[vermin]
exclusions =
""", []],
["""[vermin]
#exclusions = mod.member
""", []],
["""[vermin]
exclusions = mod.member
""", ["mod.member"]],
["""[vermin]
exclusions = mod.member
foo.bar(baz)
""", ["foo.bar(baz)", "mod.member"]],
["""[vermin]
exclusions =
mod.member
foo.bar(baz)
""", ["foo.bar(baz)", "mod.member"]],
])
def test_parse_exclusions(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.exclusions(), expected)
@VerminTest.parameterized_args([
["""[vermin]
exclusion_regex =
""", []],
["""[vermin]
#exclusion_regex = \\.pyi$
""", []],
["""[vermin]
exclusion_regex = \\.pyi$
""", [r"\.pyi$"]],
["""[vermin]
exclusion_regex = \\.pyi$
^a/b$
""", [r"\.pyi$", r"^a/b$"]],
["""[vermin]
exclusion_regex =
^a/b$
\\.pyi$
""", [r"\.pyi$", r"^a/b$"]],
])
def test_parse_exclusion_regex(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.exclusion_regex(), expected)
@VerminTest.parameterized_args([
["""[vermin]
make_paths_absolute =
""", True],
["""[vermin]
#make_paths_absolute = False
""", True],
["""[vermin]
make_paths_absolute = yes
""", True],
["""[vermin]
make_paths_absolute = no
""", False],
["""[vermin]
make_paths_absolute = True
""", True],
["""[vermin]
make_paths_absolute = False
""", False],
])
def test_parse_make_paths_absolute(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.make_paths_absolute(), expected)
def test_parse_backports(self):
bps = Backports.modules()
config = Config.parse_data("""[vermin]
backports = {}
""".format("\n ".join(bps)))
self.assertIsNotNone(config)
self.assertEqual(bps, config.backports())
config = Config.parse_data("""[vermin]
backports = unknown
""")
self.assertIsNone(config)
config = Config.parse_data("""[vermin]
backports = {}
unknown
""".format(list(bps)[0]))
self.assertIsNone(config)
def test_parse_features(self):
fs = Features.features()
config = Config.parse_data("""[vermin]
features = {}
""".format("\n ".join(fs)))
self.assertIsNotNone(config)
self.assertEqual(fs, config.features())
self.assertIsNone(Config.parse_data("""[vermin]
features = unknown
"""))
self.assertIsNone(Config.parse_data("""[vermin]
features = {}
unknown
""".format(list(fs)[0])))
def test_parse_format(self):
for fmt in vermin.formats.names():
config = Config.parse_data("""[vermin]
format = {}
""".format(fmt))
self.assertIsNotNone(config)
self.assertEqual(fmt, config.format().name())
self.assertIsNone(Config.parse_data("""[vermin]
format = unknown
"""))
@VerminTest.parameterized_args([
["""[vermin]
targets =
""", []],
["""[vermin]
#targets = 2.0
""", []],
["""[vermin]
targets = 2.0
""", [(True, (2, 0))]],
["""[vermin]
targets = 2.0-
""", [(False, (2, 0))]],
["""[vermin]
targets = 2.0
3.0
""", [(True, (2, 0)), (True, (3, 0))]],
["""[vermin]
targets = 2.0
3.0-
""", [(True, (2, 0)), (False, (3, 0))]],
["""[vermin]
targets = 2,1
3,2-
""", [(True, (2, 1)), (False, (3, 2))]],
])
def test_parse_targets(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.targets(), expected)
@VerminTest.parameterized_args([
["""[vermin]
targets = invalid
"""],
["""[vermin]
targets = 2.0 3.0
"""],
["""[vermin]
targets = 2.0
3.0
3.1
"""],
["""[vermin]
targets = 1.0
"""],
["""[vermin]
targets = 4.0
"""],
])
def test_parse_invalid_targets(self, data):
self.assertIsNone(Config.parse_data(data))
def test_target_exactness_overload(self):
self.assertEmpty(self.config.targets())
self.assertFalse(self.config.add_target((2,)))
self.assertFalse(self.config.add_target((2,), exact=False))
self.assertFalse(self.config.add_target((2,), exact=True))
self.assertEmpty(self.config.targets())
self.assertTrue(self.config.add_target((2, 3)))
self.assertTrue(self.config.add_target((2, 5), exact=False))
self.assertEqual([[True, (2, 3)], [False, (2, 5)]], self.config.targets())
self.config.clear_targets()
self.assertTrue(self.config.add_target((2, 7), exact=True))
self.assertEqual([[True, (2, 7)]], self.config.targets())
def test_add_exclusion_file_nonexistent(self):
# Should not crash on nonexistent file (exception is silently caught).
self.config.add_exclusion_file("nonexistent_file_xyz")
def test_parse_file_invalid(self):
fp = ScopedTemporaryFile()
fp.write(b"not valid ini content")
fp.close()
config = Config.parse_file(fp.path())
self.assertIsNone(config)
def test_parse_file_strips_line_whitespace(self):
fp = ScopedTemporaryFile()
fp.write(b"[vermin]\nexclusions = foo.bar\n baz.qux \n more.stuff\n")
fp.close()
config = Config.parse_file(fp.path())
self.assertIsNotNone(config)
self.assertEqual(["baz.qux", "foo.bar", "more.stuff"], config.exclusions())
def test_parse_file(self):
fp = ScopedTemporaryFile()
fp.write(b"""[vermin]
quiet = 1
verbose = 2
print_visits = on
ignore_incomp = yes
pessimistic = TrUe
""")
fp.close()
config = Config.parse_file(fp.path())
self.assertIsNotNone(config)
self.assertTrue(config.quiet())
self.assertEqual(2, config.verbose())
self.assertTrue(config.print_visits())
self.assertTrue(config.ignore_incomp())
self.assertTrue(config.pessimistic())
def test_detect_config_file_same_level(self):
tmp_fld = mkdtemp()
for candidate in CONFIG_FILE_NAMES:
path = touch(tmp_fld, candidate, "[vermin]")
self.assertEqual(path, Config.detect_config_file(tmp_fld))
os.remove(path)
rmtree(tmp_fld)
def test_detect_config_file_one_level_depth(self):
tmp_fld = mkdtemp()
depth_fld = os.path.join(tmp_fld, "depth1")
os.makedirs(depth_fld)
for candidate in CONFIG_FILE_NAMES:
path = touch(tmp_fld, candidate, "[vermin]")
self.assertEqual(path, Config.detect_config_file(depth_fld))
os.remove(path)
rmtree(tmp_fld)
def test_detect_config_file_two_level_depth(self):
tmp_fld = mkdtemp()
depth_fld = os.path.join(os.path.join(tmp_fld, "depth1"), "depth2")
os.makedirs(depth_fld)
for candidate in CONFIG_FILE_NAMES:
path = touch(tmp_fld, candidate, "[vermin]")
self.assertEqual(path, Config.detect_config_file(depth_fld))
os.remove(path)
rmtree(tmp_fld)
def test_detect_config_file_project_boundary(self):
tmp_fld = mkdtemp()
depth1_fld = os.path.join(tmp_fld, "depth1")
depth2_fld = os.path.join(depth1_fld, "depth2")
os.makedirs(depth2_fld)
# Create config at top level.
touch(tmp_fld, CONFIG_FILE_NAMES[0], "[vermin]")
# Create project boundary at depth one to stop further detection.
for candidate in PROJECT_BOUNDARIES:
boundary_fld = os.path.join(depth1_fld, candidate)
os.makedirs(boundary_fld)
self.assertIsNone(Config.detect_config_file(depth2_fld))
rmtree(boundary_fld)
rmtree(tmp_fld)
@VerminTest.parameterized_args([
["""[vermin]
eval_annotations =
""", False],
["""[vermin]
#eval_annotations = True
""", False],
["""[vermin]
eval_annotations = True
""", True],
["""[vermin]
eval_annotations = False
""", False],
])
def test_parse_eval_annotations(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.eval_annotations(), expected)
@VerminTest.parameterized_args([
["""[vermin]
only_show_violations =
""", False],
["""[vermin]
#only_show_violations = True
""", False],
["""[vermin]
only_show_violations = True
""", True],
["""[vermin]
only_show_violations = False
""", False],
])
def test_parse_only_show_violations(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.only_show_violations(), expected)
def test_issue_68_override_from_add_exclusion(self):
other = Config()
self.config.override_from(other)
# Calling `add_exclusion()` will call `set.add()` but `Config.__exclusions` has become a list
# after `override_from()` and it would therefore crash.
try:
self.config.add_exclusion("x")
except AttributeError:
self.fail("Crashed while adding exclusion.")
@VerminTest.parameterized_args([
["""[vermin]
parse_comments =
""", True],
["""[vermin]
#parse_comments = True
""", True],
["""[vermin]
parse_comments = True
""", True],
["""[vermin]
parse_comments = False
""", False],
])
def test_parse_parse_comments(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.parse_comments(), expected)
@VerminTest.parameterized_args([
["""[vermin]
scan_symlink_folders =
""", False],
["""[vermin]
#scan_symlink_folders = False
""", False],
["""[vermin]
scan_symlink_folders = True
""", True],
["""[vermin]
scan_symlink_folders = False
""", False],
])
def test_parse_scan_symlink_folders(self, data, expected):
config = Config.parse_data(data)
self.assertIsNotNone(config)
self.assertEqual(config.scan_symlink_folders(), expected)
netromdk-vermin-d650a48/tests/constants.py 0000664 0000000 0000000 00000506726 15265463462 0020755 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminConstantMemberTests(VerminTest):
def test_name_of_AttributeError(self):
self.assertOnlyIn((3, 10), self.detect("AttributeError.name"))
def test_obj_of_AttributeError(self):
self.assertOnlyIn((3, 10), self.detect("AttributeError.obj"))
def test___suppress_context___of_BaseException(self):
self.assertOnlyIn((3, 3), self.detect("BaseException.__suppress_context__"))
def test_name_of_ImportError(self):
self.assertOnlyIn((3, 3), self.detect("ImportError.name"))
def test_path_of_ImportError(self):
self.assertOnlyIn((3, 3), self.detect("ImportError.path"))
def test_name_of_NameError(self):
self.assertOnlyIn((3, 10), self.detect("NameError.name"))
def test_filename2_of_OSError(self):
self.assertOnlyIn((3, 4), self.detect("OSError.filename2"))
def test_value_of_StopIteration(self):
self.assertOnlyIn((3, 3), self.detect("StopIteration.value"))
def test_end_lineno_of_SyntaxError(self):
self.assertOnlyIn((3, 10), self.detect("SyntaxError.end_lineno"))
def test_end_offset_of_SyntaxError(self):
self.assertOnlyIn((3, 10), self.detect("SyntaxError.end_offset"))
def test___wrapped___of_classmethod(self):
self.assertOnlyIn((3, 10), self.detect("classmethod.__wrapped__"))
def test___wrapped___of_staticmethod(self):
self.assertOnlyIn((3, 10), self.detect("staticmethod.__wrapped__"))
def test___match_args___of_object(self):
self.assertOnlyIn((3, 10), self.detect("object.__match_args__"))
def test_encoding_of_file(self):
self.assertOnlyIn((2, 3), self.detect("file.encoding"))
def test_errors_of_file(self):
self.assertOnlyIn((2, 6), self.detect("file.errors"))
def test_start_of_range(self):
self.assertOnlyIn((3, 3), self.detect("range.start"))
def test_step_of_range(self):
self.assertOnlyIn((3, 3), self.detect("range.step"))
def test_stop_of_range(self):
self.assertOnlyIn((3, 3), self.detect("range.stop"))
def test__field_types_of_ast_AST(self):
self.assertOnlyIn((3, 13), self.detect("from ast import AST\nAST._field_types"))
def test__align__of_ctypes_Structure(self):
self.assertOnlyIn((3, 13), self.detect("from ctypes import Structure\nStructure._align_"))
def test_start_offset_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.start_offset"))
def test_cache_offset_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.cache_offset"))
def test_end_offset_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.end_offset"))
def test_baseopname_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.baseopname"))
def test_baseopcode_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.baseopcode"))
def test_jump_target_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.jump_target"))
def test_oparg_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.oparg"))
def test_line_number_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.line_number"))
def test_cache_info_of_dis_Instruction(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Instruction\nInstruction.cache_info"))
def test_hasarg_of_dis(self):
self.assertOnlyIn((3, 12), self.detect("from dis import hasarg"))
def test_hasexc_of_dis(self):
self.assertOnlyIn((3, 12), self.detect("from dis import hasexc"))
def test_skips_of_doctest_DocTestRunner(self):
self.assertOnlyIn((3, 13),
self.detect("from doctest import DocTestRunner\nDocTestRunner.skips"))
def test_skipped_of_doctest_DocTestRunner(self):
self.assertOnlyIn((3, 13),
self.detect("from doctest import DocTestRunner\nDocTestRunner.skipped"))
def test_verify_generated_headers_of_email_policy_Policy(self):
self.assertOnlyIn((3, 13), self.detect("""
from email.policy import Policy
Policy.verify_generated_headers
"""))
def test_FORWARDREF_of_annotationlib_Format(self):
self.assertOnlyIn((3, 14),
self.detect("from annotationlib import Format\nFormat.FORWARDREF"))
def test_STRING_of_annotationlib_Format(self):
self.assertOnlyIn((3, 14),
self.detect("from annotationlib import Format\nFormat.STRING"))
def test_VALUE_of_annotationlib_Format(self):
self.assertOnlyIn((3, 14),
self.detect("from annotationlib import Format\nFormat.VALUE"))
def test_VALUE_WITH_FAKE_GLOBALS_of_annotationlib_Format(self):
self.assertOnlyIn((3, 14), self.detect("""
from annotationlib import Format
Format.VALUE_WITH_FAKE_GLOBALS
"""))
def test_mode_of_lzma_LZMAFile(self):
self.assertOnlyIn((3, 13), self.detect("from lzma import LZMAFile\nLZMAFile.mode"))
def test_name_of_lzma_LZMAFile(self):
self.assertOnlyIn((3, 13), self.detect("from lzma import LZMAFile\nLZMAFile.name"))
def test_flags_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import flags"))
def test_ALLOW_MISSING_of_os_path(self):
self.assertOnlyIn((3, 14), self.detect("from os.path import ALLOW_MISSING"))
def test_supports_unicode_filenames_of_os_path(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect(
"from os.path import supports_unicode_filenames"))
def test_supports_bytes_environ_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import supports_bytes_environ"))
def test_environb_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import environb"))
def test_TFD_NONBLOCK_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import TFD_NONBLOCK"))
def test_TFD_CLOEXEC_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import TFD_CLOEXEC"))
def test_TFD_TIMER_ABSTIME_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import TFD_TIMER_ABSTIME"))
def test_TFD_TIMER_CANCEL_ON_SET_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import TFD_TIMER_CANCEL_ON_SET"))
def test_PRIO_PROCESS_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import PRIO_PROCESS"))
def test_PRIO_DARWIN_BG_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import PRIO_DARWIN_BG"))
def test_PRIO_DARWIN_NONUI_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import PRIO_DARWIN_NONUI"))
def test_PRIO_DARWIN_PROCESS_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import PRIO_DARWIN_PROCESS"))
def test_PRIO_DARWIN_THREAD_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import PRIO_DARWIN_THREAD"))
def test_PRIO_PGRP_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import PRIO_PGRP"))
def test_PRIO_USER_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import PRIO_USER"))
def test_F_LOCK_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import F_LOCK"))
def test_F_TLOCK_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import F_TLOCK"))
def test_F_ULOCK_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import F_ULOCK"))
def test_F_TEST_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import F_TEST"))
def test_O_CLOEXEC_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import O_CLOEXEC"))
def test_O_PATH_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import O_PATH"))
def test_O_TMPFILE_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import O_TMPFILE"))
def test_O_EVTONLY_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import O_EVTONLY"))
def test_O_FSYNC_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import O_FSYNC"))
def test_O_SYMLINK_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import O_SYMLINK"))
def test_O_NOFOLLOW_ANY_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import O_NOFOLLOW_ANY"))
def test_PIDFD_NONBLOCK_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import PIDFD_NONBLOCK"))
def test_POSIX_FADV_NORMAL_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_NORMAL"))
def test_POSIX_FADV_SEQUENTIAL_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_SEQUENTIAL"))
def test_POSIX_FADV_RANDOM_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_RANDOM"))
def test_POSIX_FADV_NOREUSE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_NOREUSE"))
def test_POSIX_FADV_WILLNEED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_WILLNEED"))
def test_POSIX_FADV_DONTNEED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import POSIX_FADV_DONTNEED"))
def test_SF_NOCACHE_of_os(self):
self.assertOnlyIn((3, 11), self.detect("from os import SF_NOCACHE"))
def test_SF_NODISKIO_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SF_NODISKIO"))
def test_SF_MNOWAIT_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SF_MNOWAIT"))
def test_SF_SYNC_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SF_SYNC"))
def test_float_info_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import float_info"))
def test_float_repr_style_of_sys(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from sys import float_repr_style"))
def test_last_exc_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import last_exc"))
def test_long_info_of_sys(self):
self.assertOnlyIn((2, 7), self.detect("from sys import long_info"))
def test_py3kwarning_of_sys(self):
self.assertOnlyIn((2, 6), self.detect("from sys import py3kwarning"))
def test_subversion_of_sys(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from sys import subversion"))
def test_api_version_of_sys(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from sys import api_version"))
def test_version_info_of_sys(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("from sys import version_info"))
def test_exc_type_str_of_traceback_TracebackException(self):
self.assertOnlyIn((3, 13), self.detect("""
from traceback import TracebackException
TracebackException.exc_type_str
"""))
def test_sentinel_of_multiprocessing_Process(self):
self.assertOnlyIn((3, 3),
self.detect("from multiprocessing import Process\np = Process()\np.sentinel"))
def test_skipped_of_unittest_TestResult(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestResult\np = TestResult()\np.skipped"))
def test_buffer_of_unittest_TestResult(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestResult\np = TestResult()\np.buffer"))
def test_failfast_of_unittest_TestResult(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestResult\np = TestResult()\np.failfast"))
def test_UTC_of_datetime(self):
self.assertOnlyIn((3, 11), self.detect("from datetime import UTC"))
def test_fold_of_datetime_datetime(self):
self.assertOnlyIn((3, 6), self.detect("from datetime import datetime\np = datetime()\np.fold"))
def test_fold_of_datetime_time(self):
self.assertOnlyIn((3, 6), self.detect("from datetime import time\np = time()\np.fold"))
def test_algorithms_of_hashlib(self):
self.assertOnlyIn((2, 7), self.detect("from hashlib import algorithms"))
def test_algorithms_available_of_hashlib(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from hashlib import algorithms_available"))
def test_algorithms_guaranteed_of_hashlib(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from hashlib import algorithms_guaranteed"))
def test_reverse_pointer_of_ipaddress_IPv4Address(self):
self.assertOnlyIn((3, 5),
self.detect("from ipaddress import IPv4Address\n"
"addr = IPv4Address('127.0.0.1')\n"
"addr.reverse_pointer"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from ipaddress import IPv4Address\n"
"addr = IPv4Address('127.0.0.1')\n"
"addr.reverse_pointer"))
def test_is_global_of_ipaddress_IPv4Address(self):
self.assertOnlyIn((3, 4),
self.detect("from ipaddress import IPv4Address\n"
"addr = IPv4Address('127.0.0.1')\n"
"addr.is_global"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from ipaddress import IPv4Address\n"
"addr = IPv4Address('127.0.0.1')\n"
"addr.is_global"))
def test_is_global_of_ipaddress_IPv6Address(self):
self.assertOnlyIn((3, 4),
self.detect("from ipaddress import IPv6Address\n"
"addr = IPv6Address(':::1')\n"
"addr.is_global"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from ipaddress import IPv6Address\n"
"addr = IPv6Address(':::1')\n"
"addr.is_global"))
def test_nested_scopes_of___future__(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from __future__ import nested_scopes"))
def test_generators_of___future__(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from __future__ import generators"))
def test_division_of___future__(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from __future__ import division"))
def test_absolute_import_of___future__(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from __future__ import absolute_import"))
def test_with_statement_of___future__(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from __future__ import with_statement"))
def test_print_function_of___future__(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from __future__ import print_function"))
def test_unicode_literals_of___future__(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from __future__ import unicode_literals"))
def test_generator_stop_of___future__(self):
self.assertOnlyIn((3, 5), self.detect("from __future__ import generator_stop"))
def test_PyCF_ALLOW_TOP_LEVEL_AWAIT_of_ast(self):
self.assertOnlyIn((3, 8), self.detect("from ast import PyCF_ALLOW_TOP_LEVEL_AWAIT"))
def test_PyCF_TYPE_COMMENTS_of_ast(self):
self.assertOnlyIn((3, 8), self.detect("from ast import PyCF_TYPE_COMMENTS"))
def test_PyCF_OPTIMIZED_AST_of_ast(self):
self.assertOnlyIn((3, 13), self.detect("from ast import PyCF_OPTIMIZED_AST"))
def test_eof_of_bz2_BZ2Decompressor(self):
self.assertOnlyIn((3, 3),
self.detect("from bz2 import BZ2Decompressor\nd = BZ2Decompressor()\nd.eof"))
def test_needs_input_of_bz2_BZ2Decompressor(self):
self.assertOnlyIn((3, 5),
self.detect("from bz2 import BZ2Decompressor\n"
"d = BZ2Decompressor()\n"
"d.needs_input"))
def test_mode_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 13),
self.detect("from bz2 import BZ2File\n"
"d = BZ2File()\n"
"d.mode"))
def test_name_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 13),
self.detect("from bz2 import BZ2File\n"
"d = BZ2File()\n"
"d.name"))
def test_maxlen_of_collections_deque(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from collections import deque\nd = deque()\nd.maxlen"))
def test_block_size_of_hmac_HMAC(self):
self.assertOnlyIn((3, 4), self.detect("from hmac import HMAC\nd = HMAC()\nd.block_size"))
def test_name_of_hmac_HMAC(self):
self.assertOnlyIn((3, 4), self.detect("from hmac import HMAC\nd = HMAC()\nd.name"))
def test_CO_COROUTINE_of_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.CO_COROUTINE"))
def test_CO_HAS_DOCSTRING_of_inspect(self):
self.assertOnlyIn((3, 14), self.detect("import inspect\ninspect.CO_HAS_DOCSTRING"))
def test_CO_ITERABLE_COROUTINE_of_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.CO_ITERABLE_COROUTINE"))
def test_CO_ASYNC_GENERATOR_of_inspect(self):
self.assertOnlyIn((3, 6), self.detect("import inspect\ninspect.CO_ASYNC_GENERATOR"))
def test_CO_METHOD_of_inspect(self):
self.assertOnlyIn((3, 14), self.detect("import inspect\ninspect.CO_METHOD"))
def test_lastResort_of_logging(self):
self.assertOnlyIn((3, 2), self.detect("import logging\nlogging.lastResort"))
def test_rpc_paths_of_SimpleXMLRPCServer_SimpleXMLRPCRequestHandler(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler\n"
"SimpleXMLRPCRequestHandler.rpc_paths"))
self.assertOnlyIn((3, 0),
self.detect("from xmlrpc.server import SimpleXMLRPCRequestHandler\n"
"SimpleXMLRPCRequestHandler.rpc_paths"))
def test_encode_threshold_of_SimpleXMLRPCServer_SimpleXMLRPCRequestHandler(self):
self.assertOnlyIn((2, 7),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler\n"
"SimpleXMLRPCRequestHandler.encode_threshold"))
def test_library_of_ssl_SSLError(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLError\nSSLError.library"))
def test_reason_of_ssl_SSLError(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLError\nSSLError.reason"))
def test_VERIFY_DEFAULT_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import VERIFY_DEFAULT"))
def test_VERIFY_CRL_CHECK_LEAF_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import VERIFY_CRL_CHECK_LEAF"))
def test_VERIFY_CRL_CHECK_CHAIN_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import VERIFY_CRL_CHECK_CHAIN"))
def test_VERIFY_X509_STRICT_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import VERIFY_X509_STRICT"))
def test_VERIFY_X509_TRUSTED_FIRST_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import VERIFY_X509_TRUSTED_FIRST"))
def test_VERIFY_X509_PARTIAL_CHAIN_of_ssl(self):
self.assertOnlyIn((3, 10), self.detect("from ssl import VERIFY_X509_PARTIAL_CHAIN"))
def test_VERIFY_ALLOW_PROXY_CERTS_of_ssl(self):
self.assertOnlyIn((3, 10), self.detect("from ssl import VERIFY_ALLOW_PROXY_CERTS"))
def test_PROTOCOL_TLS_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 6)), self.detect("from ssl import PROTOCOL_TLS"))
def test_PROTOCOL_TLSv1_1_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import PROTOCOL_TLSv1_1"))
def test_PROTOCOL_TLSv1_2_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import PROTOCOL_TLSv1_2"))
def test_OP_ALL_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OP_ALL"))
def test_OP_NO_SSLv2_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OP_NO_SSLv2"))
def test_OP_NO_SSLv3_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OP_NO_SSLv3"))
def test_OP_NO_TLSv1_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OP_NO_TLSv1"))
def test_OP_NO_TLSv1_1_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import OP_NO_TLSv1_1"))
def test_OP_NO_TLSv1_2_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import OP_NO_TLSv1_2"))
def test_OP_NO_TLSv1_3_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 7)), self.detect("from ssl import OP_NO_TLSv1_3"))
def test_OP_CIPHER_SERVER_PREFERENCE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import OP_CIPHER_SERVER_PREFERENCE"))
def test_OP_SINGLE_DH_USE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import OP_SINGLE_DH_USE"))
def test_OP_SINGLE_ECDH_USE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import OP_SINGLE_ECDH_USE"))
def test_OP_NO_COMPRESSION_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import OP_NO_COMPRESSION"))
def test_OP_NO_TICKET_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import OP_NO_TICKET"))
def test_OP_IGNORE_UNEXPECTED_EOF_of_ssl(self):
self.assertOnlyIn((3, 10), self.detect("from ssl import OP_IGNORE_UNEXPECTED_EOF"))
def test_HAS_ALPN_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 5)), self.detect("from ssl import HAS_ALPN"))
def test_HAS_ECDH_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import HAS_ECDH"))
def test_HAS_SNI_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import HAS_SNI"))
def test_HAS_NPN_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import HAS_NPN"))
def test_HAS_TLSv1_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_TLSv1"))
def test_HAS_TLSv1_1_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_TLSv1_1"))
def test_HAS_TLSv1_2_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_TLSv1_2"))
def test_HAS_TLSv1_3_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 7)), self.detect("from ssl import HAS_TLSv1_3"))
def test_HAS_PSK_ssl(self):
self.assertOnlyIn((3, 13), self.detect("from ssl import HAS_PSK"))
def test_HAS_PHA_ssl(self):
self.assertOnlyIn((3, 14), self.detect("from ssl import HAS_PHA"))
def test_HAS_NEVER_CHECK_COMMON_NAME_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_NEVER_CHECK_COMMON_NAME"))
def test_CHANNEL_BINDING_TYPES_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import CHANNEL_BINDING_TYPES"))
def test_OPENSSL_VERSION_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OPENSSL_VERSION"))
def test_OPENSSL_VERSION_INFO_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OPENSSL_VERSION_INFO"))
def test_OPENSSL_VERSION_NUMBER_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import OPENSSL_VERSION_NUMBER"))
def test_context_of_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from ssl import SSLSocket\nSSLSocket.context"))
def test_server_side_of_ssl_SSLSocket(self):
self.assertOnlyIn((3, 2), self.detect("from ssl import SSLSocket\nSSLSocket.server_side"))
def test_server_hostname_of_ssl_SSLSocket(self):
self.assertOnlyIn((3, 2), self.detect("from ssl import SSLSocket\nSSLSocket.server_hostname"))
def test_session_of_ssl_SSLSocket(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import SSLSocket\nSSLSocket.session"))
def test_session_reused_of_ssl_SSLSocket(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import SSLSocket\nSSLSocket.session_reused"))
def test_check_hostname_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 4), self.detect("from ssl import SSLContext\nSSLContext.check_hostname"))
def test_security_level_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 10), self.detect("from ssl import SSLContext\nSSLContext.security_level"))
def test_verify_flags_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 4), self.detect("from ssl import SSLContext\nSSLContext.verify_flags"))
def test_post_handshake_auth_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 8), self.detect(
"from ssl import SSLContext\nSSLContext.post_handshake_auth"))
def test_hostname_checks_common_name_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 7), self.detect(
"from ssl import SSLContext\nSSLContext.hostname_checks_common_name"))
def test_keylog_filename_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 8), self.detect("from ssl import SSLContext\nSSLContext.keylog_filename"))
def test_num_tickets_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 8), self.detect("from ssl import SSLContext\nSSLContext.num_tickets"))
def test_maximum_version_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import SSLContext\nSSLContext.maximum_version"))
def test_minimum_version_of_ssl_SSLContext(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import SSLContext\nSSLContext.minimum_version"))
def test_DEVNULL_of_subprocess(self):
self.assertOnlyIn((3, 3), self.detect("from subprocess import DEVNULL"))
def test_pax_headers_of_tarfile_TarFile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from tarfile import TarFile\nTarFile.pax_headers"))
def test_pax_headers_of_tarfile_TarInfo(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from tarfile import TarInfo\nTarInfo.pax_headers"))
def test_extraction_filter_of_tarfile_TarFile(self):
self.assertOnlyIn((3, 12), self.detect(
"from tarfile import TarFile\nTarFile.extraction_filter"))
def test_args_of_subprocess_Popen(self):
self.assertOnlyIn((3, 3), self.detect("from subprocess import Popen\nPopen.args"))
# In this test "args" cannot be matched as "subprocess.Popen.args" constant (as above)!
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("import subprocess\nargs=[]\nsubprocess.Popen(args)"))
def test_ZIP_BZIP2_of_zipfile(self):
self.assertOnlyIn((3, 3), self.detect("import zipfile\nzipfile.ZIP_BZIP2"))
def test_ZIP_LZMA_of_zipfile(self):
self.assertOnlyIn((3, 3), self.detect("import zipfile\nzipfile.ZIP_LZMA"))
def test_ZIP_ZSTANDARD_of_zipfile(self):
self.assertOnlyIn((3, 14), self.detect("import zipfile\nzipfile.ZIP_ZSTANDARD"))
def test_suffix_of_Path_of_zipfile(self):
self.assertOnlyIn((3, 11), self.detect("from zipfile import Path\nPath().suffix"))
def test_stem_of_Path_of_zipfile(self):
self.assertOnlyIn((3, 11), self.detect("from zipfile import Path\nPath().stem"))
def test_suffixes_of_Path_of_zipfile(self):
self.assertOnlyIn((3, 11), self.detect("from zipfile import Path\nPath().suffixes"))
def test_KW_ONLY_of_dataclasses(self):
self.assertOnlyIn((3, 10), self.detect("import dataclasses\ndataclasses.KW_ONLY"))
def test_METHOD_SHA512_of_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.METHOD_SHA512"))
def test_METHOD_SHA256_of_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.METHOD_SHA256"))
def test_METHOD_MD5_of_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.METHOD_MD5"))
def test_METHOD_CRYPT_of_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.METHOD_CRYPT"))
def test_METHOD_BLOWFISH_of_crypt(self):
self.assertOnlyIn((3, 7), self.detect("import crypt\ncrypt.METHOD_BLOWFISH"))
def test_methods_of_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.methods"))
def test_tau_of_math(self):
self.assertOnlyIn((3, 6), self.detect("import math\nmath.tau"))
def test_inf_of_math(self):
self.assertOnlyIn((3, 5), self.detect("import math\nmath.inf"))
def test_nan_of_math(self):
self.assertOnlyIn((3, 5), self.detect("import math\nmath.nan"))
def test_SOURCE_SUFFIXES_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect(
"from importlib import machinery\nmachinery.SOURCE_SUFFIXES"))
def test_DEBUG_BYTECODE_SUFFIXES_of_importlib_machinery(self):
self.assertOnlyIn((3, 3), self.detect(
"from importlib import machinery\nmachinery.DEBUG_BYTECODE_SUFFIXES"))
def test_OPTIMIZED_BYTECODE_SUFFIXES_of_importlib_machinery(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib import machinery\n"
"machinery.OPTIMIZED_BYTECODE_SUFFIXES"))
def test_BYTECODE_SUFFIXES_of_importlib_machinery(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib import machinery\nmachinery.BYTECODE_SUFFIXES"))
def test_EXTENSION_SUFFIXES_of_importlib_machinery(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib import machinery\nmachinery.EXTENSION_SUFFIXES"))
def test_json_from_importlib_metadata_metadata(self):
self.assertOnlyIn((3, 10),
self.detect("from importlib.metadata import metadata\n"
"metadata().json"))
def test_MAGIC_NUMBER_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.MAGIC_NUMBER"))
def test_CLOCK_BOOTTIME_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import CLOCK_BOOTTIME"))
def test_CLOCK_HIGHRES_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_HIGHRES"))
def test_CLOCK_MONOTONIC_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_MONOTONIC"))
def test_CLOCK_MONOTONIC_RAW_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_MONOTONIC_RAW"))
def test_CLOCK_MONOTONIC_RAW_APPROX_of_time(self):
self.assertOnlyIn((3, 13), self.detect("from time import CLOCK_MONOTONIC_RAW_APPROX"))
def test_CLOCK_PROCESS_CPUTIME_ID_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_PROCESS_CPUTIME_ID"))
def test_CLOCK_THREAD_CPUTIME_ID_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_THREAD_CPUTIME_ID"))
def test_CLOCK_PROF_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import CLOCK_PROF"))
def test_CLOCK_UPTIME_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import CLOCK_UPTIME"))
def test_CLOCK_UPTIME_RAW_of_time(self):
self.assertOnlyIn((3, 8), self.detect("from time import CLOCK_UPTIME_RAW"))
def test_CLOCK_UPTIME_RAW_APPROX_of_time(self):
self.assertOnlyIn((3, 13), self.detect("from time import CLOCK_UPTIME_RAW_APPROX"))
def test_CLOCK_REALTIME_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import CLOCK_REALTIME"))
def test_CLOCK_TAI_of_time(self):
self.assertOnlyIn((3, 9), self.detect("from time import CLOCK_TAI"))
def test_cssclass_noday_of_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"c=HTMLCalendar()\nc.cssclass_noday"))
def test_cssclasses_weekday_head_of_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"c=HTMLCalendar()\nc.cssclasses_weekday_head"))
def test_cssclass_month_head_of_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"c=HTMLCalendar()\nc.cssclass_month_head"))
def test_cssclass_year_of_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"c=HTMLCalendar()\nc.cssclass_year"))
def test_cssclass_year_head_of_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"c=HTMLCalendar()\nc.cssclass_year_head"))
def test_MONDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.MONDAY
"""))
def test_TUESDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.TUESDAY
"""))
def test_WEDNESDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.WEDNESDAY
"""))
def test_THURSDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.THURSDAY
"""))
def test_FRIDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.FRIDAY
"""))
def test_SATURDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.SATURDAY
"""))
def test_SUNDAY_of_calendar_Day(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Day
day = Day.SUNDAY
"""))
def test_MONDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import MONDAY"))
def test_TUESDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import TUESDAY"))
def test_WEDNESDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import WEDNESDAY"))
def test_THURSDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import THURSDAY"))
def test_FRIDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import FRIDAY"))
def test_SATURDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import SATURDAY"))
def test_SUNDAY_of_calendar(self):
self.assertOnlyIn((3, 10), self.detect("from calendar import SUNDAY"))
def test_JANUARY_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.JANUARY
"""))
def test_FEBRUARY_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.FEBRUARY
"""))
def test_MARCH_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.MARCH
"""))
def test_APRIL_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.APRIL
"""))
def test_MAY_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.MAY
"""))
def test_JUNE_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.JUNE
"""))
def test_JULY_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.JULY
"""))
def test_AUGUST_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.AUGUST
"""))
def test_SEPTEMBER_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.SEPTEMBER
"""))
def test_OCTOBER_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.OCTOBER
"""))
def test_NOVEMBER_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.NOVEMBER
"""))
def test_DECEMBER_of_calendar_Month(self):
self.assertOnlyIn((3, 12), self.detect("""
from calendar import Month
month = Month.DECEMBER
"""))
def test_JANUARY_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import JANUARY"))
def test_FEBRUARY_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import FEBRUARY"))
def test_MARCH_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import MARCH"))
def test_APRIL_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import APRIL"))
def test_MAY_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import MAY"))
def test_JUNE_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import JUNE"))
def test_JULY_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import JULY"))
def test_AUGUST_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import AUGUST"))
def test_SEPTEMBER_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import SEPTEMBER"))
def test_OCTOBER_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import OCTOBER"))
def test_NOVEMBER_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import NOVEMBER"))
def test_DECEMBER_of_calendar(self):
self.assertOnlyIn((3, 12), self.detect("from calendar import DECEMBER"))
def test_tau_of_cmath(self):
self.assertOnlyIn((3, 6), self.detect("from cmath import tau"))
def test_inf_of_cmath(self):
self.assertOnlyIn((3, 6), self.detect("from cmath import inf"))
def test_infj_of_cmath(self):
self.assertOnlyIn((3, 6), self.detect("from cmath import infj"))
def test_nan_of_cmath(self):
self.assertOnlyIn((3, 6), self.detect("from cmath import nan"))
def test_nanj_of_cmath(self):
self.assertOnlyIn((3, 6), self.detect("from cmath import nanj"))
def test_FAIL_FAST_of_doctest(self):
self.assertOnlyIn((3, 4), self.detect("import doctest\ndoctest.FAIL_FAST"))
def test_ACCESS_DEFAULT_of_mmap(self):
self.assertOnlyIn((3, 7), self.detect("import mmap\nmmap.ACCESS_DEFAULT"))
def test_MADV_NORMAL_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_NORMAL"))
def test_MADV_RANDOM_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_RANDOM"))
def test_MADV_SEQUENTIAL_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_SEQUENTIAL"))
def test_MADV_WILLNEED_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_WILLNEED"))
def test_MADV_DONTNEED_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_DONTNEED"))
def test_MADV_REMOVE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_REMOVE"))
def test_MADV_DONTFORK_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_DONTFORK"))
def test_MADV_DOFORK_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_DOFORK"))
def test_MADV_HWPOISON_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_HWPOISON"))
def test_MADV_MERGEABLE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_MERGEABLE"))
def test_MADV_UNMERGEABLE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_UNMERGEABLE"))
def test_MADV_SOFT_OFFLINE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_SOFT_OFFLINE"))
def test_MADV_HUGEPAGE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_HUGEPAGE"))
def test_MADV_NOHUGEPAGE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_NOHUGEPAGE"))
def test_MADV_DONTDUMP_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_DONTDUMP"))
def test_MADV_DODUMP_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_DODUMP"))
def test_MADV_FREE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_FREE"))
def test_MADV_FREE_REUSABLE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_FREE_REUSABLE"))
def test_MADV_FREE_REUSE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_FREE_REUSE"))
def test_MADV_NOSYNC_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_NOSYNC"))
def test_MADV_AUTOSYNC_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_AUTOSYNC"))
def test_MADV_NOCORE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_NOCORE"))
def test_MADV_CORE_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_CORE"))
def test_MADV_PROTECT_of_mmap(self):
self.assertOnlyIn((3, 8), self.detect("import mmap\nmmap.MADV_PROTECT"))
def test_MAP_POPULATE_of_mmap(self):
self.assertOnlyIn((3, 10), self.detect("import mmap\nmmap.MAP_POPULATE"))
def test_MAP_STACK_of_mmap(self):
self.assertOnlyIn((3, 11), self.detect("import mmap\nmmap.MAP_STACK"))
def test_MAP_32BIT_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_32BIT"))
def test_MAP_HASSEMAPHORE_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_HASSEMAPHORE"))
def test_MAP_JIT_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_JIT"))
def test_MAP_NOCACHE_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_NOCACHE"))
def test_MAP_NOEXTEND_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_NOEXTEND"))
def test_MAP_NORESERVE_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_NORESERVE"))
def test_MAP_RESILIENT_CODESIGN_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_RESILIENT_CODESIGN"))
def test_MAP_RESILIENT_MEDIA_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_RESILIENT_MEDIA"))
def test_MAP_TPRO_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_TPRO"))
def test_MAP_TRANSLATED_ALLOW_EXECUTE_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_TRANSLATED_ALLOW_EXECUTE"))
def test_MAP_UNIX03_of_mmap(self):
self.assertOnlyIn((3, 13), self.detect("import mmap\nmmap.MAP_UNIX03"))
def test_MFD_CLOEXEC_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_CLOEXEC"))
def test_MFD_ALLOW_SEALING_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_ALLOW_SEALING"))
def test_MFD_HUGETLB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGETLB"))
def test_MFD_HUGE_SHIFT_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_SHIFT"))
def test_MFD_HUGE_MASK_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_MASK"))
def test_MFD_HUGE_64KB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_64KB"))
def test_MFD_HUGE_512KB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_512KB"))
def test_MFD_HUGE_1MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_1MB"))
def test_MFD_HUGE_2MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_2MB"))
def test_MFD_HUGE_8MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_8MB"))
def test_MFD_HUGE_16MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_16MB"))
def test_MFD_HUGE_32MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_32MB"))
def test_MFD_HUGE_256MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_256MB"))
def test_MFD_HUGE_512MB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_512MB"))
def test_MFD_HUGE_1GB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_1GB"))
def test_MFD_HUGE_2GB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_2GB"))
def test_MFD_HUGE_16GB_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import MFD_HUGE_16GB"))
def test_XATTR_SIZE_MAX_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import XATTR_SIZE_MAX"))
def test_XATTR_CREATE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import XATTR_CREATE"))
def test_XATTR_REPLACE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import XATTR_REPLACE"))
def test_ncurses_version_of_curses(self):
self.assertOnlyIn((3, 8), self.detect("from curses import ncurses_version"))
def test_A_ITALIC_of_curses(self):
self.assertOnlyIn((3, 7), self.detect("from curses import A_ITALIC"))
def test_FMT_XML_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import FMT_XML"))
def test_FMT_BINARY_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import FMT_BINARY"))
def test_TIMEOUT_MAX_of_threading(self):
self.assertOnlyIn((3, 2), self.detect("from threading import TIMEOUT_MAX"))
def test_pycache_prefix_of_sys(self):
self.assertOnlyIn((3, 8), self.detect("from sys import pycache_prefix"))
def test_POSIX_SPAWN_OPEN_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import POSIX_SPAWN_OPEN"))
def test_POSIX_SPAWN_CLOSE_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import POSIX_SPAWN_CLOSE"))
def test_POSIX_SPAWN_DUP2_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import POSIX_SPAWN_DUP2"))
def test_OP_ENABLE_MIDDLEBOX_COMPAT_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from ssl import OP_ENABLE_MIDDLEBOX_COMPAT"))
def test_S_IFDOOR_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_IFDOOR"))
def test_S_IFPORT_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_IFPORT"))
def test_S_IFWHT_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_IFWHT"))
def test_FILE_ATTRIBUTE_ARCHIVE_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_ARCHIVE"))
def test_FILE_ATTRIBUTE_COMPRESSED_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_COMPRESSED"))
def test_FILE_ATTRIBUTE_DEVICE_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_DEVICE"))
def test_FILE_ATTRIBUTE_DIRECTORY_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_DIRECTORY"))
def test_FILE_ATTRIBUTE_ENCRYPTED_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_ENCRYPTED"))
def test_FILE_ATTRIBUTE_HIDDEN_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_HIDDEN"))
def test_FILE_ATTRIBUTE_INTEGRITY_STREAM_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_INTEGRITY_STREAM"))
def test_FILE_ATTRIBUTE_NORMAL_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_NORMAL"))
def test_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_NOT_CONTENT_INDEXED"))
def test_FILE_ATTRIBUTE_NO_SCRUB_DATA_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_NO_SCRUB_DATA"))
def test_FILE_ATTRIBUTE_OFFLINE_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_OFFLINE"))
def test_FILE_ATTRIBUTE_READONLY_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_READONLY"))
def test_FILE_ATTRIBUTE_REPARSE_POINT_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_REPARSE_POINT"))
def test_FILE_ATTRIBUTE_SPARSE_FILE_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_SPARSE_FILE"))
def test_FILE_ATTRIBUTE_SYSTEM_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_SYSTEM"))
def test_FILE_ATTRIBUTE_TEMPORARY_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_TEMPORARY"))
def test_FILE_ATTRIBUTE_VIRTUAL_of_stat(self):
self.assertOnlyIn((3, 5), self.detect("from stat import FILE_ATTRIBUTE_VIRTUAL"))
def test_IO_REPARSE_TAG_SYMLINK_of_stat(self):
self.assertOnlyIn((3, 8), self.detect("from stat import IO_REPARSE_TAG_SYMLINK"))
def test_IO_REPARSE_TAG_MOUNT_POINT_of_stat(self):
self.assertOnlyIn((3, 8), self.detect("from stat import IO_REPARSE_TAG_MOUNT_POINT"))
def test_IO_REPARSE_TAG_APPEXECLINK_of_stat(self):
self.assertOnlyIn((3, 8), self.detect("from stat import IO_REPARSE_TAG_APPEXECLINK"))
def test_ABOVE_NORMAL_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import ABOVE_NORMAL_PRIORITY_CLASS"))
def test_BELOW_NORMAL_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import BELOW_NORMAL_PRIORITY_CLASS"))
def test_HIGH_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import HIGH_PRIORITY_CLASS"))
def test_IDLE_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import IDLE_PRIORITY_CLASS"))
def test_NORMAL_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import NORMAL_PRIORITY_CLASS"))
def test_REALTIME_PRIORITY_CLASS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import REALTIME_PRIORITY_CLASS"))
def test_STARTF_FORCEONFEEDBACK_of_subprocess(self):
self.assertOnlyIn((3, 13), self.detect("from subprocess import STARTF_FORCEONFEEDBACK"))
def test_STARTF_FORCEOFFFEEDBACK_of_subprocess(self):
self.assertOnlyIn((3, 13), self.detect("from subprocess import STARTF_FORCEOFFFEEDBACK"))
def test_CREATE_NO_WINDOW_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import CREATE_NO_WINDOW"))
def test_DETACHED_PROCESS_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import DETACHED_PROCESS"))
def test_CREATE_DEFAULT_ERROR_MODE_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import CREATE_DEFAULT_ERROR_MODE"))
def test_CREATE_BREAKAWAY_FROM_JOB_of_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("from subprocess import CREATE_BREAKAWAY_FROM_JOB"))
def test_error_content_type_from_BaseHTTPServer_BaseHTTPRequestHandler(self):
self.assertOnlyIn((2, 6),
self.detect("from BaseHTTPServer import BaseHTTPRequestHandler\n"
"BaseHTTPRequestHandler().error_content_type"))
def test_httponly_from_Cookie_Morsel(self):
self.assertOnlyIn((2, 6),
self.detect("from Cookie import Morsel\n"
"Morsel().httponly"))
def test_TIMEOUT_MAX_of__thread(self):
self.assertOnlyIn((3, 2), self.detect("from _thread import TIMEOUT_MAX"))
def test_cssclass_month_from_calendar_HTMLCalendar(self):
self.assertOnlyIn((3, 7),
self.detect("from calendar import HTMLCalendar\n"
"HTMLCalendar().cssclass_month"))
def test__field_defaults_from_collections_namedtuple(self):
self.assertOnlyIn((3, 7),
self.detect("from collections import namedtuple\n"
"namedtuple()._field_defaults"))
def test_lineno_from_configparser_DuplicateSectionError(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError().lineno"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError().lineno"))
def test_source_from_configparser_DuplicateSectionError(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError().source"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError().source"))
def test_source_from_configparser_ParsingError(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ParsingError\n"
"ParsingError().source"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ParsingError\n"
"ParsingError().source"))
def test_rfc2109_from_cookielib_Cookie(self):
self.assertOnlyIn((2, 5),
self.detect("from cookielib import Cookie\n"
"Cookie().rfc2109"))
def test_rfc2109_as_netscape_from_cookielib_DefaultCookiePolicy(self):
self.assertOnlyIn((2, 5),
self.detect("from cookielib import DefaultCookiePolicy\n"
"DefaultCookiePolicy().rfc2109_as_netscape"))
def test_fieldnames_from_csv_csvreader(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from csv import csvreader\n"
"csvreader().fieldnames"))
def test_line_num_from_csv_csvreader(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from csv import csvreader\n"
"csvreader().line_num"))
def test_QUOTE_NOTNULL_from_csv(self):
self.assertOnlyIn((3, 12), self.detect("from csv import QUOTE_NOTNULL"))
def test_QUOTE_STRINGS_from_csv(self):
self.assertOnlyIn((3, 12), self.detect("from csv import QUOTE_STRINGS"))
def test_encoding_from_curses_window(self):
self.assertOnlyIn((3, 3),
self.detect("from curses import window\n"
"window().encoding"))
def test_bjunk_from_difflib_SequenceMatcher(self):
self.assertOnlyIn((3, 2),
self.detect("from difflib import SequenceMatcher\n"
"SequenceMatcher().bjunk"))
def test_bpopular_from_difflib_SequenceMatcher(self):
self.assertOnlyIn((3, 2),
self.detect("from difflib import SequenceMatcher\n"
"SequenceMatcher().bpopular"))
def test_positions_of_dis_Instruction(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.Instruction().positions"))
def test_COMPARISON_FLAGS_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import COMPARISON_FLAGS"))
def test_DONT_ACCEPT_BLANKLINE_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import DONT_ACCEPT_BLANKLINE"))
def test_ELLIPSIS_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import ELLIPSIS"))
def test_IGNORE_EXCEPTION_DETAIL_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import IGNORE_EXCEPTION_DETAIL"))
def test_NORMALIZE_WHITESPACE_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import NORMALIZE_WHITESPACE"))
def test_REPORTING_FLAGS_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import REPORTING_FLAGS"))
def test_REPORT_CDIFF_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import REPORT_CDIFF"))
def test_REPORT_NDIFF_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import REPORT_NDIFF"))
def test_REPORT_ONLY_FIRST_FAILURE_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"from doctest import REPORT_ONLY_FIRST_FAILURE"))
def test_REPORT_UDIFF_of_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from doctest import REPORT_UDIFF"))
def test_SKIP_of_doctest(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from doctest import SKIP"))
def test_defects_from_email_message_Message(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.message import Message\n"
"Message().defects"))
def test_content_manager_from_email_policy_EmailPolicy(self):
self.assertOnlyIn((3, 4),
self.detect("from email.policy import EmailPolicy\n"
"EmailPolicy().content_manager"))
def test_message_factory_from_email_policy_Policy(self):
self.assertOnlyIn((3, 6),
self.detect("from email.policy import Policy\n"
"Policy().message_factory"))
def test_utf8_of_email_policy_EmailPolicy(self):
self.assertOnlyIn((3, 5),
self.detect("from email.policy import EmailPolicy\n"
"EmailPolicy.utf8"))
def test_EHWPOISON_of_errno(self):
self.assertOnlyIn((3, 14), self.detect("from errno import EHWPOISON"))
def test_EQFULL_of_errno(self):
self.assertOnlyIn((3, 11), self.detect("from errno import EQFULL"))
def test_F_ADD_SEALS_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_ADD_SEALS"))
def test_F_DUP2FD_of_fcntl(self):
self.assertOnlyIn((3, 11), self.detect("from fcntl import F_DUP2FD"))
def test_F_DUP2FD_CLOEXEC_of_fcntl(self):
self.assertOnlyIn((3, 11), self.detect("from fcntl import F_DUP2FD_CLOEXEC"))
def test_F_GET_SEALS_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_GET_SEALS"))
def test_F_SEAL_GROW_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_SEAL_GROW"))
def test_F_SEAL_SEAL_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_SEAL_SEAL"))
def test_F_SEAL_SHRINK_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_SEAL_SHRINK"))
def test_F_SEAL_WRITE_of_fcntl(self):
self.assertOnlyIn((3, 8), self.detect("from fcntl import F_SEAL_WRITE"))
def test_F_OFD_GETLK_of_fcntl(self):
self.assertOnlyIn((3, 9), self.detect("from fcntl import F_OFD_GETLK"))
def test_F_OFD_SETLK_of_fcntl(self):
self.assertOnlyIn((3, 9), self.detect("from fcntl import F_OFD_SETLK"))
def test_F_OFD_SETLKW_of_fcntl(self):
self.assertOnlyIn((3, 9), self.detect("from fcntl import F_OFD_SETLKW"))
def test_DEFAULT_IGNORES_of_filecmp(self):
self.assertOnlyIn((3, 4), self.detect("from filecmp import DEFAULT_IGNORES"))
def test_Placeholder_of_functools(self):
self.assertOnlyIn((3, 14), self.detect("from functools import Placeholder"))
def test_callbacks_of_gc(self):
self.assertOnlyIn((3, 3), self.detect("from gc import callbacks"))
def test_mtime_from_gzip_GzipFile(self):
self.assertOnlyIn((3, 1),
self.detect("from gzip import GzipFile\n"
"GzipFile().mtime"))
def test_name_from_hashlib_hash(self):
self.assertOnlyIn((3, 4),
self.detect("from hashlib import hash\n"
"hash().name"))
def test_codepoint2name_of_htmlentitydefs(self):
self.assertOnlyIn((2, 3), self.detect("from htmlentitydefs import codepoint2name"))
def test_name2codepoint_of_htmlentitydefs(self):
self.assertOnlyIn((2, 3), self.detect("from htmlentitydefs import name2codepoint"))
def test_MISDIRECTED_REQUEST_from_http_HTTPStatus(self):
self.assertOnlyIn((3, 7),
self.detect("from http import HTTPStatus\n"
"HTTPStatus().MISDIRECTED_REQUEST"))
def test_UNAVAILABLE_FOR_LEGAL_REASONS_from_http_HTTPStatus(self):
self.assertOnlyIn((3, 8),
self.detect("from http import HTTPStatus\n"
"HTTPStatus().UNAVAILABLE_FOR_LEGAL_REASONS"))
def test_EARLY_HINTS_from_http_HTTPStatus(self):
self.assertOnlyIn((3, 9),
self.detect("from http import HTTPStatus\n"
"HTTPStatus().EARLY_HINTS"))
def test_IM_A_TEAPOT_from_http_HTTPStatus(self):
self.assertOnlyIn((3, 9),
self.detect("from http import HTTPStatus\n"
"HTTPStatus().IM_A_TEAPOT"))
def test_TOO_EARLY_from_http_HTTPStatus(self):
self.assertOnlyIn((3, 9),
self.detect("from http import HTTPStatus\n"
"HTTPStatus().TOO_EARLY"))
def test_blocksize_from_http_client_HTTPConnection(self):
self.assertOnlyIn((3, 7),
self.detect("from http.client import HTTPConnection\n"
"HTTPConnection().blocksize"))
def test_responses_of_httplib(self):
self.assertOnlyIn((2, 5), self.detect("from httplib import responses"))
def test_utf8_enabled_from_imaplib_IMAP4(self):
self.assertOnlyIn((3, 5),
self.detect("from imaplib import IMAP4\n"
"IMAP4().utf8_enabled"))
def test_description_from_inspect_Parameter_kind(self):
self.assertOnlyIn((3, 8),
self.detect("from inspect.Parameter import kind\n"
"kind().description"))
def test_SEEK_CUR_of_io(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from io import SEEK_CUR"))
def test_SEEK_END_of_io(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from io import SEEK_END"))
def test_SEEK_SET_of_io(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from io import SEEK_SET"))
def test_write_through_from_io_TextIOWrapper(self):
self.assertOnlyIn((3, 7),
self.detect("from io import TextIOWrapper\n"
"TextIOWrapper().write_through"))
def test_default_msec_format_from_logging_Formatter(self):
self.assertOnlyIn((3, 3),
self.detect("from logging import Formatter\n"
"Formatter().default_msec_format"))
def test_default_time_format_from_logging_Formatter(self):
self.assertOnlyIn((3, 3),
self.detect("from logging import Formatter\n"
"Formatter().default_time_format"))
def test_funcName_from_logging_LogRecord(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import LogRecord\n"
"LogRecord().funcName"))
def test_processName_from_logging_LogRecord(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging import LogRecord\n"
"LogRecord().processName"))
def test_manager_from_logging_LoggerAdapter(self):
self.assertOnlyIn((3, 6),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter().manager"))
def test_terminator_from_logging_StreamHandler(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import StreamHandler\n"
"StreamHandler().terminator"))
def test_namer_from_logging_handlers_BaseRotatingHandler(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import BaseRotatingHandler\n"
"BaseRotatingHandler().namer"))
def test_rotator_from_logging_handlers_BaseRotatingHandler(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import BaseRotatingHandler\n"
"BaseRotatingHandler().rotator"))
def test_needs_input_from_lzma_LZMADecompressor(self):
self.assertOnlyIn((3, 5),
self.detect("from lzma import LZMADecompressor\n"
"LZMADecompressor().needs_input"))
def test_version_of_marshal(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from marshal import version"))
def test_closed_from_mmap_mmap(self):
self.assertOnlyIn((3, 2),
self.detect("from mmap import mmap\n"
"mmap().closed"))
def test_nntp_implementation_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().nntp_implementation"))
def test_nntp_version_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().nntp_version"))
def test_CLD_CONTINUED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import CLD_CONTINUED"))
def test_CLD_DUMPED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import CLD_DUMPED"))
def test_CLD_EXITED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import CLD_EXITED"))
def test_CLD_TRAPPED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import CLD_TRAPPED"))
def test_CLD_KILLED_of_os(self):
self.assertOnlyIn((3, 9), self.detect("from os import CLD_KILLED"))
def test_CLD_STOPPED_of_os(self):
self.assertOnlyIn((3, 9), self.detect("from os import CLD_STOPPED"))
def test_EX_CANTCREAT_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_CANTCREAT"))
def test_EX_CONFIG_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_CONFIG"))
def test_EX_DATAERR_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_DATAERR"))
def test_EX_IOERR_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_IOERR"))
def test_EX_NOHOST_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_NOHOST"))
def test_EX_NOINPUT_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_NOINPUT"))
def test_EX_NOPERM_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_NOPERM"))
def test_EX_NOTFOUND_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_NOTFOUND"))
def test_EX_NOUSER_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_NOUSER"))
def test_EX_OK_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_OK"))
def test_EX_OSERR_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_OSERR"))
def test_EX_OSFILE_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_OSFILE"))
def test_EX_PROTOCOL_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_PROTOCOL"))
def test_EX_SOFTWARE_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_SOFTWARE"))
def test_EX_TEMPFAIL_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_TEMPFAIL"))
def test_EX_UNAVAILABLE_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_UNAVAILABLE"))
def test_EX_USAGE_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import EX_USAGE"))
def test_GRND_NONBLOCK_of_os(self):
self.assertOnlyIn((3, 6), self.detect("from os import GRND_NONBLOCK"))
def test_GRND_RANDOM_of_os(self):
self.assertOnlyIn((3, 6), self.detect("from os import GRND_RANDOM"))
def test_P_ALL_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import P_ALL"))
def test_P_PGID_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import P_PGID"))
def test_P_PID_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import P_PID"))
def test_RTLD_DEEPBIND_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_DEEPBIND"))
def test_RTLD_GLOBAL_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_GLOBAL"))
def test_RTLD_LAZY_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_LAZY"))
def test_RTLD_LOCAL_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_LOCAL"))
def test_RTLD_NODELETE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_NODELETE"))
def test_RTLD_NOLOAD_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_NOLOAD"))
def test_RTLD_NOW_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import RTLD_NOW"))
def test_RWF_DSYNC_of_os(self):
self.assertOnlyIn((3, 7), self.detect("from os import RWF_DSYNC"))
def test_RWF_HIPRI_of_os(self):
self.assertOnlyIn((3, 7), self.detect("from os import RWF_HIPRI"))
def test_RWF_NOWAIT_of_os(self):
self.assertOnlyIn((3, 7), self.detect("from os import RWF_NOWAIT"))
def test_RWF_SYNC_of_os(self):
self.assertOnlyIn((3, 7), self.detect("from os import RWF_SYNC"))
def test_RWF_APPEND_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import RWF_APPEND"))
def test_SCHED_BATCH_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_BATCH"))
def test_SCHED_DEADLINE_of_os(self):
self.assertOnlyIn((3, 14), self.detect("from os import SCHED_DEADLINE"))
def test_SCHED_FIFO_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_FIFO"))
def test_SCHED_IDLE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_IDLE"))
def test_SCHED_NORMAL_of_os(self):
self.assertOnlyIn((3, 14), self.detect("from os import SCHED_NORMAL"))
def test_SCHED_OTHER_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_OTHER"))
def test_SCHED_RESET_ON_FORK_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_RESET_ON_FORK"))
def test_SCHED_RR_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_RR"))
def test_SCHED_SPORADIC_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SCHED_SPORADIC"))
def test_SEEK_CUR_of_os(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from os import SEEK_CUR"))
def test_SEEK_DATA_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SEEK_DATA"))
def test_SEEK_END_of_os(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from os import SEEK_END"))
def test_SEEK_HOLE_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import SEEK_HOLE"))
def test_SEEK_SET_of_os(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from os import SEEK_SET"))
def test_ST_APPEND_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_APPEND"))
def test_ST_IMMUTABLE_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_IMMUTABLE"))
def test_ST_MANDLOCK_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_MANDLOCK"))
def test_ST_NOATIME_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_NOATIME"))
def test_ST_NODEV_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_NODEV"))
def test_ST_NODIRATIME_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_NODIRATIME"))
def test_ST_NOEXEC_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_NOEXEC"))
def test_ST_NOSUID_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import ST_NOSUID"))
def test_ST_RDONLY_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import ST_RDONLY"))
def test_ST_RELATIME_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_RELATIME"))
def test_ST_SYNCHRONOUS_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_SYNCHRONOUS"))
def test_ST_WRITE_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import ST_WRITE"))
def test_WCONTINUED_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import WCONTINUED"))
def test_WEXITED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import WEXITED"))
def test_WNOWAIT_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import WNOWAIT"))
def test_WSTOPPED_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import WSTOPPED"))
def test_WUNTRACED_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import WUNTRACED"))
def test__COPYFILE_ACL_of_os(self):
self.assertOnlyIn((3, 11), self.detect("from os import _COPYFILE_ACL"))
def test__COPYFILE_STAT_of_os(self):
self.assertOnlyIn((3, 11), self.detect("from os import _COPYFILE_STAT"))
def test__COPYFILE_XATTR_of_os(self):
self.assertOnlyIn((3, 11), self.detect("from os import _COPYFILE_XATTR"))
def test_devnull_of_os(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from os import devnull"))
def test_extsep_of_os(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from os import extsep"))
def test_killpg_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import killpg"))
def test_P_PIDFD_of_os(self):
self.assertOnlyIn((3, 9), self.detect("from os import P_PIDFD"))
def test_SPLICE_F_MOVE_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import SPLICE_F_MOVE"))
def test_SPLICE_F_NONBLOCK_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import SPLICE_F_NONBLOCK"))
def test_SPLICE_F_MORE_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import SPLICE_F_MORE"))
def test_EFD_CLOEXEC_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import EFD_CLOEXEC"))
def test_EFD_NONBLOCK_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import EFD_NONBLOCK"))
def test_EFD_SEMAPHORE_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import EFD_SEMAPHORE"))
def test_st_atime_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_atime"))
def test_st_atime_ns_from_os_stat(self):
self.assertOnlyIn((3, 3),
self.detect("from os import stat\n"
"stat().st_atime_ns"))
def test_st_attrs_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_attrs"))
def test_st_birthtime_from_os_stat(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from os import stat\n"
"stat().st_birthtime"))
def test_st_birthtime_ns_from_os_stat(self):
self.assertOnlyIn((3, 12),
self.detect("from os import stat\n"
"stat().st_birthtime_ns"))
def test_st_blksize_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_blksize"))
def test_st_blocks_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_blocks"))
def test_st_ctime_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_ctime"))
def test_st_ctime_ns_from_os_stat(self):
self.assertOnlyIn((3, 3),
self.detect("from os import stat\n"
"stat().st_ctime_ns"))
def test_st_dev_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_dev"))
def test_st_file_attributes_from_os_stat(self):
self.assertOnlyIn((3, 5),
self.detect("from os import stat\n"
"stat().st_file_attributes"))
def test_st_flags_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_flags"))
def test_st_ftype_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_ftype"))
def test_st_gen_from_os_stat(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from os import stat\n"
"stat().st_gen"))
def test_st_gid_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_gid"))
def test_st_ino_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_ino"))
def test_st_mode_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_mode"))
def test_st_mtime_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_mtime"))
def test_st_mtime_ns_from_os_stat(self):
self.assertOnlyIn((3, 3),
self.detect("from os import stat\n"
"stat().st_mtime_ns"))
def test_st_nlink_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_nlink"))
def test_st_obtype_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_obtype"))
def test_st_rdev_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_rdev"))
def test_st_reparse_tag_from_os_stat(self):
self.assertOnlyIn((3, 8),
self.detect("from os import stat\n"
"stat().st_reparse_tag"))
def test_st_size_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_size"))
def test_st_uid_from_os_stat(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import stat\n"
"stat().st_uid"))
def test_f_bavail_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_bavail"))
def test_f_bfree_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_bfree"))
def test_f_blocks_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_blocks"))
def test_f_bsize_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_bsize"))
def test_f_favail_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_favail"))
def test_f_ffree_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_ffree"))
def test_f_files_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_files"))
def test_f_flag_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_flag"))
def test_f_frsize_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_frsize"))
def test_f_fsid_from_os_statvfs(self):
self.assertOnlyIn((3, 7),
self.detect("from os import statvfs\n"
"statvfs().f_fsid"))
def test_f_namemax_from_os_statvfs(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from os import statvfs\n"
"statvfs().f_namemax"))
def test_supports_dir_fd_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import supports_dir_fd"))
def test_supports_effective_ids_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import supports_effective_ids"))
def test_supports_fd_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import supports_fd"))
def test_supports_follow_symlinks_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import supports_follow_symlinks"))
def test_info_of_pathlib(self):
self.assertOnlyIn((3, 14), self.detect("from pathlib import info"))
def test_HIGHEST_PROTOCOL_of_pickle(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from pickle import HIGHEST_PROTOCOL"))
def test_dispatch_table_from_pickle_Pickler(self):
self.assertOnlyIn((3, 3),
self.detect("from pickle import Pickler\n"
"Pickler().dispatch_table"))
def test_SortKey_of_pstats(self):
self.assertOnlyIn((3, 7), self.detect("from pstats import SortKey"))
def test_children_from_pyclbr_Class(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Class\n"
"Class().children"))
def test_end_lineno_from_pyclbr_Class(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Class\n"
"Class().end_lineno"))
def test_parent_from_pyclbr_Class(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Class\n"
"Class().parent"))
def test_children_from_pyclbr_Function(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Function\n"
"Function().children"))
def test_end_lineno_from_pyclbr_Function(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Function\n"
"Function().end_lineno"))
def test_parent_from_pyclbr_Function(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Function\n"
"Function().parent"))
def test_is_async_from_pyclbr_Function(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Function\n"
"Function().is_async"))
def test_NOFLAG_of_re(self):
self.assertOnlyIn((3, 11), self.detect("from re import NOFLAG"))
def test_U_of_re(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("from re import U"))
def test_UNICODE_of_re(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("from re import UNICODE"))
def test_colno_from_re_error(self):
self.assertOnlyIn((3, 5),
self.detect("from re import error\n"
"error().colno"))
def test_lineno_from_re_error(self):
self.assertOnlyIn((3, 5),
self.detect("from re import error\n"
"error().lineno"))
def test_msg_from_re_error(self):
self.assertOnlyIn((3, 5),
self.detect("from re import error\n"
"error().msg"))
def test_pattern_from_re_error(self):
self.assertOnlyIn((3, 5),
self.detect("from re import error\n"
"error().pattern"))
def test_pos_from_re_error(self):
self.assertOnlyIn((3, 5),
self.detect("from re import error\n"
"error().pos"))
def test_fillvalue_from_reprlib_Repr(self):
self.assertOnlyIn((3, 11),
self.detect("from reprlib import Repr\n"
"Repr().fillvalue"))
def test_maxfrozenset_from_repr_Repr(self):
self.assertOnlyIn((2, 4),
self.detect("from repr import Repr\n"
"Repr().maxfrozenset"))
def test_maxset_from_repr_Repr(self):
self.assertOnlyIn((2, 4),
self.detect("from repr import Repr\n"
"Repr().maxset"))
def test_RLIMIT_MSGQUEUE_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_MSGQUEUE"))
def test_RLIMIT_NICE_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_NICE"))
def test_RLIMIT_NPTS_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_NPTS"))
def test_RLIMIT_KQUEUES_of_resource(self):
self.assertOnlyIn((3, 10), self.detect("from resource import RLIMIT_KQUEUES"))
def test_RLIMIT_RTPRIO_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_RTPRIO"))
def test_RLIMIT_RTTIME_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_RTTIME"))
def test_RLIMIT_SBSIZE_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_SBSIZE"))
def test_RLIMIT_SIGPENDING_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_SIGPENDING"))
def test_RLIMIT_SWAP_of_resource(self):
self.assertOnlyIn((3, 4), self.detect("from resource import RLIMIT_SWAP"))
def test_RUSAGE_THREAD_of_resource(self):
self.assertOnlyIn((3, 2), self.detect("from resource import RUSAGE_THREAD"))
def test_ru_idrss_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_idrss"))
def test_ru_inblock_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_inblock"))
def test_ru_isrss_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_isrss"))
def test_ru_ixrss_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_ixrss"))
def test_ru_majflt_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_majflt"))
def test_ru_maxrss_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_maxrss"))
def test_ru_minflt_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_minflt"))
def test_ru_msgrcv_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_msgrcv"))
def test_ru_msgsnd_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_msgsnd"))
def test_ru_nivcsw_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_nivcsw"))
def test_ru_nsignals_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_nsignals"))
def test_ru_nswap_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_nswap"))
def test_ru_nvcsw_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_nvcsw"))
def test_ru_oublock_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_oublock"))
def test_ru_stime_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_stime"))
def test_ru_utime_from_resource_getrusage(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from resource import getrusage\n"
"getrusage().ru_utime"))
def test_queue_from_sched_scheduler(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from sched import scheduler\n"
"scheduler().queue"))
def test_EPOLLEXCLUSIVE_of_select(self):
self.assertOnlyIn((3, 6), self.detect("from select import EPOLLEXCLUSIVE"))
def test_PIPE_BUF_of_select(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from select import PIPE_BUF"))
def test_closed_from_select_devpoll(self):
self.assertOnlyIn((3, 4),
self.detect("from select import devpoll\n"
"devpoll().closed"))
def test_eof_from_shlex_shlex(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shlex import shlex\n"
"shlex().eof"))
def test_escape_from_shlex_shlex(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shlex import shlex\n"
"shlex().escape"))
def test_escapedquotes_from_shlex_shlex(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shlex import shlex\n"
"shlex().escapedquotes"))
def test_punctuation_chars_from_shlex_shlex(self):
self.assertOnlyIn((3, 6),
self.detect("from shlex import shlex\n"
"shlex().punctuation_chars"))
def test_whitespace_split_from_shlex_shlex(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shlex import shlex\n"
"shlex().whitespace_split"))
def test_avoids_symlink_attacks_from_shutil_rmtree(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import rmtree\n"
"rmtree().avoids_symlink_attacks"))
def test_CTRL_BREAK_EVENT_of_signal(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from signal import CTRL_BREAK_EVENT"))
def test_CTRL_C_EVENT_of_signal(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from signal import CTRL_C_EVENT"))
def test_SIGSTKFLT_of_signal(self):
self.assertOnlyIn((3, 11), self.detect("from signal import SIGSTKFLT"))
def test_SIG_BLOCK_of_signal(self):
self.assertOnlyIn((3, 3), self.detect("from signal import SIG_BLOCK"))
def test_SIG_SETMASK_of_signal(self):
self.assertOnlyIn((3, 3), self.detect("from signal import SIG_SETMASK"))
def test_SIG_UNBLOCK_of_signal(self):
self.assertOnlyIn((3, 3), self.detect("from signal import SIG_UNBLOCK"))
def test_ENABLE_USER_SITE_of_site(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from site import ENABLE_USER_SITE"))
def test_PREFIXES_of_site(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from site import PREFIXES"))
def test_USER_BASE_of_site(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from site import USER_BASE"))
def test_USER_SITE_of_site(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from site import USER_SITE"))
def test_AF_ALG_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import AF_ALG"))
def test_AF_CAN_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import AF_CAN"))
def test_AF_LINK_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import AF_LINK"))
def test_AF_QIPCRTR_of_socket(self):
self.assertOnlyIn((3, 8), self.detect("from socket import AF_QIPCRTR"))
def test_AF_RDS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import AF_RDS"))
def test_AF_TIPC_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import AF_TIPC"))
def test_AF_VSOCK_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import AF_VSOCK"))
def test_ALG_OP_DECRYPT_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_OP_DECRYPT"))
def test_ALG_OP_ENCRYPT_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_OP_ENCRYPT"))
def test_ALG_OP_SIGN_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_OP_SIGN"))
def test_ALG_OP_VERIFY_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_OP_VERIFY"))
def test_ALG_SET_AEAD_ASSOCLEN_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_AEAD_ASSOCLEN"))
def test_ALG_SET_AEAD_AUTHSIZE_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_AEAD_AUTHSIZE"))
def test_ALG_SET_IV_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_IV"))
def test_ALG_SET_KEY_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_KEY"))
def test_ALG_SET_OP_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_OP"))
def test_ALG_SET_PUBKEY_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import ALG_SET_PUBKEY"))
def test_CAN_BCM_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM"))
def test_CAN_BCM_CAN_FD_FRAME_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_CAN_FD_FRAME"))
def test_CAN_BCM_RX_ANNOUNCE_RESUME_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_ANNOUNCE_RESUME"))
def test_CAN_BCM_RX_CHANGED_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_CHANGED"))
def test_CAN_BCM_RX_CHECK_DLC_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_CHECK_DLC"))
def test_CAN_BCM_RX_DELETE_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_DELETE"))
def test_CAN_BCM_RX_FILTER_ID_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_FILTER_ID"))
def test_CAN_BCM_RX_NO_AUTOTIMER_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_NO_AUTOTIMER"))
def test_CAN_BCM_RX_READ_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_READ"))
def test_CAN_BCM_RX_RTR_FRAME_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_RTR_FRAME"))
def test_CAN_BCM_RX_SETUP_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_SETUP"))
def test_CAN_BCM_RX_STATUS_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_STATUS"))
def test_CAN_BCM_RX_TIMEOUT_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_RX_TIMEOUT"))
def test_CAN_BCM_SETTIMER_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_SETTIMER"))
def test_CAN_BCM_STARTTIMER_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_STARTTIMER"))
def test_CAN_BCM_TX_ANNOUNCE_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_ANNOUNCE"))
def test_CAN_BCM_TX_COUNTEVT_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_COUNTEVT"))
def test_CAN_BCM_TX_CP_CAN_ID_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_CP_CAN_ID"))
def test_CAN_BCM_TX_DELETE_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_DELETE"))
def test_CAN_BCM_TX_EXPIRED_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_EXPIRED"))
def test_CAN_BCM_TX_READ_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_READ"))
def test_CAN_BCM_TX_RESET_MULTI_IDX_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_RESET_MULTI_IDX"))
def test_CAN_BCM_TX_SEND_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_SEND"))
def test_CAN_BCM_TX_SETUP_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_SETUP"))
def test_CAN_BCM_TX_STATUS_of_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import CAN_BCM_TX_STATUS"))
def test_CAN_EFF_FLAG_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_EFF_FLAG"))
def test_CAN_EFF_MASK_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_EFF_MASK"))
def test_CAN_ERR_FLAG_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_ERR_FLAG"))
def test_CAN_ERR_MASK_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_ERR_MASK"))
def test_CAN_ISOTP_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import CAN_ISOTP"))
def test_CAN_J1939_of_socket(self):
self.assertOnlyIn((3, 9), self.detect("from socket import CAN_J1939"))
def test_CAN_RAW_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RAW"))
def test_CAN_RAW_ERR_FILTER_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RAW_ERR_FILTER"))
def test_CAN_RAW_JOIN_FILTERS_of_socket(self):
self.assertOnlyIn((3, 9), self.detect("from socket import CAN_RAW_JOIN_FILTERS"))
def test_CAN_RAW_FD_FRAMES_of_socket(self):
self.assertOnlyIn((3, 5), self.detect("from socket import CAN_RAW_FD_FRAMES"))
def test_CAN_RAW_FILTER_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RAW_FILTER"))
def test_CAN_RAW_LOOPBACK_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RAW_LOOPBACK"))
def test_CAN_RAW_RECV_OWN_MSGS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RAW_RECV_OWN_MSGS"))
def test_CAN_RTR_FLAG_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_RTR_FLAG"))
def test_CAN_SFF_MASK_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CAN_SFF_MASK"))
def test_IOCTL_VM_SOCKETS_GET_LOCAL_CID_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import IOCTL_VM_SOCKETS_GET_LOCAL_CID"))
def test_PF_CAN_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import PF_CAN"))
def test_PF_RDS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import PF_RDS"))
def test_RCVALL_IPLEVEL_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import RCVALL_IPLEVEL"))
def test_RCVALL_MAX_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import RCVALL_MAX"))
def test_RCVALL_OFF_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import RCVALL_OFF"))
def test_RCVALL_ON_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import RCVALL_ON"))
def test_RCVALL_SOCKETLEVELONLY_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import RCVALL_SOCKETLEVELONLY"))
def test_RDS_CANCEL_SENT_TO_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CANCEL_SENT_TO"))
def test_RDS_CMSG_RDMA_ARGS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CMSG_RDMA_ARGS"))
def test_RDS_CMSG_RDMA_DEST_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CMSG_RDMA_DEST"))
def test_RDS_CMSG_RDMA_MAP_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CMSG_RDMA_MAP"))
def test_RDS_CMSG_RDMA_STATUS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CMSG_RDMA_STATUS"))
def test_RDS_CMSG_RDMA_UPDATE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CMSG_RDMA_UPDATE"))
def test_RDS_CONG_MONITOR_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_CONG_MONITOR"))
def test_RDS_FREE_MR_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_FREE_MR"))
def test_RDS_GET_MR_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_GET_MR"))
def test_RDS_GET_MR_FOR_DEST_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_GET_MR_FOR_DEST"))
def test_RDS_RDMA_DONTWAIT_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_DONTWAIT"))
def test_RDS_RDMA_FENCE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_FENCE"))
def test_RDS_RDMA_INVALIDATE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_INVALIDATE"))
def test_RDS_RDMA_NOTIFY_ME_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_NOTIFY_ME"))
def test_RDS_RDMA_READWRITE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_READWRITE"))
def test_RDS_RDMA_SILENT_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_SILENT"))
def test_RDS_RDMA_USE_ONCE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RDMA_USE_ONCE"))
def test_RDS_RECVERR_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import RDS_RECVERR"))
def test_SCM_CREDS2_of_socket(self):
self.assertOnlyIn((3, 11), self.detect("from socket import SCM_CREDS2"))
def test_SIO_KEEPALIVE_VALS_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import SIO_KEEPALIVE_VALS"))
def test_SIO_LOOPBACK_FAST_PATH_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SIO_LOOPBACK_FAST_PATH"))
def test_SIO_RCVALL_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import SIO_RCVALL"))
def test_SOCK_CLOEXEC_of_socket(self):
self.assertOnlyIn((3, 2), self.detect("from socket import SOCK_CLOEXEC"))
def test_SOCK_NONBLOCK_of_socket(self):
self.assertOnlyIn((3, 2), self.detect("from socket import SOCK_NONBLOCK"))
def test_SOL_ALG_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SOL_ALG"))
def test_SOL_CAN_BASE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import SOL_CAN_BASE"))
def test_SOL_CAN_RAW_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import SOL_CAN_RAW"))
def test_SOL_RDS_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import SOL_RDS"))
def test_SOL_TIPC_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import SOL_TIPC"))
def test_SO_DOMAIN_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SO_DOMAIN"))
def test_SO_INCOMING_CPU_of_socket(self):
self.assertOnlyIn((3, 11), self.detect("from socket import SO_INCOMING_CPU"))
def test_SO_PASSSEC_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SO_PASSSEC"))
def test_SO_PEERSEC_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SO_PEERSEC"))
def test_SO_PROTOCOL_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import SO_PROTOCOL"))
def test_SO_VM_SOCKETS_BUFFER_MAX_SIZE_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import SO_VM_SOCKETS_BUFFER_MAX_SIZE"))
def test_SO_VM_SOCKETS_BUFFER_MIN_SIZE_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import SO_VM_SOCKETS_BUFFER_MIN_SIZE"))
def test_SO_VM_SOCKETS_BUFFER_SIZE_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import SO_VM_SOCKETS_BUFFER_SIZE"))
def test_TCP_CONGESTION_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import TCP_CONGESTION"))
def test_TCP_CONNECTION_INFO_of_socket(self):
self.assertOnlyIn((3, 11), self.detect("from socket import TCP_CONNECTION_INFO"))
def test_TCP_NOTSENT_LOWAT_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import TCP_NOTSENT_LOWAT"))
def test_TCP_USER_TIMEOUT_of_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import TCP_USER_TIMEOUT"))
def test_TCP_KEEPALIVE_of_socket(self):
self.assertOnlyIn((3, 10), self.detect("from socket import TCP_KEEPALIVE"))
def test_TIPC_ADDR_ID_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_ADDR_ID"))
def test_TIPC_ADDR_NAME_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_ADDR_NAME"))
def test_TIPC_ADDR_NAMESEQ_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_ADDR_NAMESEQ"))
def test_TIPC_CFG_SRV_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_CFG_SRV"))
def test_TIPC_CLUSTER_SCOPE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_CLUSTER_SCOPE"))
def test_TIPC_CONN_TIMEOUT_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_CONN_TIMEOUT"))
def test_TIPC_CRITICAL_IMPORTANCE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_CRITICAL_IMPORTANCE"))
def test_TIPC_DEST_DROPPABLE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_DEST_DROPPABLE"))
def test_TIPC_HIGH_IMPORTANCE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_HIGH_IMPORTANCE"))
def test_TIPC_IMPORTANCE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_IMPORTANCE"))
def test_TIPC_LOW_IMPORTANCE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_LOW_IMPORTANCE"))
def test_TIPC_MEDIUM_IMPORTANCE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_MEDIUM_IMPORTANCE"))
def test_TIPC_NODE_SCOPE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_NODE_SCOPE"))
def test_TIPC_PUBLISHED_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_PUBLISHED"))
def test_TIPC_SRC_DROPPABLE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_SRC_DROPPABLE"))
def test_TIPC_SUBSCR_TIMEOUT_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_SUBSCR_TIMEOUT"))
def test_TIPC_SUB_CANCEL_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_SUB_CANCEL"))
def test_TIPC_SUB_PORTS_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_SUB_PORTS"))
def test_TIPC_SUB_SERVICE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_SUB_SERVICE"))
def test_TIPC_TOP_SRV_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_TOP_SRV"))
def test_TIPC_WAIT_FOREVER_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_WAIT_FOREVER"))
def test_TIPC_WITHDRAWN_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_WITHDRAWN"))
def test_TIPC_ZONE_SCOPE_of_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from socket import TIPC_ZONE_SCOPE"))
def test_VMADDR_CID_ANY_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import VMADDR_CID_ANY"))
def test_VMADDR_CID_HOST_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import VMADDR_CID_HOST"))
def test_VMADDR_PORT_ANY_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import VMADDR_PORT_ANY"))
def test_IPPROTO_UDPLITE_of_socket(self):
self.assertOnlyIn((3, 9), self.detect("from socket import IPPROTO_UDPLITE"))
def test_IPPROTO_MPTCP_of_socket(self):
self.assertOnlyIn((3, 10), self.detect("from socket import IPPROTO_MPTCP"))
def test_IP_RECVTOS_of_socket(self):
self.assertOnlyIn((3, 10), self.detect("from socket import IP_RECVTOS"))
def test_LOCAL_CREDS_of_socket(self):
self.assertOnlyIn((3, 11), self.detect("from socket import LOCAL_CREDS"))
def test_LOCAL_CREDS_PERSISTENT_of_socket(self):
self.assertOnlyIn((3, 11), self.detect("from socket import LOCAL_CREDS_PERSISTENT"))
def test_has_ipv6_of_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from socket import has_ipv6"))
def test_BDADDR_BREDR_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BDADDR_BREDR"))
def test_BDADDR_LE_PUBLIC_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BDADDR_LE_PUBLIC"))
def test_BDADDR_LE_RANDOM_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BDADDR_LE_RANDOM"))
def test_SOL_RFCOMM_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SOL_RFCOMM"))
def test_SOL_L2CAP_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SOL_L2CAP"))
def test_SOL_HCI_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SOL_HCI"))
def test_SOL_SCO_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SOL_SCO"))
def test_SOL_BLUETOOTH_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SOL_BLUETOOTH"))
def test_L2CAP_LM_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM"))
def test_L2CAP_LM_AUTH_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_AUTH"))
def test_L2CAP_LM_ENCRYPT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_ENCRYPT"))
def test_L2CAP_LM_MASTER_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_MASTER"))
def test_L2CAP_LM_RELIABLE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_RELIABLE"))
def test_L2CAP_LM_SECURE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_SECURE"))
def test_L2CAP_LM_TRUSTED_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import L2CAP_LM_TRUSTED"))
def test_BT_CHANNEL_POLICY_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_CHANNEL_POLICY"))
def test_BT_CHANNEL_POLICY_BREDR_ONLY_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_CHANNEL_POLICY_BREDR_ONLY"))
def test_BT_CHANNEL_POLICY_BREDR_PREFERRED_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_CHANNEL_POLICY_BREDR_PREFERRED"))
def test_BT_CODEC_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_CODEC"))
def test_BT_DEFER_SETUP_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_DEFER_SETUP"))
def test_BT_FLUSHABLE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_FLUSHABLE"))
def test_BT_FLUSHABLE_OFF_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_FLUSHABLE_OFF"))
def test_BT_FLUSHABLE_ON_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_FLUSHABLE_ON"))
def test_BT_ISO_QOS_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_ISO_QOS"))
def test_BT_MODE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE"))
def test_BT_MODE_BASIC_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE_BASIC"))
def test_BT_MODE_ERTM_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE_ERTM"))
def test_BT_MODE_EXT_FLOWCTL_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE_EXT_FLOWCTL"))
def test_BT_MODE_LE_FLOWCTL_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE_LE_FLOWCTL"))
def test_BT_MODE_STREAMING_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_MODE_STREAMING"))
def test_BT_PHY_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY"))
def test_BT_PHY_BR_1M_1SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_BR_1M_1SLOT"))
def test_BT_PHY_BR_1M_3SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_BR_1M_3SLOT"))
def test_BT_PHY_BR_1M_5SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_BR_1M_5SLOT"))
def test_BT_PHY_EDR_2M_1SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_2M_1SLOT"))
def test_BT_PHY_EDR_2M_3SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_2M_3SLOT"))
def test_BT_PHY_EDR_2M_5SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_2M_5SLOT"))
def test_BT_PHY_EDR_3M_1SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_3M_1SLOT"))
def test_BT_PHY_EDR_3M_3SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_3M_3SLOT"))
def test_BT_PHY_EDR_3M_5SLOT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_EDR_3M_5SLOT"))
def test_BT_PHY_LE_1M_RX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_1M_RX"))
def test_BT_PHY_LE_1M_TX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_1M_TX"))
def test_BT_PHY_LE_2M_RX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_2M_RX"))
def test_BT_PHY_LE_2M_TX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_2M_TX"))
def test_BT_PHY_LE_CODED_RX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_CODED_RX"))
def test_BT_PHY_LE_CODED_TX_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PHY_LE_CODED_TX"))
def test_BT_PKT_STATUS_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_PKT_STATUS"))
def test_BT_POWER_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_POWER"))
def test_BT_POWER_FORCE_ACTIVE_OFF_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_POWER_FORCE_ACTIVE_OFF"))
def test_BT_POWER_FORCE_ACTIVE_ON_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_POWER_FORCE_ACTIVE_ON"))
def test_BT_RCVMTU_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_RCVMTU"))
def test_BT_SECURITY_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY"))
def test_BT_SECURITY_FIPS_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY_FIPS"))
def test_BT_SECURITY_HIGH_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY_HIGH"))
def test_BT_SECURITY_LOW_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY_LOW"))
def test_BT_SECURITY_MEDIUM_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY_MEDIUM"))
def test_BT_SECURITY_SDP_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SECURITY_SDP"))
def test_BT_SNDMTU_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_SNDMTU"))
def test_BT_VOICE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_VOICE"))
def test_BT_VOICE_CVSD_16BIT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_VOICE_CVSD_16BIT"))
def test_BT_VOICE_TRANSPARENT_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import BT_VOICE_TRANSPARENT"))
def test_HCI_CHANNEL_RAW_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_CHANNEL_RAW"))
def test_HCI_CHANNEL_USER_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_CHANNEL_USER"))
def test_HCI_CHANNEL_MONITOR_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_CHANNEL_MONITOR"))
def test_HCI_CHANNEL_CONTROL_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_CHANNEL_CONTROL"))
def test_HCI_CHANNEL_LOGGING_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_CHANNEL_LOGGING"))
def test_SO_HCI_EVT_FILTER_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SO_HCI_EVT_FILTER"))
def test_SO_HCI_PKT_FILTER_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SO_HCI_PKT_FILTER"))
def test_HCI_DEV_NONE_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import HCI_DEV_NONE"))
def test_SO_REUSEPORT_LB_from_socket(self):
self.assertOnlyIn((3, 14), self.detect("from socket import SO_REUSEPORT_LB"))
def test_family_from_socket_socket(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from socket import socket\n"
"socket().family"))
def test_proto_from_socket_socket(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from socket import socket\n"
"socket().proto"))
def test_type_from_socket_socket(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from socket import socket\n"
"socket().type"))
def test_block_on_close_from_socketserver_ForkingMixIn(self):
self.assertOnlyIn((3, 7),
self.detect("from socketserver import ForkingMixIn\n"
"ForkingMixIn().block_on_close"))
def test_block_on_close_from_socketserver_ThreadingMixIn(self):
self.assertOnlyIn((3, 7),
self.detect("from socketserver import ThreadingMixIn\n"
"ThreadingMixIn().block_on_close"))
def test_autocommit_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import Connection\n"
"Connection().autocommit"))
def test_sqlite_errorcode_from_sqlite3_Error(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Error\n"
"Error().sqlite_errorcode"))
def test_sqlite_errorname_from_sqlite3_Error(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Error\n"
"Error().sqlite_errorname"))
def test_SQLITE_DBCONFIG_DEFENSIVE_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_DEFENSIVE"))
def test_SQLITE_DBCONFIG_DQS_DDL_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_DQS_DDL"))
def test_SQLITE_DBCONFIG_DQS_DML_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_DQS_DML"))
def test_SQLITE_DBCONFIG_ENABLE_FKEY_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_FKEY"))
def test_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER_from_sqlite3(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER"))
def test_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION_from_sqlite3(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION"))
def test_SQLITE_DBCONFIG_ENABLE_QPSG_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_QPSG"))
def test_SQLITE_DBCONFIG_ENABLE_TRIGGER_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_TRIGGER"))
def test_SQLITE_DBCONFIG_ENABLE_VIEW_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_ENABLE_VIEW"))
def test_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE_from_sqlite3(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import SQLITE_DBCONFIG_LEGACY_ALTER_TABLE"))
def test_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT_from_sqlite3(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import SQLITE_DBCONFIG_LEGACY_FILE_FORMAT"))
def test_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE"))
def test_SQLITE_DBCONFIG_RESET_DATABASE_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_RESET_DATABASE"))
def test_SQLITE_DBCONFIG_TRIGGER_EQP_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_TRIGGER_EQP"))
def test_SQLITE_DBCONFIG_TRUSTED_SCHEMA_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_TRUSTED_SCHEMA"))
def test_SQLITE_DBCONFIG_WRITABLE_SCHEMA_from_sqlite3(self):
self.assertOnlyIn((3, 12), self.detect("from sqlite3 import SQLITE_DBCONFIG_WRITABLE_SCHEMA"))
def test_ALERT_DESCRIPTION_ACCESS_DENIED_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_ACCESS_DENIED"))
def test_ALERT_DESCRIPTION_BAD_CERTIFICATE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_BAD_CERTIFICATE"))
def test_ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE"))
def test_ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE"))
def test_ALERT_DESCRIPTION_BAD_RECORD_MAC_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_BAD_RECORD_MAC"))
def test_ALERT_DESCRIPTION_CERTIFICATE_EXPIRED_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_CERTIFICATE_EXPIRED"))
def test_ALERT_DESCRIPTION_CERTIFICATE_REVOKED_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_CERTIFICATE_REVOKED"))
def test_ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN"))
def test_ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE"))
def test_ALERT_DESCRIPTION_CLOSE_NOTIFY_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_CLOSE_NOTIFY"))
def test_ALERT_DESCRIPTION_DECODE_ERROR_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_DECODE_ERROR"))
def test_ALERT_DESCRIPTION_DECOMPRESSION_FAILURE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_DECOMPRESSION_FAILURE"))
def test_ALERT_DESCRIPTION_DECRYPT_ERROR_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_DECRYPT_ERROR"))
def test_ALERT_DESCRIPTION_HANDSHAKE_FAILURE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_HANDSHAKE_FAILURE"))
def test_ALERT_DESCRIPTION_ILLEGAL_PARAMETER_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_ILLEGAL_PARAMETER"))
def test_ALERT_DESCRIPTION_INSUFFICIENT_SECURITY_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_INSUFFICIENT_SECURITY"))
def test_ALERT_DESCRIPTION_INTERNAL_ERROR_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_INTERNAL_ERROR"))
def test_ALERT_DESCRIPTION_NO_RENEGOTIATION_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_NO_RENEGOTIATION"))
def test_ALERT_DESCRIPTION_PROTOCOL_VERSION_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_PROTOCOL_VERSION"))
def test_ALERT_DESCRIPTION_RECORD_OVERFLOW_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_RECORD_OVERFLOW"))
def test_ALERT_DESCRIPTION_UNEXPECTED_MESSAGE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_UNEXPECTED_MESSAGE"))
def test_ALERT_DESCRIPTION_UNKNOWN_CA_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("from ssl import ALERT_DESCRIPTION_UNKNOWN_CA"))
def test_ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY"))
def test_ALERT_DESCRIPTION_UNRECOGNIZED_NAME_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_UNRECOGNIZED_NAME"))
def test_ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE"))
def test_ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION"))
def test_ALERT_DESCRIPTION_USER_CANCELLED_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect(
"from ssl import ALERT_DESCRIPTION_USER_CANCELLED"))
def test_HAS_SSLv2_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_SSLv2"))
def test_HAS_SSLv3_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import HAS_SSLv3"))
def test_OP_NO_RENEGOTIATION_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import OP_NO_RENEGOTIATION"))
def test_PROTOCOL_TLS_CLIENT_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import PROTOCOL_TLS_CLIENT"))
def test_PROTOCOL_TLS_SERVER_of_ssl(self):
self.assertOnlyIn((3, 6), self.detect("from ssl import PROTOCOL_TLS_SERVER"))
def test_CLIENT_AUTH_from_ssl_Purpose(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import Purpose\n"
"Purpose().CLIENT_AUTH"))
def test_SERVER_AUTH_from_ssl_Purpose(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import Purpose\n"
"Purpose().SERVER_AUTH"))
def test_sni_callback_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 7),
self.detect("from ssl import SSLContext\n"
"SSLContext().sni_callback"))
def test_sslobject_class_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 7),
self.detect("from ssl import SSLContext\n"
"SSLContext().sslobject_class"))
def test_sslsocket_class_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 7),
self.detect("from ssl import SSLContext\n"
"SSLContext().sslsocket_class"))
def test_braceidpattern_from_string_Template(self):
self.assertOnlyIn((3, 7),
self.detect("from string import Template\n"
"Template().braceidpattern"))
def test_flags_from_string_Template(self):
self.assertOnlyIn((3, 2),
self.detect("from string import Template\n"
"Template().flags"))
def test_letters_of_string(self):
self.assertOnlyIn((2, 0), self.detect("from string import letters"))
def test_lowercase_of_string(self):
self.assertOnlyIn((2, 0), self.detect("from string import lowercase"))
def test_uppercase_of_string(self):
self.assertOnlyIn((2, 0), self.detect("from string import uppercase"))
def test_stderr_from_subprocess_CalledProcessError(self):
self.assertOnlyIn((3, 5),
self.detect("from subprocess import CalledProcessError\n"
"CalledProcessError().stderr"))
def test_stdout_from_subprocess_CalledProcessError(self):
self.assertOnlyIn((3, 5),
self.detect("from subprocess import CalledProcessError\n"
"CalledProcessError().stdout"))
def test_lpAttributeList_from_subprocess_STARTUPINFO(self):
self.assertOnlyIn((3, 7),
self.detect("from subprocess import STARTUPINFO\n"
"STARTUPINFO().lpAttributeList"))
def test_stderr_from_subprocess_TimeoutExpired(self):
self.assertOnlyIn((3, 5),
self.detect("from subprocess import TimeoutExpired\n"
"TimeoutExpired().stderr"))
def test_stdout_from_subprocess_TimeoutExpired(self):
self.assertOnlyIn((3, 5),
self.detect("from subprocess import TimeoutExpired\n"
"TimeoutExpired().stdout"))
def test___breakpointhook___of_sys(self):
self.assertOnlyIn((3, 7), self.detect("from sys import __breakpointhook__"))
def test___interactivehook___of_sys(self):
self.assertOnlyIn((3, 4), self.detect("from sys import __interactivehook__"))
def test___unraisablehook___of_sys(self):
self.assertOnlyIn((3, 8), self.detect("from sys import __unraisablehook__"))
def test__emscripten_info_of_sys(self):
self.assertOnlyIn((3, 11), self.detect("from sys import _emscripten_info"))
def test__xoptions_of_sys(self):
self.assertOnlyIn((3, 2), self.detect("from sys import _xoptions"))
def test_abiflags_of_sys(self):
self.assertOnlyIn((3, 2), self.detect("from sys import abiflags"))
def test_base_exec_prefix_of_sys(self):
self.assertOnlyIn((3, 3), self.detect("from sys import base_exec_prefix"))
def test_base_prefix_of_sys(self):
self.assertOnlyIn((3, 3), self.detect("from sys import base_prefix"))
def test_dont_write_bytecode_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import dont_write_bytecode"))
def test_platlibdir_of_sys(self):
self.assertOnlyIn((3, 9), self.detect("from sys import platlibdir"))
def test_dev_mode_from_sys_flags(self):
self.assertOnlyIn((3, 7),
self.detect("from sys import flags\n"
"flags().dev_mode"))
def test_hash_randomization_from_sys_flags(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from sys import flags\n"
"flags().hash_randomization"))
def test_isolated_from_sys_flags(self):
self.assertOnlyIn((3, 4),
self.detect("from sys import flags\n"
"flags().isolated"))
def test_quiet_from_sys_flags(self):
self.assertOnlyIn((3, 2),
self.detect("from sys import flags\n"
"flags().quiet"))
def test_utf8_mode_from_sys_flags(self):
self.assertOnlyIn((3, 7),
self.detect("from sys import flags\n"
"flags().utf8_mode"))
def test_gil_from_sys_flags(self):
self.assertOnlyIn((3, 13),
self.detect("from sys import flags\n"
"flags().gil"))
def test__jit_from_sys(self):
self.assertOnlyIn((3, 14), self.detect("from sys import _jit"))
def test_thread_inherit_context_from_sys_flags(self):
self.assertOnlyIn((3, 14),
self.detect("from sys import flags\n"
"flags().thread_inherit_context"))
def test_context_aware_warnings_from_sys_flags(self):
self.assertOnlyIn((3, 14),
self.detect("from sys import flags\n"
"flags().context_aware_warnings"))
def test_int_max_str_digits_from_sys_flags(self):
self.assertOnlyIn((3, 11),
self.detect("from sys import flags\n"
"flags().int_max_str_digits"))
def test_safe_path_from_sys_flags(self):
self.assertOnlyIn((3, 11),
self.detect("from sys import flags\n"
"flags().safe_path"))
def test_warn_default_encoding_from_sys_flags(self):
self.assertOnlyIn((3, 10),
self.detect("from sys import flags\n"
"flags().warn_default_encoding"))
def test_build_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().build"))
def test_major_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().major"))
def test_minor_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().minor"))
def test_platform_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().platform"))
def test_product_type_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().product_type"))
def test_service_pack_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().service_pack"))
def test_service_pack_major_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().service_pack_major"))
def test_service_pack_minor_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().service_pack_minor"))
def test_suite_mask_from_sys_getwindowsversion(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import getwindowsversion\n"
"getwindowsversion().suite_mask"))
def test_hash_info_of_sys(self):
self.assertOnlyIn((3, 2), self.detect("from sys import hash_info"))
def test_algorithm_from_sys_hash_info(self):
self.assertOnlyIn((3, 4),
self.detect("from sys import hash_info\n"
"hash_info().algorithm"))
def test_hash_bits_from_sys_hash_info(self):
self.assertOnlyIn((3, 4),
self.detect("from sys import hash_info\n"
"hash_info().hash_bits"))
def test_seed_bits_from_sys_hash_info(self):
self.assertOnlyIn((3, 4),
self.detect("from sys import hash_info\n"
"hash_info().seed_bits"))
def test_implementation_of_sys(self):
self.assertOnlyIn((3, 3), self.detect("from sys import implementation"))
def test_int_info_of_sys(self):
self.assertOnlyIn((3, 1), self.detect("from sys import int_info"))
def test_thread_info_of_sys(self):
self.assertOnlyIn((3, 3), self.detect("from sys import thread_info"))
def test_orig_argv_of_sys(self):
self.assertOnlyIn((3, 10), self.detect("from sys import orig_argv"))
def test_stdlib_module_names_of_sys(self):
self.assertOnlyIn((3, 10), self.detect("from sys import stdlib_module_names"))
def test_major_from_sys_version_info(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import version_info\n"
"version_info().major"))
def test_micro_from_sys_version_info(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import version_info\n"
"version_info().micro"))
def test_minor_from_sys_version_info(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import version_info\n"
"version_info().minor"))
def test_monitoring_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import monitoring"))
def test_releaselevel_from_sys_version_info(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from sys import version_info\n"
"version_info().releaselevel"))
def test_DEFAULT_FORMAT_of_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from tarfile import DEFAULT_FORMAT"))
def test_GNU_FORMAT_of_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from tarfile import GNU_FORMAT"))
def test_PAX_FORMAT_of_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from tarfile import PAX_FORMAT"))
def test_USTAR_FORMAT_of_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from tarfile import USTAR_FORMAT"))
def test_break_on_hyphens_from_textwrap_TextWrapper(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from textwrap import TextWrapper\n"
"TextWrapper().break_on_hyphens"))
def test_drop_whitespace_from_textwrap_TextWrapper(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from textwrap import TextWrapper\n"
"TextWrapper().drop_whitespace"))
def test_max_lines_from_textwrap_TextWrapper(self):
self.assertOnlyIn((3, 4),
self.detect("from textwrap import TextWrapper\n"
"TextWrapper().max_lines"))
def test_placeholder_from_textwrap_TextWrapper(self):
self.assertOnlyIn((3, 4),
self.detect("from textwrap import TextWrapper\n"
"TextWrapper().placeholder"))
def test_tabsize_from_textwrap_TextWrapper(self):
self.assertOnlyIn((3, 3),
self.detect("from textwrap import TextWrapper\n"
"TextWrapper().tabsize"))
def test_daemon_from_threading_Thread(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Thread\n"
"Thread().daemon"))
def test_ident_from_threading_Thread(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Thread\n"
"Thread().ident"))
def test_name_from_threading_Thread(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Thread\n"
"Thread().name"))
def test_native_id_from_threading_Thread(self):
self.assertOnlyIn((3, 8),
self.detect("from threading import Thread\n"
"Thread().native_id"))
def test___excepthook___from_threading(self):
self.assertOnlyIn((3, 10), self.detect("from threading import __excepthook__"))
def test_tm_gmtoff_from_time_struct_time(self):
self.assertOnlyIn((3, 3),
self.detect("from time import struct_time\n"
"struct_time().tm_gmtoff"))
def test_tm_zone_from_time_struct_time(self):
self.assertOnlyIn((3, 3),
self.detect("from time import struct_time\n"
"struct_time().tm_zone"))
def test_ASYNC_of_token(self):
self.assertOnlyIn((3, 5), self.detect("from token import ASYNC"))
def test_AWAIT_of_token(self):
self.assertOnlyIn((3, 5), self.detect("from token import AWAIT"))
def test_COMMENT_of_token(self):
self.assertOnlyIn((3, 7), self.detect("from token import COMMENT"))
def test_ENCODING_of_token(self):
self.assertOnlyIn((3, 7), self.detect("from token import ENCODING"))
def test_NL_of_token(self):
self.assertOnlyIn((3, 7), self.detect("from token import NL"))
def test_TYPE_COMMENT_of_token(self):
self.assertOnlyIn((3, 8), self.detect("from token import TYPE_COMMENT"))
def test___notes___from_traceback_TracebackException(self):
self.assertOnlyIn((3, 11),
self.detect("from traceback import TracebackException\n"
"TracebackException().__notes__"))
def test_domain_from_tracemalloc_Filter(self):
self.assertOnlyIn((3, 6),
self.detect("from tracemalloc import Filter\n"
"Filter().domain"))
def test_domain_from_tracemalloc_Trace(self):
self.assertOnlyIn((3, 6),
self.detect("from tracemalloc import Trace\n"
"Trace().domain"))
def test_total_nframe_from_tracemalloc_Traceback(self):
self.assertOnlyIn((3, 9),
self.detect("from tracemalloc import Traceback\n"
"Traceback().total_nframe"))
def test_AsyncGeneratorType_of_types(self):
self.assertOnlyIn((3, 6), self.detect("from types import AsyncGeneratorType"))
def test_BooleanType_of_types(self):
self.assertOnlyIn((2, 3), self.detect("from types import BooleanType"))
def test_CellType_of_types(self):
self.assertOnlyIn((3, 8), self.detect("from types import CellType"))
def test_ClassMethodDescriptorType_of_types(self):
self.assertOnlyIn((3, 7), self.detect("from types import ClassMethodDescriptorType"))
def test_CoroutineType_of_types(self):
self.assertOnlyIn((3, 5), self.detect("from types import CoroutineType"))
def test___spec___from_types_ModuleType(self):
self.assertOnlyIn((3, 4),
self.detect("from types import ModuleType\n"
"ModuleType().__spec__"))
def test___name___of_property(self):
self.assertOnlyIn((3, 13), self.detect("property.__name__"))
def test_NoneType_of_types(self):
self.assertOnlyIn(((2, 0), (3, 10)), self.detect("from types import NoneType"))
def test_NotImplementedType_of_types(self):
self.assertOnlyIn(((2, 5), (3, 10)), self.detect("from types import NotImplementedType"))
def test_EllipsisType_of_types(self):
self.assertOnlyIn(((2, 0), (3, 10)), self.detect("from types import EllipsisType"))
def test_UnionType_of_types(self):
self.assertOnlyIn((3, 10), self.detect("from types import UnionType"))
def test_GeneratorType_of_types(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from types import GeneratorType"))
def test_GetSetDescriptorType_of_types(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from types import GetSetDescriptorType"))
def test_MemberDescriptorType_of_types(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from types import MemberDescriptorType"))
def test_MethodDescriptorType_of_types(self):
self.assertOnlyIn((3, 7), self.detect("from types import MethodDescriptorType"))
def test_MethodWrapperType_of_types(self):
self.assertOnlyIn((3, 7), self.detect("from types import MethodWrapperType"))
def test_StringTypes_of_types(self):
self.assertOnlyIn((2, 2), self.detect("from types import StringTypes"))
def test_WrapperDescriptorType_of_types(self):
self.assertOnlyIn((3, 7), self.detect("from types import WrapperDescriptorType"))
def test_NoReturn_of_typing(self):
self.assertOnlyIn((3, 5), self.detect("from typing import NoReturn"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from typing import NoReturn"))
def test_Final_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import Final"))
self.assertOnlyIn((3, 5), self.detect("""import typing
something.Final
"""))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import Final"))
def test_Literal_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import Literal"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import Literal"))
def test_Annotated_of_typing(self):
self.assertOnlyIn((3, 9), self.detect("from typing import Annotated"))
def test_Concatenate_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import Concatenate"))
def test_ParamSpecArgs_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import ParamSpecArgs"))
def test_ParamSpecKwargs_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import ParamSpecKwargs"))
def test_TypeAlias_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import TypeAlias"))
def test_TypeGuard_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import TypeGuard"))
def test_LiteralString_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import LiteralString"))
def test_Never_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import Never"))
def test_Self_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import Self"))
def test_Required_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import Required"))
def test_NotRequired_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import NotRequired"))
def test_TypeVarTuple_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import TypeVarTuple"))
def test_Unpack_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import Unpack"))
def test_ucd_3_2_0_of_unicodedata(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from unicodedata import ucd_3_2_0"))
def test_unidata_version_of_unicodedata(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from unicodedata import unidata_version"))
def test_longMessage_from_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\n"
"TestCase().longMessage"))
def test_maxDiff_from_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\n"
"TestCase().maxDiff"))
def test_errors_from_unittest_TestLoader(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest import TestLoader\n"
"TestLoader().errors"))
def test_testNamePatterns_from_unittest_TestLoader(self):
self.assertOnlyIn((3, 7),
self.detect("from unittest import TestLoader\n"
"TestLoader().testNamePatterns"))
def test_tb_locals_from_unittest_TestResult(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest import TestResult\n"
"TestResult().tb_locals"))
def test_headers_from_urllib_error_HTTPError(self):
self.assertOnlyIn((3, 4),
self.detect("from urllib.error import HTTPError\n"
"HTTPError().headers"))
def test__UNSAFE_URL_BYTES_TO_REMOVE_of_urllib_parse(self):
self.assertOnlyIn((3, 10), self.detect("from urllib.parse import _UNSAFE_URL_BYTES_TO_REMOVE"))
def test_method_from_urllib_request_Request(self):
self.assertOnlyIn((3, 3),
self.detect("from urllib.request import Request\n"
"Request().method"))
def test_fragment_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().fragment"))
def test_hostname_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().hostname"))
def test_netloc_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().netloc"))
def test_params_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().params"))
def test_password_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().password"))
def test_path_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().path"))
def test_port_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().port"))
def test_query_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().query"))
def test_scheme_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().scheme"))
def test_username_from_urlparse_urlparse(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlparse\n"
"urlparse().username"))
def test_fragment_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().fragment"))
def test_hostname_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().hostname"))
def test_netloc_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().netloc"))
def test_password_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().password"))
def test_path_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().path"))
def test_port_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().port"))
def test_query_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().query"))
def test_scheme_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().scheme"))
def test_username_from_urlparse_urlsplit(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import urlsplit\n"
"urlsplit().username"))
def test_is_safe_from_uuid_UUID(self):
self.assertOnlyIn((3, 7),
self.detect("from uuid import UUID\n"
"UUID().is_safe"))
def test_NIL_from_uuid(self):
self.assertOnlyIn((3, 14), self.detect("from uuid import NIL"))
def test_MAX_from_uuid(self):
self.assertOnlyIn((3, 14), self.detect("from uuid import MAX"))
def test___callback___from_weakref_ref(self):
self.assertOnlyIn((3, 4),
self.detect("from weakref import ref\n"
"ref().__callback__"))
def test_REG_QWORD_of_winreg(self):
self.assertOnlyIn((3, 6), self.detect("from winreg import REG_QWORD"))
def test_REG_QWORD_LITTLE_ENDIAN_of_winreg(self):
self.assertOnlyIn((3, 6), self.detect("from winreg import REG_QWORD_LITTLE_ENDIAN"))
def test_code_from_xml_parsers_expat_ExpatError(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import ExpatError\n"
"ExpatError().code"))
def test_lineno_from_xml_parsers_expat_ExpatError(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import ExpatError\n"
"ExpatError().lineno"))
def test_offset_from_xml_parsers_expat_ExpatError(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import ExpatError\n"
"ExpatError().offset"))
def test_CurrentByteIndex_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().CurrentByteIndex"))
def test_CurrentColumnNumber_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().CurrentColumnNumber"))
def test_CurrentLineNumber_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().CurrentLineNumber"))
def test_buffer_size_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().buffer_size"))
def test_buffer_text_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().buffer_text"))
def test_buffer_used_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().buffer_used"))
def test_ordered_attributes_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().ordered_attributes"))
def test_returns_unicode_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn((2, 0),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().returns_unicode"))
def test_specified_attributes_from_xml_parsers_expat_XMLParserType(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import XMLParserType\n"
"XMLParserType().specified_attributes"))
def test_codes_from_xml_parsers_expat_errors(self):
self.assertOnlyIn((3, 2),
self.detect("from xml.parsers.expat import errors\n"
"errors().codes"))
def test_messages_from_xml_parsers_expat_errors(self):
self.assertOnlyIn((3, 2),
self.detect("from xml.parsers.expat import errors\n"
"errors().messages"))
def test_eof_from_zlib_Decompress(self):
self.assertOnlyIn((3, 3),
self.detect("from zlib import Decompress\n"
"Decompress().eof"))
def test_ZLIB_RUNTIME_VERSION_of_zlib(self):
self.assertOnlyIn((3, 3), self.detect("from zlib import ZLIB_RUNTIME_VERSION"))
def test_avoids_symlink_attacks_of_shutil_rmtree(self):
self.assertOnlyIn((3, 3), self.detect("from shutil import rmtree\n"
"rmtree.avoids_symlink_attacks"))
def test_html5_of_html_entities(self):
self.assertOnlyIn((3, 3), self.detect("from html.entities import html5"))
def test_DOMSTRING_SIZE_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import DOMSTRING_SIZE_ERR"))
def test_EMPTY_NAMESPACE_of_xml_dom(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from xml.dom import EMPTY_NAMESPACE"))
def test_HIERARCHY_REQUEST_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import HIERARCHY_REQUEST_ERR"))
def test_INDEX_SIZE_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INDEX_SIZE_ERR"))
def test_INUSE_ATTRIBUTE_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INUSE_ATTRIBUTE_ERR"))
def test_INVALID_ACCESS_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INVALID_ACCESS_ERR"))
def test_INVALID_CHARACTER_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INVALID_CHARACTER_ERR"))
def test_INVALID_MODIFICATION_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INVALID_MODIFICATION_ERR"))
def test_INVALID_STATE_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import INVALID_STATE_ERR"))
def test_NAMESPACE_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NAMESPACE_ERR"))
def test_NOT_FOUND_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NOT_FOUND_ERR"))
def test_NOT_SUPPORTED_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NOT_SUPPORTED_ERR"))
def test_NO_DATA_ALLOWED_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NO_DATA_ALLOWED_ERR"))
def test_NO_MODIFICATION_ALLOWED_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect(
"from xml.dom import NO_MODIFICATION_ALLOWED_ERR"))
def test_SYNTAX_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import SYNTAX_ERR"))
def test_WRONG_DOCUMENT_ERR_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import WRONG_DOCUMENT_ERR"))
def test_XHTML_NAMESPACE_of_xml_dom(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from xml.dom import XHTML_NAMESPACE"))
def test_XMLNS_NAMESPACE_of_xml_dom(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from xml.dom import XMLNS_NAMESPACE"))
def test_XML_NAMESPACE_of_xml_dom(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from xml.dom import XML_NAMESPACE"))
def test_softkwlist_from_keyword(self):
self.assertOnlyIn((3, 9), self.detect("from keyword import softkwlist"))
def test_HAVE_CONTEXTVAR_from_decimal(self):
self.assertOnlyIn((3, 7), self.detect("from decimal import HAVE_CONTEXTVAR"))
def test_annotations_of___future__(self):
self.assertOnlyIn((3, 7), self.detect("from __future__ import annotations"))
def test_F_GETPATH_of_fcntl(self):
self.assertOnlyIn((3, 9), self.detect("from fcntl import F_GETPATH"))
def test_F_GETPIPE_SZ_of_fcntl(self):
self.assertOnlyIn((3, 10), self.detect("from fcntl import F_GETPIPE_SZ"))
def test_F_SETPIPE_SZ_of_fcntl(self):
self.assertOnlyIn((3, 10), self.detect("from fcntl import F_SETPIPE_SZ"))
def test_COLONEQUAL_of_token(self):
self.assertOnlyIn((3, 8), self.detect("from token import COLONEQUAL"))
def test_TYPE_IGNORE_of_token(self):
self.assertOnlyIn((3, 8), self.detect("from token import TYPE_IGNORE"))
def test_args_of_unittest_mock_Mock_call_args(self):
self.assertOnlyIn((3, 8), self.detect("from unittest.mock.Mock.call_args import args"))
self.assertTrue(self.config.add_backport("mock"))
self.assertOnlyIn((3, 6), self.detect("from unittest.mock.Mock.call_args import args"))
def test_kwargs_of_unittest_mock_Mock_call_args(self):
self.assertOnlyIn((3, 8), self.detect("from unittest.mock.Mock.call_args import kwargs"))
self.assertTrue(self.config.add_backport("mock"))
self.assertOnlyIn((3, 6), self.detect("from unittest.mock.Mock.call_args import kwargs"))
def test_status_of_urllib_response_addinfourl(self):
self.assertOnlyIn((3, 9), self.detect("from urllib.response.addinfourl import status"))
def test_RLIMIT_NTHR_of_resource(self):
self.assertOnlyIn((3, 15), self.detect("from resource import RLIMIT_NTHR"))
def test_RLIMIT_THREADS_of_resource(self):
self.assertOnlyIn((3, 15), self.detect("from resource import RLIMIT_THREADS"))
def test_RLIMIT_UMTXP_of_resource(self):
self.assertOnlyIn((3, 15), self.detect("from resource import RLIMIT_UMTXP"))
def test_RLIM_SAVED_CUR_of_resource(self):
self.assertOnlyIn((3, 15), self.detect("from resource import RLIM_SAVED_CUR"))
def test_RLIM_SAVED_MAX_of_resource(self):
self.assertOnlyIn((3, 15), self.detect("from resource import RLIM_SAVED_MAX"))
def test_HAS_PSK_TLS13_of_ssl(self):
self.assertOnlyIn((3, 15), self.detect("from ssl import HAS_PSK_TLS13"))
netromdk-vermin-d650a48/tests/decorators.py 0000664 0000000 0000000 00000011360 15265463462 0021067 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminDecoratorMemberTests(VerminTest):
def test_abstractclassmethod_of_abc(self):
self.assertOnlyIn((3, 2), self.detect("from abc import abstractclassmethod"))
def test_abstractstaticmethod_of_abc(self):
self.assertOnlyIn((3, 2), self.detect("from abc import abstractstaticmethod"))
def test_asynccontextmanager_of_contextlib(self):
self.assertOnlyIn((3, 7), self.detect("from contextlib import asynccontextmanager"))
def test_global_enum_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import global_enum"))
def test_member_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import member"))
def test_nonmember_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import nonmember"))
def test_property_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import property"))
def test_verify_of_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import verify"))
def test_cached_property_of_functools(self):
self.assertOnlyIn((3, 8), self.detect("from functools import cached_property"))
def test_lru_cache_of_functools(self):
self.assertOnlyIn((3, 2), self.detect("from functools import lru_cache"))
def test_singledispatch_of_functools(self):
self.assertOnlyIn((3, 4), self.detect("from functools import singledispatch"))
def test_singledispatchmethod_of_functools(self):
self.assertOnlyIn((3, 8), self.detect("from functools import singledispatchmethod"))
def test_total_ordering_of_functools(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from functools import total_ordering"))
def test_cache_of_functools(self):
self.assertOnlyIn((3, 9), self.detect("from functools import cache"))
# As user function.
# NOTE: It is not supported to use `functools.cache` without being a user function!
visitor = self.visit("""
from functools import cache
@cache
def foo(): pass""")
self.assertEqual(["functools.cache"], visitor.user_function_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_recursive_repr_of_reprlib(self):
self.assertOnlyIn((3, 2), self.detect("from reprlib import recursive_repr"))
def test_dataclass_transform_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import dataclass_transform"))
def test_final_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import final"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import final"))
def test_runtime_checkable_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import runtime_checkable"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 8)), self.detect("from typing import runtime_checkable"))
def test_override_of_typing(self):
self.assertOnlyIn((3, 12), self.detect("from typing import override"))
def test_expectedFailure_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from unittest import expectedFailure"))
def test_skip_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from unittest import skip"))
def test_skipIf_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from unittest import skipIf"))
def test_skipUnless_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from unittest import skipUnless"))
def test_user_function_lru_cache_of_functools(self):
# As user function.
visitor = self.visit("""
from functools import lru_cache
@lru_cache
def foo(): pass""")
self.assertEqual(["functools.lru_cache"], visitor.user_function_decorators())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
# User function as-name.
visitor = self.visit("""
from functools import lru_cache as lc
@lc
def foo(): pass""")
self.assertEqual(["functools.lru_cache"], visitor.user_function_decorators())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
# User function FQN.
visitor = self.visit("""
import functools
@functools.lru_cache
def foo(): pass""")
self.assertEqual(["functools.lru_cache"], visitor.user_function_decorators())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
# Not as user function.
visitor = self.visit("""
from functools import lru_cache
@lru_cache()
def foo(): pass""")
self.assertEmpty(visitor.user_function_decorators())
self.assertOnlyIn((3, 2), visitor.minimum_versions())
def test_deprecated_of_warnings(self):
self.assertOnlyIn((3, 13), self.detect("from warnings import deprecated"))
def test_disjoint_base_of_typing(self):
self.assertOnlyIn((3, 15), self.detect("from typing import disjoint_base"))
netromdk-vermin-d650a48/tests/exception.py 0000664 0000000 0000000 00000024563 15265463462 0020731 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminExceptionMemberTests(VerminTest):
def test_BrokenBarrierError_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("from asyncio import BrokenBarrierError"))
def test_QueueShutDown_of_asyncio(self):
self.assertOnlyIn((3, 13), self.detect("from asyncio import QueueShutDown"))
def test_SSLCertVerificationError_of_ssl(self):
self.assertOnlyIn((3, 7), self.detect("from ssl import SSLCertVerificationError"))
def test_SSLZeroReturnError_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLZeroReturnError"))
def test_SSLWantReadError_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLWantReadError"))
def test_SSLWantWriteError_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLWantWriteError"))
def test_SSLSyscallError_of_ssl(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("from ssl import SSLSyscallError"))
def test_SubprocessError_of_subprocess(self):
self.assertOnlyIn((3, 3), self.detect("from subprocess import SubprocessError"))
def test_TimeoutExpired_of_subprocess(self):
self.assertOnlyIn((3, 3), self.detect("from subprocess import TimeoutExpired"))
def test_HeaderError_of_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from tarfile import HeaderError"))
def test_LinkFallbackError_of_tarfile(self):
self.assertOnlyIn((3, 9), self.detect("from tarfile import LinkFallbackError"))
def test_BadZipFile_of_zipfile(self):
self.assertOnlyIn((3, 2), self.detect("from zipfile import BadZipFile"))
def test_NoBoundaryInMultipartDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.errors import NoBoundaryInMultipartDefect"))
def test_StartBoundaryNotFoundDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.errors import StartBoundaryNotFoundDefect"))
def test_FirstHeaderLineIsContinuationDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.errors import FirstHeaderLineIsContinuationDefect"))
def test_MisplacedEnvelopeHeaderDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.errors import MisplacedEnvelopeHeaderDefect"))
def test_MalformedHeaderDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"from email.errors import MalformedHeaderDefect"))
def test_MultipartInvariantViolationDefect_of_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from email.errors import MultipartInvariantViolationDefect"))
def test_CloseBoundaryNotFoundDefect_of_email_errors(self):
self.assertOnlyIn((3, 3), self.detect("from email.errors import CloseBoundaryNotFoundDefect"))
def test_MissingHeaderBodySeparatorDefect_of_email_errors(self):
self.assertOnlyIn((3, 3), self.detect(
"from email.errors import MissingHeaderBodySeparatorDefect"))
def test_InterpolationMissingOptionError_of_ConfigParser(self):
self.assertOnlyIn((2, 3), self.detect(
"from ConfigParser import InterpolationMissingOptionError"))
def test_InterpolationSyntaxError_of_ConfigParser(self):
self.assertOnlyIn((2, 3), self.detect("from ConfigParser import InterpolationSyntaxError"))
def test_MultilineContinuationError_of_configparser(self):
self.assertOnlyIn((3, 13), self.detect("from configparser import MultilineContinuationError"))
def test_UnnamedSectionDisabledError_of_configparser(self):
self.assertOnlyIn((3, 14), self.detect("from configparser import UnnamedSectionDisabledError"))
def test_InvalidWriteError_of_configparser(self):
self.assertOnlyIn((3, 14), self.detect("from configparser import InvalidWriteError"))
def test_COMError_of_ctypes(self):
self.assertOnlyIn((3, 14), self.detect("from ctypes import COMError"))
def test_BrokenExecutor_of_concurrent_futures(self):
self.assertOnlyIn((3, 7), self.detect("from concurrent.futures import BrokenExecutor"))
def test_InvalidStateError_of_concurrent_futures(self):
self.assertOnlyIn((3, 8), self.detect("from concurrent.futures import InvalidStateError"))
def test_BrokenThreadPool_of_concurrent_futures_thread(self):
self.assertOnlyIn((3, 7), self.detect("from concurrent.futures.thread import BrokenThreadPool"))
def test_BrokenInterpreterPool_of_concurrent_interpreters(self):
self.assertOnlyIn((3, 14), self.detect("""
from concurrent.interpreters import BrokenInterpreterPool
"""))
def test_ExecutionFailed_of_concurrent_interpreters(self):
self.assertOnlyIn((3, 14), self.detect("""
from concurrent.interpreters import ExecutionFailed
"""))
def test_BrokenProcessPool_of_concurrent_futures_process(self):
self.assertOnlyIn((3, 3), self.detect(
"from concurrent.futures.process import BrokenProcessPool"))
def test_BadGzipFile_of_gzip(self):
self.assertOnlyIn((3, 8), self.detect("from gzip import BadGzipFile"))
def test_HTMLParseError_of_htmllib(self):
self.assertOnlyIn((2, 4), self.detect("from htmllib import HTMLParseError"))
def test_BadStatusLine_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import BadStatusLine"))
def test_CannotSendHeader_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import CannotSendHeader"))
def test_CannotSendRequest_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import CannotSendRequest"))
def test_HTTPException_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import HTTPException"))
def test_ImproperConnectionState_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import ImproperConnectionState"))
def test_IncompleteRead_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import IncompleteRead"))
def test_InvalidURL_of_httplib(self):
self.assertOnlyIn((2, 3), self.detect("from httplib import InvalidURL"))
def test_NotConnected_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import NotConnected"))
def test_ResponseNotReady_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import ResponseNotReady"))
def test_UnimplementedFileMode_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import UnimplementedFileMode"))
def test_UnknownProtocol_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import UnknownProtocol"))
def test_UnknownTransferEncoding_of_httplib(self):
self.assertOnlyIn((2, 0), self.detect("from httplib import UnknownTransferEncoding"))
def test_JSONDecodeError_of_json(self):
self.assertOnlyIn((3, 5), self.detect("from json import JSONDecodeError"))
def test_UnsupportedOperation_of_pathlib(self):
self.assertOnlyIn((3, 13), self.detect("from pathlib import UnsupportedOperation"))
def test_ShutDown_of_queue(self):
self.assertOnlyIn((3, 13), self.detect("from queue import ShutDown"))
def test_PatternError_of_re(self):
self.assertOnlyIn((3, 13), self.detect("from re import PatternError"))
def test_SGMLParseError_of_sgmllib(self):
self.assertOnlyIn((2, 1), self.detect("from sgmllib import SGMLParseError"))
def test_Error_of_shutil(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from shutil import Error"))
def test_SameFileError_of_shutil(self):
self.assertOnlyIn((3, 4), self.detect("from shutil import SameFileError"))
def test_SMTPNotSupportedError_of_smtplib(self):
self.assertOnlyIn((3, 5), self.detect("from smtplib import SMTPNotSupportedError"))
def test_timeout_of_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from socket import timeout"))
def test_BrokenBarrierError_of_threading(self):
self.assertOnlyIn((3, 2), self.detect("from threading import BrokenBarrierError"))
def test_SkipTest_of_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("from unittest import SkipTest"))
def test_ContentTooShortError_of_urllib(self):
self.assertOnlyIn((2, 5), self.detect("from urllib import ContentTooShortError"))
def test_DOMException_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import DOMException"))
def test_DomstringSizeErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import DomstringSizeErr"))
def test_HierarchyRequestErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import HierarchyRequestErr"))
def test_IndexSizeErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import IndexSizeErr"))
def test_InuseAttributeErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import InuseAttributeErr"))
def test_InvalidAccessErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import InvalidAccessErr"))
def test_InvalidCharacterErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import InvalidCharacterErr"))
def test_InvalidModificationErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import InvalidModificationErr"))
def test_InvalidStateErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import InvalidStateErr"))
def test_NamespaceErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NamespaceErr"))
def test_NoDataAllowedErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NoDataAllowedErr"))
def test_NoModificationAllowedErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NoModificationAllowedErr"))
def test_NotFoundErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NotFoundErr"))
def test_NotSupportedErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import NotSupportedErr"))
def test_SyntaxErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import SyntaxErr"))
def test_WrongDocumentErr_of_xml_dom(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("from xml.dom import WrongDocumentErr"))
netromdk-vermin-d650a48/tests/exclusions.py 0000664 0000000 0000000 00000006745 15265463462 0021131 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminExclusionsTests(VerminTest):
def test_module(self):
visitor = self.visit("from email.parser import FeedParser")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
self.config.add_exclusion("email.parser")
self.config.add_exclusion("email.parser.FeedParser")
visitor = self.visit("from email.parser import FeedParser")
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_kwarg(self):
visitor = self.visit("from argparse import ArgumentParser\nArgumentParser(allow_abbrev=False)")
self.assertEqual([None, (3, 5)], visitor.minimum_versions())
self.config.add_exclusion("argparse") # module
self.config.add_exclusion("argparse.ArgumentParser(allow_abbrev)") # kwarg
visitor = self.visit("from argparse import ArgumentParser\nArgumentParser(allow_abbrev=False)")
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 8)
def test_kwarg_excluded_value(self):
self.config.enable_feature("fstring-self-doc")
source = "from argparse import ArgumentParser\nArgumentParser(allow_abbrev=f'{1=}')"
visitor = self.visit(source)
self.assertTrue(visitor.fstrings_self_doc())
self.assertEqual([("argparse.ArgumentParser", "allow_abbrev")], visitor.kwargs())
self.assertEqual([None, (3, 8)], visitor.minimum_versions())
self.config.add_exclusion("argparse.ArgumentParser(allow_abbrev)")
visitor = self.visit(source)
self.assertFalse(visitor.fstrings_self_doc())
self.assertEqual([], visitor.kwargs())
self.assertEqual([(2, 7), (3, 2)], visitor.minimum_versions())
self.config.add_exclusion("argparse")
visitor = self.visit(source)
self.assertFalse(visitor.fstrings_self_doc())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_codecs_error_handler(self):
visitor = self.visit("import codecs\ncodecs.encode('test', 'utf-8', 'surrogateescape')")
self.assertEqual([None, (3, 1)], visitor.minimum_versions())
visitor = self.visit("import codecs\ncodecs.encode('test', 'utf-8', errors='surrogateescape')")
self.assertEqual([None, (3, 1)], visitor.minimum_versions())
self.config.add_exclusion("ceh=surrogateescape")
visitor = self.visit("import codecs\ncodecs.encode('test', 'utf-8', 'surrogateescape')")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
visitor = self.visit("import codecs\ncodecs.encode('test', 'utf-8', errors='surrogateescape')")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
def test_codecs_encoding(self):
visitor = self.visit("import codecs\ncodecs.encode('test', 'koi8_t')")
self.assertEqual([None, (3, 5)], visitor.minimum_versions())
visitor = self.visit("import codecs\ncodecs.encode('test', data_encoding='koi8_t')")
self.assertEqual([None, (3, 5)], visitor.minimum_versions())
self.config.add_exclusion("ce=koi8_t")
visitor = self.visit("import codecs\ncodecs.encode('test', 'koi8_t')")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
visitor = self.visit("import codecs\ncodecs.encode('test', data_encoding='koi8_t')")
self.assertEqual([(2, 4), (3, 0)], visitor.minimum_versions())
def test_long(self):
visitor = self.visit("a = long(1)")
self.assertEqual([(2, 0), None], visitor.minimum_versions())
self.config.add_exclusion("long")
visitor = self.visit("a = long(1)")
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
netromdk-vermin-d650a48/tests/fstring_detector.py 0000664 0000000 0000000 00000046404 15265463462 0022276 0 ustar 00root root 0000000 0000000 import ast
from vermin.fstring_detector import FStringDetector
from .testutils import VerminTest
def joined_strs(source):
tree = ast.parse(source)
return [n for n in ast.walk(tree) if isinstance(n, ast.JoinedStr)]
class FStringDetectorTests(VerminTest):
def assert_self_doc(self, source, expected):
detector = FStringDetector(source)
nodes = joined_strs(source)
self.assertTrue(nodes, "no f-string in: " + source)
self.assertEqual(expected, any(detector.is_self_doc(n) for n in nodes), source)
def assert_pep701(self, source, expected):
"""Assert the source's f-strings trigger the named PEP 701 violation. `None` expectation means
"no violation", not "no f-string", which is asserted separately.
"""
detector = FStringDetector(source)
nodes = joined_strs(source)
self.assertTrue(nodes, "no f-string in: " + source)
if expected is None:
self.assertTrue(all(detector.pep701_violation(n) is None for n in nodes), source)
else:
self.assertTrue(any(detector.pep701_violation(n) == expected for n in nodes), source)
def test_none_source(self):
detector = FStringDetector(None)
node = joined_strs('f"{x}"')[0]
self.assertFalse(detector.is_self_doc(node))
self.assertIsNone(detector.pep701_violation(node))
# pylint: disable=W0212
self.assertIsNone(detector._read_fstring_token(node, None))
def test_input_guards(self):
detector = FStringDetector('f"{x}"')
bare = ast.JoinedStr()
const = ast.parse("1", mode="eval").body
self.assertIsNone(detector.pep701_violation(bare))
self.assertFalse(detector.is_self_doc(const))
self.assertIsNone(detector.pep701_violation(const))
# pylint: disable=W0212
self.assertIsNone(detector._read_fstring_token(bare, 'f"{x}"'.splitlines()))
self.assertIsNone(detector._read_fstring_token(bare, []))
@VerminTest.skipUnlessVersion(3, 8)
@VerminTest.parameterized_args([
("f'{a=}'", True),
("f'hello {name=}'", True),
("f'{b=}={a}'", True),
("f'{a =}'", True),
("f'{ a=}'", True),
("f'{a= }'", True),
("f'{ a = }'", True),
("f'{1+1=}'", True),
("f'{a+b=}'", True),
("f'{-5=}'", True),
("f'{(1,2,3)=}'", True),
("f'{ {1,2,3}=}'", True),
("f'{[x for x in [1,2,3]]=}'", True),
("f'{0==1=}'", True),
("f'{3.14=:10.10}'", True),
("f'{3.14=!s:10.10}'", True),
("f'{x=!r}'", True),
("f'{x=:.2f}'", True),
("f'{f\"{3.1415=:.1f}\":*^20}'", True),
("f'{{literal}}{a=}'", True),
("f'''{\n3\n=}'''", True),
("f'{f(a=4)=}'", True),
("f\"\\N{EXCLAMATION MARK}{a=}\"", True),
("f\"{x = :.2f}\"", True),
("f\"{(x) = :.2f}\"", True),
("f\"{ 2 + 2 = }\"", True),
("f\"{''=}\"", True),
('f"""{1=: "this" is fine}"""', True),
("f'{(x)=}'", True),
("f'{a[0]=}'", True),
# CRLFs must not shift the byte offsets of nodes on later lines.
("x = 1\r\ns = f\"{x=}\"\r\n", True),
("x = 1\r\ns = f\"{x=!r}\"\r\n", True),
# Bare `\r` endings and parser-only separators, like `\v` and `\f`, in string literals must not
# shift offsets either.
("x = 1\rs = f\"{x=}\"\r", True),
("y = \"\v\f\"\ns = f\"{x=}\"\n", True),
# Implicit concat merging a leading plain string part must not misdirect the self-doc `{`-anchor
# onto that part.
('"{" f"{x=}"', True),
('"{x}" f"{y=}"', True),
('("{\\n" f"{x=}")', True),
('"}" f"{x=}"', True),
("a = 1\nf'a={a}'", False),
("a = 1\nf'={a}'", False),
("f'{a != b}'", False),
("f'{a == b}'", False),
("f'{a >= b}'", False),
("f'{a <= b}'", False),
("f'{x:=10}'", False),
("f'hello {name!r}'", False),
("f'{x!r}'", False),
("f'{x!s}'", False),
("f'{x!a}'", False),
("f'{x:.2f}'", False),
("f'val={val:.2f}'", False),
("f'{(a+b)}={x!r}'", False),
("f'{{x={a}}}'", False),
("f'{x}'", False),
("f'{x:{width}}'", False),
("f'={cos(radians(theta)):.3f}'", False),
("x = 1\r\ns = f\"{x+1}\"\r\n", False),
("x = 1\rs = f\"{x+1}\"\r", False),
])
def test_self_doc(self, source, expected):
self.assert_self_doc(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"{\n1+2\n}"', "multi_line"),
('f"{\n x +\n y\n}"', "multi_line"),
("f\"{\n'''a'''\n}\"", "multi_line"),
("'''lit''' f\"{x\n+y}\"", "multi_line"),
('f"{a \\\n}"', "multi_line"),
("f'abc {\nx\n}'", "multi_line"),
('f"{x}"', None),
('f"{x:10}"', None),
("f'''{\n3\n}'''", None),
('f"\\N{EXCLAMATION MARK}{x}"', None),
('s = (f"got {x}: "\n f"done")', None),
('s = f"{a}" f"{b}"', None),
('s = f"lit {a}" f"""{b\n+ c}"""', None),
('s = (f"got {x}: "\n f"""done\n{p\n+ q}""")', None),
])
def test_pep701_multi_line(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"outer {f"inner"}"', "nested_same_quote"),
("f'outer {f'inner'}'", "nested_same_quote"),
('f"""outer {f"""inner"""}"""', "nested_same_quote"),
('f"outer {f"""inner"""}"', "nested_same_quote"),
('f"{x:{f".2f"}}"', "nested_same_quote"),
('f"1 {f"2 {f"3"}"}"', "nested_same_quote"),
('f"normal {f"{a=}"} normal"', "nested_same_quote"),
('f"normal {f"{a:.3f}"} normal"', "nested_same_quote"),
('f"normal { {f"{ { [1, 2] } }" } } normal"', "nested_same_quote"),
('f"foo {f"bar {x}"} baz"', "nested_same_quote"),
('value = f"{f"\\{1}"}"', "nested_same_quote"),
('value = rf"{f"\\{1}"}"', "nested_same_quote"),
('value = f"{rf"\\{1}"}"', "nested_same_quote"),
('_ = "a" f"b {f"c" f"d"} e" "f"', "nested_same_quote"),
('f"\\"foo\\" {f"\\"foo\\""} \\"\\""', "nested_same_quote"),
('f"""outer {f"inner"}"""', None),
('f"outer {f\'inner\'}"', None),
("f'outer {f\"inner\"}'", None),
])
def test_pep701_nested_same_quote(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("'lit' f\"{f\"{x}\"}\"", "nested_same_quote"),
('"""lit""" f"{f"{x}"}"', "nested_same_quote"),
("'''lit''' f\"{f\"{x}\"}\"", "nested_same_quote"),
("f'{\"lit\" f'{x}'}'", "nested_same_quote"),
('f"""{rf"""{x}"""}"""', "nested_same_quote"),
('f"{fr"""{x}"""}"', "nested_same_quote"),
("f'outer {rf'''{x}'''}'", "nested_same_quote"),
('f"{F"e{fr"""{x}"""}config"}"', "nested_same_quote"),
("('lit'\n# comment between\n f\"{f\"{x}\"}\")", "nested_same_quote"),
("'pre' f\"{f'{x}'}\"", None),
("'''pre''' f\"{f'{x}'}\"", None),
# Format-spec nested f-strings are valid pre-3.12 even when same-quoted.
("f\"{x:{f'{y}'}}\"", None),
('f"""{x:{f"{y}"}}"""', None),
])
def test_pep701_nested_same_quote_implicit_concat(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"abc {a["x"]} def"', "same_quote_string"),
("f'ab {a['x']} cd'", "same_quote_string"),
('f"{d["k"]=}"', "same_quote_string"),
('f"{ {"a": k} }"', "same_quote_string"),
('f"t{ ["a"] }"', "same_quote_string"),
('f"{a["x"]["y"]}"', "same_quote_string"),
('f"{x:{"ab"}}"', "same_quote_string"),
('f"{x:{w["y"]}}"', "same_quote_string"),
("f'{ {'k': v} }'", "same_quote_string"),
# A different quote is valid since 3.6.
('f"abc {a[\'x\']} def"', None),
("f'abc {a[\"x\"]} def'", None),
('f"{x:{w[\'y\']}}"', None),
('f"{x:>a\'b}"', None),
("f'{x:{w[\"y\"]}}'", None),
# Triple-quoted f-strings allow the single-character reuse natively.
('f"""abc {a["x"]} def"""', None),
('f"""abc {a[\'x\']} def"""', None),
("f'''abc {a['x']} def'''", None),
('f"{chr(34)}"', None),
('f"{x:10}"', None),
('f"{f\'x\'}"', None),
])
def test_pep701_same_quote_string(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("f\"{'\\n'.join(x)}\"", "backslash"),
("f\"{r'\\n'}\"", "backslash"),
("f\"{'\\''}\"", "backslash"),
("t = f\"{'\\InHere'=}\"", "backslash"),
('f"{"\\xFF\\N{space}"=}"', "backslash"),
('f"{r"\\xFF"=}"', "backslash"),
("f\"{chr(10)}\"", None),
("f'hello\\nworld'", None),
])
def test_pep701_backslash(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
def test_pep701_backslash_line_continuation(self):
source = 'f"{a \\\n}"'
node = joined_strs(source)[0].values[0]
detector = FStringDetector(source)
# pylint: disable=W0212
self.assertTrue(detector._has_pep701_backslash(node, source.splitlines()))
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"""{x # comment\n}"""', "comment"),
('f"""{x\n# comment\n}"""', "comment"),
("f\"\"\"{a + 'x' # c\n}\"\"\"", "comment"),
("f\"{'#notacomment'}\"", None),
('f"{x}"', None),
# `#` in a format spec is spec filler text, valid since 3.6.
('f"""{x:>3 # c\n}"""', None),
('f"""{x:{w} # c\n}"""', None),
('f"""{x!r:>3 # c\n}"""', None),
# A comment before the format spec is a PEP 701 comment.
('f"""{x # c\n:>3}"""', "comment"),
])
def test_pep701_comment(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("('lit' f\"{x}\")", ('"', False)),
("('''lit''' f'{x}')", ("'", False)),
('(f"lit {a}" f"""{b\n+ c}""")', ('"', False)),
('f"{f"{x}"}"', ('"', False)),
('f"""{rf"""{x}"""}"""', ('"', True)),
('rf"raw {x}"', ('"', False)),
("(f'lit' f\"{x}\")", ("'", False)),
])
def test_read_fstring_token(self, source, expected):
detector = FStringDetector(source)
nodes = joined_strs(source)
self.assertTrue(nodes, "no f-string in: " + source)
# pylint: disable=W0212
got = detector._read_fstring_token(nodes[0], source.splitlines())
self.assertEqual(expected, got, source)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"""{x:>3 # c\n}"""', False),
('f"""{x:{w} # c\n}"""', False),
('f"""{x!r:>3 # c\n}"""', False),
('f"""{x # c\n:>3}"""', True),
('f"""{x\n# comment\n}"""', True),
("f\"{'#notacomment'}\"", False),
# A `#` before the format spec is a comment, but after the `:` it is literal text.
('q = "zz" + f"""{a # c\n}"""', True),
('q = "zz" + f"""{x:>3 # c\n}"""', False),
])
def test_pep701_comment_region(self, source, expected):
detector = FStringDetector(source)
node = joined_strs(source)[0].values[0]
# pylint: disable=W0212
got = detector._has_pep701_comment(node, source.splitlines())
self.assertEqual(expected, got, source)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("x = 1\r\ns = f\"{f\"{x}\"}\"\r\n", "nested_same_quote"),
("x = 1\r\ns = f\"{\r\nx\r\n}\"\r\n", "multi_line"),
("x = 1\r\ns = f\"{x # c\r\n}\"\r\n", "multi_line"),
("x = 1\r\ns = f\"\"\"{x # c\r\n}\"\"\"\r\n", "comment"),
("x = 1\r\n'''lit''' f\"{x\n+y}\"\r\n", "multi_line"),
("x = 1\r\ns = f\"{x!r}\"\r\n", None),
])
def test_pep701_crlf(self, source, expected):
self.assert_pep701(source, expected)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
# Bare `\r` endings and parser-only separators, like `\v` and `\f`, in string literals must not
# shift offsets of nodes on later lines.
("x = 1\rs = f\"{f\"{x}\"}\"\r", "nested_same_quote"),
("y = \"\v\f\"\ns = f\"{f\"{x}\"}\"\n", "nested_same_quote"),
("x = 1\rs = f\"{x}\"\r", None),
("y = \"\v\f\"\ns = f\"{x}\"\n", None),
])
def test_pep701_parser_line_breaks(self, source, expected):
self.assert_pep701(source, expected)
def _set_span(node, span):
node.lineno, node.col_offset, node.end_lineno, node.end_col_offset = span
return node
def _name(identifier, span):
return _set_span(ast.Name(id=identifier, ctx=ast.Load()), span)
def _joined(values, span):
return _set_span(ast.JoinedStr(values=values), span)
def _formatted(value, span):
return _set_span(ast.FormattedValue(value=value, conversion=-1, format_spec=None), span)
class FStringDetectorParityTests(VerminTest):
"""PEP 701 parity tests that run on every interpreter, covering analysis the 3.12-gated suite
never reaches.
"""
# pylint: disable=protected-access
def setUp(self):
super().setUp()
self.none_detector = FStringDetector(None)
# The source code is inert on purpose, being short and single-line with no braces, quotes, or
# backslashes. And thus the fabricated spans have nothing to find and must always miss.
self.detector = FStringDetector("xyz")
def assert_pep701_none(self, source, span, token):
detector = FStringDetector(source)
nodes = joined_strs(source)
self.assertTrue(nodes, "no f-string in: " + source)
# Re-apply the 3.12+ top-level span, since pre-3.12 parsers pin it to the whole f-string.
for val in nodes[0].values:
if isinstance(val, ast.FormattedValue):
_set_span(val, span)
break
for node in nodes:
self.assertIsNone(detector.pep701_violation(node), source)
got = detector._read_fstring_token(nodes[0], source.splitlines())
self.assertEqual(token, got, source)
# Spans as 3.12+ reports them, re-applied where pre-3.12 parsers pin fields to the f-string.
@VerminTest.parameterized_args([
('f"{{lit}}{x}"', (1, 9, 1, 12), ('"', False)),
('f"{a[\'x\']}"', (1, 2, 1, 10), ('"', False)),
('f"{x:{f\'{y}\'}}"', (1, 2, 1, 14), ('"', False)),
("f'outer {f\"mid\"}'", (1, 8, 1, 16), ("'", False)),
('f"\\N{EXCLAMATION MARK}{x}"', (1, 22, 1, 25), ('"', False)),
('r"lit" f"{x}"', (1, 9, 1, 12), ('"', False)),
('("lit"\n# c\n f"{y}")', (3, 3, 3, 6), ('"', False)),
("('''lit''' f'{x}')", (1, 13, 1, 16), ("'", False)),
("f\"\"\"{a + '#'}\"\"\"", (1, 4, 1, 13), ('"', True)),
('f"\\\\{x}"', (1, 4, 1, 7), ('"', False)),
])
def test_pep701_cross_version(self, source, spans, token):
self.assert_pep701_none(source, spans, token)
def test_codepoint_helpers(self):
"""Codepoint helpers on a truncated UTF-8 column and out-of-range spans."""
self.assertEqual(1, self.detector._codepoint_col(["é"], 1, 1))
self.assertIsNone(self.detector._span_offset(self.detector._lines, 4, 0))
self.assertEqual(0, self.detector._codepoint_length(["a"], 9, 0, 9, 0))
# A `lineno` in range for the char count but beyond the actual line count must return `None`
# rather than index past the per-line offset array.
single_line = FStringDetector("abc")
self.assertIsNone(single_line._span_offset(single_line._lines, 2, 0))
def test_scanner_guards(self):
"""String/brace scanners that run past their end without a closing token."""
self.assertEqual(3, self.detector._skip_string("f\"ab", 1, 3, 4))
self.assertEqual(4, self.detector._fstring_body_end("f\"ab", 1, 4, '"', False, None, None))
self.assertEqual(4, self.detector._field_end("f\"{x", 3, 4))
def test_token_span_guards(self):
# A joined span past the source.
self.assertIsNone(
self.detector._read_fstring_token(_joined([], (9, 0, 9, 1)), self.detector._lines))
# An end span past the source.
self.assertIsNone(
self.detector._read_fstring_token(_joined([], (1, 0, 9, 1)), self.detector._lines))
# A field span past the source.
bad_fv = _formatted(_name("x", (1, 1, 1, 2)), (9, 1, 9, 2))
self.assertIsNone(
self.detector._read_fstring_token(_joined([bad_fv], (1, 0, 1, 5)), self.detector._lines))
def test_build_field_contexts_guards(self):
# A node without `end_col_offset`, like it was pre-3.8, yields no contexts.
class BareStringNode:
def __init__(self, values):
self.values = values
self.lineno = 1
self.col_offset = 0
self.end_lineno = 1
truncated = BareStringNode([])
self.assertEqual({}, self.detector._build_field_contexts(truncated, self.detector._lines)[0])
# A joined span past the source yields no contexts.
self.assertEqual({}, self.detector._build_field_contexts(
_joined([], (1, 0, 9, 1)), self.detector._lines)[0])
# Real literals re-scanned under an empty joined node resolve nothing.
for source, span in (("f\"a{b}c\"", (1, 2, 1, 7)),
("f\"{{x}}\"", (1, 2, 1, 6)),
("f\"ab\\N{SPACE}cd\"", (1, 2, 1, 13))):
fabricated = FStringDetector(source)
contexts = fabricated._build_field_contexts(_joined([], span), [source])[0]
self.assertEqual({}, contexts)
# A brace outside any f-string literal falls back to the default context.
mid = FStringDetector("f\"a\" {x} f\"b\"")
contexts, default = mid._build_field_contexts(_joined([], (1, 0, 1, 13)), ["f\"a\" {x} f\"b\""])
self.assertEqual({5: ('"', False)}, contexts)
self.assertEqual(('"', False), default)
def test_resolve_field_context_fallback(self):
no_pos = ast.FormattedValue(value=_name("x", (1, 1, 1, 2)), conversion=-1, format_spec=None)
default = ("'", True)
self.assertEqual(default, self.detector._resolve_field_context(no_pos, {}, default))
def test_self_doc_walk_guards(self):
candidate = \
ast.FormattedValue(value=_name("a", (1, 1, 1, 2)), conversion=ord("r"), format_spec=None)
# An empty f-string has no fields to walk.
self.assertFalse(self.none_detector.is_self_doc(_joined([], (1, 0, 1, 3))))
# A joined span past the source triggers the out-of-range guard.
self.assertFalse(self.detector.is_self_doc(_joined([candidate], (9, 0, 9, 3))))
# A normal `!r` field is simply not self-documenting.
self.assertFalse(FStringDetector("f\"x\"").is_self_doc(_joined([candidate], (1, 0, 1, 4))))
# Value node lacking end offsets, so the walk can't read past its span.
value_no_end = ast.Name(id="a")
value_no_end.lineno, value_no_end.col_offset = 1, 3
fv_no_end = ast.FormattedValue(value=value_no_end, conversion=ord("r"), format_spec=None)
fv_no_end.lineno, fv_no_end.col_offset = 1, 2
fv_no_end.end_lineno, fv_no_end.end_col_offset = 1, 4
self.assertFalse(FStringDetector("f\"{x}\"").is_self_doc(_joined([fv_no_end], (1, 0, 1, 5))))
# Value truncated at the span's edge, where no `=` can follow.
truncated_fv = _formatted(_name("x", (1, 3, 1, 4)), (1, 2, 1, 4))
self.assertFalse(FStringDetector("f\"{x}\"").is_self_doc(_joined([truncated_fv], (1, 0, 1, 4))))
def test_violation_scan_guards(self):
sample = _formatted(_name("x", (1, 2, 1, 5)), (1, 2, 1, 6))
self.assertFalse(self.none_detector._has_same_quote_string(sample, '"'))
self.assertFalse(self.none_detector._has_pep701_backslash(sample, None))
self.assertFalse(self.none_detector._has_pep701_comment(sample, None))
bad_span = _formatted(_name("x", (1, 1, 1, 2)), (9, 0, 9, 1))
self.assertFalse(self.detector._has_same_quote_string(bad_span, '"'))
self.assertFalse(self.detector._has_pep701_comment(bad_span, self.detector._lines))
def test_backslash_scan(self):
cont = FStringDetector("f\"{a \\\n}\"")
cont_fv = _formatted(_name("a", (1, 3, 1, 4)), (1, 2, 2, 1))
self.assertTrue(cont._has_pep701_backslash(cont_fv, cont._lines))
token_error = FStringDetector("f\"ab'\\\nc}\"")
token_fv = _formatted(_name("x", (1, 3, 1, 6)), (1, 2, 1, 6))
self.assertFalse(token_error._has_pep701_backslash(token_fv, token_error._lines))
netromdk-vermin-d650a48/tests/function.py 0000664 0000000 0000000 00000670722 15265463462 0020564 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminFunctionMemberTests(VerminTest):
def test_exc_clear_of_sys(self):
self.assertOnlyIn((2, 3), self.detect("from sys import exc_clear"))
def test_exception_of_sys(self):
self.assertOnlyIn((3, 11), self.detect("from sys import exception"))
def test_getcheckinterval_of_sys(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from sys import getcheckinterval"))
def test_getdlopenflags_of_sys(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from sys import getdlopenflags"))
def test_getfilesystemencoding_of_sys(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from sys import getfilesystemencoding"))
def test_getsizeof_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import getsizeof"))
def test_getprofile_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import getprofile"))
def test_gettrace_of_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from sys import gettrace"))
def test_getwindowsversion_of_sys(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from sys import getwindowsversion"))
def test_getunicodeinternedsize_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import getunicodeinternedsize"))
def test_activate_stack_trampoline_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import activate_stack_trampoline"))
def test_deactivate_stack_trampoline_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import deactivate_stack_trampoline"))
def test_is_stack_trampoline_active_of_sys(self):
self.assertOnlyIn((3, 12), self.detect("from sys import is_stack_trampoline_active"))
def test_commonpath_of_os_path(self):
self.assertOnlyIn((3, 5), self.detect("from os.path import commonpath"))
def test_getctime_of_os_path(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os.path import getctime"))
def test_isdevdrive_of_os_path(self):
self.assertOnlyIn((3, 12), self.detect("from os.path import isdevdrive"))
def test_isjunction_of_os_path(self):
self.assertOnlyIn((3, 12), self.detect("from os.path import isjunction"))
def test_ismount_of_os_path(self):
self.assertOnlyIn((3, 4), self.detect("from os.path import ismount"))
def test_isreserved_of_os_path(self):
self.assertOnlyIn((3, 13), self.detect("from os.path import isreserved"))
def test_lexists_of_os_path(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from os.path import lexists"))
def test_realpath_of_os_path(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from os.path import realpath"))
def test_relpath_of_os_path(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from os.path import relpath"))
def test_splitroot_of_os_path(self):
self.assertOnlyIn((3, 12), self.detect("from os.path import splitroot"))
def test_getpgid_of_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("from os import getpgid"))
def test_getresgid_of_os(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from os import getresgid"))
def test_getresuid_of_os(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from os import getresuid"))
def test_getsid_of_os(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("from os import getsid"))
def test_initgroups_of_os(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from os import initgroups"))
def test_setgroups_of_os(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from os import setgroups"))
def test_setns_of_os(self):
self.assertOnlyIn((3, 12), self.detect("from os import setns"))
def test_setresgid_of_os(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from os import setresgid"))
def test_setresuid_of_os(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from os import setresuid"))
def test_fsencode_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import fsencode"))
def test_fsdecode_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import fsdecode"))
def test_fspath_of_os(self):
self.assertOnlyIn((3, 6), self.detect("from os import fspath"))
def test_getenvb_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import getenvb"))
def test_get_exec_path_of_os(self):
self.assertOnlyIn((3, 2), self.detect("from os import get_exec_path"))
def test_getgrouplist_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import getgrouplist"))
def test_getpriority_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import getpriority"))
def test_setpriority_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import setpriority"))
def test_get_blocking_of_os(self):
self.assertOnlyIn((3, 5), self.detect("from os import get_blocking"))
def test_set_blocking_of_os(self):
self.assertOnlyIn((3, 5), self.detect("from os import set_blocking"))
def test_lockf_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import lockf"))
def test_login_tty_of_os(self):
self.assertOnlyIn((3, 11), self.detect("from os import login_tty"))
def test_pipe2_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import pipe2"))
def test_posix_fallocate_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import posix_fallocate"))
def test_posix_fadvise_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import posix_fadvise"))
def test_pread_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import pread"))
def test_pwrite_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import pwrite"))
def test_sendfile_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import sendfile"))
def test_readv_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import readv"))
def test_writev_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import writev"))
def test_splice_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import splice"))
def test_startfile_of_os(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("from os import startfile"))
def test_eventfd_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import eventfd"))
def test_eventfd_read_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import eventfd_read"))
def test_eventfd_write_of_os(self):
self.assertOnlyIn((3, 10), self.detect("from os import eventfd_write"))
def test_get_terminal_size_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import get_terminal_size"))
def test_get_inheritable_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import get_inheritable"))
def test_set_inheritable_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import set_inheritable"))
def test_get_handle_inheritable_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import get_handle_inheritable"))
def test_set_handle_inheritable_of_os(self):
self.assertOnlyIn((3, 4), self.detect("from os import set_handle_inheritable"))
def test_starmap_of_multiprocessing_Pool(self):
self.assertOnlyIn((3, 3), self.detect(
"from multiprocessing import Pool\np = Pool()\np.starmap()"))
def test_starmap_async_of_multiprocessing_Pool(self):
self.assertOnlyIn((3, 3), self.detect(
"from multiprocessing import Pool\np = Pool()\np.starmap_async()"))
def test_starmap_of_multiprocessing_pool_Pool(self):
self.assertOnlyIn((3, 3), self.detect(
"from multiprocessing.pool import Pool\np = Pool()\np.starmap()"))
def test_starmap_async_of_multiprocessing_pool_Pool(self):
self.assertOnlyIn((3, 3), self.detect(
"from multiprocessing.pool import Pool\np = Pool()\np.starmap_async()"))
def test_wait_of_multiprocessing_connection(self):
self.assertOnlyIn((3, 3), self.detect(
"from multiprocessing import connection\nconnection.wait()"))
def test_get_all_start_methods_of_multiprocessing(self):
self.assertOnlyIn((3, 4), self.detect("from multiprocessing import get_all_start_methods"))
def test_get_start_method_of_multiprocessing(self):
self.assertOnlyIn((3, 4), self.detect("from multiprocessing import get_start_method"))
self.assertOnlyIn((3, 4), self.detect("import multiprocessing as mp\nmp.get_start_method"))
def test_set_start_method_of_multiprocessing(self):
self.assertOnlyIn((3, 4), self.detect("from multiprocessing import set_start_method"))
def test_get_context_of_multiprocessing(self):
self.assertOnlyIn((3, 4), self.detect("from multiprocessing import get_context"))
def test_enterAsyncContext_of_unittest_IsolatedAsyncioTestCase(self):
self.assertOnlyIn((3, 11),
self.detect("""
from unittest import IsolatedAsyncioTestCase
IsolatedAsyncioTestCase.enterAsyncContext()
"""))
def test_assertIs_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertIs()"))
def test_assertIsNot_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertIsNot()"))
def test_assertIsNone_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertIsNone()"))
def test_assertIsNotNone_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertIsNotNone()"))
def test_assertIn_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertIn()"))
def test_assertNotIn_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertNotIn()"))
def test_assertIsInstance_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\nTestCase.assertIsInstance()"))
def test_assertNotIsInstance_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\nTestCase.assertNotIsInstance()"))
def test_assertRaisesRegexp_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertRaisesRegexp()"))
def test_assertGreater_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertGreater()"))
def test_assertGreaterEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertGreaterEqual()"))
def test_assertLess_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertLess()"))
def test_assertLessEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertLessEqual()"))
def test_assertRegexpMatches_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertRegexpMatches()"))
def test_assertNotRegexpMatches_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 5)), self.detect(
"from unittest import TestCase\nTestCase.assertNotRegexpMatches()"))
def test_assertItemsEqual_of_unittest_TestCase(self):
self.assertOnlyIn((2, 7),
self.detect("from unittest import TestCase\nTestCase.assertItemsEqual()"))
def test_assertDictContainsSubset_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"from unittest import TestCase\nTestCase.assertDictContainsSubset()"))
def test_addTypeEqualityFunc_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.addTypeEqualityFunc()"))
def test_assertMultiLineEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertMultiLineEqual()"))
def test_assertSequenceEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertSequenceEqual()"))
def test_assertListEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertListEqual()"))
def test_assertTupleEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertTupleEqual()"))
def test_assertRegex_of_unittest_TestCase(self):
self.assertOnlyIn((3, 2), self.detect("from unittest import TestCase\nTestCase.assertRegex()"))
def test_assertNotRegex_of_unittest_TestCase(self):
self.assertOnlyIn((3, 2), self.detect(
"from unittest import TestCase\nTestCase.assertNotRegex()"))
def test_assertSetEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertSetEqual()"))
def test_assertDictEqual_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.assertDictEqual()"))
def test_addCleanup_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.addCleanup()"))
def test_doCleanups_of_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\nTestCase.doCleanups()"))
def test_enterClassContext_of_unittest_TestCase(self):
self.assertOnlyIn((3, 11),
self.detect("from unittest import TestCase\nTestCase.enterClassContext()"))
def test_enterContext_of_unittest_TestCase(self):
self.assertOnlyIn((3, 11),
self.detect("from unittest import TestCase\nTestCase.enterContext()"))
def test_discover_of_unittest_TestLoader(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestLoader\nTestLoader.discover()"))
def test_startTestRun_of_unittest_TestResult(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestResult\nTestResult.startTestRun()"))
def test_stopTestRun_of_unittest_TestResult(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestResult\nTestResult.stopTestRun()"))
def test_addModuleCleanup_of_unittest(self):
self.assertOnlyIn((3, 8), self.detect("from unittest import addModuleCleanup"))
def test_doModuleCleanups_of_unittest(self):
self.assertOnlyIn((3, 11), self.detect("from unittest import doModuleCleanups"))
def test_enterModuleContext_of_unittest(self):
self.assertOnlyIn((3, 11), self.detect("from unittest import enterModuleContext"))
def test_total_seconds_of_datetime_timedelta(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"from datetime import timedelta\ntimedelta.total_seconds()"))
def test_timestamp_of_datetime_datetime(self):
self.assertOnlyIn((3, 3), self.detect("from datetime import datetime\ndatetime.timestamp()"))
def test_pbkdf2_hmac_of_hashlib(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import hashlib\nhashlib.pbkdf2_hmac()"))
def test_scrypt_of_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.scrypt()"))
def test_open_of_bz2(self):
self.assertOnlyIn((3, 3), self.detect("import bz2\nbz2.open()"))
def test_peek_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.peek()"))
def test_fileno_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.fileno()"))
def test_readable_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.readable()"))
def test_seekable_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.seekable()"))
def test_writable_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.writable()"))
self.assertOnlyIn((3, 3), self.detect("import bz2\nf = bz2.BZ2File()\nf.writable()"))
self.assertOnlyIn((3, 3), self.detect("import bz2\nf = bz2.BZ2File\nf.writable"))
def test_read1_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.read1()"))
def test_readinto_of_bz2_BZ2File(self):
self.assertOnlyIn((3, 3), self.detect("from bz2 import BZ2File\nf = BZ2File()\nf.readinto()"))
def test_count_of_collections_deque(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from collections import deque\nd = deque()\nd.count()"))
def test_remove_of_collections_deque(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from collections import deque\nd = deque()\nd.remove()"))
def test_reverse_of_collections_deque(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from collections import deque\nd = deque()\nd.reverse()"))
def test_copy_of_collections_deque(self):
self.assertOnlyIn((3, 5), self.detect("from collections import deque\nd = deque()\nd.copy()"))
def test_index_of_collections_deque(self):
self.assertOnlyIn((3, 5), self.detect("from collections import deque\nd = deque()\nd.index()"))
def test_insert_of_collections_deque(self):
self.assertOnlyIn((3, 5), self.detect("from collections import deque\nd = deque()\nd.insert()"))
def test_move_to_end_of_collections_OrderedDict(self):
self.assertOnlyIn((3, 2),
self.detect("from collections import OrderedDict\n"
"d = OrderedDict()\n"
"d.move_to_end()"))
def test_subtract_of_collections_Counter(self):
self.assertOnlyIn((3, 2),
self.detect("from collections import Counter\n"
"c = Counter()\n"
"c.subtract()"))
def test_total_of_collections_Counter(self):
self.assertOnlyIn((3, 10), self.detect("""
from collections import Counter
c = Counter()
c.total()
"""))
def test___ixor___of_collections_Counter(self):
self.assertOnlyIn((3, 15),
self.detect("from collections import Counter\n"
"c = Counter()\n"
"c.__ixor__()"))
def test___xor___of_collections_Counter(self):
self.assertOnlyIn((3, 15),
self.detect("from collections import Counter\n"
"c = Counter()\n"
"c.__xor__()"))
def test_suppress_of_contextlib(self):
self.assertOnlyIn((3, 4), self.detect("import contextlib\ncontextlib.suppress()"))
def test_redirect_stdout_of_contextlib(self):
self.assertOnlyIn((3, 4), self.detect("import contextlib\ncontextlib.redirect_stdout()"))
def test_redirect_stderr_of_contextlib(self):
self.assertOnlyIn((3, 5), self.detect("import contextlib\ncontextlib.redirect_stderr()"))
def test_field_size_limit_of_csv(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import csv\ncsv.field_size_limit()"))
def test_dllist_of_ctypes_util(self):
self.assertOnlyIn((3, 14), self.detect("import ctypes.util\nctypes.util.dllist()"))
def test_find_msvcrt_of_ctypes_util(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import ctypes.util\nctypes.util.find_msvcrt()"))
def test_get_errno_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.get_errno()"))
def test_get_last_error_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.get_last_error()"))
def test_set_errno_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.set_errno()"))
def test_set_last_error_of_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.set_last_error()"))
def test_CopyComPointer_of_ctypes(self):
self.assertOnlyIn((3, 14), self.detect("import ctypes\nctypes.CopyComPointer()"))
def test_from_buffer_of_ctypes__CData(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from ctypes import _CData\n_CData.from_buffer()"))
def test_from_buffer_copy_of_ctypes__CData(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from ctypes import _CData\n_CData.from_buffer_copy()"))
def test_canonical_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.canonical()"))
def test_compare_signal_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.compare_signal()"))
def test_compare_total_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.compare_total()"))
def test_compare_total_mag_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.compare_total_mag()"))
def test_conjugate_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.conjugate()"))
def test_copy_abs_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.copy_abs()"))
def test_copy_negate_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.copy_negate()"))
def test_copy_sign_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.copy_sign()"))
def test_exp_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.exp()"))
def test_from_float_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"from decimal import Decimal\nDecimal.from_float()"))
def test_from_number_of_decimal_Decimal(self):
self.assertOnlyIn((3, 14), self.detect(
"from decimal import Decimal\nDecimal.from_number()"))
def test_fma_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.fma()"))
def test_is_canonical_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.is_canonical()"))
def test_is_finite_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_finite()"))
def test_is_infinite_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_infinite()"))
def test_is_nan_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_nan()"))
def test_is_normal_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_normal()"))
def test_is_qnan_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_qnan()"))
def test_is_signed_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_signed()"))
def test_is_snan_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_snan()"))
def test_is_subnormal_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.is_subnormal()"))
def test_is_zero_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.is_zero()"))
def test_ln_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.ln()"))
def test_log10_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.log10()"))
def test_logb_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.logb()"))
def test_logical_and_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.logical_and()"))
def test_logical_invert_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.logical_invert()"))
def test_logical_or_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.logical_or()"))
def test_logical_xor_of_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.logical_xor()"))
def test_max_mag_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.max_mag()"))
def test_min_mag_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.min_mag()"))
def test_next_minus_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.next_minus()"))
def test_next_plus_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.next_plus()"))
def test_next_toward_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.next_toward()"))
def test_number_class_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.number_class()"))
def test_radix_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from decimal import Decimal\nDecimal.radix()"))
def test_rotate_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.rotate()"))
def test_scaleb_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.scaleb()"))
def test_shift_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from decimal import Decimal\nDecimal.shift()"))
def test_to_integral_exact_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.to_integral_exact()"))
def test_to_integral_value_decimal_Decimal(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from decimal import Decimal\nDecimal.to_integral_value()"))
def test_as_integer_ratio_decimal_Decimal(self):
self.assertOnlyIn((3, 6), self.detect(
"from decimal import Decimal\nDecimal.as_integer_ratio()"))
def test_IEEEContext_decimal(self):
self.assertOnlyIn((3, 14), self.detect("import decimal\ndecimal.IEEEContext()"))
def test_localcontext_decimal(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import decimal\ndecimal.localcontext()"))
def test_create_decimal_from_float_decimal_Context(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"from decimal import Context\nContext.create_decimal_from_float()"))
def test_clear_traps_decimal_Context(self):
self.assertOnlyIn((3, 3), self.detect("from decimal import Context\nContext.clear_traps()"))
def test_context_diff_difflib(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import difflib\ndifflib.context_diff()"))
def test_unified_diff_difflib(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import difflib\ndifflib.unified_diff()"))
def test_diff_bytes_difflib(self):
self.assertOnlyIn((3, 5), self.detect("import difflib\ndifflib.diff_bytes()"))
def test_get_grouped_opcodes_difflib_SequenceMatcher(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from difflib import SequenceMatcher\n"
"SequenceMatcher.get_grouped_opcodes()"))
def test_cmp_to_key_from_functools(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import functools\nfunctools.cmp_to_key()"))
def test_reduce_from_functools(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import functools\nfunctools.reduce()"))
def test_heapify_max_from_heapq(self):
self.assertOnlyIn((3, 14), self.detect("import heapq\nheapq.heapify_max()"))
def test_heappop_max_from_heapq(self):
self.assertOnlyIn((3, 14), self.detect("import heapq\nheapq.heappop_max()"))
def test_heappush_max_from_heapq(self):
self.assertOnlyIn((3, 14), self.detect("import heapq\nheapq.heappush_max()"))
def test_heappushpop_max_from_heapq(self):
self.assertOnlyIn((3, 14), self.detect("import heapq\nheapq.heappushpop_max()"))
def test_heapreplace_max_from_heapq(self):
self.assertOnlyIn((3, 14), self.detect("import heapq\nheapq.heapreplace_max()"))
def test_heappushpop_from_heapq(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import heapq\nheapq.heappushpop()"))
def test_merge_from_heapq(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import heapq\nheapq.merge()"))
def test_nlargest_from_heapq(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import heapq\nheapq.nlargest()"))
def test_nsmallest_from_heapq(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import heapq\nheapq.nsmallest()"))
def test_compare_digest_from_hmac(self):
self.assertOnlyIn(((2, 7), (3, 3)), self.detect("import hmac\nhmac.compare_digest()"))
def test_hmac_digest(self):
self.assertOnlyIn((3, 7), self.detect("import hmac\nhmac.digest()"))
def test_isgenerator_from_inspect(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import inspect\ninspect.isgenerator()"))
def test_isgeneratorfunction_from_inspect(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import inspect\ninspect.isgeneratorfunction()"))
def test_isabstract_from_inspect(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import inspect\ninspect.isabstract()"))
def test_isdatadescriptor_from_inspect(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import inspect\ninspect.isdatadescriptor()"))
def test_isgetsetdescriptor_from_inspect(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import inspect\ninspect.isgetsetdescriptor()"))
def test_ismemberdescriptor_from_inspect(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import inspect\ninspect.ismemberdescriptor()"))
def test_ismethodwrapper_from_inspect(self):
self.assertOnlyIn((3, 11), self.detect("import inspect\ninspect.ismethodwrapper()"))
def test_ispackage_from_inspect(self):
self.assertOnlyIn((3, 14), self.detect("import inspect\ninspect.ispackage()"))
def test_cleandoc_from_inspect(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import inspect\ninspect.cleandoc()"))
def test_getcallargs_from_inspect(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import inspect\ninspect.getcallargs()"))
def test_iscoroutine_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.iscoroutine()"))
def test_iscoroutinefunction_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.iscoroutinefunction()"))
def test_isawaitable_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.isawaitable()"))
def test_isasyncgen_from_inspect(self):
self.assertOnlyIn((3, 6), self.detect("import inspect\ninspect.isasyncgen()"))
def test_isasyncgenfunction_from_inspect(self):
self.assertOnlyIn((3, 6), self.detect("import inspect\ninspect.isasyncgenfunction()"))
def test_signature_from_inspect(self):
self.assertOnlyIn((3, 3), self.detect("import inspect\ninspect.signature()"))
def test_markcoroutinefunction_from_inspect(self):
self.assertOnlyIn((3, 12), self.detect("import inspect\ninspect.markcoroutinefunction()"))
def test_getasyncgenstate_from_inspect(self):
self.assertOnlyIn((3, 12), self.detect("import inspect\ninspect.getasyncgenstate()"))
def test_getasyncgenlocals_from_inspect(self):
self.assertOnlyIn((3, 12), self.detect("import inspect\ninspect.getasyncgenlocals()"))
def test_apply_defaults_from_inspect_BoundArguments(self):
self.assertOnlyIn((3, 5), self.detect("from inspect import BoundArguments\n"
"ba = BoundArguments()\n"
"ba.apply_defaults()"))
def test_getclosurevars_from_inspect(self):
self.assertOnlyIn((3, 3), self.detect("import inspect\ninspect.getclosurevars()"))
def test_unwrap_from_inspect(self):
self.assertOnlyIn((3, 4), self.detect("import inspect\ninspect.unwrap()"))
def test_getattr_static_from_inspect(self):
self.assertOnlyIn((3, 2), self.detect("import inspect\ninspect.getattr_static()"))
def test_getgeneratorstate_from_inspect(self):
self.assertOnlyIn((3, 2), self.detect("import inspect\ninspect.getgeneratorstate()"))
def test_getgeneratorlocals_from_inspect(self):
self.assertOnlyIn((3, 3), self.detect("import inspect\ninspect.getgeneratorlocals()"))
def test_getmembers_static_from_inspect(self):
self.assertOnlyIn((3, 11), self.detect("import inspect\ninspect.getmembers_static()"))
def test_getcoroutinestate_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.getcoroutinestate()"))
def test_getcoroutinelocals_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.getcoroutinelocals()"))
def test_get_annotations_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("import inspect\ninspect.get_annotations()"))
def test_detach_from_io_BufferedIOBase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from io import BufferedIOBase\n"
"bb = BufferedIOBase()\n"
"bb.detach()"))
def test_readinto1_from_io_BufferedIOBase(self):
self.assertOnlyIn((3, 5),
self.detect("from io import BufferedIOBase\n"
"bb = BufferedIOBase()\n"
"bb.readinto1()"))
def test_readinto1_from_io_BytesIO(self):
self.assertOnlyIn((3, 5),
self.detect("from io import BytesIO\n"
"bb = BytesIO()\n"
"bb.readinto1()"))
def test_getbuffer_from_io_BytesIO(self):
self.assertOnlyIn((3, 2),
self.detect("from io import BytesIO\n"
"bb = BytesIO()\n"
"bb.getbuffer()"))
def test_detach_from_io_TextIOBase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from io import TextIOBase\n"
"bb = TextIOBase()\n"
"bb.detach()"))
def test_combinations_from_itertools(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import itertools\nitertools.combinations()"))
def test_combinations_with_replacement_from_itertools(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("import itertools\nitertools.combinations_with_replacement()"))
def test_compress_from_itertools(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import itertools\nitertools.compress()"))
def test_from_iterable_from_itertools_chain(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from itertools import chain\nchain.from_iterable()"))
def test_groupby_from_itertools(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import itertools\nitertools.groupby()"))
def test_izip_longest_from_itertools(self):
self.assertOnlyIn((2, 6), self.detect("import itertools\nitertools.izip_longest()"))
def test_pairwise_from_itertools(self):
self.assertOnlyIn((3, 10), self.detect("import itertools\nitertools.pairwise()"))
def test_permutations_from_itertools(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import itertools\nitertools.permutations()"))
def test_product_from_itertools(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import itertools\nitertools.product()"))
def test_tee_from_itertools(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import itertools\nitertools.tee()"))
def test_accumulate_from_itertools(self):
self.assertOnlyIn((3, 2), self.detect("import itertools\nitertools.accumulate()"))
def test_batched_from_itertools(self):
self.assertOnlyIn((3, 12), self.detect("from itertools import batched"))
def test_getChild_from_logging_Logger(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"from logging import Logger\nLogger.getChild()"))
def test_hasHandlers_from_logging_Logger(self):
self.assertOnlyIn((3, 2), self.detect("from logging import Logger\nLogger.hasHandlers()"))
def test__log_from_logging_LoggerAdapter(self):
self.assertOnlyIn((3, 6),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter()._log()"))
def test_getLevelNamesMapping_from_logging(self):
self.assertOnlyIn((3, 11), self.detect("import logging\nlogging.getLevelNamesMapping()"))
def test_getLogRecordFactory_from_logging(self):
self.assertOnlyIn((3, 2), self.detect("import logging\nlogging.getLogRecordFactory()"))
def test_setLogRecordFactory_from_logging(self):
self.assertOnlyIn((3, 2), self.detect("import logging\nlogging.setLogRecordFactory()"))
def test_optimize_from_pickletools(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import pickletools\npickletools.optimize()"))
def test_get_data_from_pkgutil(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import pkgutil\npkgutil.get_data()"))
def test_resolve_name_from_pkgutil(self):
self.assertOnlyIn((3, 9), self.detect("import pkgutil\npkgutil.resolve_name()"))
def test_python_branch_from_platform(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import platform\nplatform.python_branch()"))
def test_python_implementation_from_platform(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import platform\nplatform.python_implementation()"))
def test_python_revision_from_platform(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import platform\nplatform.python_revision()"))
def test_linux_distribution_from_platform(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import platform\nplatform.linux_distribution()"))
def test_run_path_from_runpy(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import runpy\nrunpy.run_path()"))
def test_split_from_shlex(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import shlex\nshlex.split()"))
def test_join_from_shlex(self):
self.assertOnlyIn((3, 8), self.detect("import shlex\nshlex.join()"))
def test_push_source_from_shlex_shlex(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import shlex\nshlex.shlex().push_source()"))
def test_pop_source_from_shlex_shlex(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import shlex\nshlex.shlex().pop_source()"))
def test_quote_from_shlex(self):
self.assertOnlyIn((3, 3), self.detect("import shlex\nshlex.quote()"))
def test_register_introspection_functions_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 3),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCServer\n"
"srv = SimpleXMLRPCServer()\n"
"srv.register_introspection_functions()"))
self.assertOnlyIn((3, 0),
self.detect("from xmlrpc.server import SimpleXMLRPCServer\n"
"srv = SimpleXMLRPCServer()\n"
"srv.register_introspection_functions()"))
def test_serialize_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().serialize()"))
def test_getlimit_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().getlimit()"))
def test_setlimit_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().setlimit()"))
def test_set_progress_handler_from_sqlite3_Connection(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.set_progress_handler()"))
def test_enable_load_extension_from_sqlite3_Connection(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.enable_load_extension()"))
def test_load_extension_from_sqlite3_Connection(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.load_extension()"))
def test_in_transaction_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 2),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.in_transaction()"))
def test_iter_dump_from_sqlite3_Connection(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.iter_dump()"))
def test_iterdump_from_sqlite3_Connection(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.iterdump()"))
def test_set_trace_callback_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 3),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.set_trace_callback()"))
def test_getconfig_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.getconfig()"))
def test_setconfig_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import Connection\n"
"conn = Connection()\n"
"conn.setconfig()"))
def test_keys_from_sqlite3_Row(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from sqlite3 import Row\n"
"conn = Row()\n"
"conn.keys()"))
def test_create_default_context_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import ssl\nssl.create_default_context()"))
def test__https_verify_certificates_from_ssl(self):
self.assertOnlyIn((2, 7), self.detect("import ssl\nssl._https_verify_certificates()"))
def test_RAND_bytes_from_ssl(self):
self.assertOnlyIn((3, 3), self.detect("import ssl\nssl.RAND_bytes()"))
def test_RAND_pseudo_bytes_from_ssl(self):
self.assertOnlyIn((3, 3), self.detect("import ssl\nssl.RAND_pseudo_bytes()"))
def test_match_hostname_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import ssl\nssl.match_hostname()"))
def test_get_default_verify_paths_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import ssl\nssl.get_default_verify_paths()"))
def test_enum_certificates_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import ssl\nssl.enum_certificates()"))
def test_enum_crls_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import ssl\nssl.enum_crls()"))
def test_set_alpn_protocols_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 5)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_alpn_protocols()"))
def test_cert_store_stats_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.cert_store_stats()"))
def test_load_default_certs_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.load_default_certs()"))
def test_get_ca_certs_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.get_ca_certs()"))
def test_get_ciphers_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 6),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.get_ciphers()"))
def test_set_npn_protocols_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_npn_protocols()"))
def test_load_dh_params_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.load_dh_params()"))
def test_set_ecdh_curve_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_ecdh_curve()"))
def test_set_psk_client_callback_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 13),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_psk_client_callback()"))
def test_set_psk_server_callback_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 13),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_psk_server_callback()"))
def test_set_servername_callback_from_ssl_SSLContext(self):
self.assertOnlyIn(((2, 7), (3, 4)),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.set_servername_callback()"))
def test_verify_client_post_handshake_from_ssl_SSLSocket(self):
self.assertOnlyIn((3, 8),
self.detect("from ssl import SSLSocket\n"
"sock = SSLSocket()\n"
"sock.verify_client_post_handshake()"))
def test_check_call_from_subprocess(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import subprocess\nsubprocess.check_call()"))
def test_check_output_from_subprocess(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import subprocess\nsubprocess.check_output()"))
def test_send_signal_from_subprocess_Popen(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from subprocess import Popen\nPopen.send_signal()"))
def test_terminate_from_subprocess_Popen(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from subprocess import Popen\nPopen.terminate()"))
def test_kill_from_subprocess_Popen(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from subprocess import Popen\nPopen.kill()"))
def test_run_from_subprocess(self):
self.assertOnlyIn((3, 5), self.detect("import subprocess\nsubprocess.run()"))
def test_extractall_from_tarfile_TarFile(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect(
"from tarfile import TarFile\nTarFile.extractall()"))
def test_fromtarfile_from_tarfile_TarInfo(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarInfo\nTarInfo.fromtarfile()"))
def test_replace_from_tarfile_TarInfo(self):
self.assertOnlyIn((3, 12), self.detect("from tarfile import TarInfo\nTarInfo.replace()"))
def test_shorten_from_textwrap(self):
self.assertOnlyIn((3, 4), self.detect("import textwrap\ntextwrap.shorten()"))
def test_indent_from_textwrap(self):
self.assertOnlyIn((3, 3), self.detect("import textwrap\ntextwrap.indent()"))
def test_timeit_from_timeit(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import timeit\ntimeit.timeit()"))
def test_repeat_from_timeit(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import timeit\ntimeit.repeat()"))
def test_info_patchlevel_from_tkinter(self):
self.assertOnlyIn((3, 11), self.detect("import tkinter\ntkinter.info_patchlevel()"))
def test_warnpy3k_from_warnings(self):
self.assertOnlyIn((2, 6), self.detect("import warnings\nwarnings.warnpy3k()"))
def test_iterkeyrefs_from_weakref_WeakKeyDictionary(self):
self.assertOnlyIn((2, 5),
self.detect("from weakref import WeakKeyDictionary\n"
"wkd = WeakKeyDictionary()\n"
"wkd.iterkeyrefs()"))
def test_keyrefs_from_weakref_WeakKeyDictionary(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from weakref import WeakKeyDictionary\n"
"wkd = WeakKeyDictionary()\n"
"wkd.keyrefs()"))
def test_itervaluerefs_from_weakref_WeakValueDictionary(self):
self.assertOnlyIn((2, 5),
self.detect("from weakref import WeakValueDictionary\n"
"wkd = WeakValueDictionary()\n"
"wkd.itervaluerefs()"))
def test_valuerefs_from_weakref_WeakValueDictionary(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from weakref import WeakValueDictionary\n"
"wkd = WeakValueDictionary()\n"
"wkd.valuerefs()"))
def test_read_environ_from_wsgiref_handlers(self):
self.assertOnlyIn((3, 2), self.detect(
"import wsgiref.handlers\nwsgiref.handlers.read_environ()"))
def test_flush_from_xml_etree_ElementTree_XMLParser(self):
self.assertOnlyIn((3, 13), self.detect("from xml.etree import ElementTree\n"
"ElementTree().XMLParser().flush()"))
def test_flush_from_xml_etree_ElementTree_XMLPullParser(self):
self.assertOnlyIn((3, 13), self.detect("from xml.etree import ElementTree\n"
"ElementTree().XMLPullParser().flush()"))
def test_fromstringlist_from_xml_etree_ElementTree(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree import ElementTree\n"
"tree = ElementTree()\n"
"tree.fromstringlist()"))
def test_register_namespace_from_xml_etree_ElementTree(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree import ElementTree\n"
"tree = ElementTree()\n"
"tree.register_namespace()"))
def test_tostringlist_from_xml_etree_ElementTree(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree import ElementTree\n"
"tree = ElementTree()\n"
"tree.tostringlist()"))
def test_extend_from_xml_etree_ElementTree_Element(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import Element\n"
"elm = Element()\n"
"elm.extend()"))
def test_iter_from_xml_etree_ElementTree_Element(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import Element\n"
"elm = Element()\n"
"elm.iter()"))
def test_iterfind_from_xml_etree_ElementTree_Element(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import Element\n"
"elm = Element()\n"
"elm.iterfind()"))
def test_itertext_from_xml_etree_ElementTree_Element(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import Element\n"
"elm = Element()\n"
"elm.itertext()"))
def test_indent_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.etree.ElementTree import indent\n"
"indent()"))
def test_iterfind_from_xml_etree_ElementTree_ElementTree(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import ElementTree\n"
"tree = ElementTree()\n"
"tree.iterfind()"))
def test_doctype_from_xml_etree_ElementTree_TreeBuilder(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from xml.etree.ElementTree import TreeBuilder\n"
"tree = TreeBuilder()\n"
"tree.doctype()"))
def test_comment_from_xml_etree_ElementTree_TreeBuilder(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree.ElementTree import TreeBuilder\n"
"tree = TreeBuilder()\n"
"tree.comment()"))
def test_start_ns_from_xml_etree_ElementTree_TreeBuilder(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree.ElementTree import TreeBuilder\n"
"tree = TreeBuilder()\n"
"tree.start_ns()"))
def test_end_ns_from_xml_etree_ElementTree_TreeBuilder(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree.ElementTree import TreeBuilder\n"
"tree = TreeBuilder()\n"
"tree.end_ns()"))
def test_canonicalize_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree import ElementTree\n"
"tree = ElementTree()\n"
"tree.canonicalize()"))
def test_open_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.open()"))
def test_extract_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.extract()"))
def test_extractall_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.extractall()"))
def test_mkdir_from_zipfile_ZipFile(self):
self.assertOnlyIn((3, 11),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.mkdir()"))
def test_setpassword_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.setpassword()"))
def test__for_archive_from_zipfile_ZipInfo(self):
self.assertOnlyIn((3, 14),
self.detect("from zipfile import ZipInfo\n"
"zi = ZipInfo()\n"
"zi._for_archive()"))
def test_from_file_from_zipfile_ZipInfo(self):
self.assertOnlyIn((3, 6),
self.detect("from zipfile import ZipInfo\n"
"zf = ZipInfo()\n"
"zf.from_file()"))
def test_is_dir_from_zipfile_ZipInfo(self):
self.assertOnlyIn((3, 6),
self.detect("from zipfile import ZipInfo\n"
"zf = ZipInfo()\n"
"zf.is_dir()"))
def test_get_filename_from_zipimport_zipimporter(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from zipimport import zipimporter\n"
"zi = zipimporter()\n"
"zi.get_filename()"))
def test_create_module_from_zipimport_zipimporter(self):
self.assertOnlyIn((3, 10),
self.detect("from zipimport import zipimporter\n"
"zi = zipimporter()\n"
"zi.create_module()"))
def test_exec_module_from_zipimport_zipimporter(self):
self.assertOnlyIn((3, 10),
self.detect("from zipimport import zipimporter\n"
"zi = zipimporter()\n"
"zi.exec_module()"))
def test_find_spec_from_zipimport_zipimporter(self):
self.assertOnlyIn((3, 10),
self.detect("from zipimport import zipimporter\n"
"zi = zipimporter()\n"
"zi.find_spec()"))
def test_invalidate_caches_from_zipimport_zipimporter(self):
self.assertOnlyIn((3, 10),
self.detect("from zipimport import zipimporter\n"
"zi = zipimporter()\n"
"zi.invalidate_caches()"))
def test_Tcl_from_Tkinter(self):
self.assertOnlyIn((2, 4), self.detect("import Tkinter\nTkinter.Tcl()"))
def test_mksalt_from_crypt(self):
self.assertOnlyIn((3, 3), self.detect("import crypt\ncrypt.mksalt()"))
def test_formatdate_from_email_utils(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import email.utils\nemail.utils.formatdate()"))
def test_localtime_from_email_utils(self):
self.assertOnlyIn((3, 3), self.detect("import email.utils\nemail.utils.localtime()"))
def test_parsedate_to_datetime_from_email_utils(self):
self.assertOnlyIn((3, 3), self.detect(
"import email.utils\nemail.utils.parsedate_to_datetime()"))
def test_format_datetime_from_email_utils(self):
self.assertOnlyIn((3, 3), self.detect("import email.utils\nemail.utils.format_datetime()"))
def test_show_flag_values_from_enum(self):
self.assertOnlyIn((3, 11), self.detect("from enum import show_flag_values"))
def test__add_alias__from_enum_Enum(self):
self.assertOnlyIn((3, 13), self.detect("from enum import Enum\nEnum._add_alias_"))
def test__add_value_alias__from_enum_Enum(self):
self.assertOnlyIn((3, 13), self.detect("from enum import Enum\nEnum._add_value_alias_"))
def test_copysign_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.copysign()"))
def test_fsum_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.fsum()"))
def test_isinf_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.isinf()"))
def test_isnan_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.isnan()"))
def test_trunc_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.trunc()"))
def test_exp2_from_math(self):
self.assertOnlyIn((3, 11), self.detect("import math\nmath.exp2()"))
def test_expm1_from_math(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import math\nmath.expm1()"))
def test_log1p_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.log1p()"))
def test_asinh_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.asinh()"))
def test_acosh_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.acosh()"))
def test_atanh_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.atanh()"))
def test_erf_from_math(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import math\nmath.erf()"))
def test_erfc_from_math(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import math\nmath.erfc()"))
def test_gamma_from_math(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import math\nmath.gamma()"))
def test_lgamma_from_math(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import math\nmath.lgamma()"))
def test_gcd_from_math(self):
self.assertOnlyIn((3, 5), self.detect("import math\nmath.gcd()"))
def test_isclose_from_math(self):
self.assertOnlyIn((3, 5), self.detect("import math\nmath.isclose()"))
def test_isfinite_from_math(self):
self.assertOnlyIn((3, 2), self.detect("import math\nmath.isfinite()"))
def test_log2_from_math(self):
self.assertOnlyIn((3, 3), self.detect("import math\nmath.log2()"))
def test_dist_from_math(self):
self.assertOnlyIn((3, 8), self.detect("import math\nmath.dist()"))
def test_cbrt_from_math(self):
self.assertOnlyIn((3, 11), self.detect("import math\nmath.cbrt()"))
def test_comb_from_math(self):
self.assertOnlyIn((3, 8), self.detect("import math\nmath.comb()"))
def test_isqrt_from_math(self):
self.assertOnlyIn((3, 8), self.detect("import math\nmath.isqrt()"))
def test_perm_from_math(self):
self.assertOnlyIn((3, 8), self.detect("import math\nmath.perm()"))
def test_prod_from_math(self):
self.assertOnlyIn((3, 8), self.detect("import math\nmath.prod()"))
def test_remainder_from_math(self):
self.assertOnlyIn((3, 7), self.detect("import math\nmath.remainder()"))
def test_sumprod_from_math(self):
self.assertOnlyIn((3, 12), self.detect("import math\nmath.sumprod()"))
def test_home_from_path(self):
self.assertOnlyIn((3, 5), self.detect("from pathlib import Path\np=Path('foo')\np.home()"))
def test_copy_from_path(self):
self.assertOnlyIn((3, 14), self.detect(
"from pathlib import Path\np=Path('foo')\np.copy()"))
def test_copy_into_from_path(self):
self.assertOnlyIn((3, 14), self.detect(
"from pathlib import Path\np=Path('foo')\np.copy_into()"))
def test_move_from_path(self):
self.assertOnlyIn((3, 14), self.detect(
"from pathlib import Path\np=Path('foo')\np.move()"))
def test_move_into_from_path(self):
self.assertOnlyIn((3, 14), self.detect(
"from pathlib import Path\np=Path('foo')\np.move_into()"))
def test_expanduser_from_path(self):
self.assertOnlyIn((3, 5), self.detect(
"from pathlib import Path\np=Path('foo')\np.expanduser()"))
def test_read_bytes_from_path(self):
self.assertOnlyIn((3, 5), self.detect(
"from pathlib import Path\np=Path('foo')\np.read_bytes()"))
def test_is_junction_from_path(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
p=Path('foo')
p.is_junction()
"""))
def test_is_mount_from_path(self):
self.assertOnlyIn((3, 7), self.detect("from pathlib import Path\np=Path('foo')\np.is_mount()"))
def test_from_uri_from_path(self):
self.assertOnlyIn((3, 13), self.detect("from pathlib import Path\np=Path.from_uri()"))
def test_read_text_from_path(self):
self.assertOnlyIn((3, 5), self.detect("from pathlib import Path\np=Path('foo')\np.read_text()"))
def test_samefile_from_path(self):
self.assertOnlyIn((3, 5), self.detect("from pathlib import Path\np=Path('foo')\np.samefile()"))
def test_walk_from_path(self):
self.assertOnlyIn((3, 12), self.detect("from pathlib import Path\np=Path('foo')\np.walk()"))
def test_write_bytes_from_path(self):
self.assertOnlyIn((3, 5), self.detect(
"from pathlib import Path\np=Path('foo')\np.write_bytes()"))
def test_write_text_from_path(self):
self.assertOnlyIn((3, 5), self.detect(
"from pathlib import Path\np=Path('foo')\np.write_text()"))
def test_link_to_from_path(self):
self.assertOnlyIn((3, 8), self.detect("from pathlib import Path\np=Path('foo')\np.link_to()"))
def test_hardlink_to_from_path(self):
self.assertOnlyIn((3, 10), self.detect("""
from pathlib import Path
p=Path('foo')
p.hardlink_to()
"""))
def test_readlink_from_path(self):
self.assertOnlyIn((3, 9), self.detect("from pathlib import Path\np=Path('foo')\np.readlink()"))
def test_is_relative_to_from_pathlib_PurePath(self):
self.assertOnlyIn((3, 9),
self.detect("from pathlib import PurePath\n"
"p = PurePath()\n"
"p.is_relative_to()"))
def test_full_match_to_from_pathlib_PurePath(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import PurePath\n"
"p = PurePath()\n"
"p.full_match()"))
def test_with_segments_from_pathlib_PurePath(self):
self.assertOnlyIn((3, 12),
self.detect("from pathlib import PurePath\n"
"p = PurePath()\n"
"p.with_segments()"))
def test_with_stem_from_pathlib_PurePath(self):
self.assertOnlyIn((3, 9),
self.detect("from pathlib import PurePath\n"
"p = PurePath()\n"
"p.with_stem()"))
def test_parser_to_from_pathlib_PurePath(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import PurePath\n"
"p = PurePath()\n"
"p.parser()"))
def test_with_stem_of_Path(self):
self.assertOnlyIn((3, 9),
self.detect("from pathlib import Path\n"
"Path('foo').with_stem('bar')"))
def test_with_segments_of_Path(self):
self.assertOnlyIn((3, 12),
self.detect("from pathlib import Path\n"
"Path('foo').with_segments('bar')"))
def test_is_relative_to_of_Path(self):
self.assertOnlyIn((3, 9),
self.detect("from pathlib import Path\n"
"Path('foo').is_relative_to('bar')"))
def test_full_match_of_Path(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\n"
"Path('foo').full_match('*')"))
def test_parser_of_Path(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\n"
"Path.parser"))
def test_set_trace_async_from_pdb(self):
self.assertOnlyIn((3, 14), self.detect("import pdb\npdb.set_trace_async()"))
def test_set_default_backend_from_pdb(self):
self.assertOnlyIn((3, 14), self.detect("import pdb\npdb.set_default_backend()"))
def test_get_default_backend_from_pdb(self):
self.assertOnlyIn((3, 14), self.detect("import pdb\npdb.get_default_backend()"))
def test_all_suffixes_of_importlib_machinery(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib import machinery\nmachinery.all_suffixes()"))
def test_find_spec_of_importlib_machinery_PathFinder(self):
self.assertOnlyIn((3, 4), self.detect(
"from importlib.machinery import PathFinder\nPathFinder.find_spec()"))
def test_find_spec_of_importlib_machinery_FileFinder(self):
self.assertOnlyIn((3, 4), self.detect(
"from importlib.machinery import FileFinder\nFileFinder.find_spec()"))
def test_create_module_of_importlib_machinery_ExtensionFileLoader(self):
self.assertOnlyIn((3, 5),
self.detect("from importlib.machinery import ExtensionFileLoader\n"
"ExtensionFileLoader.create_module()"))
def test_exec_module_of_importlib_machinery_ExtensionFileLoader(self):
self.assertOnlyIn((3, 5),
self.detect("from importlib.machinery import ExtensionFileLoader\n"
"ExtensionFileLoader.exec_module()"))
def test_get_filename_of_importlib_machinery_ExtensionFileLoader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.machinery import ExtensionFileLoader\n"
"ExtensionFileLoader.get_filename()"))
def test_cache_from_source_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.cache_from_source"))
def test_source_from_cache_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.source_from_cache"))
def test_decode_source_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.decode_source"))
def test_resolve_name_of_importlib_util(self):
self.assertOnlyIn((3, 3), self.detect("from importlib import util\nutil.resolve_name"))
def test_find_spec_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.find_spec"))
def test_module_from_spec_of_importlib_util(self):
self.assertOnlyIn((3, 5), self.detect("from importlib import util\nutil.module_from_spec"))
def test_spec_from_loader_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect("from importlib import util\nutil.spec_from_loader"))
def test_spec_from_file_location_of_importlib_util(self):
self.assertOnlyIn((3, 4), self.detect(
"from importlib import util\nutil.spec_from_file_location"))
def test_source_hash_of_importlib_util(self):
self.assertOnlyIn((3, 7), self.detect("from importlib import util\nutil.source_hash"))
def test_pthread_getcpuclockid_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import pthread_getcpuclockid"))
def test_clock_getres_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import clock_getres"))
def test_clock_gettime_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import clock_gettime"))
def test_clock_gettime_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import clock_gettime_ns"))
def test_clock_settime_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import clock_settime"))
def test_clock_settime_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import clock_settime_ns"))
def test_get_clock_info_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import get_clock_info"))
def test_monotonic_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import monotonic"))
def test_monotonic_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import monotonic_ns"))
def test_perf_counter_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import perf_counter"))
def test_perf_counter_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import perf_counter_ns"))
def test_process_time_of_time(self):
self.assertOnlyIn((3, 3), self.detect("from time import process_time"))
def test_process_time_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import process_time_ns"))
def test_thread_time_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import thread_time"))
def test_thread_time_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import thread_time_ns"))
def test_time_ns_of_time(self):
self.assertOnlyIn((3, 7), self.detect("from time import time_ns"))
def test_cancel_of_asyncio_TaskGroup(self):
self.assertOnlyIn((3, 15),
self.detect("from asyncio import TaskGroup\n"
"TaskGroup().cancel()"))
def test_run_of_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("import asyncio\nasyncio.run()"))
def test_run_coroutine_threadsafe_of_asyncio(self):
self.assertOnlyIn((3, 5), self.detect("import asyncio\nasyncio.run_coroutine_threadsafe()"))
def test_timeout_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("import asyncio\nasyncio.timeout()"))
def test_timeout_at_of_asyncio(self):
self.assertOnlyIn((3, 11), self.detect("import asyncio\nasyncio.timeout_at()"))
def test_create_task_of_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("import asyncio\nasyncio.create_task()"))
def test_current_task_of_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("import asyncio\nasyncio.current_task()"))
def test_all_tasks_of_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("import asyncio\nasyncio.all_tasks()"))
def test_capture_call_graph_of_asyncio(self):
self.assertOnlyIn((3, 14), self.detect("import asyncio\nasyncio.capture_call_graph()"))
def test_print_call_graph_of_asyncio(self):
self.assertOnlyIn((3, 14), self.detect("import asyncio\nasyncio.print_call_graph()"))
def test_parse_intermixed_args_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 7),
self.detect("from argparse import ArgumentParser\n"
"ap = ArgumentParser()\nap.parse_intermixed_args()"))
def test_parse_known_intermixed_args_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 7),
self.detect("from argparse import ArgumentParser\n"
"ap = ArgumentParser()\nap.parse_known_intermixed_args()"))
def test_byteswap_of_audioop(self):
self.assertOnlyIn((3, 4), self.detect("import audioop\naudioop.byteswap()"))
def test_alaw2lin_of_audioop(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import audioop\naudioop.alaw2lin()"))
def test_lin2alaw_of_audioop(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import audioop\naudioop.lin2alaw()"))
def test_a85encode_of_base64(self):
self.assertOnlyIn((3, 4), self.detect("import base64\nbase64.a85encode()"))
def test_a85decode_of_base64(self):
self.assertOnlyIn((3, 4), self.detect("import base64\nbase64.a85decode()"))
def test_decodebytes_of_base64(self):
self.assertOnlyIn((3, 1), self.detect("import base64\nbase64.decodebytes()"))
def test_encodebytes_of_base64(self):
self.assertOnlyIn((3, 1), self.detect("import base64\nbase64.encodebytes()"))
def test_bpformat_of_bdb_Breakpoint(self):
self.assertOnlyIn((3, 2), self.detect(
"from bdb import Breakpoint\nbp=Breakpoint()\nbp.bpformat()"))
def test_get_bpbynumber_of_bdb_Bdb(self):
self.assertOnlyIn((3, 2), self.detect("from bdb import Bdb\nbp=Bdb()\nbp.get_bpbynumber()"))
def test_clearBreakpoints_from_bdb_Breakpoint(self):
self.assertOnlyIn((3, 10),
self.detect("from bdb import Breakpoint\n"
"Breakpoint().clearBreakpoints()"))
def test_itermonthdays3_of_calendar_Calendar(self):
self.assertOnlyIn((3, 7), self.detect(
"from calendar import Calendar\nc=Calendar()\nc.itermonthdays3()"))
def test_itermonthdays4_of_calendar_Calendar(self):
self.assertOnlyIn((3, 7), self.detect(
"from calendar import Calendar\nc=Calendar()\nc.itermonthdays4()"))
def test_isfinite_of_cmath(self):
self.assertOnlyIn((3, 2), self.detect("import cmath\ncmath.isfinite()"))
def test_isclose_of_cmath(self):
self.assertOnlyIn((3, 5), self.detect("import cmath\ncmath.isclose()"))
def test_compile_file_of_compileall(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import compileall\ncompileall.compile_file()"))
def test_kill_workers_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 14), self.detect("""
import concurrent.futures.ProcessPoolExecutor
concurrent.futures.ProcessPoolExecutor.kill_workers()
"""))
def test_terminate_workers_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 14), self.detect("""
import concurrent.futures.ProcessPoolExecutor
concurrent.futures.ProcessPoolExecutor.terminate_workers()
"""))
def test_nullcontext_of_contextlib(self):
self.assertOnlyIn((3, 7), self.detect("import contextlib\ncontextlib.nullcontext()"))
def test_aclosing_of_contextlib(self):
self.assertOnlyIn((3, 10), self.detect("import contextlib\ncontextlib.aclosing()"))
def test_chdir_of_contextlib(self):
self.assertOnlyIn((3, 11), self.detect("import contextlib\ncontextlib.chdir()"))
def test_writeheader_of_csv_DictWriter(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from csv import DictWriter\n"
"DictWriter.writeheader()"))
def test_assume_default_colors_of_curses(self):
self.assertOnlyIn((3, 14), self.detect("import curses\ncurses.assume_default_colors()"))
def test_get_escdelay_of_curses(self):
self.assertOnlyIn((3, 9), self.detect("import curses\ncurses.get_escdelay()"))
def test_get_tabsize_of_curses(self):
self.assertOnlyIn((3, 9), self.detect("import curses\ncurses.get_tabsize()"))
def test_set_escdelay_of_curses(self):
self.assertOnlyIn((3, 9), self.detect("import curses\ncurses.set_escdelay()"))
def test_set_tabsize_of_curses(self):
self.assertOnlyIn((3, 9), self.detect("import curses\ncurses.set_tabsize()"))
def test_update_lines_cols_of_curses(self):
self.assertOnlyIn((3, 5), self.detect("import curses\ncurses.update_lines_cols()"))
def test_unget_wch_of_curses(self):
self.assertOnlyIn((3, 3), self.detect("import curses\ncurses.unget_wch()"))
def test_get_wch_of_curses_window(self):
self.assertOnlyIn((3, 3), self.detect("import curses.window\ncurses.window.get_wch()"))
def test_has_extended_color_support_of_curses(self):
self.assertOnlyIn((3, 10), self.detect("import curses\ncurses.has_extended_color_support()"))
def test_memoryview_at_of_curses(self):
self.assertOnlyIn((3, 14), self.detect("import curses\ncurses.memoryview_at()"))
def test_fromisoformat_of_datetime_date(self):
self.assertOnlyIn((3, 7), self.detect("from datetime import date\ndate.fromisoformat()"))
def test_fromisoformat_of_datetime_time(self):
self.assertOnlyIn((3, 7), self.detect("from datetime import time\ntime.fromisoformat()"))
def test_strptime_of_datetime_date(self):
self.assertOnlyIn((3, 14), self.detect("from datetime import date\ndate.strptime()"))
def test_strptime_of_datetime_time(self):
self.assertOnlyIn((3, 14), self.detect("from datetime import time\ntime.strptime()"))
def test_fromisoformat_of_datetime_datetime(self):
self.assertOnlyIn((3, 7), self.detect(
"from datetime import datetime\ndatetime.fromisoformat()"))
def test_fromisocalendar_of_datetime_date(self):
self.assertOnlyIn((3, 8), self.detect("from datetime import date\ndate.fromisocalendar()"))
def test_fromisocalendar_of_datetime_datetime(self):
self.assertOnlyIn((3, 8), self.detect(
"from datetime import datetime\ndatetime.fromisocalendar()"))
def test_code_info_of_dis(self):
self.assertOnlyIn((3, 2), self.detect("import dis\ndis.code_info()"))
def test_show_code_of_dis(self):
self.assertOnlyIn((3, 2), self.detect("import dis\ndis.show_code()"))
def test_get_instructions_of_dis(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.get_instructions()"))
def test_stack_effect_of_dis(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.stack_effect()"))
def test_as_integer_ratio_of_fractions_Fraction(self):
self.assertOnlyIn((3, 8),
self.detect("from fractions import Fraction\n"
"Fraction(42).as_integer_ratio()"))
self.assertOnlyIn((3, 8),
self.detect("from fractions import Fraction\n"
"f=Fraction(42)\nf.as_integer_ratio()"))
def test_is_integer_of_fractions_Fraction(self):
self.assertOnlyIn((3, 12), self.detect("""
from fractions import Fraction
Fraction(42).is_integer()
"""))
self.assertOnlyIn((3, 12), self.detect("""
from fractions import Fraction
f=Fraction(42)
f.is_integer()
"""))
def test_from_number_of_fractions_Fraction(self):
self.assertOnlyIn((3, 14), self.detect("""
from fractions import Fraction
Fraction.from_number(42)
"""))
def test_pgettext_of_gettext(self):
self.assertOnlyIn((3, 8), self.detect("import gettext\ngettext.pgettext()"))
def test_dpgettext_of_gettext(self):
self.assertOnlyIn((3, 8), self.detect("import gettext\ngettext.dpgettext()"))
def test_npgettext_of_gettext(self):
self.assertOnlyIn((3, 8), self.detect("import gettext\ngettext.npgettext()"))
def test_dnpgettext_of_gettext(self):
self.assertOnlyIn((3, 8), self.detect("import gettext\ngettext.dnpgettext()"))
def test_compress_of_gzip(self):
self.assertOnlyIn((3, 2), self.detect("import gzip\ngzip.compress()"))
def test_decompress_of_gzip(self):
self.assertOnlyIn((3, 2), self.detect("import gzip\ngzip.decompress()"))
def test_peek_of_gzip_GzipFile(self):
self.assertOnlyIn((3, 2), self.detect("from gzip import GzipFile\nGzipFile.peek()"))
def test_madvise_of_mmap_mmap(self):
self.assertOnlyIn((3, 8), self.detect("from mmap import mmap\nmmap.madvise()"))
def test_seekable_of_mmap_mmap(self):
self.assertOnlyIn((3, 13), self.detect("from mmap import mmap\nmmap.seekable()"))
def test_add_dll_directory_of_os(self):
self.assertOnlyIn((3, 8), self.detect("import os\nos.add_dll_directory()"))
def test_memfd_create_of_os(self):
self.assertOnlyIn((3, 8), self.detect("import os\nos.memfd_create()"))
def test_getxattr_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import getxattr"))
def test_grantpt_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import grantpt"))
def test_setxattr_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import setxattr"))
def test_timerfd_create_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import timerfd_create"))
def test_timerfd_settime_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import timerfd_settime"))
def test_timerfd_settime_ns_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import timerfd_settime_ns"))
def test_timerfd_gettime_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import timerfd_gettime"))
def test_timerfd_gettime_ns_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import timerfd_gettime_ns"))
def test_process_cpu_count_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import process_cpu_count"))
def test_removexattr_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import removexattr"))
def test_reload_environ_of_os(self):
self.assertOnlyIn((3, 14), self.detect("from os import reload_environ"))
def test_readinto_of_os(self):
self.assertOnlyIn((3, 14), self.detect("from os import readinto"))
def test_listxattr_of_os(self):
self.assertOnlyIn((3, 3), self.detect("from os import listxattr"))
def test_reducer_override_from_pickle_Pickler(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import Pickler\n"
"p=Pickler('foo')\n"
"p.reducer_override(None, None)"))
def test_dump_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import dump"))
def test_dumps_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import dumps"))
def test_load_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import load"))
def test_loads_of_plistlib(self):
self.assertOnlyIn((3, 4), self.detect("from plistlib import loads"))
def test_create_server_of_socket(self):
self.assertOnlyIn((3, 8), self.detect("from socket import create_server"))
def test_has_dualstack_ipv6_of_socket(self):
self.assertOnlyIn((3, 8), self.detect("from socket import has_dualstack_ipv6"))
def test_fromshare_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import fromshare"))
def test_share_of_socket_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import socket\n"
"socket().share"))
def test_close_of_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import close"))
def test_CMSG_LEN_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CMSG_LEN"))
def test_CMSG_SPACE_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import CMSG_SPACE"))
def test_sethostname_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import sethostname"))
def test_if_nameindex_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import if_nameindex"))
def test_if_nametoindex_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import if_nametoindex"))
def test_if_indextoname_of_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import if_indextoname"))
def test_detach_of_socket_socket(self):
self.assertOnlyIn((3, 2), self.detect("from socket import socket\n"
"socket().detach"))
def test_get_inheritable_of_socket_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import socket\n"
"socket().get_inheritable"))
def test_set_inheritable_of_socket_socket(self):
self.assertOnlyIn((3, 4), self.detect("from socket import socket\n"
"socket().set_inheritable"))
def test_getblocking_of_socket_socket(self):
self.assertOnlyIn((3, 7), self.detect("from socket import socket\n"
"socket().getblocking"))
def test_recvmsg_of_socket_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import socket\n"
"socket().recvmsg"))
def test_recvmsg_into_of_socket_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import socket\n"
"socket().recvmsg_into"))
def test_sendmsg_of_socket_socket(self):
self.assertOnlyIn((3, 3), self.detect("from socket import socket\n"
"socket().sendmsg"))
def test_sendmsg_afalg_of_socket_socket(self):
self.assertOnlyIn((3, 6), self.detect("from socket import socket\n"
"socket().sendmsg_afalg"))
def test_sendfile_of_socket_socket(self):
self.assertOnlyIn((3, 5), self.detect("from socket import socket\n"
"socket().sendfile"))
def test_fmean_of_statistics(self):
self.assertOnlyIn((3, 8), self.detect("from statistics import fmean"))
def test_geometric_mean_of_statistics(self):
self.assertOnlyIn((3, 8), self.detect("from statistics import geometric_mean"))
def test_harmonic_mean_of_statistics(self):
self.assertOnlyIn((3, 6), self.detect("from statistics import harmonic_mean"))
def test_multimode_of_statistics(self):
self.assertOnlyIn((3, 8), self.detect("from statistics import multimode"))
def test_quantiles_of_statistics(self):
self.assertOnlyIn((3, 8), self.detect("from statistics import quantiles"))
def test_covariance_of_statistics(self):
self.assertOnlyIn((3, 10), self.detect("from statistics import covariance"))
def test_correlation_of_statistics(self):
self.assertOnlyIn((3, 10), self.detect("from statistics import correlation"))
def test_linear_regression_of_statistics(self):
self.assertOnlyIn((3, 10), self.detect("from statistics import linear_regression"))
def test_unraisablehook_of_sys(self):
self.assertOnlyIn((3, 8), self.detect("from sys import unraisablehook"))
def test_excepthook_of_threading(self):
self.assertOnlyIn((3, 8), self.detect("from threading import excepthook"))
def test_get_native_id_of_threading(self):
self.assertOnlyIn((3, 8), self.detect("from threading import get_native_id"))
def test_get_ident_of_threading(self):
self.assertOnlyIn((3, 3), self.detect("from threading import get_ident"))
def test_main_thread_of_threading(self):
self.assertOnlyIn((3, 4), self.detect("from threading import main_thread"))
def test_generate_tokens_of_tokenize(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("from tokenize import generate_tokens"))
def test_untokenize_of_tokenize(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("from tokenize import untokenize"))
def test_open_of_tokenize(self):
self.assertOnlyIn((3, 2), self.detect("from tokenize import open"))
def test_has_default_of_typing_ParamSpec(self):
self.assertOnlyIn((3, 13), self.detect("""
from typing import ParamSpec
ParamSpec().has_default()
"""))
def test_evaluate_default_of_typing_ParamSpec(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import ParamSpec
ParamSpec().evaluate_default()
"""))
def test_evaluate_value_of_typing_TypeAliasType(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import TypeAliasType
TypeAliasType().evaluate_value()
"""))
def test_has_default_of_typing_TypeVar(self):
self.assertOnlyIn((3, 13), self.detect("""
from typing import TypeVar
TypeVar().has_default()
"""))
def test_evaluate_bound_of_typing_TypeVar(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import TypeVar
TypeVar().evaluate_bound()
"""))
def test_evaluate_default_of_typing_TypeVar(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import TypeVar
TypeVar().evaluate_default()
"""))
def test_evaluate_constraints_of_typing_TypeVar(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import TypeVar
TypeVar().evaluate_constraints()
"""))
def test_has_default_of_typing_TypeVarTuple(self):
self.assertOnlyIn((3, 13), self.detect("""
from typing import TypeVarTuple
TypeVarTuple().has_default()
"""))
def test_evaluate_default_of_typing_TypeVarTuple(self):
self.assertOnlyIn((3, 14), self.detect("""
from typing import TypeVarTuple
TypeVarTuple().evaluate_default()
"""))
def test_assert_never_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import assert_never"))
def test_assert_type_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import assert_type"))
def test_clear_overloads_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import clear_overloads"))
def test_evaluate_forward_ref_of_typing(self):
self.assertOnlyIn((3, 14), self.detect("from typing import evaluate_forward_ref"))
def test_get_protocol_members_of_typing(self):
self.assertOnlyIn((3, 13), self.detect("from typing import get_protocol_members"))
def test_get_origin_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import get_origin"))
def test_get_overloads_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import get_overloads"))
def test_get_args_of_typing(self):
self.assertOnlyIn((3, 8), self.detect("from typing import get_args"))
def test_is_typeddict_of_typing(self):
self.assertOnlyIn((3, 10), self.detect("from typing import is_typeddict"))
def test_is_protocol_of_typing(self):
self.assertOnlyIn((3, 13), self.detect("from typing import is_protocol"))
def test_reveal_type_of_typing(self):
self.assertOnlyIn((3, 11), self.detect("from typing import reveal_type"))
def test_uuid6_of_uuid(self):
self.assertOnlyIn((3, 14), self.detect("from uuid import uuid6"))
def test_uuid7_of_uuid(self):
self.assertOnlyIn((3, 14), self.detect("from uuid import uuid7"))
def test_uuid8_of_uuid(self):
self.assertOnlyIn((3, 14), self.detect("from uuid import uuid8"))
def test_is_normalized_of_unicodedata(self):
self.assertOnlyIn((3, 8), self.detect("from unicodedata import is_normalized"))
def test_addaudithook_of_sys(self):
self.assertOnlyIn((3, 8), self.detect("from sys import addaudithook"))
def test_audit_of_sys(self):
self.assertOnlyIn((3, 8), self.detect("from sys import audit"))
def test_copy_file_range_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import copy_file_range"))
def test_posix_openpt_of_os(self):
self.assertOnlyIn((3, 13), self.detect("from os import posix_openpt"))
def test_posix_spawn_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import posix_spawn"))
def test_posix_spawnp_of_os(self):
self.assertOnlyIn((3, 8), self.detect("from os import posix_spawnp"))
def test_register_at_fork_of_os(self):
self.assertOnlyIn((3, 7), self.detect("from os import register_at_fork"))
def test_S_ISDOOR_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_ISDOOR"))
def test_S_ISPORT_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_ISPORT"))
def test_S_ISWHT_of_stat(self):
self.assertOnlyIn((3, 4), self.detect("from stat import S_ISWHT"))
def test_filemode_of_stat(self):
self.assertOnlyIn((3, 3), self.detect("from stat import filemode"))
def test_ehlo_or_helo_if_needed_of_smtplib_SMTP(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from smtplib import SMTP\nSMTP.ehlo_or_helo_if_needed"))
def test_auth_of_smtplib_SMTP(self):
self.assertOnlyIn((3, 5), self.detect("from smtplib import SMTP\nSMTP.auth"))
def test_send_message_of_smtplib_SMTP(self):
self.assertOnlyIn((3, 2), self.detect("from smtplib import SMTP\nSMTP.send_message"))
def test_dictConfig_from_logging_config(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"import logging.config\nlogging.config.dictConfig()"))
def test_adjust_int_max_str_digits_from_test_support(self):
self.assertOnlyIn((3, 11), self.detect(
"import test.support\ntest.support.adjust_int_max_str_digits()"))
def test_captured_stdout_from_test_support(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import test.support\ntest.support.captured_stdout()"))
def test_catch_threading_exception_from_test_support(self):
self.assertOnlyIn((3, 8), self.detect(
"import test.support\ntest.support.catch_threading_exception()"))
def test_catch_unraisable_exception_from_test_support(self):
self.assertOnlyIn((3, 8), self.detect(
"import test.support\ntest.support.catch_unraisable_exception()"))
def test_check__all___from_test_support(self):
self.assertOnlyIn((3, 6), self.detect("import test.support\ntest.support.check__all__()"))
def test_check_py3k_warnings_from_test_support(self):
self.assertOnlyIn((2, 7), self.detect(
"import test.support\ntest.support.check_py3k_warnings()"))
def test_check_syntax_warning_from_test_support(self):
self.assertOnlyIn((3, 8), self.detect(
"import test.support\ntest.support.check_syntax_warning()"))
def test_check_warnings_from_test_support(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import test.support\ntest.support.check_warnings()"))
def test_detect_api_mismatch_from_test_support(self):
self.assertOnlyIn((3, 5), self.detect(
"import test.support\ntest.support.detect_api_mismatch()"))
def test_flush_std_streams_from_test_support(self):
self.assertOnlyIn((3, 11), self.detect(
"import test.support\ntest.support.flush_std_streams()"))
def test_import_fresh_module_from_test_support(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"import test.support\ntest.support.import_fresh_module()"))
def test_import_module_from_test_support(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"import test.support\ntest.support.import_module()"))
def test_seal_from_unittest_mock(self):
self.assertOnlyIn((3, 7), self.detect("import unittest.mock\nunittest.mock.seal()"))
self.assertTrue(self.config.add_backport("mock"))
self.assertOnlyIn(((3, 6)), self.detect("import unittest.mock\nunittest.mock.seal()"))
def test_quoteattr_from_xml_sax_saxutils(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect(
"import xml.sax.saxutils\nxml.sax.saxutils.quoteattr()"))
def test_unescape_from_xml_sax_saxutils(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect(
"import xml.sax.saxutils\nxml.sax.saxutils.unescape()"))
def test_set_from_ConfigParser_SafeConfigParser(self):
self.assertOnlyIn((2, 4),
self.detect("from ConfigParser import SafeConfigParser\n"
"SafeConfigParser().set()"))
def test_GetArgv_from_EasyDialogs(self):
self.assertOnlyIn((2, 0), self.detect("import EasyDialogs\nEasyDialogs.GetArgv()"))
def test_join_from_Queue_Queue(self):
self.assertOnlyIn((2, 5),
self.detect("from Queue import Queue\n"
"Queue().join()"))
def test_shutodown_from_queue_Queue(self):
self.assertOnlyIn((3, 13),
self.detect("from queue import Queue\n"
"Queue().shutdown()"))
def test_task_done_from_Queue_Queue(self):
self.assertOnlyIn((2, 5),
self.detect("from Queue import Queue\n"
"Queue().task_done()"))
def test_do_GET_from_SimpleHTTPServer_SimpleHTTPRequestHandler(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleHTTPServer import SimpleHTTPRequestHandler\n"
"SimpleHTTPRequestHandler().do_GET()"))
def test_server_close_from_SocketServer_BaseServer(self):
self.assertOnlyIn((2, 6),
self.detect("from SocketServer import BaseServer\n"
"BaseServer().server_close()"))
def test_shutdown_from_SocketServer_BaseServer(self):
self.assertOnlyIn((2, 6),
self.detect("from SocketServer import BaseServer\n"
"BaseServer().shutdown()"))
def test_get_native_id_from__thread(self):
self.assertOnlyIn((3, 8), self.detect("import _thread\n_thread.get_native_id()"))
def test_CreateKeyEx_from__winreg(self):
self.assertOnlyIn((2, 7), self.detect("import _winreg\n_winreg.CreateKeyEx()"))
def test_DeleteKeyEx_from__winreg(self):
self.assertOnlyIn((2, 7), self.detect("import _winreg\n_winreg.DeleteKeyEx()"))
def test_ExpandEnvironmentStrings_from__winreg(self):
self.assertOnlyIn((2, 6), self.detect("import _winreg\n_winreg.ExpandEnvironmentStrings()"))
def test_get_cache_token_from_abc(self):
self.assertOnlyIn((3, 4), self.detect("import abc\nabc.get_cache_token()"))
def test_update_abstractmethods_from_abc(self):
self.assertOnlyIn((3, 10), self.detect("import abc\nabc.update_abstractmethods()"))
def test_clear_from_array_array(self):
self.assertOnlyIn((3, 13),
self.detect("from array import array\n"
"array().clear()"))
def test_frombytes_from_array_array(self):
self.assertOnlyIn((3, 2),
self.detect("from array import array\n"
"array().frombytes()"))
def test_tobytes_from_array_array(self):
self.assertOnlyIn((3, 2),
self.detect("from array import array\n"
"array().tobytes()"))
def test_get_source_segment_from_ast(self):
self.assertOnlyIn((3, 8), self.detect("import ast\nast.get_source_segment()"))
def test_compare_from_ast(self):
self.assertOnlyIn((3, 14), self.detect("import ast\nast.compare()"))
def test_is_active_from_asyncio_AbstractChildWatcher(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import AbstractChildWatcher\n"
"AbstractChildWatcher().is_active()"))
def test_get_loop_from_asyncio_Future(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import Future\n"
"Future().get_loop()"))
def test_cancelled_from_asyncio_Handle(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import Handle\n"
"Handle().cancelled()"))
def test_is_reading_from_asyncio_ReadTransport(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import ReadTransport\n"
"ReadTransport().is_reading()"))
def test_abort_clients_from_asyncio_Server(self):
self.assertOnlyIn((3, 13),
self.detect("from asyncio import Server\n"
"Server().abort_clients()"))
def test_close_clients_from_asyncio_Server(self):
self.assertOnlyIn((3, 13),
self.detect("from asyncio import Server\n"
"Server().close_clients()"))
def test_get_loop_from_asyncio_Server(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Server\n"
"Server().get_loop()"))
def test_is_serving_from_asyncio_Server(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Server\n"
"Server().is_serving()"))
def test_serve_forever_from_asyncio_Server(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Server\n"
"Server().serve_forever()"))
def test_start_serving_from_asyncio_Server(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Server\n"
"Server().start_serving()"))
def test_readuntil_from_asyncio_StreamReader(self):
self.assertOnlyIn((3, 5),
self.detect("from asyncio import StreamReader\n"
"StreamReader().readuntil()"))
def test_is_closing_from_asyncio_StreamWriter(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import StreamWriter\n"
"StreamWriter().is_closing()"))
def test_start_tls_from_asyncio_StreamWriter(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import StreamWriter\n"
"StreamWriter().start_tls()"))
def test_wait_closed_from_asyncio_StreamWriter(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import StreamWriter\n"
"StreamWriter().wait_closed()"))
def test_get_coro_from_asyncio_Task(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import Task\n"
"Task().get_coro()"))
def test_cancelling_from_asyncio_Task(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import Task\n"
"Task().cancelling()"))
def test_get_context_from_asyncio_Task(self):
self.assertOnlyIn((3, 12),
self.detect("from asyncio import Task\n"
"Task().get_context()"))
def test_get_name_from_asyncio_Task(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import Task\n"
"Task().get_name()"))
def test_set_name_from_asyncio_Task(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import Task\n"
"Task().set_name()"))
def test_uncancel_from_asyncio_Task(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import Task\n"
"Task().uncancel()"))
def test_when_from_asyncio_TimerHandle(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import TimerHandle\n"
"TimerHandle().when()"))
def test_shutdown_from_asyncio_Queue(self):
self.assertOnlyIn((3, 13),
self.detect("from asyncio import Queue\n"
"Queue().shutdown()"))
def test_get_write_buffer_limits_from_asyncio_WriteTransport(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import WriteTransport\n"
"WriteTransport().get_write_buffer_limits()"))
def test_get_running_loop_from_asyncio(self):
self.assertOnlyIn((3, 7), self.detect("import asyncio\nasyncio.get_running_loop()"))
def test_isfuture_from_asyncio(self):
self.assertOnlyIn((3, 5), self.detect("import asyncio\nasyncio.isfuture()"))
def test_connect_accepted_socket_from_asyncio_loop(self):
self.assertOnlyIn((3, 5),
self.detect("from asyncio import loop\n"
"loop().connect_accepted_socket()"))
def test_create_future_from_asyncio_loop(self):
self.assertOnlyIn((3, 5),
self.detect("from asyncio import loop\n"
"loop().create_future()"))
def test_get_exception_handler_from_asyncio_loop(self):
self.assertOnlyIn((3, 5),
self.detect("from asyncio import loop\n"
"loop().get_exception_handler()"))
def test_sendfile_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"loop().sendfile()"))
def test_shutdown_asyncgens_from_asyncio_loop(self):
self.assertOnlyIn((3, 6),
self.detect("from asyncio import loop\n"
"loop().shutdown_asyncgens()"))
def test_sock_recv_into_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"loop().sock_recv_into()"))
def test_sock_recvfrom_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"loop().sock_recvfrom()"))
def test_sock_recvfrom_into_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"loop().sock_recvfrom_into()"))
def test_sock_sendto_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"loop().sock_sendto()"))
def test_sock_sendfile_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"loop().sock_sendfile()"))
def test_start_tls_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"loop().start_tls()"))
def test_shutdown_default_executor_from_asyncio_loop(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import loop\n"
"loop().shutdown_default_executor()"))
def test_to_thread_from_asyncio(self):
self.assertOnlyIn((3, 9), self.detect("from asyncio import to_thread"))
def test_eager_task_factory_from_asyncio(self):
self.assertOnlyIn((3, 12), self.detect("from asyncio import eager_task_factory"))
def test_create_eager_task_factory_from_asyncio(self):
self.assertOnlyIn((3, 12), self.detect("from asyncio import create_eager_task_factory"))
def test_handle_accepted_from_asyncore_dispatcher(self):
self.assertOnlyIn((3, 2),
self.detect("import asyncore\nasyncore.dispatcher.handle_accepted()"))
def test_b85decode_from_base64(self):
self.assertOnlyIn((3, 4), self.detect("import base64\nbase64.b85decode()"))
def test_b85encode_from_base64(self):
self.assertOnlyIn((3, 4), self.detect("import base64\nbase64.b85encode()"))
def test_b32hexencode_from_base64(self):
self.assertOnlyIn((3, 10), self.detect("import base64\nbase64.b32hexencode()"))
def test_b32hexdecode_from_base64(self):
self.assertOnlyIn((3, 10), self.detect("import base64\nbase64.b32hexdecode()"))
def test_z85decode_from_base64(self):
self.assertOnlyIn((3, 13), self.detect("import base64\nbase64.z85decode()"))
def test_z85encode_from_base64(self):
self.assertOnlyIn((3, 13), self.detect("import base64\nbase64.z85encode()"))
def test_getfirst_from_cgi_FieldStorage(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from cgi import FieldStorage\n"
"FieldStorage().getfirst()"))
def test_getlist_from_cgi_FieldStorage(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from cgi import FieldStorage\n"
"FieldStorage().getlist()"))
def test_isinf_from_cmath(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import cmath\ncmath.isinf()"))
def test_isnan_from_cmath(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import cmath\ncmath.isnan()"))
def test_phase_from_cmath(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import cmath\ncmath.phase()"))
def test_polar_from_cmath(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import cmath\ncmath.polar()"))
def test_rect_from_cmath(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import cmath\ncmath.rect()"))
def test_decode_from_codecs(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import codecs\ncodecs.decode()"))
def test_encode_from_codecs(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import codecs\ncodecs.encode()"))
def test_getincrementaldecoder_from_codecs(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect(
"import codecs\ncodecs.getincrementaldecoder()"))
def test_getincrementalencoder_from_codecs(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect(
"import codecs\ncodecs.getincrementalencoder()"))
def test_iterdecode_from_codecs(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import codecs\ncodecs.iterdecode()"))
def test_iterencode_from_codecs(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import codecs\ncodecs.iterencode()"))
def test_namereplace_errors_from_codecs(self):
self.assertOnlyIn((3, 5), self.detect("import codecs\ncodecs.namereplace_errors()"))
def test_unregister_from_codecs(self):
self.assertOnlyIn((3, 10), self.detect("import codecs\ncodecs.unregister()"))
def test___getnewargs___from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().__getnewargs__()"))
def test___rmod___from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().__rmod__()"))
def test_casefold_from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().casefold()"))
def test_format_map_from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().format_map()"))
def test_isprintable_from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().isprintable()"))
def test_maketrans_from_collections_UserString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections import UserString\n"
"UserString().maketrans()"))
def test_removeprefix_from_collections_UserString(self):
self.assertOnlyIn((3, 9),
self.detect("from collections import UserString\n"
"UserString().removeprefix()"))
def test_removesuffix_from_collections_UserString(self):
self.assertOnlyIn((3, 9),
self.detect("from collections import UserString\n"
"UserString().removesuffix()"))
def test_clear_from_collections_abc_MutableSequence(self):
self.assertOnlyIn((3, 3),
self.detect("from collections.abc import MutableSequence\n"
"MutableSequence().clear()"))
def test_copy_from_collections_abc_MutableSequence(self):
self.assertOnlyIn((3, 3),
self.detect("from collections.abc import MutableSequence\n"
"MutableSequence().copy()"))
def test_read_dict_from_configparser_ConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_dict()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_dict()"))
def test_read_file_from_configparser_ConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_file()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_file()"))
def test_read_string_from_configparser_ConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_string()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser().read_string()"))
def test_read_dict_from_configparser_RawConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_dict()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_dict()"))
def test_read_file_from_configparser_RawConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_file()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_file()"))
def test_read_string_from_configparser_RawConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_string()"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser().read_string()"))
def test_replace_from_copy(self):
self.assertOnlyIn((3, 13), self.detect("import copy\ncopy.replace()"))
def test_get_wch_from_curses_window(self):
self.assertOnlyIn((3, 3),
self.detect("from curses import window\n"
"window().get_wch()"))
def test_strptime_from_datetime_datetime(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from datetime import datetime\n"
"datetime().strptime()"))
def test_clear_from_dbm_gdbm(self):
self.assertOnlyIn((3, 13), self.detect("from dbm import gdbm\ngdbm.clear()"))
def test_clear_from_dbm_ndbm(self):
self.assertOnlyIn((3, 13), self.detect("from dbm import ndbm\nndbm.clear()"))
def test_reorganize_of_dbm_dumb(self):
self.assertOnlyIn((3, 15), self.detect("from dbm import dumb\ndumb.reorganize()"))
def test_reorganize_of_dbm_sqlite3(self):
self.assertOnlyIn((3, 15), self.detect("from dbm import sqlite3\nsqlite3.reorganize()"))
def test_DocFileSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import doctest\ndoctest.DocFileSuite()"))
def test_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import doctest\ndoctest.DocTestSuite()"))
def test_debug_from_doctest(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import doctest\ndoctest.debug()"))
def test_debug_src_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import doctest\ndoctest.debug_src()"))
def test_register_optionflag_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import doctest\ndoctest.register_optionflag()"))
def test_script_from_examples_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import doctest\ndoctest.script_from_examples()"))
def test_set_unittest_reportflags_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import doctest\ndoctest.set_unittest_reportflags()"))
def test_testfile_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import doctest\ndoctest.testfile()"))
def test_testsource_from_doctest(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import doctest\ndoctest.testsource()"))
def test_clone_from_email_generator_Generator(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.generator import Generator\n"
"Generator().clone()"))
def test_flatten_from_email_generator_Generator(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.generator import Generator\n"
"Generator().flatten()"))
def test_get_content_disposition_from_email_message_EmailMessage(self):
self.assertOnlyIn((3, 5),
self.detect("from email.message import EmailMessage\n"
"EmailMessage().get_content_disposition()"))
def test___bytes___from_email_message_Message(self):
self.assertOnlyIn((3, 4),
self.detect("from email.message import Message\n"
"Message().__bytes__()"))
def test_as_bytes_from_email_message_Message(self):
self.assertOnlyIn((3, 4),
self.detect("from email.message import Message\n"
"Message().as_bytes()"))
def test_del_param_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().del_param()"))
def test_get_charset_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_charset()"))
def test_get_content_charset_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_content_charset()"))
def test_get_content_disposition_from_email_message_Message(self):
self.assertOnlyIn((3, 5),
self.detect("from email.message import Message\n"
"Message().get_content_disposition()"))
def test_get_content_maintype_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_content_maintype()"))
def test_get_content_subtype_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_content_subtype()"))
def test_get_content_type_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_content_type()"))
def test_get_default_type_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().get_default_type()"))
def test_replace_header_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().replace_header()"))
def test_set_charset_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().set_charset()"))
def test_set_default_type_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().set_default_type()"))
def test_set_param_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().set_param()"))
def test_set_type_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"Message().set_type()"))
def test_message_from_binary_file_from_email(self):
self.assertOnlyIn((3, 2), self.detect("import email\nemail.message_from_binary_file()"))
def test_message_from_bytes_from_email(self):
self.assertOnlyIn((3, 2), self.detect("import email\nemail.message_from_bytes()"))
def test_dump_c_stack_from_faulthandler(self):
self.assertOnlyIn((3, 14), self.detect("import faulthandler\nfaulthandler.dump_c_stack()"))
def test_clear_cache_from_filecmp(self):
self.assertOnlyIn((3, 4), self.detect("import filecmp\nfilecmp.clear_cache()"))
def test_fileno_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import fileinput\nfileinput.fileno()"))
def test_hook_compressed_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect(
"import fileinput\nfileinput.hook_compressed()"))
def test_hook_encoded_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import fileinput\nfileinput.hook_encoded()"))
def test_filter_from_fnmatch(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import fnmatch\nfnmatch.filter()"))
def test_filterfalse_from_fnmatch(self):
self.assertOnlyIn((3, 14), self.detect("import fnmatch\nfnmatch.filterfalse()"))
def test_mlsd_from_ftplib_FTP(self):
self.assertOnlyIn((3, 3),
self.detect("from ftplib import FTP\n"
"FTP().mlsd()"))
def test_ccc_from_ftplib_FTP_TLS(self):
self.assertOnlyIn((3, 3),
self.detect("from ftplib import FTP_TLS\n"
"FTP_TLS().ccc()"))
def test_freeze_from_gc(self):
self.assertOnlyIn((3, 7), self.detect("import gc\ngc.freeze()"))
def test_get_count_from_gc(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import gc\ngc.get_count()"))
def test_get_freeze_count_from_gc(self):
self.assertOnlyIn((3, 7), self.detect("import gc\ngc.get_freeze_count()"))
def test_get_objects_from_gc(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import gc\ngc.get_objects()"))
def test_get_referents_from_gc(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import gc\ngc.get_referents()"))
def test_get_referrers_from_gc(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import gc\ngc.get_referrers()"))
def test_get_stats_from_gc(self):
self.assertOnlyIn((3, 4), self.detect("import gc\ngc.get_stats()"))
def test_is_tracked_from_gc(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import gc\ngc.is_tracked()"))
def test_is_finalized_from_gc(self):
self.assertOnlyIn((3, 9), self.detect("import gc\ngc.is_finalized()"))
def test_unfreeze_from_gc(self):
self.assertOnlyIn((3, 7), self.detect("import gc\ngc.unfreeze()"))
def test_gnu_getopt_from_getopt(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import getopt\ngetopt.gnu_getopt()"))
def test_lgettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().lgettext()"))
def test_lngettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().lngettext()"))
def test_ngettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().ngettext()"))
def test_npgettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn((3, 8),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().npgettext()"))
def test_pgettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn((3, 8),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().pgettext()"))
def test_ungettext_from_gettext_GNUTranslations(self):
self.assertOnlyIn((2, 3),
self.detect("from gettext import GNUTranslations\n"
"GNUTranslations().ungettext()"))
def test_lgettext_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().lgettext()"))
def test_lngettext_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().lngettext()"))
def test_ngettext_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().ngettext()"))
def test_npgettext_from_gettext_NullTranslations(self):
self.assertOnlyIn((3, 8),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().npgettext()"))
def test_output_charset_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().output_charset()"))
def test_pgettext_from_gettext_NullTranslations(self):
self.assertOnlyIn((3, 8),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().pgettext()"))
def test_set_output_charset_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().set_output_charset()"))
def test_ungettext_from_gettext_NullTranslations(self):
self.assertOnlyIn((2, 3),
self.detect("from gettext import NullTranslations\n"
"NullTranslations().ungettext()"))
def test_bind_textdomain_codeset_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import gettext\ngettext.bind_textdomain_codeset()"))
def test_dngettext_from_gettext(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import gettext\ngettext.dngettext()"))
def test_ldgettext_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import gettext\ngettext.ldgettext()"))
def test_ldngettext_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import gettext\ngettext.ldngettext()"))
def test_lgettext_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import gettext\ngettext.lgettext()"))
def test_lngettext_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import gettext\ngettext.lngettext()"))
def test_ngettext_from_gettext(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import gettext\ngettext.ngettext()"))
def test_escape_from_glob(self):
self.assertOnlyIn((3, 4), self.detect("import glob\nglob.escape()"))
def test_iglob_from_glob(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import glob\nglob.iglob()"))
def test_translate_from_glob(self):
self.assertOnlyIn((3, 13), self.detect("import glob\nglob.translate()"))
def test_blake2b_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.blake2b()"))
def test_blake2s_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.blake2s()"))
def test_file_digest_from_hashlib(self):
self.assertOnlyIn((3, 11), self.detect("import hashlib\nhashlib.file_digest()"))
def test_sha3_224_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.sha3_224()"))
def test_sha3_256_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.sha3_256()"))
def test_sha3_384_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.sha3_384()"))
def test_sha3_512_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.sha3_512()"))
def test_shake_128_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.shake_128()"))
def test_shake_256_from_hashlib(self):
self.assertOnlyIn((3, 6), self.detect("import hashlib\nhashlib.shake_256()"))
def test_escape_from_html(self):
self.assertOnlyIn((3, 2), self.detect("import html\nhtml.escape()"))
def test_unescape_from_html(self):
self.assertOnlyIn((3, 4), self.detect("import html\nhtml.unescape()"))
def test_set_debuglevel_from_http_client_HTTPConnection(self):
self.assertOnlyIn((3, 1),
self.detect("from http.client import HTTPConnection\n"
"HTTPConnection().set_debuglevel()"))
def test_set_tunnel_from_http_client_HTTPConnection(self):
self.assertOnlyIn((3, 2),
self.detect("from http.client import HTTPConnection\n"
"HTTPConnection().set_tunnel()"))
def test_readinto_from_http_client_HTTPResponse(self):
self.assertOnlyIn((3, 3),
self.detect("from http.client import HTTPResponse\n"
"HTTPResponse().readinto()"))
def test_flush_headers_from_http_server_BaseHTTPRequestHandler(self):
self.assertOnlyIn((3, 3),
self.detect("from http.server import BaseHTTPRequestHandler\n"
"BaseHTTPRequestHandler().flush_headers()"))
def test_handle_expect_100_from_http_server_BaseHTTPRequestHandler(self):
self.assertOnlyIn((3, 2),
self.detect("from http.server import BaseHTTPRequestHandler\n"
"BaseHTTPRequestHandler().handle_expect_100()"))
def test_send_response_only_from_http_server_BaseHTTPRequestHandler(self):
self.assertOnlyIn((3, 2),
self.detect("from http.server import BaseHTTPRequestHandler\n"
"BaseHTTPRequestHandler().send_response_only()"))
def test_set_tunnel_from_httplib_HTTPConnection(self):
self.assertOnlyIn((2, 7),
self.detect("from httplib import HTTPConnection\n"
"HTTPConnection().set_tunnel()"))
def test_getheaders_from_httplib_HTTPResponse(self):
self.assertOnlyIn((2, 4),
self.detect("from httplib import HTTPResponse\n"
"HTTPResponse().getheaders()"))
def test_burst_from_imaplib_Idler(self):
self.assertOnlyIn((3, 14),
self.detect("from imaplib import Idler\n"
"Idler().burst()"))
def test_deleteacl_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().deleteacl()"))
def test_enable_from_imaplib_IMAP4(self):
self.assertOnlyIn((3, 5),
self.detect("from imaplib import IMAP4\n"
"IMAP4().enable()"))
def test_getannotation_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().getannotation()"))
def test_getquota_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().getquota()"))
def test_getquotaroot_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().getquotaroot()"))
def test_idle_from_imaplib_IMAP4(self):
self.assertOnlyIn((3, 14),
self.detect("from imaplib import IMAP4\n"
"IMAP4().idle()"))
def test_login_cram_md5_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().login_cram_md5()"))
def test_myrights_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().myrights()"))
def test_namespace_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().namespace()"))
def test_proxyauth_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().proxyauth()"))
def test_setannotation_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().setannotation()"))
def test_setquota_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().setquota()"))
def test_starttls_from_imaplib_IMAP4(self):
self.assertOnlyIn((3, 2),
self.detect("from imaplib import IMAP4\n"
"IMAP4().starttls()"))
def test_thread_from_imaplib_IMAP4(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from imaplib import IMAP4\n"
"IMAP4().thread()"))
def test_unselect_from_imaplib_IMAP4(self):
self.assertOnlyIn((3, 9),
self.detect("from imaplib import IMAP4\n"
"IMAP4().unselect()"))
def test_acquire_lock_from_imp(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import imp\nimp.acquire_lock()"))
def test_cache_from_source_from_imp(self):
self.assertOnlyIn((3, 2), self.detect("import imp\nimp.cache_from_source()"))
def test_get_tag_from_imp(self):
self.assertOnlyIn((3, 2), self.detect("import imp\nimp.get_tag()"))
def test_release_lock_from_imp(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import imp\nimp.release_lock()"))
def test_source_from_cache_from_imp(self):
self.assertOnlyIn((3, 2), self.detect("import imp\nimp.source_from_cache()"))
def test_exec_module_from_importlib_abc_InspectLoader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import InspectLoader\n"
"InspectLoader().exec_module()"))
def test_source_to_code_from_importlib_abc_InspectLoader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import InspectLoader\n"
"InspectLoader().source_to_code()"))
def test_create_module_from_importlib_abc_Loader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import Loader\n"
"Loader().create_module()"))
def test_exec_module_from_importlib_abc_Loader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import Loader\n"
"Loader().exec_module()"))
def test_module_repr_from_importlib_abc_Loader(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib.abc import Loader\n"
"Loader().module_repr()"))
def test_find_spec_from_importlib_abc_MetaPathFinder(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import MetaPathFinder\n"
"MetaPathFinder().find_spec()"))
def test_find_spec_from_importlib_abc_PathEntryFinder(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import PathEntryFinder\n"
"PathEntryFinder().find_spec()"))
def test_exec_module_from_importlib_abc_SourceLoader(self):
self.assertOnlyIn((3, 4),
self.detect("from importlib.abc import SourceLoader\n"
"SourceLoader().exec_module()"))
def test_path_stats_from_importlib_abc_SourceLoader(self):
self.assertOnlyIn((3, 3),
self.detect("from importlib.abc import SourceLoader\n"
"SourceLoader().path_stats()"))
def test_find_loader_from_importlib(self):
self.assertOnlyIn((3, 3), self.detect("import importlib\nimportlib.find_loader()"))
def test_invalidate_caches_from_importlib(self):
self.assertOnlyIn((3, 3), self.detect("import importlib\nimportlib.invalidate_caches()"))
def test_create_module_from_importlib_machinery_BuiltinImporter(self):
self.assertOnlyIn((3, 5),
self.detect("from importlib.machinery import BuiltinImporter\n"
"BuiltinImporter().create_module()"))
def test_exec_module_from_importlib_machinery_BuiltinImporter(self):
self.assertOnlyIn((3, 5),
self.detect("from importlib.machinery import BuiltinImporter\n"
"BuiltinImporter().exec_module()"))
def test_reload_from_importlib(self):
self.assertOnlyIn((3, 4), self.detect("import importlib\nimportlib.reload()"))
def test_files_from_importlib_resources(self):
self.assertOnlyIn((3, 9), self.detect(
"import importlib.resources\nimportlib.resources.files()"))
def test_as_file_from_importlib_resources(self):
self.assertOnlyIn((3, 9), self.detect("import importlib.resources\n"
"importlib.resources.as_file()"))
def test_from_callable_from_inspect_Signature(self):
self.assertOnlyIn((3, 5),
self.detect("from inspect import Signature\n"
"Signature().from_callable()"))
def test_reconfigure_from_io_TextIOWrapper(self):
self.assertOnlyIn((3, 7),
self.detect("from io import TextIOWrapper\n"
"TextIOWrapper().reconfigure()"))
def test_open_code_from_io(self):
self.assertOnlyIn((3, 8), self.detect("import io\nio.open_code()"))
def test_text_encoding_from_io(self):
self.assertOnlyIn((3, 10), self.detect("import io\nio.text_encoding()"))
def test___format___from_ipaddress_IPv4Address(self):
self.assertOnlyIn((3, 9),
self.detect("from ipaddress import IPv4Address\n"
"IPv4Address().__format__()"))
def test_subnet_of_from_ipaddress_IPv4Network(self):
self.assertOnlyIn((3, 7),
self.detect("from ipaddress import IPv4Network\n"
"IPv4Network().subnet_of()"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from ipaddress import IPv4Network\n"
"IPv4Network().subnet_of()"))
def test_supernet_of_from_ipaddress_IPv4Network(self):
self.assertOnlyIn((3, 7),
self.detect("from ipaddress import IPv4Network\n"
"IPv4Network().supernet_of()"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from ipaddress import IPv4Network\n"
"IPv4Network().supernet_of()"))
def test___format___from_ipaddress_IPv6Address(self):
self.assertOnlyIn((3, 9),
self.detect("from ipaddress import IPv6Address\n"
"IPv6Address().__format__()"))
def test_lazycache_from_linecache(self):
self.assertOnlyIn((3, 5), self.detect("import linecache\nlinecache.lazycache()"))
def test_currency_from_locale(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import locale\nlocale.currency()"))
def test_delocalize_from_locale(self):
self.assertOnlyIn((3, 5), self.detect("import locale\nlocale.delocalize()"))
def test_localize_from_locale(self):
self.assertOnlyIn((3, 10), self.detect("import locale\nlocale.localize()"))
def test_format_string_from_locale(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import locale\nlocale.format_string()"))
def test_getdefaultlocale_from_locale(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import locale\nlocale.getdefaultlocale()"))
def test_getencoding_from_locale(self):
self.assertOnlyIn((3, 11), self.detect("import locale\nlocale.getencoding()"))
def test_getlocale_from_locale(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import locale\nlocale.getlocale()"))
def test_getpreferredencoding_from_locale(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import locale\nlocale.getpreferredencoding()"))
def test_normalize_from_locale(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import locale\nlocale.normalize()"))
def test_resetlocale_from_locale(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import locale\nlocale.resetlocale()"))
def test_getEffectiveLevel_from_logging_LoggerAdapter(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter().getEffectiveLevel()"))
def test_hasHandlers_from_logging_LoggerAdapter(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter().hasHandlers()"))
def test_isEnabledFor_from_logging_LoggerAdapter(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter().isEnabledFor()"))
def test_setLevel_from_logging_LoggerAdapter(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import LoggerAdapter\n"
"LoggerAdapter().setLevel()"))
def test_setStream_from_logging_StreamHandler(self):
self.assertOnlyIn((3, 7),
self.detect("from logging import StreamHandler\n"
"StreamHandler().setStream()"))
def test_rotate_from_logging_handlers_BaseRotatingHandler(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import BaseRotatingHandler\n"
"BaseRotatingHandler().rotate()"))
def test_rotation_filename_from_logging_handlers_BaseRotatingHandler(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import BaseRotatingHandler\n"
"BaseRotatingHandler().rotation_filename()"))
def test_enqueue_sentinel_from_logging_handlers_QueueListener(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import QueueListener\n"
"QueueListener().enqueue_sentinel()"))
def test_reopenIfNeeded_from_logging_handlers_WatchedFileHandler(self):
self.assertOnlyIn((3, 6),
self.detect("from logging.handlers import WatchedFileHandler\n"
"WatchedFileHandler().reopenIfNeeded()"))
def test_get_bytes_from_mailbox_Mailbox(self):
self.assertOnlyIn((3, 2),
self.detect("from mailbox import Mailbox\n"
"Mailbox().get_bytes()"))
def test_factorial_from_math(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import math\nmath.factorial()"))
def test_fma_from_math(self):
self.assertOnlyIn((3, 13), self.detect("import math\nmath.fma()"))
def test_lcm_from_math(self):
self.assertOnlyIn((3, 9), self.detect("import math\nmath.lcm()"))
def test_nextafter_from_math(self):
self.assertOnlyIn((3, 9), self.detect("import math\nmath.nextafter()"))
def test_ulp_from_math(self):
self.assertOnlyIn((3, 9), self.detect("import math\nmath.ulp()"))
def test_read_windows_registry_from_mimetypes_MimeTypes(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from mimetypes import MimeTypes\n"
"MimeTypes().read_windows_registry()"))
def test_guess_file_type_from_mimetypes(self):
self.assertOnlyIn((3, 13), self.detect("import mimetypes\nmimetypes.guess_file_type()"))
def test_guess_file_type_from_mimetypes_MimeTypes(self):
self.assertOnlyIn((3, 13), self.detect("""
from mimetypes import MimeTypes
MimeTypes().guess_file_type()
"""))
def test_Close_from_msilib_Database(self):
self.assertOnlyIn((3, 7),
self.detect("from msilib import Database\n"
"Database().Close()"))
def test_getwch_from_msvcrt(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import msvcrt\nmsvcrt.getwch()"))
def test_getwche_from_msvcrt(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import msvcrt\nmsvcrt.getwche()"))
def test_putwch_from_msvcrt(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import msvcrt\nmsvcrt.putwch()"))
def test_ungetwch_from_msvcrt(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import msvcrt\nmsvcrt.ungetwch()"))
def test_wait_for_from_multiprocessing_Condition(self):
self.assertOnlyIn((3, 3),
self.detect("from multiprocessing import Condition\n"
"Condition().wait_for()"))
def test_locked_from_multiprocessing_Lock(self):
self.assertOnlyIn((3, 14),
self.detect("from multiprocessing import Lock\n"
"Lock().locked()"))
def test_locked_from_multiprocessing_RLock(self):
self.assertOnlyIn((3, 14),
self.detect("from multiprocessing import RLock\n"
"RLock().locked()"))
def test_close_from_multiprocessing_Process(self):
self.assertOnlyIn((3, 7),
self.detect("from multiprocessing import Process\n"
"Process().close()"))
def test_interrupt_from_multiprocessing_Process(self):
self.assertOnlyIn((3, 14),
self.detect("from multiprocessing import Process\n"
"Process().interrupt()"))
def test_kill_from_multiprocessing_Process(self):
self.assertOnlyIn((3, 7),
self.detect("from multiprocessing import Process\n"
"Process().kill()"))
def test_Barrier_from_multiprocessing_managers_SyncManager(self):
self.assertOnlyIn((3, 3),
self.detect("from multiprocessing.managers import SyncManager\n"
"SyncManager().Barrier()"))
def test_wait_for_from_multiprocessing_managers_SyncManager_Condition(self):
self.assertOnlyIn((3, 3),
self.detect("from multiprocessing.managers.SyncManager import Condition\n"
"Condition().wait_for()"))
def test_parent_process_from_multiprocessing(self):
self.assertOnlyIn((3, 8), self.detect(
"import multiprocessing\nmultiprocessing.parent_process()"))
def test_close_from_multiprocessing_SimpleQueue(self):
self.assertOnlyIn((3, 9), self.detect(
"from multiprocessing import SimpleQueue\n"
"multiprocessing.SimpleQueue().close()"))
def test_get_default_domain_from_nis(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import nis\nnis.get_default_domain()"))
def test_description_from_nntplib_NNTP(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from nntplib import NNTP\n"
"NNTP().description()"))
def test_descriptions_from_nntplib_NNTP(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from nntplib import NNTP\n"
"NNTP().descriptions()"))
def test_getcapabilities_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().getcapabilities()"))
def test_login_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().login()"))
def test_over_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().over()"))
def test_starttls_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"NNTP().starttls()"))
def test___call___from_operator(self):
self.assertOnlyIn((3, 11), self.detect("import operator\noperator.__call__()"))
def test___eq___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__eq__()"))
def test___floordiv___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__floordiv__()"))
def test___ge___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__ge__()"))
def test___gt___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__gt__()"))
def test___iadd___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__iadd__()"))
def test___iand___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__iand__()"))
def test___iconcat___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__iconcat__()"))
def test___idiv___from_operator(self):
self.assertOnlyIn((2, 5), self.detect("import operator\noperator.__idiv__()"))
def test___ifloordiv___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__ifloordiv__()"))
def test___ilshift___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__ilshift__()"))
def test___imatmul___from_operator(self):
self.assertOnlyIn((3, 5), self.detect("import operator\noperator.__imatmul__()"))
def test___imod___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__imod__()"))
def test___imul___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__imul__()"))
def test___index___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__index__()"))
def test___ior___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__ior__()"))
def test___ipow___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__ipow__()"))
def test___irepeat___from_operator(self):
self.assertOnlyIn((2, 5), self.detect("import operator\noperator.__irepeat__()"))
def test___irshift___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__irshift__()"))
def test___isub___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__isub__()"))
def test___itruediv___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__itruediv__()"))
def test___ixor___from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.__ixor__()"))
def test___le___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__le__()"))
def test___lt___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__lt__()"))
def test___matmul___from_operator(self):
self.assertOnlyIn((3, 5), self.detect("import operator\noperator.__matmul__()"))
def test___ne___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__ne__()"))
def test___pow___from_operator(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import operator\noperator.__pow__()"))
def test___repeat___from_operator(self):
self.assertOnlyIn((2, 0), self.detect("import operator\noperator.__repeat__()"))
def test___truediv___from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.__truediv__()"))
def test_attrgetter_from_operator(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import operator\noperator.attrgetter()"))
def test_call_from_operator(self):
self.assertOnlyIn((3, 11), self.detect("import operator\noperator.call()"))
def test_eq_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.eq()"))
def test_floordiv_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.floordiv()"))
def test_ge_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.ge()"))
def test_gt_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.gt()"))
def test_iadd_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.iadd()"))
def test_iand_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.iand()"))
def test_iconcat_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.iconcat()"))
def test_idiv_from_operator(self):
self.assertOnlyIn((2, 5), self.detect("import operator\noperator.idiv()"))
def test_ifloordiv_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.ifloordiv()"))
def test_ilshift_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.ilshift()"))
def test_imatmul_from_operator(self):
self.assertOnlyIn((3, 5), self.detect("import operator\noperator.imatmul()"))
def test_imod_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.imod()"))
def test_imul_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.imul()"))
def test_index_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.index()"))
def test_ior_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.ior()"))
def test_ipow_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.ipow()"))
def test_irepeat_from_operator(self):
self.assertOnlyIn((2, 5), self.detect("import operator\noperator.irepeat()"))
def test_irshift_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.irshift()"))
def test_is__from_operator(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import operator\noperator.is_()"))
def test_is_none_from_operator(self):
self.assertOnlyIn((3, 14), self.detect("import operator\noperator.is_none()"))
def test_is_not_none_from_operator(self):
self.assertOnlyIn((3, 14), self.detect("import operator\noperator.is_not_none()"))
def test_is_not_from_operator(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import operator\noperator.is_not()"))
def test_isub_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.isub()"))
def test_itemgetter_from_operator(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import operator\noperator.itemgetter()"))
def test_itruediv_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.itruediv()"))
def test_ixor_from_operator(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import operator\noperator.ixor()"))
def test_le_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.le()"))
def test_length_hint_from_operator(self):
self.assertOnlyIn((3, 4), self.detect("import operator\noperator.length_hint()"))
def test_lt_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.lt()"))
def test_matmul_from_operator(self):
self.assertOnlyIn((3, 5), self.detect("import operator\noperator.matmul()"))
def test_methodcaller_from_operator(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import operator\noperator.methodcaller()"))
def test_ne_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.ne()"))
def test_pow_from_operator(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import operator\noperator.pow()"))
def test_repeat_from_operator(self):
self.assertOnlyIn((2, 0), self.detect("import operator\noperator.repeat()"))
def test_truediv_from_operator(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import operator\noperator.truediv()"))
def test_is_junction_from_os_DirEntry(self):
self.assertOnlyIn((3, 12), self.detect("""
from os import DirEntry
DirEntry().is_junction()
"""))
def test_WCOREDUMP_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.WCOREDUMP()"))
def test_WIFCONTINUED_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.WIFCONTINUED()"))
def test_chflags_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.chflags()"))
def test_chroot_from_os(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import os\nos.chroot()"))
def test_closerange_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.closerange()"))
def test_cpu_count_from_os(self):
self.assertOnlyIn((3, 4), self.detect("import os\nos.cpu_count()"))
def test_fchdir_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.fchdir()"))
def test_fchmod_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.fchmod()"))
def test_fchown_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.fchown()"))
def test_fwalk_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.fwalk()"))
def test_getcwdu_from_os(self):
self.assertOnlyIn((2, 3), self.detect("import os\nos.getcwdu()"))
def test_getloadavg_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.getloadavg()"))
def test_getrandom_from_os(self):
self.assertOnlyIn((3, 6), self.detect("import os\nos.getrandom()"))
def test_lchflags_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.lchflags()"))
def test_lchmod_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import os\nos.lchmod()"))
def test_lchown_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.lchown()"))
def test_listdrives_from_os(self):
self.assertOnlyIn((3, 12), self.detect("import os\nos.listdrives()"))
def test_listmounts_from_os(self):
self.assertOnlyIn((3, 12), self.detect("import os\nos.listmounts()"))
def test_listvolumes_from_os(self):
self.assertOnlyIn((3, 12), self.detect("import os\nos.listvolumes()"))
def test_major_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.major()"))
def test_makedev_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.makedev()"))
def test_minor_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.minor()"))
def test_mknod_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.mknod()"))
def test_popen2_from_os(self):
self.assertOnlyIn((2, 0), self.detect("import os\nos.popen2()"))
def test_popen3_from_os(self):
self.assertOnlyIn((2, 0), self.detect("import os\nos.popen3()"))
def test_popen4_from_os(self):
self.assertOnlyIn((2, 0), self.detect("import os\nos.popen4()"))
def test_preadv_from_os(self):
self.assertOnlyIn((3, 7), self.detect("import os\nos.preadv()"))
def test_ptsname_from_os(self):
self.assertOnlyIn((3, 13), self.detect("import os\nos.ptsname()"))
def test_pwritev_from_os(self):
self.assertOnlyIn((3, 7), self.detect("import os\nos.pwritev()"))
def test_replace_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.replace()"))
self.assertEqual([(0, 0), (0, 0)], self.detect("""import os
s = "some string"
s.replace()
"""))
def test_scandir_from_os(self):
self.assertOnlyIn((3, 5), self.detect("import os\nos.scandir()"))
def test_close_from_os_scandir(self):
self.assertOnlyIn((3, 6),
self.detect("from os import scandir\n"
"scandir().close()"))
def test_sched_get_priority_max_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_get_priority_max()"))
def test_sched_get_priority_min_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_get_priority_min()"))
def test_sched_getaffinity_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_getaffinity()"))
def test_sched_getparam_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_getparam()"))
def test_sched_getscheduler_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_getscheduler()"))
def test_sched_rr_get_interval_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_rr_get_interval()"))
def test_sched_setaffinity_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_setaffinity()"))
def test_sched_setparam_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_setparam()"))
def test_sched_setscheduler_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_setscheduler()"))
def test_sched_yield_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sched_yield()"))
def test_sync_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.sync()"))
def test_truncate_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.truncate()"))
def test_unlockpt_from_os(self):
self.assertOnlyIn((3, 13), self.detect("import os\nos.unlockpt()"))
def test_unshare_from_os(self):
self.assertOnlyIn((3, 12), self.detect("import os\nos.unshare()"))
def test_urandom_from_os(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import os\nos.urandom()"))
def test_wait3_from_os(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import os\nos.wait3()"))
def test_wait4_from_os(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import os\nos.wait4()"))
def test_waitid_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nos.waitid()"))
def test_walk_from_os(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import os\nos.walk()"))
def test_pidfd_open_from_os(self):
self.assertOnlyIn((3, 9), self.detect("import os\nos.pidfd_open()"))
def test_waitstatus_to_exitcode_from_os(self):
self.assertOnlyIn((3, 9), self.detect("import os\nos.waitstatus_to_exitcode()"))
def test_win32_edition_from_platform(self):
self.assertOnlyIn((3, 8), self.detect("import platform\nplatform.win32_edition()"))
def test_win32_is_iot_from_platform(self):
self.assertOnlyIn((3, 8), self.detect("import platform\nplatform.win32_is_iot()"))
def test_freedesktop_os_release_from_platform(self):
self.assertOnlyIn((3, 10), self.detect("import platform\nplatform.freedesktop_os_release()"))
def test_invalidate_caches_from_platform(self):
self.assertOnlyIn((3, 14), self.detect("import platform\nplatform.invalidate_caches()"))
def test_capa_from_poplib_POP3(self):
self.assertOnlyIn((3, 4),
self.detect("from poplib import POP3\n"
"POP3().capa()"))
def test_stls_from_poplib_POP3(self):
self.assertOnlyIn((3, 4),
self.detect("from poplib import POP3\n"
"POP3().stls()"))
def test_utf8_from_poplib_POP3(self):
self.assertOnlyIn((3, 5),
self.detect("from poplib import POP3\n"
"POP3().utf8()"))
def test_format_from_pprint_PrettyPrinter(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from pprint import PrettyPrinter\n"
"PrettyPrinter().format()"))
def test_pp_from_pprint(self):
self.assertOnlyIn((3, 8), self.detect("import pprint\npprint.pp()"))
def test_binomialvariate_from_random(self):
self.assertOnlyIn((3, 12), self.detect("import random\nrandom.binomialvariate()"))
def test_choices_from_random(self):
self.assertOnlyIn((3, 6), self.detect("import random\nrandom.choices()"))
def test_getrandbits_from_random(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import random\nrandom.getrandbits()"))
def test_getstate_from_random(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import random\nrandom.getstate()"))
def test_jumpahead_from_random(self):
self.assertOnlyIn((2, 1), self.detect("import random\nrandom.jumpahead()"))
def test_sample_from_random(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import random\nrandom.sample()"))
def test_setstate_from_random(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import random\nrandom.setstate()"))
def test_triangular_from_random(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import random\nrandom.triangular()"))
def test_randbytes_from_random(self):
self.assertOnlyIn((3, 9), self.detect("import random\nrandom.randbytes()"))
def test_fullmatch_from_re_Pattern(self):
self.assertOnlyIn((3, 4),
self.detect("from re import Pattern\n"
"Pattern().fullmatch()"))
def test_finditer_from_re(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import re\nre.finditer()"))
def test_fullmatch_from_re(self):
self.assertOnlyIn((3, 4), self.detect("import re\nre.fullmatch()"))
def test_append_history_file_from_readline(self):
self.assertOnlyIn((3, 5), self.detect("import readline\nreadline.append_history_file()"))
def test_clear_history_from_readline(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import readline\nreadline.clear_history()"))
def test_get_completer_from_readline(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import readline\nreadline.get_completer()"))
def test_get_completion_type_from_readline(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import readline\nreadline.get_completion_type()"))
def test_get_current_history_length_from_readline(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect(
"import readline\nreadline.get_current_history_length()"))
def test_get_history_item_from_readline(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import readline\nreadline.get_history_item()"))
def test_remove_history_item_from_readline(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import readline\nreadline.remove_history_item()"))
def test_replace_history_item_from_readline(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import readline\nreadline.replace_history_item()"))
def test_set_auto_history_from_readline(self):
self.assertOnlyIn((3, 6), self.detect("import readline\nreadline.set_auto_history()"))
def test_set_completion_display_matches_hook_from_readline(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import readline\nreadline.set_completion_display_matches_hook()"))
def test_set_pre_input_hook_from_readline(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect(
"import readline\nreadline.set_pre_input_hook()"))
def test_set_startup_hook_from_readline(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import readline\nreadline.set_startup_hook()"))
def test_prlimit_from_resource(self):
self.assertOnlyIn((3, 4), self.detect("import resource\nresource.prlimit()"))
def test_devpoll_from_select(self):
self.assertOnlyIn((3, 3), self.detect("import select\nselect.devpoll()"))
def test_close_from_select_devpoll(self):
self.assertOnlyIn((3, 4),
self.detect("from select import devpoll\n"
"devpoll().close()"))
def test_fileno_from_select_devpoll(self):
self.assertOnlyIn((3, 4),
self.detect("from select import devpoll\n"
"devpoll().fileno()"))
def test_epoll_from_select(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import select\nselect.epoll()"))
def test_kevent_from_select(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import select\nselect.kevent()"))
def test_kqueue_from_select(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import select\nselect.kqueue()"))
def test_modify_from_select_poll(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from select import poll\n"
"poll().modify()"))
def test_convert_charref_from_sgmllib_SGMLParser(self):
self.assertOnlyIn((2, 5),
self.detect("from sgmllib import SGMLParser\n"
"SGMLParser().convert_charref()"))
def test_convert_codepoint_from_sgmllib_SGMLParser(self):
self.assertOnlyIn((2, 5),
self.detect("from sgmllib import SGMLParser\n"
"SGMLParser().convert_codepoint()"))
def test_convert_entityref_from_sgmllib_SGMLParser(self):
self.assertOnlyIn((2, 5),
self.detect("from sgmllib import SGMLParser\n"
"SGMLParser().convert_entityref()"))
def test_chown_from_shutil(self):
self.assertOnlyIn((3, 3), self.detect("import shutil\nshutil.chown()"))
def test_disk_usage_from_shutil(self):
self.assertOnlyIn((3, 3), self.detect("import shutil\nshutil.disk_usage()"))
def test_get_archive_formats_from_shutil(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import shutil\nshutil.get_archive_formats()"))
def test_get_terminal_size_from_shutil(self):
self.assertOnlyIn((3, 3), self.detect("import shutil\nshutil.get_terminal_size()"))
def test_get_unpack_formats_from_shutil(self):
self.assertOnlyIn((3, 2), self.detect("import shutil\nshutil.get_unpack_formats()"))
def test_ignore_patterns_from_shutil(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import shutil\nshutil.ignore_patterns()"))
def test_make_archive_from_shutil(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import shutil\nshutil.make_archive()"))
def test_move_from_shutil(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import shutil\nshutil.move()"))
def test_register_archive_format_from_shutil(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"import shutil\nshutil.register_archive_format()"))
def test_register_unpack_format_from_shutil(self):
self.assertOnlyIn((3, 2), self.detect("import shutil\nshutil.register_unpack_format()"))
def test_unpack_archive_from_shutil(self):
self.assertOnlyIn((3, 2), self.detect("import shutil\nshutil.unpack_archive()"))
def test_unregister_archive_format_from_shutil(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"import shutil\nshutil.unregister_archive_format()"))
def test_unregister_unpack_format_from_shutil(self):
self.assertOnlyIn((3, 2), self.detect("import shutil\nshutil.unregister_unpack_format()"))
def test_which_from_shutil(self):
self.assertOnlyIn((3, 3), self.detect("import shutil\nshutil.which()"))
def test_getitimer_from_signal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import signal\nsignal.getitimer()"))
def test_pthread_kill_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.pthread_kill()"))
def test_pthread_sigmask_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.pthread_sigmask()"))
def test_raise_signal_from_signal(self):
self.assertOnlyIn((3, 8), self.detect("import signal\nsignal.raise_signal()"))
def test_set_wakeup_fd_from_signal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import signal\nsignal.set_wakeup_fd()"))
def test_setitimer_from_signal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import signal\nsignal.setitimer()"))
def test_siginterrupt_from_signal(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import signal\nsignal.siginterrupt()"))
def test_sigpending_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.sigpending()"))
def test_sigtimedwait_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.sigtimedwait()"))
def test_sigwait_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.sigwait()"))
def test_sigwaitinfo_from_signal(self):
self.assertOnlyIn((3, 3), self.detect("import signal\nsignal.sigwaitinfo()"))
def test_strsignal_from_signal(self):
self.assertOnlyIn((3, 8), self.detect("import signal\nsignal.strsignal()"))
def test_valid_signals_from_signal(self):
self.assertOnlyIn((3, 8), self.detect("import signal\nsignal.valid_signals()"))
def test_pidfd_send_signal_from_signal(self):
self.assertOnlyIn((3, 9), self.detect("import signal\nsignal.pidfd_send_signal()"))
def test_getsitepackages_from_site(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import site\nsite.getsitepackages()"))
def test_getuserbase_from_site(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import site\nsite.getuserbase()"))
def test_getusersitepackages_from_site(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import site\nsite.getusersitepackages()"))
def test_starttls_from_smtplib_SMTP(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from smtplib import SMTP\n"
"SMTP().starttls()"))
def test_create_connection_from_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import socket\nsocket.create_connection()"))
def test_getaddrinfo_from_socket(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import socket\nsocket.getaddrinfo()"))
def test_getdefaulttimeout_from_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import socket\nsocket.getdefaulttimeout()"))
def test_getnameinfo_from_socket(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import socket\nsocket.getnameinfo()"))
def test_inet_ntop_from_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import socket\nsocket.inet_ntop()"))
def test_inet_pton_from_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import socket\nsocket.inet_pton()"))
def test_setdefaulttimeout_from_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import socket\nsocket.setdefaulttimeout()"))
def test_gettimeout_from_socket_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from socket import socket\n"
"socket().gettimeout()"))
def test_ioctl_from_socket_socket(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from socket import socket\n"
"socket().ioctl()"))
def test_recv_into_from_socket_socket(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from socket import socket\n"
"socket().recv_into()"))
def test_recvfrom_into_from_socket_socket(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from socket import socket\n"
"socket().recvfrom_into()"))
def test_settimeout_from_socket_socket(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from socket import socket\n"
"socket().settimeout()"))
def test_socketpair_from_socket(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import socket\nsocket.socketpair()"))
def test_service_actions_from_socketserver_BaseServer(self):
self.assertOnlyIn((3, 3),
self.detect("from socketserver import BaseServer\n"
"BaseServer().service_actions()"))
def test_backup_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 7),
self.detect("from sqlite3 import Connection\n"
"Connection().backup()"))
def test_blobopen_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().blobopen()"))
def test_create_window_function_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().create_window_function()"))
def test_deserialize_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 11),
self.detect("from sqlite3 import Connection\n"
"Connection().deserialize()"))
def test_compression_from_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().compression()"))
def test_get_channel_binding_from_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().get_channel_binding()"))
def test_get_unverified_chain_from_ssl_SSLSocket(self):
self.assertOnlyIn((3, 13),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().get_unverified_chain()"))
def test_get_verified_chain_from_ssl_SSLSocket(self):
self.assertOnlyIn((3, 13),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().get_verified_chain()"))
def test_selected_alpn_protocol_from_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 5)),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().selected_alpn_protocol()"))
def test_selected_npn_protocol_from_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 3)),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().selected_npn_protocol()"))
def test_sendfile_from_ssl_SSLSocket(self):
self.assertOnlyIn((3, 5),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().sendfile()"))
def test_shared_ciphers_from_ssl_SSLSocket(self):
self.assertOnlyIn((3, 5),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().shared_ciphers()"))
def test_version_from_ssl_SSLSocket(self):
self.assertOnlyIn(((2, 7), (3, 5)),
self.detect("from ssl import SSLSocket\n"
"SSLSocket().version()"))
def test_get_identifiers_from_string_Template(self):
self.assertOnlyIn((3, 11), self.detect("""
from string import Template
Template().get_identifiers()
"""))
def test_is_valid_from_string_Template(self):
self.assertOnlyIn((3, 11), self.detect("""
from string import Template
Template().is_valid()
"""))
def test_rsplit_from_string(self):
self.assertOnlyIn((2, 4), self.detect("import string\nstring.rsplit()"))
def test_iter_unpack_from_struct_Struct(self):
self.assertOnlyIn((3, 4),
self.detect("from struct import Struct\n"
"Struct().iter_unpack()"))
def test_iter_unpack_from_struct(self):
self.assertOnlyIn((3, 4), self.detect("import struct\nstruct.iter_unpack()"))
def test_pack_into_from_struct(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import struct\nstruct.pack_into()"))
def test_unpack_from_from_struct(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import struct\nstruct.unpack_from()"))
def test_is_annotated_from_symtable_Symbol(self):
self.assertOnlyIn((3, 6),
self.detect("from symtable import Symbol\n"
"Symbol().is_annotated()"))
def test_is_type_parameter_from_symtable_Symbol(self):
self.assertOnlyIn((3, 14),
self.detect("from symtable import Symbol\n"
"Symbol().is_type_parameter()"))
def test_is_free_class_from_symtable_Symbol(self):
self.assertOnlyIn((3, 14),
self.detect("from symtable import Symbol\n"
"Symbol().is_free_class()"))
def test_is_comp_iter_from_symtable_Symbol(self):
self.assertOnlyIn((3, 14),
self.detect("from symtable import Symbol\n"
"Symbol().is_comp_iter()"))
def test_is_comp_cell_from_symtable_Symbol(self):
self.assertOnlyIn((3, 14),
self.detect("from symtable import Symbol\n"
"Symbol().is_comp_cell()"))
def test__clear_internal_caches_from_sys(self):
self.assertOnlyIn((3, 13), self.detect("import sys\nsys._clear_internal_caches()"))
def test__clear_type_cache_from_sys(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import sys\nsys._clear_type_cache()"))
def test__current_frames_from_sys(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import sys\nsys._current_frames()"))
def test__debugmallocstats_from_sys(self):
self.assertOnlyIn((3, 3), self.detect("import sys\nsys._debugmallocstats()"))
def test__enablelegacywindowsfsencoding_from_sys(self):
self.assertOnlyIn((3, 6), self.detect("import sys\nsys._enablelegacywindowsfsencoding()"))
def test__is_gil_enabled_from_sys(self):
self.assertOnlyIn((3, 13), self.detect("import sys\nsys._is_gil_enabled()"))
def test__is_interned_from_sys(self):
self.assertOnlyIn((3, 13), self.detect("import sys\nsys._is_interned()"))
def test__is_immortal_from_sys(self):
self.assertOnlyIn((3, 14), self.detect("import sys\nsys._is_immortal()"))
def test_remote_exec_from_sys(self):
self.assertOnlyIn((3, 14), self.detect("import sys\nsys.remote_exec()"))
def test_breakpointhook_from_sys(self):
self.assertOnlyIn((3, 7), self.detect("import sys\nsys.breakpointhook()"))
def test_get_asyncgen_hooks_from_sys(self):
self.assertOnlyIn((3, 6), self.detect("import sys\nsys.get_asyncgen_hooks()"))
def test_get_coroutine_origin_tracking_depth_from_sys(self):
self.assertOnlyIn((3, 7), self.detect("import sys\nsys.get_coroutine_origin_tracking_depth()"))
def test_get_int_max_str_digits_from_sys(self):
self.assertOnlyIn((3, 11), self.detect("import sys\nsys.get_int_max_str_digits()"))
def test_set_int_max_str_digits_from_sys(self):
self.assertOnlyIn((3, 11), self.detect("import sys\nsys.set_int_max_str_digits()"))
def test_getallocatedblocks_from_sys(self):
self.assertOnlyIn((3, 4), self.detect("import sys\nsys.getallocatedblocks()"))
def test_getandroidapilevel_from_sys(self):
self.assertOnlyIn((3, 7), self.detect("import sys\nsys.getandroidapilevel()"))
def test_getfilesystemencodeerrors_from_sys(self):
self.assertOnlyIn((3, 6), self.detect("import sys\nsys.getfilesystemencodeerrors()"))
def test_getswitchinterval_from_sys(self):
self.assertOnlyIn((3, 2), self.detect("import sys\nsys.getswitchinterval()"))
def test_is_finalizing_from_sys(self):
self.assertOnlyIn((3, 5), self.detect("import sys\nsys.is_finalizing()"))
def test_set_asyncgen_hooks_from_sys(self):
self.assertOnlyIn((3, 6), self.detect("import sys\nsys.set_asyncgen_hooks()"))
def test_set_coroutine_origin_tracking_depth_from_sys(self):
self.assertOnlyIn((3, 7), self.detect("import sys\nsys.set_coroutine_origin_tracking_depth()"))
def test_setdefaultencoding_from_sys(self):
self.assertOnlyIn((2, 0), self.detect("import sys\nsys.setdefaultencoding()"))
def test_setdlopenflags_from_sys(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import sys\nsys.setdlopenflags()"))
def test_setswitchinterval_from_sys(self):
self.assertOnlyIn((3, 2), self.detect("import sys\nsys.setswitchinterval()"))
def test_settscdump_from_sys(self):
self.assertOnlyIn((2, 4), self.detect("import sys\nsys.settscdump()"))
def test_read_sb_data_from_telnetlib_Telnet(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from telnetlib import Telnet\n"
"Telnet().read_sb_data()"))
def test_NamedTemporaryFile_from_tempfile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect(
"import tempfile\ntempfile.NamedTemporaryFile()"))
def test_SpooledTemporaryFile_from_tempfile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import tempfile\ntempfile.SpooledTemporaryFile()"))
def test_TemporaryDirectory_from_tempfile(self):
self.assertOnlyIn((3, 2), self.detect("import tempfile\ntempfile.TemporaryDirectory()"))
def test_gettempdir_from_tempfile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import tempfile\ntempfile.gettempdir()"))
def test_gettempdirb_from_tempfile(self):
self.assertOnlyIn((3, 5), self.detect("import tempfile\ntempfile.gettempdirb()"))
def test_gettempprefixb_from_tempfile(self):
self.assertOnlyIn((3, 5), self.detect("import tempfile\ntempfile.gettempprefixb()"))
def test_mkdtemp_from_tempfile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import tempfile\ntempfile.mkdtemp()"))
def test_mkstemp_from_tempfile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import tempfile\ntempfile.mkstemp()"))
def test_tcgetwinsize_from_termios(self):
self.assertOnlyIn((3, 11), self.detect("import termios\ntermios.tcgetwinsize()"))
def test_tcsetwinsize_from_termios(self):
self.assertOnlyIn((3, 11), self.detect("import termios\ntermios.tcsetwinsize()"))
def test_interrupt_main_from_thread(self):
self.assertOnlyIn((2, 3), self.detect("import thread\nthread.interrupt_main()"))
def test_stack_size_from_thread(self):
self.assertOnlyIn((2, 5), self.detect("import thread\nthread.stack_size()"))
def test_notify_all_from_threading_Condition(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Condition\n"
"Condition().notify_all()"))
def test_wait_for_from_threading_Condition(self):
self.assertOnlyIn((3, 2),
self.detect("from threading import Condition\n"
"Condition().wait_for()"))
def test_locked_from_threading_Condition(self):
self.assertOnlyIn((3, 14),
self.detect("from threading import Condition\n"
"Condition().locked()"))
def test_locked_from_threading_RLock(self):
self.assertOnlyIn((3, 14),
self.detect("from threading import RLock\n"
"RLock().locked()"))
def test_is_set_from_threading_Event(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Event\n"
"Event().is_set()"))
def test_is_alive_from_threading_Thread(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from threading import Thread\n"
"Thread().is_alive()"))
def test_active_count_from_threading(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import threading\nthreading.active_count()"))
def test_current_thread_from_threading(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import threading\nthreading.current_thread()"))
def test_setprofile_from_threading(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import threading\nthreading.setprofile()"))
def test_setprofile_all_threads_from_threading(self):
self.assertOnlyIn((3, 12), self.detect("import threading\nthreading.setprofile_all_threads()"))
def test_getprofile_from_threading(self):
self.assertOnlyIn((3, 10), self.detect("import threading\nthreading.getprofile()"))
def test_gettrace_from_threading(self):
self.assertOnlyIn((3, 10), self.detect("import threading\nthreading.gettrace()"))
def test_settrace_from_threading(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import threading\nthreading.settrace()"))
def test_settrace_all_threads_from_threading(self):
self.assertOnlyIn((3, 12), self.detect("import threading\nthreading.settrace_all_threads()"))
def test_stack_size_from_threading(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import threading\nthreading.stack_size()"))
def test_tzset_from_time(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import time\ntime.tzset()"))
def test_autorange_from_timeit_Timer(self):
self.assertOnlyIn((3, 6),
self.detect("from timeit import Timer\n"
"Timer().autorange()"))
def test_format_frame_summary_from_traceback_StackSummary(self):
self.assertOnlyIn((3, 11), self.detect("""
from traceback import StackSummary
StackSummary().format_frame_summary()
"""))
def test_print_from_traceback_TracebackException(self):
self.assertOnlyIn((3, 11), self.detect("""
from traceback import TracebackException
TracebackException().print()
"""))
def test_clear_frames_from_traceback(self):
self.assertOnlyIn((3, 4), self.detect("import traceback\ntraceback.clear_frames()"))
def test_format_exc_from_traceback(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import traceback\ntraceback.format_exc()"))
def test_walk_stack_from_traceback(self):
self.assertOnlyIn((3, 5), self.detect("import traceback\ntraceback.walk_stack()"))
def test_walk_tb_from_traceback(self):
self.assertOnlyIn((3, 5), self.detect("import traceback\ntraceback.walk_tb()"))
def test_replace_from_types_CodeType(self):
self.assertOnlyIn((3, 8),
self.detect("from types import CodeType\n"
"CodeType().replace()"))
def test_DynamicClassAttribute_from_types(self):
self.assertOnlyIn((3, 4), self.detect("import types\ntypes.DynamicClassAttribute()"))
def test_clear_from_types_FrameType(self):
self.assertOnlyIn((3, 4),
self.detect("from types import FrameType\n"
"FrameType().clear()"))
def test_coroutine_from_types(self):
self.assertOnlyIn((3, 5), self.detect("import types\ntypes.coroutine()"))
def test_get_original_bases_from_types(self):
self.assertOnlyIn((3, 12), self.detect("import types\ntypes.get_original_bases()"))
def test_new_class_from_types(self):
self.assertOnlyIn((3, 3), self.detect("import types\ntypes.new_class()"))
def test_prepare_class_from_types(self):
self.assertOnlyIn((3, 3), self.detect("import types\ntypes.prepare_class()"))
def test_resolve_bases_from_types(self):
self.assertOnlyIn((3, 7), self.detect("import types\ntypes.resolve_bases()"))
def test_east_asian_width_from_unicodedata(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect(
"import unicodedata\nunicodedata.east_asian_width()"))
def test_normalize_from_unicodedata(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import unicodedata\nunicodedata.normalize()"))
def test_addClassCleanup_from_unittest_TestCase(self):
self.assertOnlyIn((3, 8),
self.detect("from unittest import TestCase\n"
"TestCase().addClassCleanup()"))
def test_assertCountEqual_from_unittest_TestCase(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import TestCase\n"
"TestCase().assertCountEqual()"))
def test_assertLogs_from_unittest_TestCase(self):
self.assertOnlyIn((3, 4),
self.detect("from unittest import TestCase\n"
"TestCase().assertLogs()"))
def test_assertNoLogs_from_unittest_TestCase(self):
self.assertOnlyIn((3, 10),
self.detect("from unittest import TestCase\n"
"TestCase().assertNoLogs()"))
def test_assertRaisesRegex_from_unittest_TestCase(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import TestCase\n"
"TestCase().assertRaisesRegex()"))
def test_assertWarns_from_unittest_TestCase(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import TestCase\n"
"TestCase().assertWarns()"))
def test_assertWarnsRegex_from_unittest_TestCase(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import TestCase\n"
"TestCase().assertWarnsRegex()"))
def test_assertIsSubclass_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertIsSubclass()"))
def test_assertNotIsSubclass_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertNotIsSubclass()"))
def test_assertStartsWith_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertStartsWith()"))
def test_assertNotStartsWith_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertNotStartsWith()"))
def test_assertEndsWith_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertEndsWith()"))
def test_assertNotEndsWith_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertNotEndsWith()"))
def test_assertHasAttr_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertHasAttr()"))
def test_assertNotHasAttr_from_unittest_TestCase(self):
self.assertOnlyIn((3, 14),
self.detect("from unittest import TestCase\n"
"TestCase().assertNotHasAttr()"))
def test_doClassCleanups_from_unittest_TestCase(self):
self.assertOnlyIn((3, 8),
self.detect("from unittest import TestCase\n"
"TestCase().doClassCleanups()"))
def test_setUpClass_from_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\n"
"TestCase().setUpClass()"))
def test_skipTest_from_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import TestCase\n"
"TestCase().skipTest()"))
def test_subTest_from_unittest_TestCase(self):
self.assertOnlyIn((3, 4),
self.detect("from unittest import TestCase\n"
"TestCase().subTest()"))
def test_tearDownClass_from_unittest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\n"
"TestCase().tearDownClass()"))
def test_addSubTest_from_unittest_TestResult(self):
self.assertOnlyIn((3, 4),
self.detect("from unittest import TestResult\n"
"TestResult().addSubTest()"))
def test_installHandler_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import unittest\nunittest.installHandler()"))
def test_assert_called_from_unittest_mock_Mock(self):
self.assertOnlyIn((3, 6),
self.detect("from unittest.mock import Mock\n"
"Mock().assert_called()"))
def test_assert_called_once_from_unittest_mock_Mock(self):
self.assertOnlyIn((3, 6),
self.detect("from unittest.mock import Mock\n"
"Mock().assert_called_once()"))
def test_assert_not_called_from_unittest_mock_Mock(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest.mock import Mock\n"
"Mock().assert_not_called()"))
def test_registerResult_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import unittest\nunittest.registerResult()"))
def test_removeHandler_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import unittest\nunittest.removeHandler()"))
def test_removeResult_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import unittest\nunittest.removeResult()"))
def test_http_error_308_from_urllib_request_HTTPRedirectHandler(self):
self.assertOnlyIn((3, 11),
self.detect("from urllib.request import HTTPRedirectHandler\n"
"HTTPRedirectHandler().http_error_308()"))
def test_remove_header_from_urllib_request_Request(self):
self.assertOnlyIn((3, 4),
self.detect("from urllib.request import Request\n"
"Request().remove_header()"))
def test_crawl_delay_from_urllib_robotparser_RobotFileParser(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.robotparser import RobotFileParser\n"
"RobotFileParser().crawl_delay()"))
def test_request_rate_from_urllib_robotparser_RobotFileParser(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.robotparser import RobotFileParser\n"
"RobotFileParser().request_rate()"))
def test_site_maps_from_urllib_robotparser_RobotFileParser(self):
self.assertOnlyIn((3, 8),
self.detect("from urllib.robotparser import RobotFileParser\n"
"RobotFileParser().site_maps()"))
def test_getcode_from_urllib_urlopen(self):
self.assertOnlyIn((2, 6),
self.detect("from urllib import urlopen\n"
"urlopen().getcode()"))
def test_add_unredirected_header_from_urllib2_Request(self):
self.assertOnlyIn((2, 4),
self.detect("from urllib2 import Request\n"
"Request().add_unredirected_header()"))
def test_has_header_from_urllib2_Request(self):
self.assertOnlyIn((2, 4),
self.detect("from urllib2 import Request\n"
"Request().has_header()"))
def test_geturl_from_urlparse_ParseResult(self):
self.assertOnlyIn((2, 5),
self.detect("from urlparse import ParseResult\n"
"ParseResult().geturl()"))
def test_parse_qs_from_urlparse(self):
self.assertOnlyIn((2, 6), self.detect("import urlparse\nurlparse.parse_qs()"))
def test_parse_qsl_from_urlparse(self):
self.assertOnlyIn((2, 6), self.detect("import urlparse\nurlparse.parse_qsl()"))
def test_urlsplit_from_urlparse(self):
self.assertOnlyIn((2, 2), self.detect("import urlparse\nurlparse.urlsplit()"))
def test_urlunsplit_from_urlparse(self):
self.assertOnlyIn((2, 2), self.detect("import urlparse\nurlparse.urlunsplit()"))
def test_create_from_venv(self):
self.assertOnlyIn((3, 3), self.detect("import venv\nvenv.create()"))
def test_open_new_tab_from_webbrowser_controller(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from webbrowser import controller\n"
"controller().open_new_tab()"))
def test_open_new_tab_from_webbrowser(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import webbrowser\nwebbrowser.open_new_tab()"))
def test_CreateKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2), self.detect("import winreg\nwinreg.CreateKeyEx()"))
def test_DeleteKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2), self.detect("import winreg\nwinreg.DeleteKeyEx()"))
def test_MessageBeep_from_winsound(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import winsound\nwinsound.MessageBeep()"))
def test_normalize_from_xml_dom_Node(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.dom import Node\n"
"Node().normalize()"))
def test_toprettyxml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"Node().toprettyxml()"))
def test_pi_from_xml_etree_ElementTree_TreeBuilder(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree.ElementTree import TreeBuilder\n"
"TreeBuilder().pi()"))
def test_EntityDeclHandler_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().EntityDeclHandler()"))
def test_GetInputContext_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().GetInputContext()"))
def test_SetAllocTrackerActivationThreshold_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn((3, 14),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().SetAllocTrackerActivationThreshold()"))
def test_SetAllocTrackerMaximumAmplification_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn((3, 14),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().SetAllocTrackerMaximumAmplification()"))
def test_UseForeignDTD_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().UseForeignDTD()"))
def test_XmlDeclHandler_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().XmlDeclHandler()"))
def test_buffer_size_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().buffer_size()"))
def test_buffer_text_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().buffer_text()"))
def test_buffer_used_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().buffer_used()"))
def test_ordered_attributes_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().ordered_attributes()"))
def test_specified_attributes_from_xml_parsers_expat_xmlparser(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.parsers.expat import xmlparser\n"
"xmlparser().specified_attributes()"))
def test_copy_from_zlib_Compress(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from zlib import Compress\n"
"Compress().copy()"))
def test_copy_from_zlib_Decompress(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from zlib import Decompress\n"
"Decompress().copy()"))
def test_unparse_from_ast(self):
self.assertOnlyIn((3, 9), self.detect("import ast\nast.unparse()"))
def test_reset_peak_from_tracemalloc(self):
self.assertOnlyIn((3, 9), self.detect("import tracemalloc\ntracemalloc.reset_peak()"))
def test_fill_from_turtle(self):
self.assertOnlyIn((3, 14), self.detect("import turtle\nturtle.fill()"))
def test_no_animation_from_turtle(self):
self.assertOnlyIn((3, 14), self.detect("import turtle\nturtle.no_animation()"))
def test_poly_from_turtle(self):
self.assertOnlyIn((3, 14), self.detect("import turtle\nturtle.poly()"))
def test_save_from_turtle(self):
self.assertOnlyIn((3, 14), self.detect("import turtle\nturtle.save()"))
def test_upgrade_dependencies_from_venv_EnvBuilder(self):
self.assertOnlyIn((3, 9),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder().upgrade_dependencies()"))
def test_create_git_ignore_file_from_venv_EnvBuilder(self):
self.assertOnlyIn((3, 13),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder().create_git_ignore_file()"))
def test_issoftkeyword_from_keyword(self):
self.assertOnlyIn((3, 9), self.detect("from keyword import issoftkeyword"))
def test_print_warning_from_test_support(self):
self.assertOnlyIn((3, 9), self.detect("from test.support import print_warning"))
def test_wait_process_from_test_support(self):
self.assertOnlyIn((3, 9), self.detect("from test.support import wait_process"))
def test_skip_if_broken_multiprocessing_synchronize_from_test_support(self):
self.assertOnlyIn((3, 10), self.detect("""
from test.support import skip_if_broken_multiprocessing_synchronize
"""))
def test_check_disallow_instantiation_from_test_support(self):
self.assertOnlyIn((3, 10), self.detect("""
from test.support import check_disallow_instantiation
"""))
def test_zscore_from_statistics_NormalDist(self):
self.assertOnlyIn((3, 9),
self.detect("from statistics import NormalDist\nNormalDist().zscore()"))
def test_kde_from_statistics(self):
self.assertOnlyIn((3, 13),
self.detect("import statistics\nstatistics.kde()"))
def test_kde_random_from_statistics(self):
self.assertOnlyIn((3, 13),
self.detect("import statistics\nstatistics.kde_random()"))
def test_send_fds_from_socket(self):
self.assertOnlyIn((3, 9), self.detect("from socket import send_fds"))
def test_recv_fds_from_socket(self):
self.assertOnlyIn((3, 9), self.detect("from socket import recv_fds"))
def test_create_module_from_importlib_machinery_FrozenImporter(self):
self.assertOnlyIn((3, 4),
self.detect("import importlib.machinery.FrozenImporter\n"
"importlib.machinery.FrozenImporter.create_module()"))
def test_exec_module_from_importlib_machinery_FrozenImporter(self):
self.assertOnlyIn((3, 4),
self.detect("import importlib.machinery.FrozenImporter\n"
"importlib.machinery.FrozenImporter.exec_module()"))
def test_get_stats_profile_from_pstats_Stats(self):
self.assertOnlyIn((3, 9), self.detect("import pstats.Stats\npstats.Stats.get_stats_profile()"))
def test__get_preferred_schemes_from_sysconfig(self):
self.assertOnlyIn((3, 10), self.detect("from sysconfig import _get_preferred_schemes"))
def test_get_preferred_scheme_from_sysconfig(self):
self.assertOnlyIn((3, 10), self.detect("from sysconfig import get_preferred_scheme"))
def test_get_default_scheme_from_sysconfig(self):
self.assertOnlyIn((3, 10), self.detect("from sysconfig import get_default_scheme"))
def test_packages_distributions_from_importlib_metadata(self):
self.assertOnlyIn((3, 10), self.detect("from importlib.metadata import packages_distributions"))
def test___notes___from_BaseException(self):
self.assertOnlyIn((3, 11), self.detect("BaseException.__notes__()"))
def test_add_note_from_BaseException(self):
self.assertOnlyIn((3, 11), self.detect("BaseException.add_note()"))
def test_take_bytes_of_bytearray(self):
self.assertOnlyIn((3, 15), self.detect("bytearray.take_bytes()"))
def test_default_content_type_of_SimpleHTTPRequestHandler(self):
self.assertOnlyIn((3, 15),
self.detect(
"import http.server\n"
"http.server.SimpleHTTPRequestHandler.default_content_type"))
def test_fmax_of_math(self):
self.assertOnlyIn((3, 15), self.detect("from math import fmax"))
def test_fmin_of_math(self):
self.assertOnlyIn((3, 15), self.detect("from math import fmin"))
def test_isnormal_of_math(self):
self.assertOnlyIn((3, 15), self.detect("from math import isnormal"))
def test_issubnormal_of_math(self):
self.assertOnlyIn((3, 15), self.detect("from math import issubnormal"))
def test_signbit_of_math(self):
self.assertOnlyIn((3, 15), self.detect("from math import signbit"))
def test_set_name_of_mmap(self):
self.assertOnlyIn((3, 15), self.detect("import mmap\nmmap.mmap.set_name()"))
def test_statx_of_os(self):
self.assertOnlyIn((3, 15), self.detect("from os import statx"))
def test_prefixmatch_of_Pattern(self):
self.assertOnlyIn((3, 15), self.detect("import re\nre.Pattern.prefixmatch()"))
def test_prefixmatch_of_re(self):
self.assertOnlyIn((3, 15), self.detect("from re import prefixmatch"))
def test_reorganize_of_Shelf(self):
self.assertOnlyIn((3, 15), self.detect("import shelve\nshelve.Shelf.reorganize()"))
def test_get_groups_of_SSLContext(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLContext.get_groups()"))
def test_set_ciphersuites_of_SSLContext(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLContext.set_ciphersuites()"))
def test_set_client_sigalgs_of_SSLContext(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLContext.set_client_sigalgs()"))
def test_set_groups_of_SSLContext(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLContext.set_groups()"))
def test_set_server_sigalgs_of_SSLContext(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLContext.set_server_sigalgs()"))
def test_client_sigalg_of_SSLSocket(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLSocket.client_sigalg"))
def test_group_of_SSLSocket(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLSocket.group"))
def test_server_sigalg_of_SSLSocket(self):
self.assertOnlyIn((3, 15), self.detect("import ssl\nssl.SSLSocket.server_sigalg"))
def test_get_sigalgs_of_ssl(self):
self.assertOnlyIn((3, 15), self.detect("from ssl import get_sigalgs"))
def test_get_cells_of_Function(self):
self.assertOnlyIn((3, 15), self.detect("import symtable\nsymtable.Function.get_cells()"))
def test_is_cell_of_Symbol(self):
self.assertOnlyIn((3, 15), self.detect("import symtable\nsymtable.Symbol.is_cell()"))
def test_abi_info_of_sys(self):
self.assertOnlyIn((3, 15), self.detect("from sys import abi_info"))
def test_get_lazy_imports_of_sys(self):
self.assertOnlyIn((3, 15), self.detect("from sys import get_lazy_imports"))
def test_set_lazy_imports_of_sys(self):
self.assertOnlyIn((3, 15), self.detect("from sys import set_lazy_imports"))
def test_set_lazy_imports_filter_of_sys(self):
self.assertOnlyIn((3, 15), self.detect("from sys import set_lazy_imports_filter"))
def test_concurrent_tee_of_threading(self):
self.assertOnlyIn((3, 15), self.detect("from threading import concurrent_tee"))
def test_serialize_iterator_of_threading(self):
self.assertOnlyIn((3, 15), self.detect("from threading import serialize_iterator"))
def test_synchronized_iterator_of_threading(self):
self.assertOnlyIn((3, 15), self.detect("from threading import synchronized_iterator"))
def test_detail_of_Event(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.Event.detail"))
def test_user_data_of_Event(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.Event.user_data"))
def test_search_all_of_Text(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.Text.search_all()"))
def test_grid_content_of_tkinter(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.grid_content()"))
def test_pack_content_of_tkinter(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.pack_content()"))
def test_place_content_of_tkinter(self):
self.assertOnlyIn((3, 15), self.detect("import tkinter\ntkinter.place_content()"))
def test_TypeForm_from_typing(self):
self.assertOnlyIn((3, 15), self.detect("from typing import TypeForm"))
def test_FrameLocalsProxyType_from_types(self):
self.assertOnlyIn((3, 15), self.detect("from types import FrameLocalsProxyType"))
def test_LazyImportType_from_types(self):
self.assertOnlyIn((3, 15), self.detect("from types import LazyImportType"))
def test_MacOS_from_webbrowser(self):
self.assertOnlyIn((3, 15), self.detect("from webbrowser import MacOS"))
def test_block_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import block"))
def test_extended_pictographic_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import extended_pictographic"))
def test_grapheme_cluster_break_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import grapheme_cluster_break"))
def test_indic_conjunct_break_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import indic_conjunct_break"))
def test_iter_graphemes_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import iter_graphemes"))
def test_isxidcontinue_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import isxidcontinue"))
def test_isxidstart_of_unicodedata(self):
self.assertOnlyIn((3, 15), self.detect("from unicodedata import isxidstart"))
def test_getformat_of_Wave_read(self):
self.assertOnlyIn((3, 15), self.detect("import wave\nwave.Wave_read.getformat()"))
def test_getformat_of_Wave_write(self):
self.assertOnlyIn((3, 15), self.detect("import wave\nwave.Wave_write.getformat()"))
def test_setformat_of_Wave_write(self):
self.assertOnlyIn((3, 15), self.detect("import wave\nwave.Wave_write.setformat()"))
def test_setparams_of_Wave_write(self):
self.assertOnlyIn((3, 15), self.detect("import wave\nwave.Wave_write.setparams()"))
def test_is_valid_name_of_xml(self):
self.assertOnlyIn((3, 15), self.detect("from xml import is_valid_name"))
def test_is_valid_text_of_xml(self):
self.assertOnlyIn((3, 15), self.detect("from xml import is_valid_text"))
def test_SetBillionLaughsAttackProtectionActivationThreshold(self):
self.assertOnlyIn((3, 15),
self.detect(
"import xml.parsers.expat\n"
"xml.parsers.expat.xmlparser."
"SetBillionLaughsAttackProtectionActivationThreshold"))
def test_SetBillionLaughsAttackProtectionMaximumAmplification(self):
self.assertOnlyIn((3, 15),
self.detect(
"import xml.parsers.expat\n"
"xml.parsers.expat.xmlparser."
"SetBillionLaughsAttackProtectionMaximumAmplification"))
def test_adler32_combine_of_zlib(self):
self.assertOnlyIn((3, 15), self.detect("from zlib import adler32_combine"))
def test_crc32_combine_of_zlib(self):
self.assertOnlyIn((3, 15), self.detect("from zlib import crc32_combine"))
def test_a2b_ascii85_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import a2b_ascii85"))
def test_a2b_base32_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import a2b_base32"))
def test_a2b_base85_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import a2b_base85"))
def test_b2a_ascii85_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import b2a_ascii85"))
def test_b2a_base32_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import b2a_base32"))
def test_b2a_base85_of_binascii(self):
self.assertOnlyIn((3, 15), self.detect("from binascii import b2a_base85"))
netromdk-vermin-d650a48/tests/general.py 0000664 0000000 0000000 00000137733 15265463462 0020354 0 ustar 00root root 0000000 0000000 import sys
import os
import re
import io
from os.path import abspath, basename, join, splitext
from tempfile import NamedTemporaryFile, mkdtemp
from shutil import rmtree
from multiprocessing import cpu_count
import vermin.processor
import vermin.detection
from vermin import combine_versions, InvalidVersionException, detect_paths, \
detect_paths_incremental, probably_python_file, Processor, reverse_range, dotted_name, \
remove_whitespace, main, sort_line_column, sort_line_column_parsable, version_strings, \
format_title_descs, DEFAULT_PROCESSES
from vermin.formats import DefaultFormat, ParsableFormat, GitHubFormat
from vermin.utility import compare_requirements
from .testutils import VerminTest, current_version, ScopedTemporaryFile, detect, visit, touch, \
working_dir
class _MockPool:
def __init__(self, imap_raise=None):
self.close_called = False
self.join_called = False
self._imap_raise = imap_raise
def close(self):
self.close_called = True
def join(self):
self.join_called = True
def imap(self, _, __):
if self._imap_raise is not None:
raise self._imap_raise
return []
class VerminGeneralTests(VerminTest):
def test_detect_without_config(self):
self.config.add_exclusion("abc")
self.config.add_exclusion("abc.ABC")
self.assertNotEqual(self.detect("from abc import ABC"),
detect("from abc import ABC", config=None))
def test_visit_without_config(self):
self.config.add_exclusion("abc")
self.config.add_exclusion("abc.ABC")
self.assertNotEqual(self.visit("from abc import ABC").minimum_versions(),
visit("from abc import ABC", config=None).minimum_versions())
def test_visit_has_output_text(self):
# Use level 2 since that triggers output text in SourceVisitor.
self.config.set_verbose(2)
# Earlier, it wouldn't have output text defined because `minimum_versions()` wasn't called.
visitor = self.visit("from abc import ABC")
self.assertNotEmpty(visitor.output_text())
def test_visit_output_text_dedup(self):
self.config.set_verbose(2)
# Same member used twice should produce one output line.
visitor = self.visit("import os; os.cpu_count(); os.cpu_count()")
lines = visitor.output_text().splitlines()
self.assertEqual(len(lines), 1)
self.assertIn("os.cpu_count", lines[0])
def test_visit_output_text_has_correct_lines(self):
self.config.set_verbose(3) # Line numbers start at verbosity 3.
visitor = self.visit("""a = 1
import abc
b = 2
if 1:
import zoneinfo
import argparse
c = 3
""")
# Output text is sorted for line numbers/columns when verbosity level is 3+.
self.assertEqual(visitor.output_text(), """L2 C7: 'abc' module requires 2.6, 3.0
L5 C9: 'zoneinfo' module requires !2, 3.9
L6 C9: 'argparse' module requires 2.7, 3.2
""")
def test_visit_output_text_has_correct_lines_parsable(self):
self.config.set_format(ParsableFormat())
src = """a = 1
import abc
b = 2
if 1:
import zoneinfo
import argparse
c = 3
"""
visitor = self.visit(src)
self.assertEqual(visitor.output_text(), """:2:7:2.6:3.0:'abc' module
:5:9:!2:3.9:'zoneinfo' module
:6:9:2.7:3.2:'argparse' module
""")
visitor = self.visit(src, path="test.py")
self.assertEqual(visitor.output_text(), """test.py:2:7:2.6:3.0:'abc' module
test.py:5:9:!2:3.9:'zoneinfo' module
test.py:6:9:2.7:3.2:'argparse' module
""")
# Paths with ":" or "\n" aren't allowed with parsable format. On Windows, paths cannot contain
# ":" except for the drive part so the test doesn't make sense.
if not sys.platform.startswith("win32"):
with self.assertRaises(AssertionError):
self.visit(src, path="te:st.py")
with self.assertRaises(AssertionError):
self.visit(src, path="te\nst.py")
def test_visit_output_text_has_correct_lines_github(self):
self.config.set_format(GitHubFormat())
# error level for target violations only
self.config.add_target((3, 4), False)
# path should be relativized to cwd
test_cwd_rel = os.path.join("sub", "test.py")
test_cwd_abs = os.path.join(os.path.abspath(os.getcwd()), test_cwd_rel)
src = """a = 1
import abc
b = 2
if 1:
import zoneinfo
import argparse
c = 3
"""
paths = (None, ""), ("test.py", "test.py"), (test_cwd_abs, test_cwd_rel)
for path, path_str in paths:
visitor = self.visit(src, path=path)
self.assertEqual(visitor.output_text(), (
"""::notice file={path},line=2,col=7,title=Requires Python 2.6%2C 3.0::'abc' module
::error file={path},line=5,col=9,title=Requires Python !2%2C 3.9::'zoneinfo' module
::notice file={path},line=6,col=9,title=Requires Python 2.7%2C 3.2::'argparse' module
""".format(path=path_str)))
# subclasses ParsableFormat, so should also reject these paths
if not sys.platform.startswith("win32"):
with self.assertRaises(AssertionError):
self.visit(src, path="te:st.py")
with self.assertRaises(AssertionError):
self.visit(src, path="te\nst.py")
def test_visit_output_text_has_correct_lines_colored(self):
self.config.set_format(DefaultFormat(colored=True))
self.config.set_verbose(3)
# error coloring for target violations only
self.config.add_target((3, 4), False)
# example cwd
src = """a = 1
import abc
b = 2
if 1:
import zoneinfo
import argparse
c = 3
"""
visitor = self.visit(src, path="test.py")
self.assertEqual(visitor.output_text(), (
"""\033[92mL2 C7: 'abc' module requires 2.6, 3.0\033[0m
\033[91mL5 C9: 'zoneinfo' module requires !2, 3.9\033[0m
\033[92mL6 C9: 'argparse' module requires 2.7, 3.2\033[0m
"""))
def test_format(self):
# Empty field name requires 2.7+
visitor = self.visit("print('{}'.format(42))")
self.assertTrue(visitor.format27())
# Non-empty field name requires 2.6+
visitor = self.visit("print('{0}'.format(42))")
self.assertFalse(visitor.format27())
def test_strftime_directives(self):
visitor = self.visit("from datetime import datetime\ndatetime.now().strftime('%A %d. %B %Y')")
self.assertOnlyIn(("A", "d", "B", "Y"), visitor.strftime_directives())
visitor = self.visit("from datetime import datetime\ndatetime.strptime('2018', '%Y')")
self.assertOnlyIn("Y", visitor.strftime_directives())
def test_modules(self):
visitor = self.visit("import ast\nimport sys, argparse\nfrom os import *")
self.assertOnlyIn(("ast", "sys", "argparse", "os"), visitor.modules())
def test_member_class(self):
visitor = self.visit("from abc import ABC")
self.assertOnlyIn("abc.ABC", visitor.members())
visitor = self.visit("import abc\nclass a(abc.ABC): pass")
self.assertOnlyIn("abc.ABC", visitor.members())
def test_member_function(self):
visitor = self.visit("from sys import exc_clear")
self.assertOnlyIn("sys.exc_clear", visitor.members())
def test_member_constant(self):
visitor = self.visit("from sys import version_info")
self.assertOnlyIn("sys.version_info", visitor.members())
def test_member_kwargs(self):
visitor = self.visit("from os import open\nfd = open(dir_fd = None)")
self.assertOnlyIn([("os.open", "dir_fd")], visitor.kwargs())
visitor = self.visit("fd = open(dir_fd = None)")
self.assertOnlyIn([("open", "dir_fd")], visitor.kwargs())
visitor = self.visit("ZipFile().writestr(compress_type=None)")
self.assertOnlyIn([("ZipFile.writestr", "compress_type")], visitor.kwargs())
def test_probably_python_file(self):
tmp_fld = mkdtemp()
self.assertTrue(probably_python_file(touch(tmp_fld, "test.py")))
self.assertTrue(probably_python_file(touch(tmp_fld, "test.pyw")))
self.assertFalse(probably_python_file(touch(tmp_fld, "test.pyc")))
# Empty file isn't python.
f = touch(tmp_fld, "test")
self.assertFalse(probably_python_file(f))
# Magic line.
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("#!/usr/bin/env python\n")
self.assertTrue(probably_python_file(f))
# Binary file isn't python code.
f = touch(tmp_fld, "binary")
with open(f, mode="wb") as fp:
fp.write(b"\x80\x89\x90")
self.assertFalse(probably_python_file(f))
rmtree(tmp_fld)
def test_detect_paths(self):
paths = detect_paths([abspath("vermin")], config=self.config)
self.assertEqual(21, len(paths))
def test_detect_hidden_paths(self):
tmp_fld = mkdtemp()
files = [touch(tmp_fld, ".test.py"), touch(tmp_fld, "test.py"), touch(tmp_fld, ".test2.py"),
touch(tmp_fld, "test2.py")]
paths = detect_paths([tmp_fld], hidden=False, config=self.config)
without_dot = [files[1], files[3]]
self.assertEqualItems(without_dot, paths)
paths2 = detect_paths([tmp_fld], hidden=True, config=self.config)
self.assertEqualItems(files, paths2)
rmtree(tmp_fld)
def test_detect_paths_incrementally(self):
tmp_fld = mkdtemp()
files = [touch(tmp_fld, ".test.py"), touch(tmp_fld, "test.py"), touch(tmp_fld, ".test2.py"),
touch(tmp_fld, "test2.py")]
depth = 0
hidden = False
ignore_chars = []
scan_symlink_folders = False
(accepted, further_args) = detect_paths_incremental(
([tmp_fld], depth, hidden, ignore_chars, scan_symlink_folders, self.config))
self.assertEmpty(accepted)
self.assertEqual(len(further_args), 1)
(paths, depth, hidden, ignore_chars, scan_symlink_folders, config) = further_args[0]
self.assertEqualItems(paths, [files[1], files[3]])
self.assertEqual(depth, 1)
self.assertFalse(hidden)
self.assertEmpty(ignore_chars)
self.assertFalse(scan_symlink_folders)
self.assertNotEqual(config, None)
rmtree(tmp_fld)
def test_detect_hidden_paths_incrementally(self):
tmp_fld = mkdtemp()
files = [touch(tmp_fld, ".test.py"), touch(tmp_fld, "test.py"), touch(tmp_fld, ".test2.py"),
touch(tmp_fld, "test2.py")]
depth = 0
hidden = True
ignore_chars = []
scan_symlink_folders = False
(accepted, further_args) = detect_paths_incremental(
([tmp_fld], depth, hidden, ignore_chars, scan_symlink_folders, self.config))
self.assertEmpty(accepted)
self.assertEqual(len(further_args), 1)
(paths, depth, hidden, ignore_chars, scan_symlink_folders, config) = further_args[0]
self.assertEqualItems(paths, [files[0], files[1], files[2], files[3]])
self.assertEqual(depth, 1)
self.assertTrue(hidden)
self.assertEmpty(ignore_chars)
self.assertFalse(scan_symlink_folders)
self.assertNotEqual(config, None)
rmtree(tmp_fld)
# Even though hidden=False it will detect files given at the top level (depth=0) because those
# files were directly specified on the CLI in real cases.
def test_detect_top_level_paths_incrementally(self):
tmp_fld = mkdtemp()
files = [touch(tmp_fld, ".test.py"), touch(tmp_fld, "test.py"), touch(tmp_fld, ".test2.py"),
touch(tmp_fld, "test2.py")]
depth = 0
hidden = False
ignore_chars = []
scan_symlink_folders = False
(accepted, further_args) = detect_paths_incremental(
(files, depth, hidden, ignore_chars, scan_symlink_folders, self.config))
self.assertEqualItems(accepted, files)
self.assertEmpty(further_args)
rmtree(tmp_fld)
def test_detect_nonexistent_paths_incrementally(self):
depth = 0
hidden = False
ignore_chars = []
scan_symlink_folders = False
(accepted, further_args) = detect_paths_incremental((["i-do-not-exist"], depth, hidden,
ignore_chars, scan_symlink_folders,
self.config))
self.assertEmpty(accepted)
self.assertEmpty(further_args)
def test_detect_nonexistent_paths_with_dot_incrementally(self):
depth = 0
hidden = False
ignore_chars = []
scan_symlink_folders = False
(accepted, further_args) = detect_paths_incremental(([".i-start-with-dot"], depth, hidden,
ignore_chars, scan_symlink_folders,
self.config))
self.assertEmpty(accepted)
self.assertEmpty(further_args)
# Files directly specified at depth 0 should be accepted in any case, even if not with .py or
# heuristics, but extensions and heuristics must be used further down.
def test_detect_vermin_paths_directly(self):
tmp_fld = mkdtemp()
# Won't be picked by heuristics.
f = touch(tmp_fld, "no-shebang")
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
paths = detect_paths([tmp_fld], config=self.config)
self.assertEmpty(paths)
paths = detect_paths([join(tmp_fld, "no-shebang")], config=self.config)
self.assertEqual(paths, [f])
rmtree(tmp_fld)
# Ensure all proper Python source code files are detected: py, py3, pyw, pyj, pyi
def test_detect_vermin_paths_all_exts(self):
tmp_fld = mkdtemp()
exts = ('py', 'py3', 'pyw', 'pyj', 'pyi')
for ext in exts:
f = touch(tmp_fld, "code." + ext)
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
found_exts = set()
for path in detect_paths([tmp_fld], config=self.config):
_, ext = splitext(path)
found_exts.add(ext[1:])
self.assertEqualItems(found_exts, exts)
rmtree(tmp_fld)
# Ensure all non-Python source code files are not detected: pyc, pyd, pxd, pyx, pyo
def test_detect_vermin_paths_no_invalid_exts(self):
tmp_fld = mkdtemp()
exts = ("pyc", "pyd", "pxd", "pyx", "pyo")
for ext in exts:
f = touch(tmp_fld, "code." + ext)
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
# Since the detection ignores the extensions, no body of this for-loop will be executed.
found_exts = set()
for path in detect_paths([tmp_fld], config=self.config): # pragma: no cover
_, ext = splitext(path)
found_exts.add(ext[1:])
self.assertEmpty(found_exts)
rmtree(tmp_fld)
def test_exclude_pyi_regex(self):
tmp_fld = mkdtemp()
# With the default of --make-paths-absolute, this will match .pyi files in any subdirectory. The
# most common use case for --exclude-regex is expected to be for file extensions, so it's great
# that will work regardless of the --make-paths-absolute setting.
self.config.add_exclusion_regex(r"\.pyi$")
f = touch(tmp_fld, "code.pyi")
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
paths = detect_paths([tmp_fld], config=self.config)
self.assertEmpty(paths)
rmtree(tmp_fld)
def test_exclude_directory_regex(self):
tmp_fld = mkdtemp()
# Excluding the directory .../a should exclude any files recursively beneath it as well.
self.config.add_exclusion_regex('^' + re.escape(join(tmp_fld, "a")) + '$')
# Create .../a and .../a/b directories.
os.mkdir(join(tmp_fld, "a"))
os.mkdir(join(tmp_fld, "a/b"))
paths = ["code.py", "a/code.py", "a/b/code.py"]
for p in paths:
f = touch(tmp_fld, p)
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
paths = detect_paths([tmp_fld], config=self.config)
self.assertEqual(paths, [join(tmp_fld, "code.py")])
rmtree(tmp_fld)
def test_exclude_regex_relative(self):
tmp_fld = mkdtemp()
# Keep paths relative, and provide patterns matching relative paths.
self.config.set_make_paths_absolute(False)
self.config.add_exclusion_regex("^a{0}b$".format(re.escape(os.path.sep)))
self.config.add_exclusion_regex("^a{0}.+pyi$".format(re.escape(os.path.sep)))
# Create .../a and .../a/b directories.
os.mkdir(join(tmp_fld, "a"))
os.mkdir(join(tmp_fld, "a", "b"))
paths = [
join("a", "code.py"),
join("a", "code.pyi"),
join("a", "b", "code.py"),
]
for p in paths:
f = touch(tmp_fld, p)
with open(f, mode="w", encoding="utf-8") as fp:
fp.write("print('this is code')")
# Temporarily modify the working directory.
with working_dir(tmp_fld):
paths = detect_paths(["a"], config=self.config)
self.assertEqual(paths, [join("a", "code.py")])
# When running on Windows, this can sometimes fail:
# PermissionError: [WinError 32] The process cannot access the file because it is being used
# by another process:
# 'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmpAAAANNNN'
# But we can ignore that since the files reside in a temporary folder anyway, and the
# folders/files aren't being used any longer either.
rmtree(tmp_fld, ignore_errors=True)
def test_detect_vermin_min_versions(self):
paths = detect_paths([abspath("vermin")], config=self.config)
processor = Processor()
(mins, _incomp, _unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertOnlyIn((3, 0), mins)
self.assertEmpty(backports)
self.assertTrue(used_novermin)
self.assertFalse(maybe_anns)
def test_detect_vermin_min_versions_parsable(self):
paths = detect_paths([abspath("vermin")], config=self.config)
processor = Processor()
self.config.set_format(ParsableFormat())
(mins, _incomp, _unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertOnlyIn((3, 0), mins)
self.assertEmpty(backports)
self.assertTrue(used_novermin)
self.assertFalse(maybe_anns)
@VerminTest.parameterized_args([
([(2, 0), (3, 0)], [(2, 0), (3, 1)], [(2, 0), (3, 1)]),
([2, (3, 0)], [(2, 0), 3.1], [(2, 0), (3, 1)]),
([(2, 0), 3], [2, 3.1], [(2, 0), (3, 1)]),
([2.0, 3.0], [2.0, 3.1], [(2, 0), (3, 1)]),
([2.1, 3.0], [2.0, 3.0], [(2, 1), (3, 0)]),
([2.0, 3.0], [None, 3.0], [None, (3, 0)]),
([2.0, None], [2.0, 3.0], [(2, 0), None]),
([2.0, 3.0], [None, None], [None, None]),
([None, None], [2.0, 3.0], [None, None]),
([0, 3.0], [0, 3.0], [(0, 0), (3, 0)]),
([0, 3.0], [2.0, 3.0], [(2, 0), (3, 0)]),
([2.0, 3.0], [0, 3.0], [(2, 0), (3, 0)]),
([2.0, 0], [2.0, 3.0], [(2, 0), (3, 0)]),
([2.0, 3.0], [2.0, 0], [(2, 0), (3, 0)]),
])
def test_combine_versions(self, lhs, rhs, expected):
self.assertEqual(combine_versions(lhs, rhs, self.config), expected)
@VerminTest.parameterized_exceptions([
(AssertionError, [None], [None, None]), # Not same size.
(AssertionError, [None, None], [None]), # Not same size.
(InvalidVersionException, [2.0, None], [None, 3.0]),
(InvalidVersionException, [None, 3.0], [2.0, None]),
])
def test_combine_versions_assert(self, lhs, rhs):
combine_versions(lhs, rhs, self.config)
@VerminTest.parameterized_args([
([0.0, 0.0], None, "~2, ~3"),
([2.0, 0.0], None, "2.0, ~3"),
([2.0, 3.0], None, "2.0, 3.0"),
([0.0, 3.1], None, "~2, 3.1"),
([None, 3.0], None, "!2, 3.0"),
([2.0, None], None, "2.0, !3"),
([None, None], None, "!2, !3"),
([0.0, 3.1], ":", "~2:3.1"),
([None, 3.0], ":", "!2:3.0"),
([2.0, None], ":", "2.0:!3"),
([None, None], ":", "!2:!3"),
([2.3], None, "2.3"),
([3.4], None, "3.4"),
([2.3, 2.7, 3.1], None, "2.3, 2.7, 3.1"),
([2.0, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9],
None, "2.0, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9"),
])
def test_version_strings(self, versions, separator, expected):
self.assertEqual(version_strings(versions, separator), expected)
@VerminTest.parameterized_exceptions([
(AssertionError, []), # Cannot be empty.
# If there is at least one zero value, then there can only be one or two values!
(AssertionError, [1, 0.0, 2]),
(AssertionError, [1, 0, 2]),
(AssertionError, [1, (0, 0), 2]),
(AssertionError, [1, 2, 3, 0.0]),
(AssertionError, [(0, 0), 2, 3, 4]),
])
def test_version_strings_assert(self, versions):
version_strings(versions)
@VerminTest.parameterized_args([
("import abc", [(2, 6), (3, 0)]),
# (2.6, 3.0) vs. (2.7, 3.2) = (2.7, 3.2)
("import abc, argparse", [(2, 7), (3, 2)]),
# (2.6, 3.0) vs. (None, 3.4) = (None, 3.4)
("import abc\nfrom abc import ABC", (3, 4)),
# (2.0, None) vs. (2.0, 3.0) = (2.0, None)
("import repr\nfrom sys import getdefaultencoding", (2, 0)),
])
def test_detect_min_version(self, source, min_versions):
self.assertDetectMinVersions(source, min_versions)
@VerminTest.parameterized_exceptions([
# (2.0, None) vs. (None, 3.0) = both exclude the other major version -> exception!
(InvalidVersionException, "import copy_reg, http"),
])
def test_detect_min_version_assert(self, source):
self.detect(source)
def test_ignore_non_top_level_imports(self):
vers = [(0, 0), (0, 0)]
self.assertNotEqual(vers, self.detect("from typing import Final")) # Don't ignore
self.assertEqual(vers, self.detect("from .typing import Final")) # Ignore
self.assertEqual(vers, self.detect("from ..typing import Final")) # Ignore
@VerminTest.parameterized_args([
([1, 2, 3], [2, 1, 0]),
([1, 2], [1, 0]),
([], []),
])
def test_reverse_range(self, values, expected):
self.assertEqual(list(reverse_range(values)), expected)
@VerminTest.parameterized_args([
(["hello", "world"], "hello.world"),
(["foo", ["bar", "baz"], "boom"], "foo.bar.baz.boom"),
(["foo", ("bar", "baz"), "boom"], "foo.bar.baz.boom"),
(1, "1"),
(4.2, "4.2"),
([1, 2, 3], "1.2.3"),
("right", "right"),
(["hello", None, "world"], "hello.world"),
(["foo", (None, "baz"), None], "foo.baz"),
])
def test_dotted_name(self, names, expected):
self.assertEqual(dotted_name(names), expected)
@VerminTest.parameterized_exceptions([
# Invalid values yield `assert False`.
(AssertionError, [4.2]),
])
def test_dotted_name_assert(self, names):
dotted_name(names)
@VerminTest.parameterized_args([
("abc", None, "abc"),
("abc", ["a", "c"], "b"),
(" \t\n\r\f\v", None, ""),
(" \t1\n2\r3\f\v", ["1", "3"], "2"),
])
def test_remove_whitespace(self, value, extras, expected):
self.assertEqual(remove_whitespace(value, extras), expected)
def test_sort_line_column(self):
text = [
"L2: two",
"hello, world",
"L2 C10: two ten",
"L1: one",
"L3: three",
"print",
"L2 C2: two two",
]
expected = [
"print",
"hello, world",
"L1: one",
"L2: two",
"L2 C2: two two",
"L2 C10: two ten",
"L3: three"
]
value = text
value.sort(key=sort_line_column)
self.assertEqual(value, expected)
# Repeated sortings yield the same.
value2 = text
value2.sort(key=sort_line_column)
self.assertEqual(value2, expected)
def test_sort_line_column_parsable(self):
text = [
"final_annotation.py:7::!2:3.6:variable annotations",
"final_annotation.py:1:5:!2:3.5:'typing' module",
"final_annotation.py:3::!2:3.8:final variable annotations",
"final_annotation.py:7::!2:3.8:final variable annotations",
# This line won't actually happen but it's handled anyway.
"weird line",
"final_annotation.py:4::!2:3.6:variable annotations",
"final_annotation.py:1::!2:3.5:'typing' module",
"final_annotation.py:3::!2:3.6:variable annotations",
"final_annotation.py:4::!2:3.8:final variable annotations",
"final_annotation.py:1:7:!2:3.8:'typing.Final' member",
]
expected = [
"weird line",
"final_annotation.py:1::!2:3.5:'typing' module",
"final_annotation.py:1:5:!2:3.5:'typing' module",
"final_annotation.py:1:7:!2:3.8:'typing.Final' member",
"final_annotation.py:3::!2:3.6:variable annotations",
"final_annotation.py:3::!2:3.8:final variable annotations",
"final_annotation.py:4::!2:3.6:variable annotations",
"final_annotation.py:4::!2:3.8:final variable annotations",
"final_annotation.py:7::!2:3.6:variable annotations",
"final_annotation.py:7::!2:3.8:final variable annotations",
]
value = text
value.sort(key=sort_line_column_parsable)
self.assertEqual(value, expected)
# Repeated sortings yield the same.
value2 = text
value2.sort(key=sort_line_column_parsable)
self.assertEqual(value2, expected)
def test_assign_rvalue_attribute(self):
self.assertEqual([None, (3, 3)], self.detect("import bz2\nv = bz2.BZ2File\nv.writable"))
def test_user_defined(self):
visitor = self.visit("def hello(): pass\nhello2()\nclass foo(): pass")
self.assertOnlyIn(["hello", "foo"], visitor.user_defined())
def test_ignore_members_when_user_defined_funcs(self):
# `next()` was builtin from 2.6.
visitor = self.visit("def next(): pass\nnext()")
self.assertOnlyIn("next", visitor.user_defined())
self.assertEmpty(visitor.members())
def test_ignore_members_when_user_defined_classes(self):
# `bytearray` was builtin from 2.6.
visitor = self.visit("class bytearray: pass\nba = bytearray()")
self.assertOnlyIn(["bytearray", "ba"], visitor.user_defined())
self.assertEmpty(visitor.members())
def test_ignore_modules_when_user_defined_funcs(self):
# This test relies on the rule for "SimpleXMLRPCServer" module.
# Ignore module due to class def.
visitor = self.visit("import SimpleXMLRPCServer\n"
"def SimpleXMLRPCServer(): pass\n"
"src = SimpleXMLRPCServer()")
self.assertOnlyIn(["SimpleXMLRPCServer", "src"], visitor.user_defined())
self.assertEmpty(visitor.modules())
def test_ignore_modules_when_user_defined_classes(self):
# This test relies on the rule for "SimpleXMLRPCServer" module.
# Ignore module due to class def.
visitor = self.visit("import SimpleXMLRPCServer\n"
"class SimpleXMLRPCServer: pass\n"
"src = SimpleXMLRPCServer()")
self.assertOnlyIn(["SimpleXMLRPCServer", "src"], visitor.user_defined())
self.assertEmpty(visitor.modules())
def test_mod_inverse_pow(self):
# All arguments must be ints.
visitor = self.visit("pow(1.1, -1, 3)")
self.assertFalse(visitor.modular_inverse_pow())
visitor = self.visit("pow(1, -1.0, 3)")
self.assertFalse(visitor.modular_inverse_pow())
visitor = self.visit("pow(1, -1, 3.0)")
self.assertFalse(visitor.modular_inverse_pow())
# The second argument can be negative to yield modular inverse calculation.
visitor = self.visit("pow(1, -2, 3)")
self.assertTrue(visitor.modular_inverse_pow())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
def test_main_no_args(self):
# Print usage and exit with code 1.
with self.assertRaises(SystemExit) as ex:
main()
self.assertEqual(ex.exception.code, 1)
def test_main_full_usage(self):
# Print full usage and exit with code 0.
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "--help"]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 0)
def test_main_print_version(self):
# Print version and exit with code 0.
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "--version"]
main()
self.assertEqual(ex.exception.code, 0)
with self.assertRaises(SystemExit) as ex:
sys.argv[1] = "-V"
main()
self.assertEqual(ex.exception.code, 0)
sys.argv = [sys.argv[0]]
def test_main_print_versions_range(self):
fp = ScopedTemporaryFile()
fp.writeln(b"import weakref")
fp.close()
# Print versions range and exit with code 0.
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "--versions", fp.path()]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 0)
def test_main_no_paths(self):
# The path doesn't exist and isn't a .py file which means no paths are detected.
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "nonexistentfilethatisntpy"]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 1)
def test_main_no_rules_hit(self):
# Python file that doesn't hit any rules should exit successfully.
fp = ScopedTemporaryFile()
fp.close()
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], fp.path()]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 0)
def test_main_target_not_met(self):
# Ensure exit code 1 when target isn't met.
fp = ScopedTemporaryFile()
fp.close()
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "-t=3.0", fp.path()]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 1)
def test_main_no_rules_hit_target_not_met_violations_mode(self):
# Python file that doesn't hit any rules, even with targets, should exit successfully for
# violations mode.
fp = ScopedTemporaryFile()
fp.close()
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "-t=3.0", "--violations", fp.path()]
main()
sys.argv = [sys.argv[0]]
self.assertEqual(ex.exception.code, 0)
@VerminTest.skipUnlessPlatform("win32")
def test_main_parsable_dont_ignore_paths_with_colon_in_drive_part(self):
# Tests that detection of paths works with ":" in them (due to parsable format) especially on
# Windows where the first part of an absolute path, the drive part, contains a ":".
# Detect newly created file path in parent folder even though using parsable format.
tmp_fld = mkdtemp()
touch(tmp_fld, "test.py")
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "--format", "parsable", tmp_fld]
main()
sys.argv = [sys.argv[0]]
rmtree(tmp_fld)
# Check for no error. It would incorrectly yield "No files specified to analyze!" before the
# fix.
self.assertEqual(ex.exception.code, 0)
def test_main_parsable_has_last_results_line(self):
tmp_fld = mkdtemp()
file_name = "test.py"
path = join(tmp_fld, file_name)
touch(tmp_fld, file_name)
temp_stdout = io.StringIO()
backup_stdout = sys.stdout
with self.assertRaises(SystemExit) as ex:
sys.argv = [sys.argv[0], "--format", "parsable", tmp_fld]
sys.stdout = temp_stdout
main()
sys.argv = [sys.argv[0]]
sys.stdout = backup_stdout
rmtree(tmp_fld)
# Check successful execution.
self.assertEqual(ex.exception.code, 0)
# Check that the last line is on the form `:::v2:v3:`.
lines = temp_stdout.getvalue().splitlines()
self.assertEqual(len(lines), 2)
self.assertEqual(lines[0], "{}:::~2:~3:".format(path))
self.assertEqual(lines[1], ":::~2:~3:")
def test_process_file_not_Found(self):
path = "nonexistent"
res = Processor.process_individual((path, self.config))
self.assertNotEqual(res, None)
self.assertEqual(res.path, path)
self.assertEqual(res.mins, [(0, 0), (0, 0)])
self.assertEqual(res.node, None)
def test_process_runtests_py(self):
proc_res = Processor.process_individual((sys.argv[0], self.config))
self.assertEqual(basename(proc_res.path), "runtests.py")
self.assertEqual(proc_res.mins, [(2, 7), (3, 2)])
self.assertEmpty(proc_res.text)
self.assertEmpty(proc_res.bps)
def test_process_syntax_error(self):
# Syntax error triggers minimum versions [0, 0].
fp = ScopedTemporaryFile()
fp.write(b'(') # SyntaxError: unexpected EOF while parsing
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEqual(proc_res.mins, [(0, 0), (0, 0)])
self.assertTrue(proc_res.text.startswith("error: "))
self.assertEmpty(proc_res.bps)
@VerminTest.skipUnlessVersion(3, 12)
def test_process_syntax_error_null_bytes(self):
# SyntaxError: source code string cannot contain null bytes
fp = ScopedTemporaryFile()
fp.write(b'\0')
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEqual(proc_res.mins, [(0, 0), (0, 0)])
self.assertTrue(proc_res.text.startswith("error: "))
self.assertEmpty(proc_res.bps)
def test_process_invalid_versions(self):
with ScopedTemporaryFile() as fp:
fp.write(b"""long(42)
breakpoint()
""")
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEqual(proc_res.mins, None)
msg = "'long' member (requires 2.0, !3) vs. 'breakpoint' member (requires !2, 3.7)"
self.assertEqual(proc_res.text, msg)
self.assertEmpty(proc_res.bps)
with ScopedTemporaryFile() as fp:
fp.write(b"""try:
import socketserver
except ImportError:
import SocketServer
""")
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEqual(proc_res.mins, None)
msg = "'socketserver' module (requires !2, 3.0) vs. 'SocketServer' module (requires 2.0, !3)"
self.assertEqual(proc_res.text, msg)
self.assertEmpty(proc_res.bps)
with ScopedTemporaryFile() as fp:
fp.write(b"""import time
time.strftime("%u", gmtime())
from urllib import urlopen
urlopen(context=None)
""")
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEqual(proc_res.mins, None)
msg =\
"strftime directive 'u' (requires !2, 3.6) vs. 'urllib.urlopen(context)' (requires 2.7, !3)"
self.assertEqual(proc_res.text, msg)
self.assertEmpty(proc_res.bps)
def test_process_file_using_backport(self):
fp = ScopedTemporaryFile()
fp.writeln(b"import typing")
fp.close()
proc_res = Processor.process_individual((fp.path(), self.config))
self.assertEmpty(proc_res.text)
self.assertEqualItems(["typing"], proc_res.bps)
def test_processor_value_error(self):
fp = ScopedTemporaryFile()
fp.write(b"\0")
fp.close()
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertFalse(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
def test_processor_incompatible(self):
fp = ScopedTemporaryFile()
fp.writeln(b"import Queue") # 2.0, !3
fp.writeln(b"import builtins") # !2, 3.0
fp.close()
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertTrue(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
def test_processor_separately_incompatible(self):
paths = []
codes = [
b"import Queue\n", # 2.0, !3
b"import builtins\n", # !2, 3.0
]
for code in codes:
with NamedTemporaryFile(suffix=".py", delete=False) as fp:
fp.write(code)
fp.close()
paths.append(fp.name)
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(2, 0), None]) # Because the Queue file is analyzed first.
self.assertTrue(incomp)
self.assertEqual(unique_versions, [(2, 0), (3, 0)])
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
for path in paths:
os.remove(path)
def test_processor_used_novermin(self):
fp = ScopedTemporaryFile()
fp.writeln(b"import Queue # novm") # 2.0, !3
fp.writeln(b"import builtins") # !2, 3.0
fp.close()
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
print(mins)
self.assertEqual(mins, [None, (3, 0)])
self.assertFalse(incomp)
self.assertEqual(unique_versions, [(3, 0)])
self.assertEmpty(backports)
self.assertTrue(used_novermin)
self.assertFalse(maybe_anns)
def test_processor_indent_show_output_text(self):
self.config.set_verbose(4) # Ensure output text.
# Trigger SourceVisitor.__nprint() while visiting AST, which is one way to add some output text.
self.config.set_print_visits(True)
fp = ScopedTemporaryFile()
fp.write(b"""def foo(): pass
foo() # Ignoring member 'foo' because it's user-defined!
import Queue
class Queue: pass # Ignoring module 'Queue' because it's user-defined!
def any(): pass
any(test=1) # Ignoring function 'any' because it's user-defined!
print('hello') # print(expr) requires 2+ or 3+
""")
fp.close()
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(2, 0), (3, 0)])
self.assertEqual(unique_versions, [(2, 0), (3, 0)])
self.assertFalse(incomp)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
# Since python 3.8+, the multiprocessing context on macOS started using spawn() instead of fork(),
# which means that the concurrently run functionality doesn't inherit the same information. It was
# fixed such that when spawn() is used, it reestablishes the information that isn't inherited.
# This test fails if that isn't done, and always succeeds when fork() is used.
def test_processor_argparse_backport_spawn_or_fork(self):
fp = ScopedTemporaryFile()
fp.writeln(b"import argparse") # 2.7, 3.2
fp.close()
self.config.add_backport("argparse") # -> 2.3, 3.1
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(2, 3), (3, 1)])
self.assertFalse(incomp)
self.assertEqual(unique_versions, [(2, 3), (3, 1)])
self.assertEqual(backports, {"argparse"})
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
def test_processor_maybe_annotations(self):
fp = ScopedTemporaryFile()
fp.write(b"list[str]()") # Generic annotations used.
fp.close()
self.config.set_eval_annotations(False)
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertFalse(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertTrue(maybe_anns)
# Evaluating annotations is turned off by default.
def test_processor_maybe_annotations_default(self):
fp = ScopedTemporaryFile()
fp.write(b"list[str]()") # Generic annotations used.
fp.close()
paths = [fp.path()]
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) =\
processor.process(paths, self.config)
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertFalse(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertTrue(maybe_anns)
def test_processor_runtime_error_pool_constructor_bootstrap(self):
orig = vermin.processor.mp.Pool
msg = "An attempt has been made to start a new process before the current " \
"process has finished its bootstrapping phase."
def raise_pool(*_, **__):
raise RuntimeError(msg)
vermin.processor.mp.Pool = raise_pool
try:
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) = \
Processor().process([abspath("vermin")], self.config)
finally:
vermin.processor.mp.Pool = orig
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertFalse(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
def test_processor_runtime_error_pool_constructor_other(self):
orig = vermin.processor.mp.Pool
def raise_pool(*_, **__):
raise RuntimeError("some other error")
vermin.processor.mp.Pool = raise_pool
try:
with self.assertRaises(RuntimeError):
Processor().process([abspath("vermin")], self.config)
finally:
vermin.processor.mp.Pool = orig
def test_processor_runtime_error_imap_bootstrap(self):
orig = vermin.processor.mp.Pool
msg = "An attempt has been made to start a new process before the current " \
"process has finished its bootstrapping phase."
mock = _MockPool(imap_raise=RuntimeError(msg))
vermin.processor.mp.Pool = lambda *_, **__: mock
try:
(mins, incomp, unique_versions, backports, used_novermin, maybe_anns) = \
Processor().process([abspath("vermin")], self.config)
finally:
vermin.processor.mp.Pool = orig
self.assertEqual(mins, [(0, 0), (0, 0)])
self.assertFalse(incomp)
self.assertEmpty(unique_versions)
self.assertEmpty(backports)
self.assertFalse(used_novermin)
self.assertFalse(maybe_anns)
self.assertTrue(mock.close_called)
self.assertTrue(mock.join_called)
def test_processor_runtime_error_imap_other(self):
orig = vermin.processor.mp.Pool
mock = _MockPool(imap_raise=RuntimeError("some other error"))
vermin.processor.mp.Pool = lambda *_, **__: mock
try:
with self.assertRaises(RuntimeError):
Processor().process([abspath("vermin")], self.config)
finally:
vermin.processor.mp.Pool = orig
self.assertTrue(mock.close_called)
self.assertTrue(mock.join_called)
def test_detect_paths_runtime_error_pool_constructor_bootstrap(self):
orig = vermin.detection.Pool
msg = "An attempt has been made to start a new process before the current " \
"process has finished its bootstrapping phase."
def raise_pool(*_, **__):
raise RuntimeError(msg)
vermin.detection.Pool = raise_pool
try:
paths = detect_paths([abspath("vermin")], config=self.config)
finally:
vermin.detection.Pool = orig
self.assertEmpty(paths)
def test_detect_paths_runtime_error_pool_constructor_other(self):
orig = vermin.detection.Pool
def raise_pool(*_, **__):
raise RuntimeError("some other error")
vermin.detection.Pool = raise_pool
try:
with self.assertRaises(RuntimeError):
detect_paths([abspath("vermin")], config=self.config)
finally:
vermin.detection.Pool = orig
def test_detect_paths_runtime_error_imap_bootstrap(self):
orig = vermin.detection.Pool
msg = "An attempt has been made to start a new process before the current " \
"process has finished its bootstrapping phase."
mock = _MockPool(imap_raise=RuntimeError(msg))
vermin.detection.Pool = lambda *_, **__: mock
try:
paths = detect_paths([abspath("vermin")], config=self.config)
finally:
vermin.detection.Pool = orig
self.assertEmpty(paths)
self.assertTrue(mock.close_called)
self.assertTrue(mock.join_called)
def test_detect_paths_runtime_error_imap_other(self):
orig = vermin.detection.Pool
mock = _MockPool(imap_raise=RuntimeError("some other error"))
vermin.detection.Pool = lambda *_, **__: mock
try:
with self.assertRaises(RuntimeError):
detect_paths([abspath("vermin")], config=self.config)
finally:
vermin.detection.Pool = orig
self.assertTrue(mock.close_called)
self.assertTrue(mock.join_called)
def test_format_title_descs(self):
descs = (
("one", [
"one.one",
"one.two",
"one.three"
]),
("two", [
"two.one",
"two.two",
"two.three"
]),
("three", [
"three.one",
"three.two",
"three.three"
]),
)
titles = ["one", "two", "three"]
self.assertEqual("""one - one.one
one.two
one.three
two - two.one
two.two
two.three
three - three.one
three.two
three.three""", format_title_descs(descs, titles))
self.assertEqual(""" one - one.one
one.two
one.three
two - two.one
two.two
two.three
three - three.one
three.two
three.three""", format_title_descs(descs, titles, indent=2))
def test_pessimistic_syntax_error(self):
expected = [(0, 0), (0, 0)]
self.assertEqual(expected, self.detect("if")) # invalid syntax: if
self.config.set_pessimistic(True)
expected[current_version().major - 2] = None
self.assertEqual(expected, self.detect("if"))
def test_default_processes(self):
self.assertEqual(cpu_count(), DEFAULT_PROCESSES)
def test_compare_requirements_py2_and_py3_compatible(self):
reqs = [(2, 7), (3, 6)]
# User provides only one target
self.assertFalse(compare_requirements(reqs, [(True, (2, 6))]))
self.assertFalse(compare_requirements(reqs, [(False, (2, 6))]))
self.assertTrue(compare_requirements(reqs, [(True, (2, 7))]))
self.assertTrue(compare_requirements(reqs, [(False, (2, 7))]))
self.assertFalse(compare_requirements(reqs, [(True, (3, 3))]))
self.assertFalse(compare_requirements(reqs, [(False, (3, 3))]))
self.assertTrue(compare_requirements(reqs, [(True, (3, 6))]))
self.assertTrue(compare_requirements(reqs, [(False, (3, 6))]))
self.assertFalse(compare_requirements(reqs, [(True, (3, 7))]))
self.assertTrue(compare_requirements(reqs, [(False, (3, 7))]))
# Missing and invalid targets
self.assertFalse(compare_requirements(reqs, []))
self.assertFalse(compare_requirements(reqs, [(True, (4, 1))]))
# User provides multiple valid requirements, return true when both are
# satisfied.
self.assertTrue(compare_requirements(reqs, [(True, (2, 7)), (False, (3, 7))]))
self.assertFalse(compare_requirements(reqs, [(True, (2, 7)), (True, (3, 7))]))
# User provides valid along with invalid version: fail because the target
# major version is missing
self.assertFalse(compare_requirements(reqs, [(True, (2, 7)), (False, (4, 7))]))
self.assertFalse(compare_requirements(reqs, [(True, (2, 7)), (True, (4, 7))]))
def test_compare_requirements_py2_only(self):
reqs = [(2, 7)]
# Correct major version, compare against minor version
self.assertFalse(compare_requirements(reqs, [(True, (2, 6))]))
self.assertFalse(compare_requirements(reqs, [(False, (2, 6))]))
self.assertTrue(compare_requirements(reqs, [(True, (2, 7))]))
self.assertTrue(compare_requirements(reqs, [(False, (2, 7))]))
# The user specifies the wrong major version: this will always fail
self.assertFalse(compare_requirements(reqs, [(True, (3, 3))]))
self.assertFalse(compare_requirements(reqs, [(False, (3, 3))]))
self.assertFalse(compare_requirements(reqs, [(True, (3, 6))]))
self.assertFalse(compare_requirements(reqs, [(False, (3, 6))]))
self.assertFalse(compare_requirements(reqs, [(True, (3, 7))]))
self.assertFalse(compare_requirements(reqs, [(False, (3, 7))]))
self.assertFalse(compare_requirements(reqs, [(True, (4, 1))]))
# Missing target: fail
self.assertFalse(compare_requirements(reqs, []))
# Multiple targets: fail because one target major version is missing
self.assertFalse(compare_requirements(reqs, [(False, (2, 7)), (False, (3, 6))]))
def test_compare_requirements_py3_only(self):
reqs = [(3, 6)]
# The user specifies the wrong major version: this will always fail
self.assertFalse(compare_requirements(reqs, [(True, (2, 6))]))
self.assertFalse(compare_requirements(reqs, [(False, (2, 6))]))
self.assertFalse(compare_requirements(reqs, [(True, (2, 7))]))
self.assertFalse(compare_requirements(reqs, [(False, (2, 7))]))
self.assertFalse(compare_requirements(reqs, [(True, (4, 1))]))
# Correct major version, compare against minor version
self.assertFalse(compare_requirements(reqs, [(True, (3, 3))]))
self.assertFalse(compare_requirements(reqs, [(False, (3, 3))]))
self.assertTrue(compare_requirements(reqs, [(True, (3, 6))]))
self.assertTrue(compare_requirements(reqs, [(False, (3, 6))]))
self.assertFalse(compare_requirements(reqs, [(True, (3, 7))]))
self.assertTrue(compare_requirements(reqs, [(False, (3, 7))]))
# Missing and invalid requirements
self.assertFalse(compare_requirements(reqs, []))
# Multiple targets: fail because one target amjor version is missing
self.assertFalse(compare_requirements(reqs, [(False, (2, 7)), (False, (3, 6))]))
netromdk-vermin-d650a48/tests/kwargs.py 0000664 0000000 0000000 00000644077 15265463462 0020241 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest, current_version
class VerminKwargsTests(VerminTest):
def test_name_of_ImportError(self):
self.assertOnlyIn((3, 3), self.detect("ImportError(name=None)"))
def test_path_of_ImportError(self):
self.assertOnlyIn((3, 3), self.detect("ImportError(path=None)"))
def test_filename2_of_OSError(self):
self.assertOnlyIn((3, 4), self.detect("OSError(filename2=None)"))
def test_encoding_of_bytearray_decode(self):
self.assertOnlyIn((3, 2), self.detect("bytearray.decode(encoding=None)"))
def test_errors_of_bytearray_decode(self):
self.assertOnlyIn((3, 2), self.detect("bytearray.decode(errors=None)"))
def test_bytes_per_sep_of_bytearray_hex(self):
self.assertOnlyIn((3, 8), self.detect("bytearray.hex(bytes_per_sep=None)"))
def test_sep_of_bytearray_hex(self):
self.assertOnlyIn((3, 8), self.detect("bytearray.hex(sep=None)"))
def test_delete_of_bytearray_translate(self):
self.assertOnlyIn((3, 6), self.detect("bytearray.translate(delete=None)"))
def test_encoding_of_bytes_decode(self):
self.assertOnlyIn((3, 2), self.detect("bytes.decode(encoding=None)"))
def test_errors_of_bytes_decode(self):
self.assertOnlyIn((3, 2), self.detect("bytes.decode(errors=None)"))
def test_bytes_per_sep_of_bytes_hex(self):
self.assertOnlyIn((3, 8), self.detect("bytes.hex(bytes_per_sep=None)"))
def test_sep_of_bytes_hex(self):
self.assertOnlyIn((3, 8), self.detect("bytes.hex(sep=None)"))
def test_delete_of_bytes_translate(self):
self.assertOnlyIn((3, 6), self.detect("bytes.translate(delete=None)"))
def test_bytes_per_sep_of_memoryview_hex(self):
self.assertOnlyIn((3, 8), self.detect("memoryview.hex(bytes_per_sep=None)"))
def test_sep_of_memoryview_hex(self):
self.assertOnlyIn((3, 8), self.detect("memoryview.hex(sep=None)"))
def test_key_of_sorted(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("sorted(key=None)"))
def test_reverse_of_sorted(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("sorted(reverse=None)"))
def test_count_of_str_replace(self):
self.assertOnlyIn((3, 13), self.detect("str.replace(count=None)"))
def test_optimize_of_ast_parse(self):
self.assertOnlyIn((3, 13), self.detect("from ast import parse\nparse(optimize=None)"))
def test_indent_of_ast_dump(self):
self.assertOnlyIn((3, 9), self.detect("from ast import dump\ndump(indent=None)"))
def test_show_empty_of_ast_dump(self):
self.assertOnlyIn((3, 13), self.detect("from ast import dump\ndump(show_empty=None)"))
def test_allow_unnamed_section_of_configparser_ConfigParser(self):
self.assertOnlyIn((3, 13), self.detect("""
from configparser import ConfigParser
ConfigParser(allow_unnamed_section=None)
"""))
def test_allow_unnamed_section_of_configparser_RawConfigParser(self):
self.assertOnlyIn((3, 13), self.detect("""
from configparser import RawConfigParser
RawConfigParser(allow_unnamed_section=None)
"""))
def test_show_offsets_of_dis_Bytecode(self):
self.assertOnlyIn((3, 13), self.detect("from dis import Bytecode\nBytecode(show_offsets=None)"))
def test_show_offsets_of_dis_disassemble(self):
self.assertOnlyIn((3, 13),
self.detect("from dis import disassemble\ndisassemble(show_offsets=None)"))
def test_show_offsets_of_dis_distb(self):
self.assertOnlyIn((3, 13), self.detect("from dis import distb\ndistb(show_offsets=None)"))
def test_strict_of_email_utils_getaddresses(self):
self.assertOnlyIn((3, 13), self.detect("""
from email.utils import getaddresses
getaddresses(strict=None)
"""))
def test_strict_of_email_utils_parseaddr(self):
self.assertOnlyIn((3, 13),
self.detect("from email.utils import parseaddr\nparseaddr(strict=None)"))
def test_strict_of_itertools_batched(self):
self.assertOnlyIn((3, 13), self.detect("from itertools import batched\nbatched(strict=None)"))
def test_allow_code_of_marshal_dump(self):
self.assertOnlyIn((3, 13), self.detect("from marshal import dump\ndump(allow_code=None)"))
def test_allow_code_of_marshal_dumps(self):
self.assertOnlyIn((3, 13), self.detect("from marshal import dumps\ndumps(allow_code=None)"))
def test_allow_code_of_marshal_load(self):
self.assertOnlyIn((3, 13), self.detect("from marshal import load\nload(allow_code=None)"))
def test_allow_code_of_marshal_loads(self):
self.assertOnlyIn((3, 13), self.detect("from marshal import loads\nloads(allow_code=None)"))
def test_recurse_symlinks_of_pathlib_Path_glob(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.glob(recurse_symlinks=None)"))
def test_recurse_symlinks_of_pathlib_Path_rglob(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.rglob(recurse_symlinks=None)"))
def test_follow_symlinks_of_pathlib_Path_is_file(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.is_file(follow_symlinks=None)"))
def test_follow_symlinks_of_pathlib_Path_is_dir(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.is_dir(follow_symlinks=None)"))
def test_follow_symlinks_of_pathlib_Path_exists_chained_receiver(self):
# A chained receiver like `Path.cwd().exists(..)` must still resolve to the
# `pathlib.Path.exists` kwarg rule and not be hidden by the intermediate `cwd()` call. See #327.
self.assertOnlyIn((3, 12),
self.detect("from pathlib import Path\n"
"Path.cwd().exists(follow_symlinks=True)"))
def test_follow_symlinks_of_pathlib_Path_is_file_chained_receiver(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\n"
"Path.cwd().is_file(follow_symlinks=True)"))
def test_follow_symlinks_of_pathlib_Path_is_dir_chained_receiver(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\n"
"Path.cwd().is_dir(follow_symlinks=True)"))
def test_follow_symlinks_of_pathlib_Path_is_file_multi_hop(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\n"
"Path.cwd().resolve().is_file(follow_symlinks=True)"))
def test_follow_symlinks_of_pathlib_Path_exists_aliased_module(self):
self.assertOnlyIn((3, 12),
self.detect("import pathlib as pl\n"
"pl.Path.cwd().exists(follow_symlinks=True)"))
def test_follow_symlinks_of_unrelated_chain_not_detected(self):
self.assertNotIn((3, 12),
self.detect("foo.bar().exists(follow_symlinks=True)\n"))
def test_follow_symlinks_of_pathlib_Path_owner(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.owner(follow_symlinks=None)"))
def test_follow_symlinks_of_pathlib_Path_group(self):
self.assertOnlyIn((3, 13),
self.detect("from pathlib import Path\nPath.group(follow_symlinks=None)"))
def test_weights_of_statistics_fmean(self):
self.assertOnlyIn((3, 11), self.detect("""
from statistics import fmean
fmean(weights=None)
"""))
def test_weights_of_statistics_harmonic_mean(self):
self.assertOnlyIn((3, 10), self.detect("""
from statistics import harmonic_mean
harmonic_mean(weights=None)
"""))
def test_proportional_of_statistics_linear_regression(self):
self.assertOnlyIn((3, 11), self.detect("""
from statistics import linear_regression
linear_regression(proportional=None)
"""))
def test_dir_fd_of_shutil_chown(self):
self.assertOnlyIn((3, 13), self.detect("from shutil import chown\nchown(dir_fd=None)"))
def test_follow_symlinks_of_shutil_chown(self):
self.assertOnlyIn((3, 13), self.detect("from shutil import chown\nchown(follow_symlinks=None)"))
def test_start_of_sum(self):
self.assertOnlyIn((3, 8), self.detect("sum(start=None)"))
def test_platform_version_of_sys_getwindowsversion(self):
self.assertOnlyIn((3, 6), self.detect("sys.getwindowsversion(platform_version=None)"))
def test_filter_of_sqlite3_Connection_iterdump(self):
self.assertOnlyIn((3, 13), self.detect("""
from sqlite3 import Connection
Connection.iterdump(filter=None)
"""))
def test_inheritable_of_dup2_from_os(self):
self.assertOnlyIn((3, 4), self.detect("import os\nv = os.dup2(inheritable=True)"))
self.assertOnlyIn((3, 4), self.detect("from os import dup2\nv = dup2(inheritable=True)"))
def test_dir_fd_of_open_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.open(dir_fd=None)"))
def test_dir_fd_of_access_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.access(dir_fd=None)"))
def test_effective_ids_of_access_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.access(effective_ids=None)"))
def test_follow_symlinks_of_access_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.access(follow_symlinks=None)"))
def test_follow_symlinks_of_chflags_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.chflags(follow_symlinks=None)"))
def test_dir_fd_of_chmod_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.chmod(dir_fd=None)"))
def test_follow_symlinks_of_chmod_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.chmod(follow_symlinks=None)"))
def test_dir_fd_of_chown_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.chown(dir_fd=None)"))
def test_follow_symlinks_of_chown_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.chown(follow_symlinks=None)"))
def test_src_dir_fd_of_link_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.link(src_dir_fd=None)"))
def test_dst_dir_fd_of_link_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.link(dst_dir_fd=None)"))
def test_follow_symlinks_of_link_from_os(self):
self.assertOnlyIn((3, 3), self.detect("import os\nv = os.link(follow_symlinks=None)"))
def test_show_group_of_traceback_TracebackException_format_exception_only(self):
self.assertOnlyIn((3, 13), self.detect("""
from traceback import TracebackException
TracebackException.format_exception_only(show_group=None)
"""))
def test_maxtasksperchild_of_Pool_from_multiprocessing(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"import multiprocessing\nmultiprocessing.Pool(maxtasksperchild=3)"))
def test_daemon_of_Process_from_multiprocessing(self):
self.assertOnlyIn((3, 3),
self.detect("import multiprocessing\nmultiprocessing.Process(daemon=None)"))
def test_compact_of_PrettyPrinter_from_pprint(self):
self.assertOnlyIn((3, 4), self.detect("import pprint\npprint.PrettyPrinter(compact=True)"))
def test_compact_of_pformat_from_pprint(self):
self.assertOnlyIn((3, 4), self.detect("import pprint\npprint.pformat(compact=True)"))
def test_compact_of_pprint_from_pprint(self):
self.assertOnlyIn((3, 4), self.detect("import pprint\npprint.pprint(compact=True)"))
def test_delta_of_assertAlmostEqual_from_unitest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"from unittest import TestCase\nTestCase.assertAlmostEqual(delta=1)"))
def test_delta_of_assertNotAlmostEqual_from_unitest_TestCase(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import TestCase\n"
"TestCase.assertNotAlmostEqual(delta=1)"))
def test_fold_of_datetime_from_datetime(self):
self.assertOnlyIn((3, 6), self.detect("from datetime import datetime\ndatetime(fold=1)"))
def test_tzinfo_of_combine_from_datetime(self):
self.assertOnlyIn((3, 6), self.detect(
"from datetime import datetime\ndatetime.combine(tzinfo=1)"))
def test_fold_of_replace_from_datetime(self):
self.assertOnlyIn((3, 6), self.detect(
"from datetime import datetime\ndatetime.replace(fold=1)"))
def test_timespec_of_isoformat_from_datetime(self):
self.assertOnlyIn((3, 6),
self.detect("from datetime import datetime\ndatetime.isoformat(timespec=1)"))
def test_fold_of_replace_from_datetime_time(self):
self.assertOnlyIn((3, 6), self.detect("from datetime import time\ntime.replace(fold=1)"))
def test_timespec_of_isoformat_from_datetime_time(self):
self.assertOnlyIn((3, 6), self.detect("from datetime import time\ntime.isoformat(timespec=1)"))
def test_domain_of_Filter_from_tracemalloc(self):
self.assertOnlyIn((3, 6), self.detect("import tracemalloc\ntracemalloc.Filter(domain=1)"))
def test_compact_of_TracebackException_from_traceback(self):
self.assertOnlyIn((3, 10), self.detect("""
from traceback import TracebackException
TracebackException(compact=1)
"""))
def test_max_length_of_decompress_from_bz2_BZ2Decompressor(self):
self.assertOnlyIn((3, 5),
self.detect("from bz2 import BZ2Decompressor\n"
"d = BZ2Decompressor()\n"
"d.decompress(max_length=1)"))
def test_maxlen_of_deque_from_collections(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import collections\ncollections.deque(maxlen=1)"))
def test_rename_of_namedtuple_from_collections(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("import collections\ncollections.namedtuple(rename=True)"))
def test_module_of_namedtuple_from_collections(self):
self.assertOnlyIn((3, 6), self.detect(
"import collections\ncollections.namedtuple(module=None)"))
def test_defaults_of_namedtuple_from_collections(self):
self.assertOnlyIn((3, 7), self.detect(
"import collections\ncollections.namedtuple(defaults=None)"))
def test_m_of_ChainMap_new_child_from_collections(self):
self.assertOnlyIn((3, 4), self.detect(
"import collections\ncollections.ChainMap.new_child(m=None)"))
def test_stop_of_index_from_collections_abc_ByteString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import ByteString\n"
"x = ByteString()\n"
"x.index(stop=None)"))
def test_start_of_index_from_collections_abc_ByteString(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import ByteString\n"
"x = ByteString()\n"
"x.index(start=None)"))
def test_stop_of_index_from_collections_abc_MutableSequence(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import MutableSequence\n"
"x = MutableSequence()\n"
"x.index(stop=None)"))
def test_start_of_index_from_collections_abc_MutableSequence(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import MutableSequence\n"
"x = MutableSequence()\n"
"x.index(start=None)"))
def test_stop_of_index_from_collections_abc_Sequence(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import Sequence\n"
"x = Sequence()\n"
"x.index(stop=None)"))
def test_start_of_index_from_collections_abc_Sequence(self):
self.assertOnlyIn((3, 5),
self.detect("from collections.abc import Sequence\n"
"x = Sequence()\n"
"x.index(start=None)"))
def test_use_last_error_of_CDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import ctypes\nctypes.CDLL(use_last_error=True)"))
def test_use_errno_of_CDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.CDLL(use_errno=True)"))
def test_use_last_error_of_OleDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import ctypes\nctypes.OleDLL(use_last_error=True)"))
def test_use_errno_of_OleDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.OleDLL(use_errno=True)"))
def test_use_last_error_of_WinDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import ctypes\nctypes.WinDLL(use_last_error=True)"))
def test_use_errno_of_WinDLL_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ctypes\nctypes.WinDLL(use_errno=True)"))
def test_use_last_error_of_CFUNCTYPE_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("import ctypes\nctypes.CFUNCTYPE(use_last_error=True)"))
def test_use_errno_of_CFUNCTYPE_from_ctypes(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"import ctypes\nctypes.CFUNCTYPE(use_errno=True)"))
def test_autojunk_of_SequenceMatcher_from_difflib(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("import difflib\ndifflib.SequenceMatcher(autojunk=True)"))
def test_charset_of_make_file_from_difflib(self):
self.assertOnlyIn((3, 5), self.detect("from difflib import HtmlDiff\n"
"HtmlDiff.make_file(charset=True)"))
def test_use_builtin_types_of_SimpleXMLRPCServer_from_xmlrpc_server(self):
self.assertOnlyIn((3, 3), self.detect("from xmlrpc.server import SimpleXMLRPCServer\n"
"SimpleXMLRPCServer(use_builtin_types=True)"))
def test_use_builtin_types_of_CGIXMLRPCRequestHandler_from_xmlrpc_server(self):
self.assertOnlyIn((3, 3), self.detect("from xmlrpc.server import CGIXMLRPCRequestHandler\n"
"CGIXMLRPCRequestHandler(use_builtin_types=True)"))
def test_use_builtin_types_of_DocXMLRPCServer_from_xmlrpc_server(self):
self.assertOnlyIn((3, 3), self.detect("from xmlrpc.server import DocXMLRPCServer\n"
"DocXMLRPCServer(use_builtin_types=True)"))
def test_initial_of_reduce_from_functools(self):
self.assertOnlyIn((3, 14), self.detect("import functools\nfunctools.reduce(initial=3)"))
def test_typed_of_lru_cache_from_functools(self):
self.assertOnlyIn((3, 3), self.detect("import functools\nfunctools.lru_cache(typed=3)"))
def test_key_of_nlargest_from_heapq(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import heapq\nheapq.nlargest(key=3)"))
def test_key_of_nsmallest_from_heapq(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import heapq\nheapq.nsmallest(key=3)"))
def test_key_of_merge_from_heapq(self):
self.assertOnlyIn((3, 5), self.detect("import heapq\nheapq.merge(key=3)"))
def test_reverse_of_merge_from_heapq(self):
self.assertOnlyIn((3, 5), self.detect("import heapq\nheapq.merge(reverse=True)"))
def test_follow_wrapped_of_signature_from_inspect(self):
self.assertOnlyIn((3, 5), self.detect("import inspect\ninspect.signature(follow_wrapped=True)"))
def test_eval_str_of_signature_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("import inspect\ninspect.signature(eval_str=True)"))
def test_globals_of_signature_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("import inspect\ninspect.signature(globals=True)"))
def test_locals_of_signature_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("import inspect\ninspect.signature(locals=True)"))
def test_quote_annotation_strings_of_Signature_from_inspect(self):
self.assertOnlyIn((3, 14), self.detect("""
from inspect import Signature
Signature.format(quote_annotation_strings=False)
"""))
def test_globals_of_Signature_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("""
from inspect import Signature
Signature.from_callable(globals=True)
"""))
def test_locals_of_Signature_from_inspect(self):
self.assertOnlyIn((3, 10), self.detect("""
from inspect import Signature
Signature.from_callable(locals=True)
"""))
def test_annotation_format_of_signature_from_inspect(self):
self.assertOnlyIn((3, 14), self.detect("""
from inspect import signature
signature(annotation_format=True)
"""))
def test_write_through_of_TextIOWrapper_from_io(self):
self.assertOnlyIn((3, 3), self.detect("import io\nio.TextIOWrapper(write_through=True)"))
def test_encoding_of_TextIOWrapper_reconfigure_from_io(self):
self.assertOnlyIn((3, 11),
self.detect("import io\nio.TextIOWrapper.reconfigure(encoding=None)"))
def test_func_of_accumulate_from_itertools(self):
self.assertOnlyIn((3, 3), self.detect("import itertools\nitertools.accumulate(func=None)"))
def test_step_of_count_from_itertools(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import itertools\nitertools.count(step=None)"))
def test_object_pairs_hook_of_load_from_json(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect(
"import json\njson.load(object_pairs_hook=None)"))
def test_object_pairs_hook_of_JSONDecoder_from_json(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("import json\njson.JSONDecoder(object_pairs_hook=None)"))
def test_func_of_makeRecord_from_logging_Logger(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import Logger\nLogger.makeRecord(func=None)"))
def test_extra_of_makeRecord_from_logging_Logger(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import Logger\nLogger.makeRecord(extra=None)"))
def test_func_of_LogRecord_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import LogRecord\nLogRecord(func=None)"))
def test_extra_of_debug_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import logging\nlogging.debug(extra=None)"))
def test_stack_info_of_debug_from_logging(self):
self.assertOnlyIn((3, 2), self.detect("import logging\nlogging.debug(stack_info=None)"))
def test_style_of_Formatter_from_logging(self):
self.assertOnlyIn((3, 2), self.detect("import logging\nlogging.Formatter(style=None)"))
def test_annotate_of_dis_from_pickletools(self):
self.assertOnlyIn((3, 2), self.detect("import pickletools\npickletools.dis(annotate=None)"))
def test_posix_of_split_from_shlex(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import shlex\nshlex.split(posix=None)"))
def test_punctuation_chars_of_shlex_from_shlex(self):
self.assertOnlyIn((3, 6), self.detect("import shlex\nshlex.shlex(punctuation_chars=None)"))
def test_allow_none_of_SimpleXMLRPCServer_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCServer\n"
"SimpleXMLRPCServer(allow_none=True)"))
def test_encoding_of_SimpleXMLRPCServer_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCServer\n"
"SimpleXMLRPCServer(encoding=True)"))
def test_bind_and_activate_of_SimpleXMLRPCServer_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 6),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCServer\n"
"SimpleXMLRPCServer(bind_and_activate=True)"))
def test_allow_none_of_CGIXMLRPCRequestHandler_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleXMLRPCServer import CGIXMLRPCRequestHandler\n"
"CGIXMLRPCRequestHandler(allow_none=True)"))
def test_encoding_of_CGIXMLRPCRequestHandler_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 5),
self.detect("from SimpleXMLRPCServer import CGIXMLRPCRequestHandler\n"
"CGIXMLRPCRequestHandler(encoding=True)"))
def test_allow_dotted_names_of_register_instance_from_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 3),
self.detect("from SimpleXMLRPCServer import SimpleXMLRPCServer\n"
"srv = SimpleXMLRPCServer()\n"
"srv.register_instance(allow_dotted_names=True)"))
self.assertOnlyIn((3, 0),
self.detect("from xmlrpc.server import SimpleXMLRPCServer\n"
"srv = SimpleXMLRPCServer()\n"
"srv.register_instance(allow_dotted_names=True)"))
def test_ciphers_of_wrap_socket_from_ssl(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import ssl\nssl.wrap_socket(ciphers=None)"))
def test_password_of_load_cert_chain_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 3),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.load_cert_chain(password=None)"))
def test_cadata_of_load_verify_locations_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 4),
self.detect("from ssl import SSLContext\n"
"ctx = SSLContext()\n"
"ctx.load_verify_locations(cadata=None)"))
def test_encoding_of_run_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect("import subprocess\nsubprocess.run(encoding=None)"))
def test_errors_of_run_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect("import subprocess\nsubprocess.run(errors=None)"))
def test_encoding_of_getoutput_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("import subprocess\nsubprocess.getoutput(encoding=None)"))
def test_errors_of_getoutput_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("import subprocess\nsubprocess.getoutput(errors=None)"))
def test_encoding_of_getstatusoutput_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("import subprocess\nsubprocess.getstatusoutput(encoding=None)"))
def test_errors_of_getstatusoutput_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("import subprocess\nsubprocess.getstatusoutput(errors=None)"))
def test_encoding_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect(
"import subprocess\nsubprocess.check_output(encoding=None)"))
def test_errors_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect(
"import subprocess\nsubprocess.check_output(errors=None)"))
def test_text_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("import subprocess\nsubprocess.check_output(text=None)"))
def test_pass_fds_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import Popen\n"
"Popen(pass_fds=True)"))
def test_restore_signals_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import Popen\n"
"Popen(restore_signals=True)"))
def test_start_new_session_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import Popen\n"
"Popen(start_new_session=True)"))
def test_encoding_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect("import subprocess\nsubprocess.Popen(encoding=None)"))
def test_errors_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 6), self.detect("import subprocess\nsubprocess.Popen(errors=None)"))
def test_text_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 7), self.detect("import subprocess\nsubprocess.Popen(text=None)"))
def test_timeout_of_wait_from_subprocess_Popen(self):
self.assertOnlyIn((3, 3), self.detect("from subprocess import Popen\nPopen.wait(timeout=None)"))
def test_stderr_of_CalledProcessError_from_subprocess(self):
self.assertOnlyIn((3, 5),
self.detect("""
from subprocess import CalledProcessError
CalledProcessError(stderr=None)"""))
def test_stderr_of_TimeoutExpired_from_subprocess(self):
self.assertOnlyIn((3, 5),
self.detect("""
from subprocess import TimeoutExpired
TimeoutExpired(stderr=None)"""))
def test_timeout_of_communicate_from_subprocess_Popen(self):
self.assertOnlyIn((3, 3),
self.detect("from subprocess import Popen\nPopen.communicate(timeout=None)"))
def test_timeout_of_call_from_subprocess(self):
self.assertOnlyIn((3, 3), self.detect("import subprocess\nsubprocess.call(timeout=None)"))
def test_timeout_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 3), self.detect("import subprocess\nsubprocess.check_call(timeout=None)"))
def test_timeout_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 3), self.detect(
"import subprocess\nsubprocess.check_output(timeout=None)"))
def test_input_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 4), self.detect("import subprocess\nsubprocess.check_output(input=None)"))
def test_exclude_of_add_from_tarfile_TarFile(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from tarfile import TarFile\ntf = TarFile()\ntf.add(exclude=None)"))
def test_filter_of_add_from_tarfile_TarFile(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect(
"from tarfile import TarFile\ntf = TarFile()\ntf.add(filter=None)"))
def test_format_of_tobuf_from_tarfile_TarInfo(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from tarfile import TarInfo\ntf = TarInfo()\ntf.tobuf(format=None)"))
def test_encoding_of_tobuf_from_tarfile_TarInfo(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarInfo\n"
"tf = TarInfo()\n"
"tf.tobuf(encoding=None)"))
def test_errors_of_tobuf_from_tarfile_TarInfo(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect(
"from tarfile import TarInfo\ntf = TarInfo()\ntf.tobuf(errors=None)"))
def test_members_of_list_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 5), self.detect(
"from tarfile import TarFile\ntf = TarFile()\ntf.list(members=None)"))
def test_filter_of_extractall_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 12),
self.detect("from tarfile import TarFile\n"
"tf = TarFile()\n"
"tf.extractall(filter=None)"))
def test_numeric_owner_of_extractall_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 5),
self.detect("from tarfile import TarFile\n"
"tf = TarFile()\n"
"tf.extractall(numeric_owner=None)"))
def test_set_attrs_of_extract_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 2),
self.detect("from tarfile import TarFile\n"
"tf = TarFile()\n"
"tf.extract(set_attrs=None)"))
def test_filter_of_extract_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 12),
self.detect("from tarfile import TarFile\n"
"tf = TarFile()\n"
"tf.extract(filter=None)"))
def test_numeric_owner_of_extract_from_tarfile_TarFile(self):
self.assertOnlyIn((3, 5),
self.detect("from tarfile import TarFile\n"
"tf = TarFile()\n"
"tf.extract(numeric_owner=None)"))
def test_module_globals_of_warn_explicit_from_warnings(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("import warnings\nwarnings.warn_explicit(module_globals=None)"))
def test_line_of_formatwarning_from_warnings(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("import warnings\nwarnings.formatwarning(line=None)"))
def test_source_of_warn_explicit_from_warnings(self):
self.assertOnlyIn((3, 6),
self.detect("import warnings\nwarnings.warn_explicit(source=None)"))
def test_source_of_warn_from_warnings(self):
self.assertOnlyIn((3, 6),
self.detect("import warnings\nwarnings.warn(source=None)"))
def test_short_empty_elements_of_tostring_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 4),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostring(short_empty_elements=None)"))
def test_xml_declaration_of_tostring_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostring(xml_declaration=None)"))
def test_default_namespace_of_tostring_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostring(default_namespace=None)"))
def test_short_empty_elements_of_tostringlist_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 4),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostringlist(short_empty_elements=None)"))
def test_xml_declaration_of_tostringlist_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostringlist(xml_declaration=None)"))
def test_default_namespace_of_tostringlist_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 8),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.tostringlist(default_namespace=None)"))
def test_short_empty_elements_of_write_from_xml_etree_ElementTree(self):
self.assertOnlyIn((3, 4),
self.detect("from xml.etree import ElementTree\n"
"ElementTree.write(short_empty_elements=None)"))
def test_use_datetime_of_ServerProxy_from_xmlrpclib_ServerProxy(self):
self.assertOnlyIn((2, 5),
self.detect("from xmlrpclib import ServerProxy\n"
"ServerProxy(use_datetime=None)"))
def test_context_of_ServerProxy_from_xmlrpclib_ServerProxy(self):
self.assertOnlyIn((2, 7),
self.detect("from xmlrpclib import ServerProxy\n"
"ServerProxy(context=None)"))
def test_use_datetime_of_loads_from_xmlrpclib(self):
self.assertOnlyIn((2, 5),
self.detect("import xmlrpclib\n"
"xmlrpclib.loads(use_datetime=None)"))
def test_pwd_of_read_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.read(pwd=None)"))
def test_compress_type_of_writestr_from_zipfile_ZipFile(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from zipfile import ZipFile\n"
"zf = ZipFile()\n"
"zf.writestr(compress_type=None)"))
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from zipfile import ZipFile\n"
"ZipFile().writestr(compress_type=None)"))
def test_filterfunc_of_writepy_from_zipfile_PyZipFile(self):
self.assertOnlyIn((3, 4),
self.detect("from zipfile import PyZipFile\n"
"zf = PyZipFile()\n"
"zf.writepy(filterfunc=None)"))
def test_optimize_of_PyZipFile_from_zipfile(self):
self.assertOnlyIn((3, 2),
self.detect("from zipfile import PyZipFile\n"
"PyZipFile(optimize=None)"))
def test_unsafe_of_Mock_from_unittest_mock(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest.mock import Mock\n"
"Mock(unsafe=False)"))
def test_with_pip_of_EnvBuilder_from_venv(self):
self.assertOnlyIn((3, 4),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder(with_pip=False)"))
def test_upgrade_deps_of_EnvBuilder_from_venv(self):
self.assertOnlyIn((3, 9),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder(upgrade_deps=False)"))
def test_scm_ignore_files_of_EnvBuilder_from_venv(self):
self.assertOnlyIn((3, 13),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder(scm_ignore_files=False)"))
def test_prompt_of_EnvBuilder_from_venv(self):
self.assertOnlyIn((3, 6),
self.detect("from venv import EnvBuilder\n"
"EnvBuilder(prompt=False)"))
def test_with_pip_of_create_from_venv(self):
self.assertOnlyIn((3, 4),
self.detect("from venv import create\n"
"create(with_pip=False)"))
def test_scm_ignore_files_of_create_from_venv(self):
self.assertOnlyIn((3, 13),
self.detect("from venv import create\n"
"create(scm_ignore_files=False)"))
def test_upgrade_deps_of_create_from_venv(self):
self.assertOnlyIn((3, 9),
self.detect("from venv import create\n"
"create(upgrade_deps=False)"))
def test_prompt_of_create_from_venv(self):
self.assertOnlyIn((3, 6),
self.detect("from venv import create\n"
"create(prompt=None)"))
def test_flags_of_compile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("compile(flags=None)"))
def test_dont_inherit_of_compile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("compile(dont_inherit=None)"))
def test_optimize_of_compile(self):
self.assertOnlyIn((3, 2), self.detect("compile(optimize=None)"))
def test_start_of_enumerate(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("enumerate(start=None)"))
def test_closure_of_exec(self):
self.assertOnlyIn((3, 11), self.detect("exec(closure=None)"))
def test_globals_of_exec(self):
self.assertOnlyIn((3, 13), self.detect("exec(globals=None)"))
def test_locals_of_exec(self):
self.assertOnlyIn((3, 13), self.detect("exec(locals=None)"))
def test_globals_of_eval(self):
self.assertOnlyIn((3, 13), self.detect("eval(globals=None)"))
def test_locals_of_eval(self):
self.assertOnlyIn((3, 13), self.detect("eval(locals=None)"))
def test_key_of_max(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("max(key=None)"))
def test_default_of_max(self):
self.assertOnlyIn((3, 4), self.detect("max(default=None)"))
def test_key_of_min(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("min(key=None)"))
def test_trackfd_of_mmap_mmap(self):
self.assertOnlyIn((3, 13), self.detect("from mmap import mmap\nmmap(trackfd=None)"))
def test_default_of_min(self):
self.assertOnlyIn((3, 4), self.detect("min(default=None)"))
def test_level_of___import__(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("__import__(level=None)"))
def test_closefd_of_open(self):
self.assertOnlyIn((3, 0), self.detect("open(closefd=None)"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from io import open\n"
"open(closefd=None)"))
def test_encoding_of_open(self):
self.assertOnlyIn((3, 0), self.detect("open(encoding=None)"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from io import open\n"
"open(encoding=None)"))
def test_errors_of_open(self):
self.assertOnlyIn((3, 0), self.detect("open(errors=None)"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from io import open\n"
"open(errors=None)"))
def test_newline_of_open(self):
self.assertOnlyIn((3, 0), self.detect("open(newline=None)"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("from io import open\n"
"open(newline=None)"))
def test_opener_of_open(self):
self.assertOnlyIn((3, 3), self.detect("open(opener=None)"))
def test_flush_of_print(self):
# `print()` is not a function in v2.
self.assertOnlyIn((3, 3), self.detect("print(flush=None)"))
def test_policy_of_email_mime_base_MIMEBase(self):
self.assertOnlyIn((3, 6), self.detect(
"from email.mime.base import MIMEBase\nMIMEBase(policy=None)"))
def test_policy_of_email_mime_multipart_MIMEMultipart(self):
self.assertOnlyIn((3, 6),
self.detect("from email.mime.multipart import MIMEMultipart\n"
"MIMEMultipart(policy=None)"))
def test_policy_of_email_mime_application_MIMEApplication(self):
self.assertOnlyIn((3, 6),
self.detect("from email.mime.application import MIMEApplication\n"
"MIMEApplication(policy=None)"))
def test_policy_of_email_mime_audio_MIMEAudio(self):
self.assertOnlyIn((3, 6),
self.detect("from email.mime.audio import MIMEAudio\nMIMEAudio(policy=None)"))
def test_policy_of_email_mime_image_MIMEImage(self):
self.assertOnlyIn((3, 6),
self.detect("from email.mime.image import MIMEImage\nMIMEImage(policy=None)"))
def test_policy_of_email_mime_message_MIMEMessage(self):
self.assertOnlyIn((3, 6),
self.detect("from email.mime.message import MIMEMessage\n"
"MIMEMessage(policy=None)"))
def test_policy_of_email_mime_text_MIMEText(self):
self.assertOnlyIn((3, 6), self.detect(
"from email.mime.text import MIMEText\nMIMEText(policy=None)"))
def test_domain_of_email_utils_make_msgid(self):
self.assertOnlyIn((3, 2), self.detect(
"import email.utils\nemail.utils.make_msgid(domain=None)"))
def test_charset_of_email_utils_formataddr(self):
self.assertOnlyIn((3, 3), self.detect(
"import email.utils\nemail.utils.formataddr(charset=None)"))
def test_strict_of_email_message_from_string(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("import email\nemail.message_from_string(strict=None)"))
def test_strict_of_email_message_from_file(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("import email\nemail.message_from_file(strict=None)"))
def test_policy_of_email_parser_BytesFeedParser(self):
self.assertOnlyIn((3, 3),
self.detect("from email.parser import BytesFeedParser\n"
"BytesFeedParser(policy=None)"))
def test_policy_of_email_parser_FeedParser(self):
self.assertOnlyIn((3, 3),
self.detect("from email.parser import FeedParser\n"
"FeedParser(policy=None)"))
def test_policy_of_email_generator_BytesGenerator(self):
self.assertOnlyIn((3, 3),
self.detect("from email.generator import BytesGenerator\n"
"BytesGenerator(policy=None)"))
def test_policy_of_email_generator_Generator(self):
self.assertOnlyIn((3, 3),
self.detect("from email.generator import Generator\n"
"Generator(policy=None)"))
def test_linesep_of_email_generator_Generator_flatten(self):
self.assertOnlyIn((3, 2),
self.detect("from email.generator import Generator\n"
"g=Generator()\ng.flatten(linesep=None)"))
def test_linesep_of_email_header_Header_encode(self):
self.assertOnlyIn((3, 2),
self.detect("from email.header import Header\n"
"g=Header()\ng.encode(linesep=None)"))
def test_base_of_math_log(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import math\nmath.log(base=None)"))
def test_steps_of_math_nextafter(self):
self.assertOnlyIn((3, 12), self.detect("import math\nmath.nextafter(steps=None)"))
def test_exit_ok_of_path_mkdir(self):
self.assertOnlyIn(
(3, 5), self.detect("from pathlib import Path\np=Path('foo')\np.mkdir(exist_ok=True)"))
def test_parent_mode_of_path_mkdir(self):
self.assertOnlyIn(
(3, 15),
self.detect("from pathlib import Path\np=Path('foo')\np.mkdir(parent_mode=0o700)"))
def test_strict_of_path_resolve(self):
self.assertOnlyIn(
(3, 6), self.detect("from pathlib import Path\np=Path('foo')\np.resolve(strict=True)"))
def test_follow_symlinks_of_path_chmod(self):
self.assertOnlyIn((3, 10), self.detect("""
from pathlib import Path
p=Path('foo')
p.chmod(follow_symlinks=True)
"""))
def test_follow_symlinks_of_path_exists(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
p=Path('foo')
p.exists(follow_symlinks=True)
"""))
def test_case_sensitive_of_path_glob(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
p=Path('foo')
p.glob(case_sensitive=True)
"""))
def test_case_sensitive_of_path_rglob(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
p=Path('foo')
p.rglob(case_sensitive=True)
"""))
def test_follow_symlinks_of_path_stat(self):
self.assertOnlyIn((3, 10), self.detect("""
from pathlib import Path
p=Path('foo')
p.stat(follow_symlinks=True)
"""))
def test_newline_of_path_write_text(self):
self.assertOnlyIn((3, 10), self.detect("""
from pathlib import Path
p=Path('foo')
p.write_text(newline=True)
"""))
def test_newline_of_path_read_text(self):
self.assertOnlyIn((3, 13), self.detect("""
from pathlib import Path
p=Path('foo')
p.read_text(newline=True)
"""))
def test_case_sensitive_of_purepath_match(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import PurePath
p=PurePath('foo')
p.match(case_sensitive=True)
"""))
def test_walk_up_of_purepath_relative_to(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import PurePath
p=PurePath('foo')
p.relative_to(walk_up=True)
"""))
def test_case_sensitive_of_path_match_via_Path(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
Path('foo').match(case_sensitive=True)
"""))
def test_walk_up_of_path_relative_to_via_Path(self):
self.assertOnlyIn((3, 12), self.detect("""
from pathlib import Path
Path('foo').relative_to('bar', walk_up=True)
"""))
def test_optimization_of_importlib_util_cache_from_source(self):
self.assertOnlyIn((3, 5),
self.detect("from importlib.util import cache_from_source\n"
"cache_from_source(optimization=None)"))
def test_allow_abbrev_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 5), self.detect(
"import argparse\nargparse.ArgumentParser(allow_abbrev=True)"))
def test_color_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 14), self.detect("""
import argparse
argparse.ArgumentParser(color=True)
"""))
def test_exit_on_error_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 9),
self.detect("import argparse\nargparse.ArgumentParser(exit_on_error=True)"))
def test_suggest_on_error_of_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 14), self.detect("""
import argparse
argparse.ArgumentParser(suggest_on_error=True)
"""))
def test_deprecated_of_argparse_ArgumentParser_add_argument(self):
self.assertOnlyIn((3, 13), self.detect("""
import argparse
parser = argparse.ArgumentParser(prog='test')
parser.add_argument(deprecated=True)
"""))
def test_deprecated_of_argparse_ArgumentParser_add_parser(self):
self.assertOnlyIn((3, 13), self.detect("""
import argparse
parser = argparse.ArgumentParser(prog='test')
parser.add_parser(deprecated=True)
"""))
def test_skip_of_bdb_Bdb(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import bdb\nbdb.Bdb(skip=True)"))
def test_backtick_of_binascii_b2a_uu(self):
self.assertOnlyIn((3, 7), self.detect("import binascii\nbinascii.b2a_uu(backtick=True)"))
def test_strict_mode_of_binascii_a2b_base64(self):
self.assertOnlyIn((3, 11), self.detect("""
import binascii
binascii.a2b_base64(strict_mode=True)
"""))
def test_newline_of_binascii_b2a_base64(self):
self.assertOnlyIn((3, 6), self.detect("import binascii\nbinascii.b2a_base64(newline=True)"))
def test_separator_of_parse_from_cgi(self):
self.assertOnlyIn((3, 6),
self.detect("from cgi import parse\n"
"parse(separator=None)"))
def test_encoding_of_cgi_parse_multipart(self):
self.assertOnlyIn((3, 7), self.detect("import cgi\ncgi.parse_multipart(encoding='utf-8')"))
def test_errors_of_cgi_parse_multipart(self):
self.assertOnlyIn((3, 7), self.detect("import cgi\ncgi.parse_multipart(errors='utf-8')"))
def test_separator_of_cgi_parse_multipart(self):
self.assertOnlyIn((3, 6), self.detect("import cgi\ncgi.parse_multipart(separator='-')"))
def test_max_num_fields_of_parse_qs_from_cgi(self):
self.assertOnlyIn((2, 7),
self.detect("from cgi import parse_qs\n"
"parse_qs(max_num_fields=None)"))
def test_max_num_fields_of_parse_qsl_from_cgi(self):
self.assertOnlyIn((2, 7),
self.detect("from cgi import parse_qsl\n"
"parse_qsl(max_num_fields=None)"))
def test_exitmsg_of_code_interact(self):
self.assertOnlyIn((3, 6), self.detect("import code\ncode.interact(exitmsg='hello')"))
def test_legacy_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 2), self.detect(
"import compileall\ncompileall.compile_dir(legacy='hello')"))
def test_optimize_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 2), self.detect(
"import compileall\ncompileall.compile_dir(optimize='hello')"))
def test_invalidation_mode_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 7),
self.detect("import compileall\n"
"compileall.compile_dir(invalidation_mode='hello')"))
def test_stripdir_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_dir(stripdir=None)"))
def test_prependdir_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_dir(prependdir=None)"))
def test_limit_sl_dest_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_dir(limit_sl_dest=None)"))
def test_hardlink_dupes_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_dir(hardlink_dupes=None)"))
def test_workers_of_compileall_compile_dir(self):
self.assertOnlyIn((3, 5),
self.detect("import compileall\n"
"compileall.compile_dir(workers=None)"))
def test_legacy_of_compileall_compile_path(self):
self.assertOnlyIn((3, 2), self.detect(
"import compileall\ncompileall.compile_path(legacy='hello')"))
def test_optimize_of_compileall_compile_path(self):
self.assertOnlyIn((3, 2),
self.detect("import compileall\ncompileall.compile_path(optimize='hello')"))
def test_invalidation_mode_of_compileall_compile_path(self):
self.assertOnlyIn((3, 7),
self.detect("import compileall\n"
"compileall.compile_path(invalidation_mode='hello')"))
def test_invalidation_mode_of_compileall_compile_file(self):
self.assertOnlyIn((3, 7),
self.detect("import compileall\n"
"compileall.compile_file(invalidation_mode='hello')"))
def test_stripdir_of_compileall_compile_file(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_file(stripdir=None)"))
def test_prependdir_of_compileall_compile_file(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_file(prependdir=None)"))
def test_limit_sl_dest_of_compileall_compile_file(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_file(limit_sl_dest=None)"))
def test_hardlink_dupes_of_compileall_compile_file(self):
self.assertOnlyIn((3, 9),
self.detect("import compileall\n"
"compileall.compile_file(hardlink_dupes=None)"))
def test_buffersize_of_concurrent_futures_Executor_map(self):
self.assertOnlyIn((3, 14),
self.detect("from concurrent.futures import Executor\n"
"Executor().map(buffersize=123)"))
def test_chunksize_of_concurrent_futures_Executor_map(self):
self.assertOnlyIn((3, 5),
self.detect("from concurrent.futures import Executor\n"
"Executor().map(chunksize=123)"))
def test_cancel_futures_of_concurrent_futures_Executor_shutdown(self):
self.assertOnlyIn((3, 9),
self.detect("from concurrent.futures import Executor\n"
"Executor().shutdown(cancel_futures=True)"))
def test_thread_name_prefix_of_concurrent_futures_ThreadPoolExecutor(self):
self.assertOnlyIn((3, 6),
self.detect("from concurrent.futures import ThreadPoolExecutor\n"
"ThreadPoolExecutor(thread_name_prefix='123')"))
def test_initializer_of_concurrent_futures_ThreadPoolExecutor(self):
self.assertOnlyIn((3, 7),
self.detect("from concurrent.futures import ThreadPoolExecutor\n"
"ThreadPoolExecutor(initializer='123')"))
def test_initargs_of_concurrent_futures_ThreadPoolExecutor(self):
self.assertOnlyIn((3, 7),
self.detect("from concurrent.futures import ThreadPoolExecutor\n"
"ThreadPoolExecutor(initargs=0)"))
def test_max_tasks_per_child_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 11),
self.detect("from concurrent.futures import ProcessPoolExecutor\n"
"ProcessPoolExecutor(max_tasks_per_child='123')"))
def test_mp_context_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 7),
self.detect("from concurrent.futures import ProcessPoolExecutor\n"
"ProcessPoolExecutor(mp_context='123')"))
def test_initializer_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 7),
self.detect("from concurrent.futures import ProcessPoolExecutor\n"
"ProcessPoolExecutor(initializer='123')"))
def test_initargs_of_concurrent_futures_ProcessPoolExecutor(self):
self.assertOnlyIn((3, 7),
self.detect("from concurrent.futures import ProcessPoolExecutor\n"
"ProcessPoolExecutor(initargs=0)"))
def test_rounds_of_crypt_mksalt(self):
self.assertOnlyIn((3, 7), self.detect("import crypt\ncrypt.mksalt(rounds=8)"))
def test_show_caches_of_dis_Bytecode(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.Bytecode(show_caches=True)"))
def test_show_positions_of_dis_Bytecode(self):
self.assertOnlyIn((3, 14), self.detect("import dis\ndis.Bytecode(show_positions=True)"))
def test_show_caches_of_dis_dis(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.dis(show_caches=True)"))
def test_show_positions_of_dis_dis(self):
self.assertOnlyIn((3, 14), self.detect("import dis\ndis.dis(show_positions=True)"))
def test_show_caches_of_dis_distb(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.distb(show_caches=True)"))
def test_show_positions_of_dis_distb(self):
self.assertOnlyIn((3, 14), self.detect("import dis\ndis.distb(show_positions=True)"))
def test_show_caches_of_dis_disassemble(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.disassemble(show_caches=True)"))
def test_show_caches_of_dis_disco(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.disco(show_caches=True)"))
def test_show_positions_of_dis_disco(self):
self.assertOnlyIn((3, 14), self.detect("import dis\ndis.disco(show_positions=True)"))
def test_show_caches_of_dis_get_instructions(self):
self.assertOnlyIn((3, 11), self.detect("import dis\ndis.get_instructions(show_caches=True)"))
def test_file_of_dis_show_code(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.show_code(file=8)"))
def test_file_of_dis_dis(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.dis(file=8)"))
def test_depth_of_dis_dis(self):
self.assertOnlyIn((3, 7), self.detect("import dis\ndis.dis(depth=8)"))
def test_file_of_dis_distb(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.distb(file=8)"))
def test_file_of_dis_disco(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.disco(file=8)"))
def test_file_of_dis_disassemble(self):
self.assertOnlyIn((3, 4), self.detect("import dis\ndis.disassemble(file=8)"))
def test_mtime_of_gzip_compress(self):
self.assertOnlyIn((3, 8), self.detect("import gzip\ngzip.compress(mtime=8)"))
def test_encoding_of_gzip_open(self):
self.assertOnlyIn((3, 3), self.detect("import gzip\ngzip.open(encoding='utf-8')"))
def test_errors_of_gzip_open(self):
self.assertOnlyIn((3, 3), self.detect("import gzip\ngzip.open(errors=True)"))
def test_newline_of_gzip_open(self):
self.assertOnlyIn((3, 3), self.detect("import gzip\ngzip.open(newline=None)"))
def test_encoding_of_str_decode(self):
self.assertOnlyIn((2, 7), self.detect("'test'.decode(encoding=None)"))
def test_errors_of_str_decode(self):
self.assertOnlyIn((2, 7), self.detect("'test'.decode(errors=None)"))
def test_encoding_of_str_encode(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("'test'.encode(encoding=None)"))
def test_errors_of_str_encode(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("'test'.encode(errors=None)"))
def test_filter_of_zipapp_create_archive(self):
self.assertOnlyIn((3, 7), self.detect("import zipapp\nzipapp.create_archive(filter=None)"))
def test_compressed_of_zipapp_create_archive(self):
self.assertOnlyIn((3, 7), self.detect("import zipapp\nzipapp.create_archive(compressed=True)"))
def test_timeout_of_smtplib_SMTP(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import smtplib\nsmtplib.SMTP(timeout=1)"))
def test_timeout_of_smtplib_LMTP(self):
self.assertOnlyIn((3, 9), self.detect("import smtplib\nsmtplib.LMTP(timeout=1)"))
def test_source_address_of_smtplib_SMTP(self):
self.assertOnlyIn((3, 3), self.detect("import smtplib\nsmtplib.SMTP(source_address=1)"))
def test_source_address_of_smtplib_SMTP_SSL(self):
self.assertOnlyIn((3, 3), self.detect("import smtplib\nsmtplib.SMTP_SSL(source_address=1)"))
def test_context_of_smtplib_SMTP_SSL(self):
self.assertOnlyIn((3, 3), self.detect("import smtplib\nsmtplib.SMTP_SSL(context=1)"))
def test_context_of_smtplib_SMTP_starttls(self):
self.assertOnlyIn((3, 3), self.detect("import smtplib\nsmtplib.SMTP.starttls(context=1)"))
def test_text_of_subprocess_run(self):
self.assertOnlyIn((3, 7), self.detect("import subprocess\nsubprocess.run(text=True)"))
def test_capture_output_of_subprocess_run(self):
self.assertOnlyIn((3, 7), self.detect("import subprocess\nsubprocess.run(capture_output=1)"))
def test_lpAttributeList_of_subprocess_STARTUPINFO(self):
self.assertOnlyIn((3, 7),
self.detect("import subprocess\nsubprocess.STARTUPINFO(lpAttributeList=1)"))
def test_allow_no_value_of_ConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import ConfigParser\n"
"ConfigParser(allow_no_value=None)"))
def test_dict_type_of_ConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import ConfigParser\n"
"ConfigParser(dict_type=None)"))
def test_allow_no_value_of_RawConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import RawConfigParser\n"
"RawConfigParser(allow_no_value=None)"))
def test_dict_type_of_RawConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import RawConfigParser\n"
"RawConfigParser(dict_type=None)"))
def test_allow_no_value_of_SafeConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import SafeConfigParser\n"
"SafeConfigParser(allow_no_value=None)"))
def test_dict_type_of_SafeConfigParser_from_ConfigParser(self):
self.assertOnlyIn((2, 6),
self.detect("from ConfigParser import SafeConfigParser\n"
"SafeConfigParser(dict_type=None)"))
def test_useTk_of_Tk_from_Tkinter(self):
self.assertOnlyIn((2, 4),
self.detect("from Tkinter import Tk\n"
"Tk(useTk=None)"))
def test_encoding_of_FileType_from_argparse(self):
self.assertOnlyIn((3, 4),
self.detect("from argparse import FileType\n"
"FileType(encoding=None)"))
def test_errors_of_FileType_from_argparse(self):
self.assertOnlyIn((3, 4),
self.detect("from argparse import FileType\n"
"FileType(errors=None)"))
def test_feature_version_of_parse_from_ast(self):
self.assertOnlyIn((3, 8),
self.detect("from ast import parse\n"
"parse(feature_version=None)"))
def test_type_comments_of_parse_from_ast(self):
self.assertOnlyIn((3, 8),
self.detect("from ast import parse\n"
"parse(type_comments=None)"))
def test_context_of_Task_from_asyncio(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import Task\n"
"Task(context=None)"))
def test_eager_start_of_Task_from_asyncio(self):
self.assertOnlyIn((3, 12),
self.detect("from asyncio import Task\n"
"Task(eager_start=None)"))
def test_name_of_Task_from_asyncio(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import Task\n"
"Task(name=None)"))
def test_context_of_create_task_from_asyncio(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import create_task\n"
"create_task(context=None)"))
def test_eager_start_of_create_task_from_asyncio(self):
self.assertOnlyIn((3, 14),
self.detect("from asyncio import create_task\n"
"create_task(eager_start=None)"))
def test_name_of_create_task_from_asyncio(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import create_task\n"
"create_task(name=None)"))
def test_ssl_handshake_timeout_of_open_connection_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import open_connection\n"
"open_connection(ssl_handshake_timeout=None)"))
def test_ssl_handshake_timeout_of_open_unix_connection_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import open_unix_connection\n"
"open_unix_connection(ssl_handshake_timeout=None)"))
def test_path_of_open_unix_connection_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import open_unix_connection\n"
"open_unix_connection(path=None)"))
def test_loop_factory_of_run_from_asyncio(self):
self.assertOnlyIn((3, 12),
self.detect("from asyncio import run\n"
"run(loop_factory=None)"))
def test_ssl_handshake_timeout_of_start_server_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import start_server\n"
"start_server(ssl_handshake_timeout=None)"))
def test_start_serving_of_start_server_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import start_server\n"
"start_server(start_serving=None)"))
def test_ssl_handshake_timeout_of_start_unix_server_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import start_unix_server\n"
"start_unix_server(ssl_handshake_timeout=None)"))
def test_start_serving_of_start_unix_server_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import start_unix_server\n"
"start_unix_server(start_serving=None)"))
def test_path_of_start_unix_server_from_asyncio(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import start_unix_server\n"
"start_unix_server(path=None)"))
def test_bytes_per_sep_of_b2a_hex_from_binascii(self):
self.assertOnlyIn((3, 8),
self.detect("from binascii import b2a_hex\n"
"b2a_hex(bytes_per_sep=None)"))
def test_sep_of_b2a_hex_from_binascii(self):
self.assertOnlyIn((3, 8),
self.detect("from binascii import b2a_hex\n"
"b2a_hex(sep=None)"))
def test_bytes_per_sep_of_hexlify_from_binascii(self):
self.assertOnlyIn((3, 8),
self.detect("from binascii import hexlify\n"
"hexlify(bytes_per_sep=None)"))
def test_sep_of_hexlify_from_binascii(self):
self.assertOnlyIn((3, 8),
self.detect("from binascii import hexlify\n"
"hexlify(sep=None)"))
def test_base_of_log_from_cmath(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from cmath import log\n"
"log(base=None)"))
def test_stdin_of_Cmd_from_cmd(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from cmd import Cmd\n"
"Cmd(stdin=None)"))
def test_stdout_of_Cmd_from_cmd(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from cmd import Cmd\n"
"Cmd(stdout=None)"))
def test_allow_no_value_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(allow_no_value=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(allow_no_value=None)"))
def test_comment_prefixes_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(comment_prefixes=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(comment_prefixes=None)"))
def test_converters_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 5),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(converters=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(converters=None)"))
def test_default_section_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(default_section=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(default_section=None)"))
def test_delimiters_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(delimiters=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(delimiters=None)"))
def test_empty_lines_in_values_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(empty_lines_in_values=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(empty_lines_in_values=None)"))
def test_interpolation_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(interpolation=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(interpolation=None)"))
def test_strict_of_ConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(strict=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ConfigParser\n"
"ConfigParser(strict=None)"))
def test_allow_no_value_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(allow_no_value=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(allow_no_value=None)"))
def test_comment_prefixes_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(comment_prefixes=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(comment_prefixes=None)"))
def test_converters_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 5),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(converters=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(converters=None)"))
def test_default_section_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(default_section=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(default_section=None)"))
def test_delimiters_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(delimiters=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(delimiters=None)"))
def test_empty_lines_in_values_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(empty_lines_in_values=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(empty_lines_in_values=None)"))
def test_interpolation_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(interpolation=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(interpolation=None)"))
def test_strict_of_RawConfigParser_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(strict=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import RawConfigParser\n"
"RawConfigParser(strict=None)"))
def test_lineno_of_DuplicateSectionError_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError(lineno=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError(lineno=None)"))
def test_source_of_DuplicateSectionError_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError(source=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import DuplicateSectionError\n"
"DuplicateSectionError(source=None)"))
def test_source_of_ParsingError_from_configparser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ParsingError\n"
"ParsingError(source=None)"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)),
self.detect("from configparser import ParsingError\n"
"ParsingError(source=None)"))
def test_winmode_of_CDLL_from_ctypes(self):
self.assertOnlyIn((3, 8),
self.detect("from ctypes import CDLL\n"
"CDLL(winmode=None)"))
def test_winmode_of_OleDLL_from_ctypes(self):
self.assertOnlyIn((3, 8),
self.detect("from ctypes import OleDLL\n"
"OleDLL(winmode=None)"))
def test_winmode_of_WinDLL_from_ctypes(self):
self.assertOnlyIn((3, 8),
self.detect("from ctypes import WinDLL\n"
"WinDLL(winmode=None)"))
def test_jump_of_stack_effect_from_dis(self):
self.assertOnlyIn((3, 8),
self.detect("from dis import stack_effect\n"
"stack_effect(jump=None)"))
def test_encoding_of_DocFileSuite_from_doctest(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from doctest import DocFileSuite\n"
"DocFileSuite(encoding=None)"))
def test_extraglobs_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(extraglobs=None)"))
def test_globs_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(globs=None)"))
def test_optionflags_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(optionflags=None)"))
def test_setUp_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(setUp=None)"))
def test_tearDown_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(tearDown=None)"))
def test_test_finder_of_DocTestSuite_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import DocTestSuite\n"
"DocTestSuite(test_finder=None)"))
def test_pm_of_debug_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import debug\n"
"debug(pm=None)"))
def test_encoding_of_testfile_from_doctest(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from doctest import testfile\n"
"testfile(encoding=None)"))
def test_exclude_empty_of_testmod_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import testmod\n"
"testmod(exclude_empty=None)"))
def test_extraglobs_of_testmod_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import testmod\n"
"testmod(extraglobs=None)"))
def test_optionflags_of_testmod_from_doctest(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from doctest import testmod\n"
"testmod(optionflags=None)"))
def test_raise_on_error_of_testmod_from_doctest(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from doctest import testmod\n"
"testmod(raise_on_error=None)"))
def test_policy_of_message_from_binary_file_from_email(self):
self.assertOnlyIn((3, 3),
self.detect("from email import message_from_binary_file\n"
"message_from_binary_file(policy=None)"))
def test_policy_of_message_from_bytes_from_email(self):
self.assertOnlyIn((3, 3),
self.detect("from email import message_from_bytes\n"
"message_from_bytes(policy=None)"))
def test_policy_of_message_from_file_from_email(self):
self.assertOnlyIn((3, 3),
self.detect("from email import message_from_file\n"
"message_from_file(policy=None)"))
def test_policy_of_message_from_string_from_email(self):
self.assertOnlyIn((3, 3),
self.detect("from email import message_from_string\n"
"message_from_string(policy=None)"))
def test_start_of_Enum_from_enum(self):
self.assertOnlyIn((3, 5),
self.detect("from enum import Enum\n"
"Enum(start=None)"))
self.assertTrue(self.config.add_backport("enum"))
self.assertOnlyIn(((2, 4), (3, 3)),
self.detect("from enum import Enum\n"
"Enum(start=None)"))
def test_mode_of_FileInput_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from fileinput import FileInput\n"
"FileInput(mode=None)"))
def test_openhook_of_FileInput_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from fileinput import FileInput\n"
"FileInput(openhook=None)"))
def test_encoding_of_FileInput_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import FileInput
FileInput(encoding=None)
"""))
def test_errors_of_FileInput_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import FileInput
FileInput(errors=None)
"""))
def test_errors_of_hook_encoded_from_fileinput(self):
self.assertOnlyIn((3, 6),
self.detect("from fileinput import hook_encoded\n"
"hook_encoded(errors=None)"))
def test_encoding_of_hook_compressed_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import hook_compressed
hook_compressed(encoding=None)
"""))
def test_errors_of_hook_compressed_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import hook_compressed
hook_compressed(errors=None)
"""))
def test_mode_of_input_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from fileinput import input\n"
"input(mode=None)"))
def test_openhook_of_input_from_fileinput(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from fileinput import input\n"
"input(openhook=None)"))
def test_encoding_of_input_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import input
input(encoding=None)
"""))
def test_errors_of_input_from_fileinput(self):
self.assertOnlyIn((3, 10), self.detect("""
from fileinput import input
input(errors=None)
"""))
def test_source_address_of_FTP_from_ftplib(self):
self.assertOnlyIn((3, 3),
self.detect("from ftplib import FTP\n"
"FTP(source_address=None)"))
def test_timeout_of_FTP_from_ftplib(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from ftplib import FTP\n"
"FTP(timeout=None)"))
def test_context_of_FTP_TLS_from_ftplib(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from ftplib import FTP_TLS\n"
"FTP_TLS(context=None)"))
def test_source_address_of_FTP_TLS_from_ftplib(self):
self.assertOnlyIn((3, 3),
self.detect("from ftplib import FTP_TLS\n"
"FTP_TLS(source_address=None)"))
def test_generation_of_collect_from_gc(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from gc import collect\n"
"collect(generation=None)"))
def test_generation_of_get_objects_from_gc(self):
self.assertOnlyIn((3, 8),
self.detect("from gc import get_objects\n"
"get_objects(generation=None)"))
def test_echo_char_of_getpass_from_getpass(self):
self.assertOnlyIn((3, 14),
self.detect("from getpass import getpass\n"
"getpass(echo_char=None)"))
def test_stream_of_getpass_from_getpass(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from getpass import getpass\n"
"getpass(stream=None)"))
def test_codeset_of_install_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import install\n"
"install(codeset=None)"))
def test_names_of_install_from_gettext(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from gettext import install\n"
"install(names=None)"))
def test_codeset_of_translation_from_gettext(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from gettext import translation\n"
"translation(codeset=None)"))
def test_recursive_of_glob_from_glob(self):
self.assertOnlyIn((3, 5),
self.detect("from glob import glob\n"
"glob(recursive=None)"))
def test_dir_fd_of_glob_from_glob(self):
self.assertOnlyIn((3, 10),
self.detect("from glob import glob\n"
"glob(dir_fd=None)"))
def test_include_hidden_of_glob_from_glob(self):
self.assertOnlyIn((3, 11),
self.detect("from glob import glob\n"
"glob(include_hidden=None)"))
def test_root_dir_of_glob_from_glob(self):
self.assertOnlyIn((3, 10),
self.detect("from glob import glob\n"
"glob(root_dir=None)"))
def test_dir_fd_of_iglob_from_glob(self):
self.assertOnlyIn((3, 10),
self.detect("from glob import iglob\n"
"iglob(dir_fd=None)"))
def test_include_hidden_of_iglob_from_glob(self):
self.assertOnlyIn((3, 11),
self.detect("from glob import iglob\n"
"iglob(include_hidden=None)"))
def test_root_dir_of_iglob_from_glob(self):
self.assertOnlyIn((3, 10),
self.detect("from glob import iglob\n"
"iglob(root_dir=None)"))
def test_mtime_of_GzipFile_from_gzip(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from gzip import GzipFile\n"
"GzipFile(mtime=None)"))
def test_source_address_of_HTTPConnection_from_httplib(self):
self.assertOnlyIn((2, 7),
self.detect("from httplib import HTTPConnection\n"
"HTTPConnection(source_address=None)"))
def test_timeout_of_HTTPConnection_from_httplib(self):
self.assertOnlyIn((2, 6),
self.detect("from httplib import HTTPConnection\n"
"HTTPConnection(timeout=None)"))
def test_context_of_HTTPSConnection_from_httplib(self):
self.assertOnlyIn((2, 7),
self.detect("from httplib import HTTPSConnection\n"
"HTTPSConnection(context=None)"))
def test_source_address_of_HTTPSConnection_from_httplib(self):
self.assertOnlyIn((2, 7),
self.detect("from httplib import HTTPSConnection\n"
"HTTPSConnection(source_address=None)"))
def test_timeout_of_HTTPSConnection_from_httplib(self):
self.assertOnlyIn((2, 6),
self.detect("from httplib import HTTPSConnection\n"
"HTTPSConnection(timeout=None)"))
def test_ssl_context_of_IMAP4_SSL_from_imaplib(self):
self.assertOnlyIn((3, 3),
self.detect("from imaplib import IMAP4_SSL\n"
"IMAP4_SSL(ssl_context=None)"))
def test_timeout_of_IMAP4_SSL_from_imaplib(self):
self.assertOnlyIn((3, 9),
self.detect("from imaplib import IMAP4_SSL\n"
"IMAP4_SSL(timeout=None)"))
def test_timeout_of_IMAP4_from_imaplib(self):
self.assertOnlyIn((3, 9),
self.detect("from imaplib import IMAP4\n"
"IMAP4(timeout=None)"))
def test_timeout_of_IMAP4_open_from_imaplib(self):
self.assertOnlyIn((3, 9),
self.detect("from imaplib import IMAP4\n"
"IMAP4().open(timeout=None)"))
def test_opener_of_FileIO_from_io(self):
self.assertOnlyIn((3, 3),
self.detect("from io import FileIO\n"
"FileIO(opener=None)"))
def test_opener_of_open_from_io(self):
self.assertOnlyIn((3, 3),
self.detect("from io import open\n"
"open(opener=None)"))
def test_initial_of_accumulate_from_itertools(self):
self.assertOnlyIn((3, 8),
self.detect("from itertools import accumulate\n"
"accumulate(initial=None)"))
def test_module_globals_of_getline_from_linecache(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from linecache import getline\n"
"getline(module_globals=None)"))
def test_monetary_of_format_from_locale(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("import locale\n"
"locale.format(monetary=None)"))
def test_monetary_of_format_string_from_locale(self):
self.assertOnlyIn((3, 7),
self.detect("from locale import format_string\n"
"format_string(monetary=None)"))
def test_delay_of_FileHandler_from_logging(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging import FileHandler\n"
"FileHandler(delay=None)"))
def test_errors_of_FileHandler_from_logging(self):
self.assertOnlyIn((3, 9),
self.detect("from logging import FileHandler\n"
"FileHandler(errors=None)"))
def test_validate_of_Formatter_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Formatter\n"
"Formatter(validate=None)"))
def test_defaults_of_Formatter_from_logging(self):
self.assertOnlyIn((3, 10),
self.detect("from logging import Formatter\n"
"Formatter(defaults=None)"))
def test_datefmt_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(datefmt=None)"))
def test_filemode_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(filemode=None)"))
def test_filename_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(filename=None)"))
def test_force_of_basicConfig_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import basicConfig\n"
"basicConfig(force=None)"))
def test_format_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(format=None)"))
def test_handlers_of_basicConfig_from_logging(self):
self.assertOnlyIn((3, 3),
self.detect("from logging import basicConfig\n"
"basicConfig(handlers=None)"))
def test_level_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(level=None)"))
def test_stream_of_basicConfig_from_logging(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from logging import basicConfig\n"
"basicConfig(stream=None)"))
def test_style_of_basicConfig_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import basicConfig\n"
"basicConfig(style=None)"))
def test_extra_of_critical_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import critical\n"
"critical(extra=None)"))
def test_stack_info_of_critical_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import critical\n"
"critical(stack_info=None)"))
def test_stacklevel_of_critical_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import critical\n"
"critical(stacklevel=None)"))
def test_stacklevel_of_debug_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import debug\n"
"debug(stacklevel=None)"))
def test_extra_of_error_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import error\n"
"error(extra=None)"))
def test_stack_info_of_error_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import error\n"
"error(stack_info=None)"))
def test_stacklevel_of_error_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import error\n"
"error(stacklevel=None)"))
def test_extra_of_exception_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import exception\n"
"exception(extra=None)"))
def test_stack_info_of_exception_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import exception\n"
"exception(stack_info=None)"))
def test_stacklevel_of_exception_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import exception\n"
"exception(stacklevel=None)"))
def test_extra_of_info_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import info\n"
"info(extra=None)"))
def test_stack_info_of_info_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import info\n"
"info(stack_info=None)"))
def test_stacklevel_of_info_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import info\n"
"info(stacklevel=None)"))
def test_extra_of_log_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import log\n"
"log(extra=None)"))
def test_stack_info_of_log_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import log\n"
"log(stack_info=None)"))
def test_stacklevel_of_log_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import log\n"
"log(stacklevel=None)"))
def test_stack_info_of_warn_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import warn\n"
"warn(stack_info=None)"))
def test_stacklevel_of_warn_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import warn\n"
"warn(stacklevel=None)"))
def test_extra_of_warning_from_logging(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from logging import warning\n"
"warning(extra=None)"))
def test_stack_info_of_warning_from_logging(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import warning\n"
"warning(stack_info=None)"))
def test_stacklevel_of_warning_from_logging(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import warning\n"
"warning(stacklevel=None)"))
def test_domain_of_cat_from_nis(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from nis import cat\n"
"cat(domain=None)"))
def test_domain_of_maps_from_nis(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from nis import maps\n"
"maps(domain=None)"))
def test_domain_of_match_from_nis(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from nis import match\n"
"match(domain=None)"))
def test_usenetrc_of_NNTP_from_nntplib(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from nntplib import NNTP\n"
"NNTP(usenetrc=None)"))
def test_dir_fd_of_lstat_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import lstat\n"
"lstat(dir_fd=None)"))
def test_exist_ok_of_makedirs_from_os(self):
self.assertOnlyIn((3, 2),
self.detect("from os import makedirs\n"
"makedirs(exist_ok=None)"))
def test_parent_mode_of_makedirs_from_os(self):
self.assertOnlyIn((3, 15),
self.detect("from os import makedirs\n"
"makedirs(parent_mode=0o700)"))
def test_dir_fd_of_mkdir_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import mkdir\n"
"mkdir(dir_fd=None)"))
def test_dir_fd_of_mkfifo_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import mkfifo\n"
"mkfifo(dir_fd=None)"))
def test_dir_fd_of_mknod_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import mknod\n"
"mknod(dir_fd=None)"))
def test_dir_fd_of_readlink_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import readlink\n"
"readlink(dir_fd=None)"))
def test_dir_fd_of_remove_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import remove\n"
"remove(dir_fd=None)"))
def test_dst_dir_fd_of_rename_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import rename\n"
"rename(dst_dir_fd=None)"))
def test_src_dir_fd_of_rename_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import rename\n"
"rename(src_dir_fd=None)"))
def test_dir_fd_of_rmdir_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import rmdir\n"
"rmdir(dir_fd=None)"))
def test_operation_of_startfile_from_os(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from os import startfile\n"
"startfile(operation=None)"))
def test_arguments_of_startfile_from_os(self):
self.assertOnlyIn((3, 10),
self.detect("from os import startfile\n"
"startfile(arguments=None)"))
def test_cwd_of_startfile_from_os(self):
self.assertOnlyIn((3, 10),
self.detect("from os import startfile\n"
"startfile(cwd=None)"))
def test_show_cmd_of_startfile_from_os(self):
self.assertOnlyIn((3, 10),
self.detect("from os import startfile\n"
"startfile(show_cmd=None)"))
def test_dir_fd_of_stat_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import stat\n"
"stat(dir_fd=None)"))
def test_follow_symlinks_of_stat_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import stat\n"
"stat(follow_symlinks=None)"))
def test_dir_fd_of_symlink_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import symlink\n"
"symlink(dir_fd=None)"))
def test_dir_fd_of_unlink_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import unlink\n"
"unlink(dir_fd=None)"))
def test_dir_fd_of_utime_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import utime\n"
"utime(dir_fd=None)"))
def test_follow_symlinks_of_utime_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import utime\n"
"utime(follow_symlinks=None)"))
def test_ns_of_utime_from_os(self):
self.assertOnlyIn((3, 3),
self.detect("from os import utime\n"
"utime(ns=None)"))
def test_followlinks_of_walk_from_os(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from os import walk\n"
"walk(followlinks=None)"))
def test_strict_of_realpath_from_os_path(self):
self.assertOnlyIn((3, 10),
self.detect("from os.path import realpath\n"
"realpath(strict=None)"))
def test_nosigint_of_Pdb_from_pdb(self):
self.assertOnlyIn((3, 2),
self.detect("from pdb import Pdb\n"
"Pdb(nosigint=None)"))
def test_readrc_of_Pdb_from_pdb(self):
self.assertOnlyIn((3, 6),
self.detect("from pdb import Pdb\n"
"Pdb(readrc=None)"))
def test_skip_of_Pdb_from_pdb(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from pdb import Pdb\n"
"Pdb(skip=None)"))
def test_backend_of_Pdb_from_pdb(self):
self.assertOnlyIn((3, 14),
self.detect("from pdb import Pdb\n"
"Pdb(backend=None)"))
def test_colorize_of_Pdb_from_pdb(self):
self.assertOnlyIn((3, 14),
self.detect("from pdb import Pdb\n"
"Pdb(colorize=None)"))
def test_mode_of_Pdb_from_pdb(self):
self.assertOnlyIn((3, 14),
self.detect("from pdb import Pdb\n"
"Pdb(mode=None)"))
def test_commands_of_set_trace_from_pdb(self):
self.assertOnlyIn((3, 14),
self.detect("from pdb import set_trace\n"
"set_trace(commands=None)"))
def test_header_of_set_trace_from_pdb(self):
self.assertOnlyIn((3, 7),
self.detect("from pdb import set_trace\n"
"set_trace(header=None)"))
def test_buffer_callback_of_Pickler_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import Pickler\n"
"Pickler(buffer_callback=None)"))
def test_protocol_of_Pickler_from_pickle(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from pickle import Pickler\n"
"Pickler(protocol=None)"))
def test_buffers_of_Unpickler_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import Unpickler\n"
"Unpickler(buffers=None)"))
def test_encoding_of_Unpickler_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import Unpickler\n"
"Unpickler(encoding=None)"))
def test_errors_of_Unpickler_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import Unpickler\n"
"Unpickler(errors=None)"))
def test_buffer_callback_of_dump_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import dump\n"
"dump(buffer_callback=None)"))
def test_protocol_of_dump_from_pickle(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from pickle import dump\n"
"dump(protocol=None)"))
def test_buffer_callback_of_dumps_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import dumps\n"
"dumps(buffer_callback=None)"))
def test_protocol_of_dumps_from_pickle(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from pickle import dumps\n"
"dumps(protocol=None)"))
def test_buffers_of_load_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import load\n"
"load(buffers=None)"))
def test_encoding_of_load_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import load\n"
"load(encoding=None)"))
def test_errors_of_load_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import load\n"
"load(errors=None)"))
def test_buffers_of_loads_from_pickle(self):
self.assertOnlyIn((3, 8),
self.detect("from pickle import loads\n"
"loads(buffers=None)"))
def test_encoding_of_loads_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import loads\n"
"loads(encoding=None)"))
def test_errors_of_loads_from_pickle(self):
self.assertOnlyIn((3, 0),
self.detect("from pickle import loads\n"
"loads(errors=None)"))
def test_timeout_of_POP3_from_poplib(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from poplib import POP3\n"
"POP3(timeout=None)"))
def test_context_of_POP3_SSL_from_poplib(self):
self.assertOnlyIn((3, 2),
self.detect("from poplib import POP3_SSL\n"
"POP3_SSL(context=None)"))
def test_sort_dicts_of_PrettyPrinter_from_pprint(self):
self.assertOnlyIn((3, 8),
self.detect("from pprint import PrettyPrinter\n"
"PrettyPrinter(sort_dicts=None)"))
def test_underscore_numbers_of_PrettyPrinter_from_pprint(self):
self.assertOnlyIn((3, 10),
self.detect("from pprint import PrettyPrinter\n"
"PrettyPrinter(underscore_numbers=None)"))
def test_expand_of_PrettyPrinter_from_pprint(self):
self.assertOnlyIn((3, 15),
self.detect("from pprint import PrettyPrinter\n"
"PrettyPrinter(expand=True)"))
def test_depth_of_pformat_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pformat\n"
"pformat(depth=None)"))
def test_indent_of_pformat_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pformat\n"
"pformat(indent=None)"))
def test_sort_dicts_of_pformat_from_pprint(self):
self.assertOnlyIn((3, 8),
self.detect("from pprint import pformat\n"
"pformat(sort_dicts=None)"))
def test_width_of_pformat_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pformat\n"
"pformat(width=None)"))
def test_underscore_numbers_of_pformat_from_pprint(self):
self.assertOnlyIn((3, 10),
self.detect("from pprint import pformat\n"
"pformat(underscore_numbers=None)"))
def test_expand_of_pformat_from_pprint(self):
self.assertOnlyIn((3, 15),
self.detect("from pprint import pformat\n"
"pformat(expand=True)"))
def test_expand_of_pp_from_pprint(self):
self.assertOnlyIn((3, 15),
self.detect("from pprint import pp\n"
"pp(expand=True)"))
def test_depth_of_pprint_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pprint\n"
"pprint(depth=None)"))
def test_indent_of_pprint_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pprint\n"
"pprint(indent=None)"))
def test_sort_dicts_of_pprint_from_pprint(self):
self.assertOnlyIn((3, 8),
self.detect("from pprint import pprint\n"
"pprint(sort_dicts=None)"))
def test_width_of_pprint_from_pprint(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from pprint import pprint\n"
"pprint(width=None)"))
def test_underscore_numbers_of_pprint_from_pprint(self):
self.assertOnlyIn((3, 10),
self.detect("from pprint import pprint\n"
"pprint(underscore_numbers=None)"))
def test_expand_of_pprint_from_pprint(self):
self.assertOnlyIn((3, 15),
self.detect("from pprint import pprint\n"
"pprint(expand=True)"))
def test_invalidation_mode_of_compile_from_py_compile(self):
self.assertOnlyIn((3, 7),
self.detect("from py_compile import compile\n"
"compile(invalidation_mode=None)"))
def test_optimize_of_compile_from_py_compile(self):
self.assertOnlyIn((3, 2),
self.detect("from py_compile import compile\n"
"compile(optimize=None)"))
def test_quiet_of_compile_from_py_compile(self):
self.assertOnlyIn((3, 8),
self.detect("from py_compile import compile\n"
"compile(quiet=None)"))
def test_end_lineno_of_Class_from_pyclbr(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Class\n"
"Class(end_lineno=None)"))
def test_parent_of_Class_from_pyclbr(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Class\n"
"Class(parent=None)"))
def test_end_lineno_of_Function_from_pyclbr(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Function\n"
"Function(end_lineno=None)"))
def test_is_async_of_Function_from_pyclbr(self):
self.assertOnlyIn((3, 10),
self.detect("from pyclbr import Function\n"
"Function(is_async=None)"))
def test_parent_of_Function_from_pyclbr(self):
self.assertOnlyIn((3, 7),
self.detect("from pyclbr import Function\n"
"Function(parent=None)"))
def test_flags_of_findall_from_re(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from re import findall\n"
"findall(flags=None)"))
def test_flags_of_finditer_from_re(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from re import finditer\n"
"finditer(flags=None)"))
def test_flags_of_split_from_re(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from re import split\n"
"split(flags=None)"))
def test_flags_of_sub_from_re(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from re import sub\n"
"sub(flags=None)"))
def test_flags_of_subn_from_re(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from re import subn\n"
"subn(flags=None)"))
def test_flags_of_epoll_from_select(self):
self.assertOnlyIn((3, 3),
self.detect("from select import epoll\n"
"epoll(flags=None)"))
def test_timeout_of_control_from_select(self):
self.assertOnlyIn((3, 0),
self.detect("""
from select import kqueue
kqueue().control(timeout=1)
"""))
def test_keyencoding_of_Shelf_from_shelve(self):
self.assertOnlyIn((3, 2),
self.detect("from shelve import Shelf\n"
"Shelf(keyencoding=None)"))
def test_protocol_of_Shelf_from_shelve(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shelve import Shelf\n"
"Shelf(protocol=None)"))
def test_protocol_of_open_from_shelve(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from shelve import open\n"
"open(protocol=None)"))
def test_follow_symlinks_of_copy_from_shutil(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import copy\n"
"copy(follow_symlinks=None)"))
def test_follow_symlinks_of_copy2_from_shutil(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import copy2\n"
"copy2(follow_symlinks=None)"))
def test_follow_symlinks_of_copyfile_from_shutil(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import copyfile\n"
"copyfile(follow_symlinks=None)"))
def test_follow_symlinks_of_copymode_from_shutil(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import copymode\n"
"copymode(follow_symlinks=None)"))
def test_follow_symlinks_of_copystat_from_shutil(self):
self.assertOnlyIn((3, 3),
self.detect("from shutil import copystat\n"
"copystat(follow_symlinks=None)"))
def test_copy_function_of_copytree_from_shutil(self):
self.assertOnlyIn((3, 2),
self.detect("from shutil import copytree\n"
"copytree(copy_function=None)"))
def test_dirs_exist_ok_of_copytree_from_shutil(self):
self.assertOnlyIn((3, 8),
self.detect("from shutil import copytree\n"
"copytree(dirs_exist_ok=None)"))
def test_ignore_of_copytree_from_shutil(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from shutil import copytree\n"
"copytree(ignore=None)"))
def test_ignore_dangling_symlinks_of_copytree_from_shutil(self):
self.assertOnlyIn((3, 2),
self.detect("from shutil import copytree\n"
"copytree(ignore_dangling_symlinks=None)"))
def test_copy_function_of_move_from_shutil(self):
self.assertOnlyIn((3, 5),
self.detect("from shutil import move\n"
"move(copy_function=None)"))
def test_dir_fd_of_rmtree_from_shutil(self):
self.assertOnlyIn((3, 11),
self.detect("from shutil import rmtree\n"
"rmtree(dir_fd=None)"))
def test_onexc_of_rmtree_from_shutil(self):
self.assertOnlyIn((3, 12),
self.detect("from shutil import rmtree\n"
"rmtree(onexc=None)"))
def test_filter_of_unpack_archive_from_shutil(self):
self.assertOnlyIn((3, 12),
self.detect("from shutil import unpack_archive\n"
"unpack_archive(filter=None)"))
def test_warn_on_full_buffer_of_set_wakeup_fd_from_signal(self):
self.assertOnlyIn((3, 7),
self.detect("from signal import set_wakeup_fd\n"
"set_wakeup_fd(warn_on_full_buffer=None)"))
def test_decode_data_of_SMTPChannel_from_smtpd(self):
self.assertOnlyIn((3, 5),
self.detect("from smtpd import SMTPChannel\n"
"SMTPChannel(decode_data=None)"))
def test_enable_SMTPUTF8_of_SMTPChannel_from_smtpd(self):
self.assertOnlyIn((3, 5),
self.detect("from smtpd import SMTPChannel\n"
"SMTPChannel(enable_SMTPUTF8=None)"))
def test_decode_data_of_SMTPServer_from_smtpd(self):
self.assertOnlyIn((3, 5),
self.detect("from smtpd import SMTPServer\n"
"SMTPServer(decode_data=None)"))
def test_enable_SMTPUTF8_of_SMTPServer_from_smtpd(self):
self.assertOnlyIn((3, 5),
self.detect("from smtpd import SMTPServer\n"
"SMTPServer(enable_SMTPUTF8=None)"))
def test_map_of_SMTPServer_from_smtpd(self):
self.assertOnlyIn((3, 4),
self.detect("from smtpd import SMTPServer\n"
"SMTPServer(map=None)"))
def test_source_address_of_create_connection_from_socket(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from socket import create_connection\n"
"create_connection(source_address=None)"))
def test_all_errors_of_create_connection_from_socket(self):
self.assertOnlyIn((3, 11),
self.detect("from socket import create_connection\n"
"create_connection(all_errors=None)"))
def test_optlen_of_setsockopt_from_socket(self):
self.assertOnlyIn((3, 6),
self.detect("from socket import setsockopt\n"
"setsockopt(optlen=None)"))
def test_autocommit_of_connect_from_sqlite3(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import connect\n"
"connect(autocommit=None)"))
def test_uri_of_connect_from_sqlite3(self):
self.assertOnlyIn((3, 4),
self.detect("from sqlite3 import connect\n"
"connect(uri=None)"))
def test_chars_of_lstrip_from_string(self):
self.assertOnlyIn((2, 3),
self.detect("from string import lstrip\n"
"lstrip(chars=None)"))
def test_chars_of_rstrip_from_string(self):
self.assertOnlyIn((2, 3),
self.detect("from string import rstrip\n"
"rstrip(chars=None)"))
def test_chars_of_strip_from_string(self):
self.assertOnlyIn((2, 3),
self.detect("from string import strip\n"
"strip(chars=None)"))
def test_encoding_of_TarFile_from_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarFile\n"
"TarFile(encoding=None)"))
def test_errors_of_TarFile_from_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarFile\n"
"TarFile(errors=None)"))
def test_format_of_TarFile_from_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarFile\n"
"TarFile(format=None)"))
def test_pax_headers_of_TarFile_from_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarFile\n"
"TarFile(pax_headers=None)"))
def test_stream_of_TarFile_from_tarfile(self):
self.assertOnlyIn((3, 13),
self.detect("from tarfile import TarFile\n"
"TarFile(stream=None)"))
def test_tarinfo_of_TarFile_from_tarfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tarfile import TarFile\n"
"TarFile(tarinfo=None)"))
def test_timeout_of_Telnet_from_telnetlib(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from telnetlib import Telnet\n"
"Telnet(timeout=None)"))
def test_delete_of_NamedTemporaryFile_from_tempfile(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from tempfile import NamedTemporaryFile\n"
"NamedTemporaryFile(delete=None)"))
def test_errors_of_NamedTemporaryFile_from_tempfile(self):
self.assertOnlyIn((3, 8),
self.detect("from tempfile import NamedTemporaryFile\n"
"NamedTemporaryFile(errors=None)"))
def test_delete_on_close_of_NamedTemporaryFile_from_tempfile(self):
self.assertOnlyIn((3, 12),
self.detect("from tempfile import NamedTemporaryFile\n"
"NamedTemporaryFile(delete_on_close=None)"))
def test_errors_of_SpooledTemporaryFile_from_tempfile(self):
self.assertOnlyIn((3, 8),
self.detect("from tempfile import SpooledTemporaryFile\n"
"SpooledTemporaryFile(errors=None)"))
def test_errors_of_TemporaryFile_from_tempfile(self):
self.assertOnlyIn((3, 8),
self.detect("from tempfile import TemporaryFile\n"
"TemporaryFile(errors=None)"))
def test_delete_of_TemporaryDirectory_from_tempfile(self):
self.assertOnlyIn((3, 12),
self.detect("from tempfile import TemporaryDirectory\n"
"TemporaryDirectory(delete=None)"))
def test_ignore_cleanup_errors_of_TemporaryDirectory_from_tempfile(self):
self.assertOnlyIn((3, 10),
self.detect("from tempfile import TemporaryDirectory\n"
"TemporaryDirectory(ignore_cleanup_errors=None)"))
def test_daemon_of_Thread_from_threading(self):
self.assertOnlyIn((3, 3),
self.detect("from threading import Thread\n"
"Thread(daemon=None)"))
def test_context_of_Thread_from_threading(self):
self.assertOnlyIn((3, 14),
self.detect("from threading import Thread\n"
"Thread(context=None)"))
def test_globals_of_Timer_from_timeit(self):
self.assertOnlyIn((3, 5),
self.detect("from timeit import Timer\n"
"Timer(globals=None)"))
def test_globals_of_repeat_from_timeit(self):
self.assertOnlyIn((3, 5),
self.detect("from timeit import repeat\n"
"repeat(globals=None)"))
def test_globals_of_timeit_from_timeit(self):
self.assertOnlyIn((3, 5),
self.detect("from timeit import timeit\n"
"timeit(globals=None)"))
def test_root_of_nametofont_from_tkinter_font(self):
self.assertOnlyIn((3, 10),
self.detect("from tkinter.font import nametofont\n"
"nametofont(root=None)"))
def test_tb_locals_of_TextTestRunner_from_unittest(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest import TextTestRunner\n"
"TextTestRunner(tb_locals=None)"))
def test_warnings_of_TextTestRunner_from_unittest(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import TextTestRunner\n"
"TextTestRunner(warnings=None)"))
def test_buffer_of_main_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import main\n"
"main(buffer=None)"))
def test_catchbreak_of_main_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import main\n"
"main(catchbreak=None)"))
def test_exit_of_main_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 1)),
self.detect("from unittest import main\n"
"main(exit=None)"))
def test_failfast_of_main_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import main\n"
"main(failfast=None)"))
def test_verbosity_of_main_from_unittest(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from unittest import main\n"
"main(verbosity=None)"))
def test_warnings_of_main_from_unittest(self):
self.assertOnlyIn((3, 2),
self.detect("from unittest import main\n"
"main(warnings=None)"))
def test_context_of_URLopener_from_urllib(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib import URLopener\n"
"URLopener(context=None)"))
def test_context_of_urlopen_from_urllib(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib import urlopen\n"
"urlopen(context=None)"))
def test_proxies_of_urlopen_from_urllib(self):
self.assertOnlyIn((2, 3),
self.detect("from urllib import urlopen\n"
"urlopen(proxies=None)"))
def test_context_of_urlretrieve_from_urllib(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib import urlretrieve\n"
"urlretrieve(context=None)"))
def test_context_of_HTTPSHandler_from_urllib2(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib2 import HTTPSHandler\n"
"HTTPSHandler(context=None)"))
def test_cadefault_of_urlopen_from_urllib2(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib2 import urlopen\n"
"urlopen(cadefault=None)"))
def test_cafile_of_urlopen_from_urllib2(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib2 import urlopen\n"
"urlopen(cafile=None)"))
def test_capth_of_urlopen_from_urllib2(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib2 import urlopen\n"
"urlopen(capth=None)"))
def test_context_of_urlopen_from_urllib2(self):
self.assertOnlyIn((2, 7),
self.detect("from urllib2 import urlopen\n"
"urlopen(context=None)"))
def test_timeout_of_urlopen_from_urllib2(self):
self.assertOnlyIn((2, 6),
self.detect("from urllib2 import urlopen\n"
"urlopen(timeout=None)"))
def test_max_num_fields_of_parse_qs_from_urlparse(self):
self.assertOnlyIn((2, 7),
self.detect("from urlparse import parse_qs\n"
"parse_qs(max_num_fields=None)"))
def test_max_num_fields_of_parse_qsl_from_urlparse(self):
self.assertOnlyIn((2, 7),
self.detect("from urlparse import parse_qsl\n"
"parse_qsl(max_num_fields=None)"))
def test_backtick_of_encode_from_uu(self):
self.assertOnlyIn((3, 7),
self.detect("from uu import encode\n"
"encode(backtick=None)"))
def test_action_of_catch_warnings_from_warnings(self):
self.assertOnlyIn((3, 11),
self.detect("from warnings import catch_warnings\n"
"catch_warnings(action=None)"))
def test_append_of_catch_warnings_from_warnings(self):
self.assertOnlyIn((3, 11),
self.detect("from warnings import catch_warnings\n"
"catch_warnings(append=None)"))
def test_category_of_catch_warnings_from_warnings(self):
self.assertOnlyIn((3, 11),
self.detect("from warnings import catch_warnings\n"
"catch_warnings(category=None)"))
def test_lineno_of_catch_warnings_from_warnings(self):
self.assertOnlyIn((3, 11),
self.detect("from warnings import catch_warnings\n"
"catch_warnings(lineno=None)"))
def test_line_of_showwarning_from_warnings(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from warnings import showwarning\n"
"showwarning(line=None)"))
def test_preferred_of_register_from_webbrowser(self):
self.assertOnlyIn((3, 7),
self.detect("from webbrowser import register\n"
"register(preferred=None)"))
def test_key_of_OpenKey_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKey\n"
"OpenKey(key=None)"))
def test_sub_key_of_OpenKey_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKey\n"
"OpenKey(sub_key=None)"))
def test_reserved_of_OpenKey_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKey\n"
"OpenKey(reserved=None)"))
def test_access_of_OpenKey_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKey\n"
"OpenKey(access=None)"))
def test_key_of_OpenKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKeyEx\n"
"OpenKeyEx(key=None)"))
def test_sub_key_of_OpenKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKeyEx\n"
"OpenKeyEx(sub_key=None)"))
def test_reserved_of_OpenKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKeyEx\n"
"OpenKeyEx(reserved=None)"))
def test_access_of_OpenKeyEx_from_winreg(self):
self.assertOnlyIn((3, 2),
self.detect("from winreg import OpenKeyEx\n"
"OpenKeyEx(access=None)"))
def test_compresslevel_of_ZipFile_from_zipfile(self):
self.assertOnlyIn((3, 7),
self.detect("from zipfile import ZipFile\n"
"ZipFile(compresslevel=None)"))
def test_metadata_encoding_of_ZipFile_from_zipfile(self):
self.assertOnlyIn((3, 11),
self.detect("from zipfile import ZipFile\n"
"ZipFile(metadata_encoding=None)"))
def test_strict_timestamps_of_ZipFile_from_zipfile(self):
self.assertOnlyIn((3, 8),
self.detect("from zipfile import ZipFile\n"
"ZipFile(strict_timestamps=None)"))
def test_level_of_compress_from_zlib(self):
self.assertOnlyIn((3, 6),
self.detect("from zlib import compress\n"
"compress(level=None)"))
def test_wbits_of_compress_from_zlib(self):
self.assertOnlyIn((3, 11),
self.detect("from zlib import compress\n"
"compress(wbits=None)"))
def test_zdict_of_compressobj_from_zlib(self):
self.assertOnlyIn((3, 3),
self.detect("from zlib import compressobj\n"
"compressobj(zdict=None)"))
def test_bufsize_of_decompress_from_zlib(self):
self.assertOnlyIn((3, 6),
self.detect("from zlib import decompress\n"
"decompress(bufsize=None)"))
def test_wbits_of_decompress_from_zlib(self):
self.assertOnlyIn((3, 6),
self.detect("from zlib import decompress\n"
"decompress(wbits=None)"))
def test_zdict_of_decompressobj_from_zlib(self):
self.assertOnlyIn((3, 3),
self.detect("from zlib import decompressobj\n"
"decompressobj(zdict=None)"))
def test_policy_of_Message_from_email_message(self):
self.assertOnlyIn((3, 3),
self.detect("from email.message import Message\n"
"Message(policy=None)"))
def test_policy_of_BytesParser_from_email_parser(self):
self.assertOnlyIn((3, 3),
self.detect("from email.parser import BytesParser\n"
"BytesParser(policy=None)"))
def test_policy_of_Parser_from_email_parser(self):
self.assertOnlyIn((3, 3),
self.detect("from email.parser import Parser\n"
"Parser(policy=None)"))
def test_headersonly_of_parse_from_email_parser_Parser(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.parser import Parser\n"
"Parser().parse(headersonly=None)"))
def test_headersonly_of_parsestr_from_email_parser_Parser(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.parser import Parser\n"
"Parser().parsestr(headersonly=None)"))
def test_mangle_from__of_Policy_from_email_policy(self):
self.assertOnlyIn((3, 5),
self.detect("from email.policy import Policy\n"
"Policy(mangle_from_=None)"))
def test_convert_charrefs_of_HTMLParser_from_html_parser(self):
self.assertOnlyIn((3, 4),
self.detect("from html.parser import HTMLParser\n"
"HTMLParser(convert_charrefs=None)"))
def test_blocksize_of_HTTPConnection_from_http_client(self):
self.assertOnlyIn((3, 7),
self.detect("from http.client import HTTPConnection\n"
"HTTPConnection(blocksize=None)"))
def test_source_address_of_HTTPConnection_from_http_client(self):
self.assertOnlyIn((3, 2),
self.detect("from http.client import HTTPConnection\n"
"HTTPConnection(source_address=None)"))
def test_check_hostname_of_HTTPSConnection_from_http_client(self):
self.assertOnlyIn((3, 2),
self.detect("from http.client import HTTPSConnection\n"
"HTTPSConnection(check_hostname=None)"))
def test_context_of_HTTPSConnection_from_http_client(self):
self.assertOnlyIn((3, 2),
self.detect("from http.client import HTTPSConnection\n"
"HTTPSConnection(context=None)"))
def test_source_address_of_HTTPSConnection_from_http_client(self):
self.assertOnlyIn((3, 2),
self.detect("from http.client import HTTPSConnection\n"
"HTTPSConnection(source_address=None)"))
def test_disable_existing_loggers_of_fileConfig_from_logging_config(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging.config import fileConfig\n"
"fileConfig(disable_existing_loggers=None)"))
def test_encoding_of_fileConfig_from_logging_config(self):
self.assertOnlyIn((3, 10),
self.detect("from logging.config import fileConfig\n"
"fileConfig(encoding=None)"))
def test_verify_of_listen_from_logging_config(self):
self.assertOnlyIn((3, 4),
self.detect("from logging.config import listen\n"
"listen(verify=None)"))
def test_context_of_HTTPHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 5),
self.detect("from logging.handlers import HTTPHandler\n"
"HTTPHandler(context=None)"))
def test_flushOnClose_of_MemoryHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 6),
self.detect("from logging.handlers import MemoryHandler\n"
"MemoryHandler(flushOnClose=None)"))
def test_respect_handler_level_of_QueueListener_from_logging_handlers(self):
self.assertOnlyIn((3, 5),
self.detect("from logging.handlers import QueueListener\n"
"QueueListener(respect_handler_level=None)"))
def test_delay_of_RotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging.handlers import RotatingFileHandler\n"
"RotatingFileHandler(delay=None)"))
def test_credentials_of_SMTPHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging.handlers import SMTPHandler\n"
"SMTPHandler(credentials=None)"))
def test_secure_of_SMTPHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 7), (3, 0)),
self.detect("from logging.handlers import SMTPHandler\n"
"SMTPHandler(secure=None)"))
def test_timeout_of_SMTPHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 3),
self.detect("from logging.handlers import SMTPHandler\n"
"SMTPHandler(timeout=None)"))
def test_socktype_of_SysLogHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from logging.handlers import SysLogHandler\n"
"SysLogHandler(socktype=None)"))
def test_timeout_of_SysLogHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 14),
self.detect("from logging.handlers import SysLogHandler\n"
"SysLogHandler(timeout=None)"))
def test_atTime_of_TimedRotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 4),
self.detect("from logging.handlers import TimedRotatingFileHandler\n"
"TimedRotatingFileHandler(atTime=None)"))
def test_delay_of_TimedRotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging.handlers import TimedRotatingFileHandler\n"
"TimedRotatingFileHandler(delay=None)"))
def test_utc_of_TimedRotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from logging.handlers import TimedRotatingFileHandler\n"
"TimedRotatingFileHandler(utc=None)"))
def test_context_of_Pool_from_multiprocessing_pool(self):
self.assertOnlyIn((3, 4),
self.detect("from multiprocessing.pool import Pool\n"
"Pool(context=None)"))
def test_shutdown_timeout_of_BaseManager_from_multiprocessing_managers(self):
self.assertOnlyIn((3, 11),
self.detect("from multiprocessing.managers import BaseManager\n"
"BaseManager(shutdown_timeout=None)"))
def test_maxtasksperchild_of_Pool_from_multiprocessing_pool(self):
self.assertOnlyIn((3, 2),
self.detect("from multiprocessing.pool import Pool\n"
"Pool(maxtasksperchild=None)"))
def test_quiet_of_check_warnings_from_test_support(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from test.support import check_warnings\n"
"check_warnings(quiet=None)"))
def test_encoding_of_parse_qs_from_urllib_parse(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.parse import parse_qs\n"
"parse_qs(encoding=None)"))
def test_errors_of_parse_qs_from_urllib_parse(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.parse import parse_qs\n"
"parse_qs(errors=None)"))
def test_max_num_fields_of_parse_qs_from_urllib_parse(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.parse import parse_qs\n"
"parse_qs(max_num_fields=None)"))
def test_separator_of_parse_qs_from_urllib_parse(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.parse import parse_qs\n"
"parse_qs(separator=None)"))
def test_encoding_of_parse_qsl_from_urllib_parse(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.parse import parse_qsl\n"
"parse_qsl(encoding=None)"))
def test_errors_of_parse_qsl_from_urllib_parse(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.parse import parse_qsl\n"
"parse_qsl(errors=None)"))
def test_max_num_fields_of_parse_qsl_from_urllib_parse(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.parse import parse_qsl\n"
"parse_qsl(max_num_fields=None)"))
def test_separator_of_parse_qsl_from_urllib_parse(self):
self.assertOnlyIn((3, 6),
self.detect("from urllib.parse import parse_qsl\n"
"parse_qsl(separator=None)"))
def test_quote_via_of_urlencode_from_urllib_parse(self):
self.assertOnlyIn((3, 5),
self.detect("from urllib.parse import urlencode\n"
"urlencode(quote_via=None)"))
def test_check_hostname_of_HTTPSHandler_from_urllib_request(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.request import HTTPSHandler\n"
"HTTPSHandler(check_hostname=None)"))
def test_context_of_HTTPSHandler_from_urllib_request(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.request import HTTPSHandler\n"
"HTTPSHandler(context=None)"))
def test_method_of_Request_from_urllib_request(self):
self.assertOnlyIn((3, 3),
self.detect("from urllib.request import Request\n"
"Request(method=None)"))
def test_cadefault_of_urlopen_from_urllib_request(self):
self.assertOnlyIn((3, 3),
self.detect("from urllib.request import urlopen\n"
"urlopen(cadefault=None)"))
def test_cafile_of_urlopen_from_urllib_request(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.request import urlopen\n"
"urlopen(cafile=None)"))
def test_capath_of_urlopen_from_urllib_request(self):
self.assertOnlyIn((3, 2),
self.detect("from urllib.request import urlopen\n"
"urlopen(capath=None)"))
def test_context_of_urlopen_from_urllib_request(self):
self.assertOnlyIn((3, 4),
self.detect("from urllib.request import urlopen\n"
"urlopen(context=None)"))
def test_add_scheme_of_pathname2url_from_urllib_request(self):
self.assertOnlyIn((3, 14),
self.detect("from urllib.request import pathname2url\n"
"pathname2url(add_scheme=None)"))
def test_require_scheme_of_url2pathname_from_urllib_request(self):
self.assertOnlyIn((3, 14),
self.detect("from urllib.request import url2pathname\n"
"url2pathname(require_scheme=None)"))
def test_resolve_host_of_url2pathname_from_urllib_request(self):
self.assertOnlyIn((3, 14),
self.detect("from urllib.request import url2pathname\n"
"url2pathname(resolve_host=None)"))
def test_context_of_ServerProxy_from_xmlrpc_client(self):
self.assertOnlyIn((3, 4),
self.detect("from xmlrpc.client import ServerProxy\n"
"ServerProxy(context=None)"))
def test_headers_of_ServerProxy_from_xmlrpc_client(self):
self.assertOnlyIn((3, 8),
self.detect("from xmlrpc.client import ServerProxy\n"
"ServerProxy(headers=None)"))
def test_use_builtin_types_of_ServerProxy_from_xmlrpc_client(self):
self.assertOnlyIn((3, 3),
self.detect("from xmlrpc.client import ServerProxy\n"
"ServerProxy(use_builtin_types=None)"))
def test_use_builtin_types_of_loads_from_xmlrpc_client(self):
self.assertOnlyIn((3, 3),
self.detect("from xmlrpc.client import loads\n"
"loads(use_builtin_types=None)"))
def test_short_empty_elements_of_XMLGenerator_from_xml_sax_saxutils(self):
self.assertOnlyIn((3, 2),
self.detect("from xml.sax.saxutils import XMLGenerator\n"
"XMLGenerator(short_empty_elements=None)"))
def test_timestamp_of_date_time_string_from_BaseHTTPServer_BaseHTTPRequestHandler(self):
self.assertOnlyIn((2, 5),
self.detect("from BaseHTTPServer import BaseHTTPRequestHandler\n"
"x = BaseHTTPRequestHandler()\n"
"x.date_time_string(timestamp=None)"))
def test_timeout_of_get_from_Queue_Queue(self):
self.assertOnlyIn((2, 3),
self.detect("from Queue import Queue\n"
"x = Queue()\n"
"x.get(timeout=None)"))
def test_timeout_of_put_from_Queue_Queue(self):
self.assertOnlyIn((2, 3),
self.detect("from Queue import Queue\n"
"x = Queue()\n"
"x.put(timeout=None)"))
def test_timeout_of_acquire_from__thread_lock(self):
self.assertOnlyIn((3, 2),
self.detect("from _thread import lock\n"
"x = lock()\n"
"x.acquire(timeout=None)"))
def test_required_of_add_subparsers_from_argparse_ArgumentParser(self):
self.assertOnlyIn((3, 7),
self.detect("from argparse import ArgumentParser\n"
"x = ArgumentParser()\n"
"x.add_subparsers(required=None)"))
def test_context_of_add_done_callback_from_asyncio_Future(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import Future\n"
"x = Future()\n"
"x.add_done_callback(context=None)"))
def test_context_of_call_at_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.call_at(context=None)"))
def test_context_of_call_later_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.call_later(context=None)"))
def test_context_of_call_soon_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.call_soon(context=None)"))
def test_context_of_call_soon_threadsafe_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.call_soon_threadsafe(context=None)"))
def test_ssl_handshake_timeout_of_connect_accepted_socket_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.connect_accepted_socket(ssl_handshake_timeout=None)"))
def test_ssl_shutdown_timeout_of_connect_accepted_socket_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.connect_accepted_socket(ssl_shutdown_timeout=None)"))
def test_happy_eyeballs_delay_of_create_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_connection(happy_eyeballs_delay=None)"))
def test_interleave_of_create_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_connection(interleave=None)"))
def test_ssl_handshake_timeout_of_create_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_connection(ssl_handshake_timeout=None)"))
def test_ssl_shutdown_timeout_of_create_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_connection(ssl_shutdown_timeout=None)"))
def test_allow_broadcast_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(allow_broadcast=None)"))
def test_family_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(family=None)"))
def test_flags_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(flags=None)"))
def test_proto_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(proto=None)"))
def test_reuse_address_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(reuse_address=None)"))
def test_reuse_port_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(reuse_port=None)"))
def test_sock_of_create_datagram_endpoint_from_asyncio_loop(self):
self.assertOnlyIn((3, 4),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_datagram_endpoint(sock=None)"))
def test_ssl_handshake_timeout_of_create_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 6),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_server(ssl_handshake_timeout=None)"))
def test_ssl_shutdown_timeout_of_create_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_server(ssl_shutdown_timeout=None)"))
def test_start_serving_of_create_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 6),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_server(start_serving=None)"))
def test_name_of_create_task_from_asyncio_loop(self):
self.assertOnlyIn((3, 8),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_task(name=None)"))
def test_context_of_create_task_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_task(context=None)"))
def test_ssl_handshake_timeout_of_create_unix_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_connection(ssl_handshake_timeout=None)"))
def test_ssl_shutdown_timeout_of_create_unix_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_connection(ssl_shutdown_timeout=None)"))
def test_path_of_create_unix_connection_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_connection(path=None)"))
def test_ssl_handshake_timeout_of_create_unix_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_server(ssl_handshake_timeout=None)"))
def test_start_serving_of_create_unix_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_server(start_serving=None)"))
def test_path_of_create_unix_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 7),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_server(path=None)"))
def test_ssl_shutdown_timeout_of_create_unix_server_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.create_unix_server(ssl_shutdown_timeout=None)"))
def test_ssl_shutdown_timeout_of_start_tls_from_asyncio_loop(self):
self.assertOnlyIn((3, 11),
self.detect("from asyncio import loop\n"
"x = loop()\n"
"x.start_tls(ssl_shutdown_timeout=None)"))
def test_chars_of_read_from_codecs_StreamReader(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from codecs import StreamReader\n"
"x = StreamReader()\n"
"x.read(chars=None)"))
def test_firstline_of_read_from_codecs_StreamReader(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from codecs import StreamReader\n"
"x = StreamReader()\n"
"x.read(firstline=None)"))
def test_keepends_of_readline_from_codecs_StreamReader(self):
self.assertOnlyIn(((2, 4), (3, 0)),
self.detect("from codecs import StreamReader\n"
"x = StreamReader()\n"
"x.readline(keepends=None)"))
def test_encoding_of_read_from_configparser_ConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import ConfigParser\n"
"x = ConfigParser()\n"
"x.read(encoding=None)"))
def test_encoding_of_read_from_configparser_RawConfigParser(self):
self.assertOnlyIn((3, 2),
self.detect("from configparser import RawConfigParser\n"
"x = RawConfigParser()\n"
"x.read(encoding=None)"))
def test_source_address_of_connect_from_ftplib_FTP(self):
self.assertOnlyIn((3, 3),
self.detect("from ftplib import FTP\n"
"x = FTP()\n"
"x.connect(source_address=None)"))
def test_timeout_of_connect_from_ftplib_FTP(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from ftplib import FTP\n"
"x = FTP()\n"
"x.connect(timeout=None)"))
def test_callback_of_storbinary_from_ftplib_FTP(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from ftplib import FTP\n"
"x = FTP()\n"
"x.storbinary(callback=None)"))
def test_rest_of_storbinary_from_ftplib_FTP(self):
self.assertOnlyIn(((2, 7), (3, 2)),
self.detect("from ftplib import FTP\n"
"x = FTP()\n"
"x.storbinary(rest=None)"))
def test_callback_of_storlines_from_ftplib_FTP(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from ftplib import FTP\n"
"x = FTP()\n"
"x.storlines(callback=None)"))
def test_names_of_install_from_gettext_NullTranslations(self):
self.assertOnlyIn(((2, 5), (3, 0)),
self.detect("from gettext import NullTranslations\n"
"x = NullTranslations()\n"
"x.install(names=None)"))
def test_message_body_of_endheaders_from_httplib_HTTPConnection(self):
self.assertOnlyIn((2, 7),
self.detect("from httplib import HTTPConnection\n"
"x = HTTPConnection()\n"
"x.endheaders(message_body=None)"))
def test_skip_accept_encoding_of_putrequest_from_httplib_HTTPConnection(self):
self.assertOnlyIn((2, 4),
self.detect("from httplib import HTTPConnection\n"
"x = HTTPConnection()\n"
"x.putrequest(skip_accept_encoding=None)"))
def test_stack_info_of_critical_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.critical(stack_info=None)"))
def test_stacklevel_of_critical_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.critical(stacklevel=None)"))
def test_stack_info_of_debug_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.debug(stack_info=None)"))
def test_stacklevel_of_debug_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.debug(stacklevel=None)"))
def test_stack_info_of_error_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.error(stack_info=None)"))
def test_stacklevel_of_error_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.error(stacklevel=None)"))
def test_stack_info_of_exception_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.exception(stack_info=None)"))
def test_stacklevel_of_exception_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.exception(stacklevel=None)"))
def test_stack_info_of_info_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.info(stack_info=None)"))
def test_stacklevel_of_info_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.info(stacklevel=None)"))
def test_stack_info_of_log_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.log(stack_info=None)"))
def test_stacklevel_of_log_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.log(stacklevel=None)"))
def test_stack_info_of_warn_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.warn(stack_info=None)"))
def test_stacklevel_of_warn_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.warn(stacklevel=None)"))
def test_stack_info_of_warning_from_logging_Logger(self):
self.assertOnlyIn((3, 2),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.warning(stack_info=None)"))
def test_stacklevel_of_warning_from_logging_Logger(self):
self.assertOnlyIn((3, 8),
self.detect("from logging import Logger\n"
"x = Logger()\n"
"x.warning(stacklevel=None)"))
def test_max_length_of_decompress_from_lzma_LZMADecompressor(self):
self.assertOnlyIn((3, 5),
self.detect("from lzma import LZMADecompressor\n"
"x = LZMADecompressor()\n"
"x.decompress(max_length=None)"))
def test_group_pattern_of_list_from_nntplib_NNTP(self):
self.assertOnlyIn((3, 2),
self.detect("from nntplib import NNTP\n"
"x = NNTP()\n"
"x.list(group_pattern=None)"))
def test_missing_ok_of_unlink_from_pathlib_Path(self):
self.assertOnlyIn((3, 8),
self.detect("from pathlib import Path\n"
"x = Path()\n"
"x.unlink(missing_ok=None)"))
def test_kwargs_of_enter_from_sched_scheduler(self):
self.assertOnlyIn((3, 3),
self.detect("from sched import scheduler\n"
"x = scheduler()\n"
"x.enter(kwargs=None)"))
def test_kwargs_of_enterabs_from_sched_scheduler(self):
self.assertOnlyIn((3, 3),
self.detect("from sched import scheduler\n"
"x = scheduler()\n"
"x.enterabs(kwargs=None)"))
def test_blocking_of_run_from_sched_scheduler(self):
self.assertOnlyIn((3, 3),
self.detect("from sched import scheduler\n"
"x = scheduler()\n"
"x.run(blocking=None)"))
def test_initial_response_ok_of_login_from_smtplib_SMTP(self):
self.assertOnlyIn((3, 5),
self.detect("from smtplib import SMTP\n"
"x = SMTP()\n"
"x.login(initial_response_ok=None)"))
def test_deterministic_of_create_function_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 8),
self.detect("from sqlite3 import Connection\n"
"x = Connection()\n"
"x.create_function(deterministic=None)"))
def test_entrypoint_of_load_extension_from_sqlite3_Connection(self):
self.assertOnlyIn((3, 12),
self.detect("from sqlite3 import Connection\n"
"x = Connection()\n"
"x.load_extension(entrypoint=None)"))
def test_session_of_wrap_bio_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 6),
self.detect("from ssl import SSLContext\n"
"x = SSLContext()\n"
"x.wrap_bio(session=None)"))
def test_session_of_wrap_socket_from_ssl_SSLContext(self):
self.assertOnlyIn((3, 6),
self.detect("from ssl import SSLContext\n"
"x = SSLContext()\n"
"x.wrap_socket(session=None)"))
def test_timeout_of_get_server_certificate_from_ssl(self):
self.assertOnlyIn((3, 10), self.detect("""
from ssl import get_server_certificate
get_server_certificate(timeout=None)
"""))
def test_timeout_of_open_from_telnetlib_Telnet(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from telnetlib import Telnet\n"
"x = Telnet()\n"
"x.open(timeout=None)"))
def test_size_of_truncate_from_tempfile_SpooledTemporaryFile(self):
self.assertOnlyIn((3, 3),
self.detect("from tempfile import SpooledTemporaryFile\n"
"x = SpooledTemporaryFile()\n"
"x.truncate(size=None)"))
def test_timeout_of_acquire_from_threading_Lock(self):
self.assertOnlyIn((3, 2),
self.detect("from threading import Lock\n"
"x = Lock()\n"
"x.acquire(timeout=None)"))
def test_blocking_of_acquire_from_threading_Lock(self):
self.assertOnlyIn((3, 0),
self.detect("from threading import Lock\n"
"x = Lock()\n"
"x.acquire(blocking=None)"))
def test_timeout_of_acquire_from_threading_RLock(self):
self.assertOnlyIn((3, 2),
self.detect("from threading import RLock\n"
"x = RLock()\n"
"x.acquire(timeout=None)"))
def test_blocking_of_acquire_from_threading_RLock(self):
self.assertOnlyIn((3, 0),
self.detect("from threading import RLock\n"
"x = RLock()\n"
"x.acquire(blocking=None)"))
def test_timeout_of_acquire_from_threading_Semaphore(self):
self.assertOnlyIn((3, 2),
self.detect("from threading import Semaphore\n"
"x = Semaphore()\n"
"x.acquire(timeout=None)"))
def test_msg_of_assertRaises_from_unittest_TestCase(self):
self.assertOnlyIn((3, 3),
self.detect("from unittest import TestCase\n"
"x = TestCase()\n"
"x.assertRaises(msg=None)"))
def test_msg_of_assertRaisesRegex_from_unittest_TestCase(self):
self.assertOnlyIn((3, 3),
self.detect("from unittest import TestCase\n"
"x = TestCase()\n"
"x.assertRaisesRegex(msg=None)"))
def test_msg_of_assertWarns_from_unittest_TestCase(self):
self.assertOnlyIn((3, 3),
self.detect("from unittest import TestCase\n"
"x = TestCase()\n"
"x.assertWarns(msg=None)"))
def test_msg_of_assertWarnsRegex_from_unittest_TestCase(self):
self.assertOnlyIn((3, 3),
self.detect("from unittest import TestCase\n"
"x = TestCase()\n"
"x.assertWarnsRegex(msg=None)"))
def test_pattern_of_loadTestsFromModule_from_unittest_TestLoader(self):
self.assertOnlyIn((3, 5),
self.detect("from unittest import TestLoader\n"
"x = TestLoader()\n"
"x.loadTestsFromModule(pattern=None)"))
def test_timeout_of_open_from_urllib2_OpenerDirector(self):
self.assertOnlyIn((2, 6),
self.detect("from urllib2 import OpenerDirector\n"
"x = OpenerDirector()\n"
"x.open(timeout=None)"))
def test_strict_timestamps_of_from_file_from_zipfile_ZipInfo(self):
self.assertOnlyIn((3, 8),
self.detect("from zipfile import ZipInfo\n"
"x = ZipInfo()\n"
"x.from_file(strict_timestamps=None)"))
def test_max_length_of_decompress_from_zlib_Decompress(self):
self.assertOnlyIn((3, 6),
self.detect("from zlib import Decompress\n"
"x = Decompress()\n"
"x.decompress(max_length=None)"))
def test_replace_of_set_param_from_email_message_EmailMessage(self):
self.assertOnlyIn((3, 4),
self.detect("from email.message import EmailMessage\n"
"x = EmailMessage()\n"
"x.set_param(replace=None)"))
def test_policy_of_as_string_from_email_message_Message(self):
self.assertOnlyIn((3, 4),
self.detect("from email.message import Message\n"
"x = Message()\n"
"x.as_string(policy=None)"))
def test_unquote_of_get_param_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"x = Message()\n"
"x.get_param(unquote=None)"))
def test_unquote_of_get_params_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"x = Message()\n"
"x.get_params(unquote=None)"))
def test_replace_of_set_param_from_email_message_Message(self):
self.assertOnlyIn((3, 4),
self.detect("from email.message import Message\n"
"x = Message()\n"
"x.set_param(replace=None)"))
def test_charset_of_set_payload_from_email_message_Message(self):
self.assertOnlyIn(((2, 2), (3, 0)),
self.detect("from email.message import Message\n"
"x = Message()\n"
"x.set_payload(charset=None)"))
def test_encode_chunked_of_endheaders_from_http_client_HTTPConnection(self):
self.assertOnlyIn((3, 6),
self.detect("from http.client import HTTPConnection\n"
"x = HTTPConnection()\n"
"x.endheaders(encode_chunked=None)"))
def test_encode_chunked_of_request_from_http_client_HTTPConnection(self):
self.assertOnlyIn((3, 6),
self.detect("from http.client import HTTPConnection\n"
"x = HTTPConnection()\n"
"x.request(encode_chunked=None)"))
def test_explain_of_send_error_from_http_server_BaseHTTPRequestHandler(self):
self.assertOnlyIn((3, 4),
self.detect("from http.server import BaseHTTPRequestHandler\n"
"x = BaseHTTPRequestHandler()\n"
"x.send_error(explain=None)"))
def test_directory_of_SimpleHTTPRequestHandler_from_http_server(self):
self.assertOnlyIn((3, 7),
self.detect("from http.server import SimpleHTTPRequestHandler\n"
"SimpleHTTPRequestHandler(directory=None)"))
def test_return_value_of_reset_mock_from_unittest_mock_Mock(self):
self.assertOnlyIn((3, 6),
self.detect("from unittest.mock import Mock\n"
"x = Mock()\n"
"x.reset_mock(return_value=None)"))
def test_side_effect_of_reset_mock_from_unittest_mock_Mock(self):
self.assertOnlyIn((3, 6),
self.detect("from unittest.mock import Mock\n"
"x = Mock()\n"
"x.reset_mock(side_effect=None)"))
def test_encoding_of_writexml_from_xml_dom_minidom_Document(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.dom.minidom import Document\n"
"x = Document()\n"
"x.writexml(encoding=None)"))
def test_encoding_of_toprettyxml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.toprettyxml(encoding=None)"))
def test_standalone_of_toprettyxml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.toprettyxml(standalone=None)"))
def test_encoding_of_toxml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 3), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.toxml(encoding=None)"))
def test_standalone_of_toxml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.toxml(standalone=None)"))
def test_addindent_of_writexml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.writexml(addindent=None)"))
def test_indent_of_writexml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.writexml(indent=None)"))
def test_newl_of_writexml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn(((2, 1), (3, 0)),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.writexml(newl=None)"))
def test_standalone_of_writexml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.writexml(standalone=None)"))
def test_encoding_of_writexml_from_xml_dom_minidom_Node(self):
self.assertOnlyIn((3, 0),
self.detect("from xml.dom.minidom import Node\n"
"x = Node()\n"
"x.writexml(encoding=None)"))
def test_short_empty_elements_of_write_from_xml_etree_ElementTree_ElementTree(self):
self.assertOnlyIn((3, 4),
self.detect("from xml.etree.ElementTree import ElementTree\n"
"x = ElementTree()\n"
"x.write(short_empty_elements=None)"))
def test_indent_of_dump_from_ast(self):
self.assertOnlyIn((3, 9),
self.detect("from ast import dump\n"
"dump(indent=None)"))
def test_include_extras_of_get_type_hints_from_typing(self):
self.assertOnlyIn((3, 9),
self.detect("from typing import get_type_hints\n"
"get_type_hints(include_extras=None)"))
def test_base_url_of_include_from_xml_etree_ElementInclude(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.etree import ElementInclude\n"
"x = ElementInclude()\n"
"x.include(base_url=None)"))
def test_max_depth_of_include_from_xml_etree_ElementInclude(self):
self.assertOnlyIn((3, 9),
self.detect("from xml.etree import ElementInclude\n"
"x = ElementInclude()\n"
"x.include(max_depth=None)"))
def test_msg_of_cancel_from_asyncio_Task(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Task\n"
"x = Task()\n"
"x.cancel(msg=None)"))
def test_usedforsecurity_of_new_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import new\n"
"new(usedforsecurity=None)"))
def test_usedforsecurity_of_blake2b_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import blake2b\n"
"blake2b(usedforsecurity=None)"))
def test_usedforsecurity_of_blake2s_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import blake2s\n"
"blake2s(usedforsecurity=None)"))
def test_usedforsecurity_of_md5_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import md5\n"
"md5(usedforsecurity=None)"))
def test_usedforsecurity_of_sha1_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha1\n"
"sha1(usedforsecurity=None)"))
def test_usedforsecurity_of_sha224_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha224\n"
"sha224(usedforsecurity=None)"))
def test_usedforsecurity_of_sha256_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha256\n"
"sha256(usedforsecurity=None)"))
def test_usedforsecurity_of_sha384_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha384\n"
"sha384(usedforsecurity=None)"))
def test_usedforsecurity_of_sha512_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha512\n"
"sha512(usedforsecurity=None)"))
def test_usedforsecurity_of_sha3_224_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha3_224\n"
"sha3_224(usedforsecurity=None)"))
def test_usedforsecurity_of_sha3_256_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha3_256\n"
"sha3_256(usedforsecurity=None)"))
def test_usedforsecurity_of_sha3_384_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha3_384\n"
"sha3_384(usedforsecurity=None)"))
def test_usedforsecurity_of_sha3_512_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import sha3_512\n"
"sha3_512(usedforsecurity=None)"))
def test_usedforsecurity_of_shake_128_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import shake_128\n"
"shake_128(usedforsecurity=None)"))
def test_usedforsecurity_of_shake_256_from_hashlib(self):
self.assertOnlyIn((3, 9),
self.detect("from hashlib import shake_256\n"
"shake_256(usedforsecurity=None)"))
def test_counts_of_sample_from_random(self):
self.assertOnlyIn((3, 9),
self.detect("from random import sample\n"
"sample(counts=None)"))
def test_encoding_of_FTP_from_ftplib(self):
self.assertOnlyIn((3, 9),
self.detect("from ftplib import FTP\n"
"FTP(encoding=None)"))
def test_encoding_of_FTP_TLS_from_ftplib(self):
self.assertOnlyIn((3, 9),
self.detect("from ftplib import FTP_TLS\n"
"FTP_TLS(encoding=None)"))
def test_recursive_of_iglob_from_glob(self):
self.assertOnlyIn((3, 5),
self.detect("from glob import iglob\n"
"iglob(recursive=None)"))
def test_encoding_of_basicConfig_from_logging(self):
self.assertOnlyIn((3, 9),
self.detect("from logging import basicConfig\n"
"basicConfig(encoding=None)"))
def test_errors_of_basicConfig_from_logging(self):
self.assertOnlyIn((3, 9),
self.detect("from logging import basicConfig\n"
"basicConfig(errors=None)"))
def test_errors_of_RotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 9),
self.detect("from logging.handlers import RotatingFileHandler\n"
"RotatingFileHandler(errors=None)"))
def test_errors_of_TimedRotatingFileHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 9),
self.detect("from logging.handlers import TimedRotatingFileHandler\n"
"TimedRotatingFileHandler(errors=None)"))
def test_errors_of_WatchedFileHandler_from_logging_handlers(self):
self.assertOnlyIn((3, 9),
self.detect("from logging.handlers import WatchedFileHandler\n"
"WatchedFileHandler(errors=None)"))
def test_in_fd_of_sendfile_from_os(self):
self.assertOnlyIn((3, 9),
self.detect("from os import sendfile\n"
"sendfile(in_fd=None)"))
def test_out_fd_of_sendfile_from_os(self):
self.assertOnlyIn((3, 9),
self.detect("from os import sendfile\n"
"sendfile(out_fd=None)"))
def test_extra_groups_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import Popen\n"
"Popen(extra_groups=None)"))
def test_group_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import Popen\n"
"Popen(group=None)"))
def test_umask_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import Popen\n"
"Popen(umask=None)"))
def test_user_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import Popen\n"
"Popen(user=None)"))
def test_pipesize_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 10),
self.detect("from subprocess import Popen\n"
"Popen(pipesize=None)"))
def test_process_group_of_Popen_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("from subprocess import Popen\n"
"Popen(process_group=None)"))
def test_process_group_of_call_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("from subprocess import call\n"
"call(process_group=None)"))
def test_process_group_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("from subprocess import check_call\n"
"check_call(process_group=None)"))
def test_process_group_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 11),
self.detect("from subprocess import check_output\n"
"check_output(process_group=None)"))
def test_encoding_of_call_from_subprocess(self):
self.assertOnlyIn((3, 6),
self.detect("from subprocess import call\n"
"call(encoding=None)"))
def test_errors_of_call_from_subprocess(self):
self.assertOnlyIn((3, 6),
self.detect("from subprocess import call\n"
"call(errors=None)"))
def test_extra_groups_of_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import call\n"
"call(extra_groups=None)"))
def test_group_of_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import call\n"
"call(group=None)"))
def test_pass_fds_of_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import call\n"
"call(pass_fds=None)"))
def test_restore_signals_of_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import call\n"
"call(restore_signals=None)"))
def test_start_new_session_of_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import call\n"
"call(start_new_session=None)"))
def test_text_of_call_from_subprocess(self):
self.assertOnlyIn((3, 7),
self.detect("from subprocess import call\n"
"call(text=None)"))
def test_umask_of_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import call\n"
"call(umask=None)"))
def test_user_of_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import call\n"
"call(user=None)"))
def test_pipesize_of_call_from_subprocess(self):
self.assertOnlyIn((3, 10),
self.detect("from subprocess import call\n"
"call(pipesize=None)"))
def test_encoding_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 6),
self.detect("from subprocess import check_call\n"
"check_call(encoding=None)"))
def test_errors_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 6),
self.detect("from subprocess import check_call\n"
"check_call(errors=None)"))
def test_extra_groups_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_call\n"
"check_call(extra_groups=None)"))
def test_group_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_call\n"
"check_call(group=None)"))
def test_pass_fds_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_call\n"
"check_call(pass_fds=None)"))
def test_restore_signals_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_call\n"
"check_call(restore_signals=None)"))
def test_start_new_session_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_call\n"
"check_call(start_new_session=None)"))
def test_text_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 7),
self.detect("from subprocess import check_call\n"
"check_call(text=None)"))
def test_umask_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_call\n"
"check_call(umask=None)"))
def test_user_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_call\n"
"check_call(user=None)"))
def test_pipesize_of_check_call_from_subprocess(self):
self.assertOnlyIn((3, 10),
self.detect("from subprocess import check_call\n"
"check_call(pipesize=None)"))
def test_extra_groups_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_output\n"
"check_output(extra_groups=None)"))
def test_group_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_output\n"
"check_output(group=None)"))
def test_pass_fds_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_output\n"
"check_output(pass_fds=None)"))
def test_restore_signals_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_output\n"
"check_output(restore_signals=None)"))
def test_start_new_session_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 2),
self.detect("from subprocess import check_output\n"
"check_output(start_new_session=None)"))
def test_umask_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_output\n"
"check_output(umask=None)"))
def test_user_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import check_output\n"
"check_output(user=None)"))
def test_pipesize_of_check_output_from_subprocess(self):
self.assertOnlyIn((3, 10),
self.detect("from subprocess import check_output\n"
"check_output(pipesize=None)"))
def test_extra_groups_of_run_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import run\n"
"run(extra_groups=None)"))
def test_group_of_run_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import run\n"
"run(group=None)"))
def test_umask_of_run_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import run\n"
"run(umask=None)"))
def test_user_of_run_from_subprocess(self):
self.assertOnlyIn((3, 9),
self.detect("from subprocess import run\n"
"run(user=None)"))
def test_pipesize_of_run_from_subprocess(self):
self.assertOnlyIn((3, 10),
self.detect("from subprocess import run\n"
"run(pipesize=None)"))
def test_msg_of_cancel_from_asyncio_Future(self):
self.assertOnlyIn((3, 9),
self.detect("from asyncio import Future\n"
"x = Future()\n"
"x.cancel(msg=None)"))
def test_n_of_release_from_threading_Semaphore(self):
self.assertOnlyIn((3, 9),
self.detect("from threading import Semaphore\n"
"x = Semaphore()\n"
"x.release(n=None)"))
def test_base_of_pow(self):
self.assertOnlyIn((3, 8), self.detect("pow(base=None)"))
def test_exp_of_pow(self):
self.assertOnlyIn((3, 8), self.detect("pow(exp=None)"))
def test_mod_of_pow(self):
self.assertOnlyIn((3, 8), self.detect("pow(mod=None)"))
def test_strict_of_zip(self):
self.assertOnlyIn((3, 10), self.detect("zip(strict=True)"))
def test_key_of_bisect_bisect(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.bisect(key='x')
"""))
def test_key_of_bisect_bisect_left(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.bisect_left(key='x')
"""))
def test_key_of_bisect_bisect_right(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.bisect_right(key='x')
"""))
def test_key_of_bisect_insort(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.insort(key='x')
"""))
def test_key_of_bisect_insort_left(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.insort_left(key='x')
"""))
def test_key_of_bisect_insort_right(self):
self.assertOnlyIn((3, 10), self.detect("""
import bisect
bisect.insort_right(key='x')
"""))
def test_max_threads_of_dump_traceback_from_faulthandler(self):
self.assertOnlyIn((3, 15), self.detect("""
from faulthandler import dump_traceback
dump_traceback(max_threads=None)
"""))
def test_max_threads_of_dump_traceback_later_from_faulthandler(self):
self.assertOnlyIn((3, 15), self.detect("""
from faulthandler import dump_traceback_later
dump_traceback_later(max_threads=None)
"""))
def test_max_threads_of_enable_from_faulthandler(self):
self.assertOnlyIn((3, 15), self.detect("""
from faulthandler import enable
enable(max_threads=None)
"""))
def test_max_threads_of_register_from_faulthandler(self):
self.assertOnlyIn((3, 15), self.detect("""
from faulthandler import register
register(max_threads=None)
"""))
def test_max_response_headers_of_HTTPConnection_from_http_client(self):
self.assertOnlyIn((3, 15), self.detect("""
from http.client import HTTPConnection
HTTPConnection(max_response_headers=None)
"""))
def test_max_response_headers_of_HTTPSConnection_from_http_client(self):
self.assertOnlyIn((3, 15), self.detect("""
from http.client import HTTPSConnection
HTTPSConnection(max_response_headers=None)
"""))
def test_extra_response_headers_of_SimpleHTTPRequestHandler_from_http_server(self):
self.assertOnlyIn((3, 15), self.detect("""
from http.server import SimpleHTTPRequestHandler
SimpleHTTPRequestHandler(extra_response_headers=None)
"""))
def test_fallback_to_class_doc_of_getdoc_from_inspect(self):
self.assertOnlyIn((3, 15), self.detect("""
from inspect import getdoc
getdoc(fallback_to_class_doc=None)
"""))
def test_inherit_class_doc_of_getdoc_from_inspect(self):
self.assertOnlyIn((3, 15), self.detect("""
from inspect import getdoc
getdoc(inherit_class_doc=None)
"""))
def test_array_hook_of_load_from_json(self):
self.assertOnlyIn((3, 15), self.detect("""
from json import load
load(array_hook=None)
"""))
def test_array_hook_of_loads_from_json(self):
self.assertOnlyIn((3, 15), self.detect("""
from json import loads
loads(array_hook=None)
"""))
def test_target_time_of_autorange_from_timeit_Timer(self):
self.assertOnlyIn((3, 15), self.detect("""
from timeit import Timer
x = Timer()
x.autorange(target_time=None)
"""))
def test_nolinestop_of_search_from_tkinter_Text(self):
self.assertOnlyIn((3, 15), self.detect("""
from tkinter import Text
x = Text()
x.search(nolinestop=None)
"""))
def test_strictlimits_of_search_from_tkinter_Text(self):
self.assertOnlyIn((3, 15), self.detect("""
from tkinter import Text
x = Text()
x.search(strictlimits=None)
"""))
def test_formatter_of_assertLogs_from_unittest_TestCase(self):
self.assertOnlyIn((3, 15), self.detect("""
from unittest import TestCase
x = TestCase()
x.assertLogs(formatter=None)
"""))
def test_missing_as_none_of_urldefrag_from_urllib_parse(self):
self.assertOnlyIn((3, 15), self.detect("""
from urllib.parse import urldefrag
urldefrag(missing_as_none=None)
"""))
def test_missing_as_none_of_urlparse_from_urllib_parse(self):
self.assertOnlyIn((3, 15), self.detect("""
from urllib.parse import urlparse
urlparse(missing_as_none=None)
"""))
def test_missing_as_none_of_urlsplit_from_urllib_parse(self):
self.assertOnlyIn((3, 15), self.detect("""
from urllib.parse import urlsplit
urlsplit(missing_as_none=None)
"""))
def test_keep_empty_of_urlunparse_from_urllib_parse(self):
self.assertOnlyIn((3, 15), self.detect("""
from urllib.parse import urlunparse
urlunparse(keep_empty=None)
"""))
def test_keep_empty_of_urlunsplit_from_urllib_parse(self):
self.assertOnlyIn((3, 15), self.detect("""
from urllib.parse import urlunsplit
urlunsplit(keep_empty=None)
"""))
def test_kw_only_of_dataclasses_dataclass(self):
self.assertOnlyIn((3, 10), self.detect("""
from dataclasses import dataclass
@dataclass(kw_only=True)
class Foo: pass
"""))
def test_match_args_of_dataclasses_dataclass(self):
self.assertOnlyIn((3, 10), self.detect("""
from dataclasses import dataclass
@dataclass(match_args=True)
class Foo: pass
"""))
def test_slots_of_dataclasses_dataclass(self):
self.assertOnlyIn((3, 10), self.detect("""
from dataclasses import dataclass
@dataclass(slots=True)
class Foo: pass
"""))
def test_kw_only_of_dataclasses_field(self):
self.assertOnlyIn((3, 10), self.detect("""
from dataclasses import dataclass, field
@dataclass
class Foo:
bar = field(kw_only=False)
"""))
# variable annotations requires !2, 3.6
if current_version() >= (3, 6):
self.assertOnlyIn((3, 10), self.detect("""
from dataclasses import dataclass, field
@dataclass
class Foo:
bar: int = field(kw_only=False)
"""))
def test_module_of_compile(self):
self.assertOnlyIn((3, 15),
self.detect("""
compile(source='', module='m')
"""))
def test_module_of_ast_parse(self):
self.assertOnlyIn((3, 15),
self.detect("""
from ast import parse
parse('', module='m')
"""))
def test_module_of_symtable_symtable(self):
self.assertOnlyIn((3, 15),
self.detect("""
import symtable
symtable.symtable('x', 'f', 'exec', module='m')
"""))
def test_fullname_of_source_to_code_from_importlib_abc(self):
self.assertOnlyIn((3, 15),
self.detect("""
from importlib.abc import InspectLoader
InspectLoader.source_to_code('x', fullname='m')
"""))
def test_canonical_of_base64_a85decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.a85decode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_b16decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b16decode(b'', ignorechars=b'')
"""))
def test_wrapcol_of_base64_b16encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b16encode(b'', wrapcol=76)
"""))
def test_canonical_of_base64_b32decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32decode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_b32decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32decode(b'', ignorechars=b'')
"""))
def test_padded_of_base64_b32decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32decode(b'', padded=True)
"""))
def test_padded_of_base64_b32encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32encode(b'', padded=True)
"""))
def test_wrapcol_of_base64_b32encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32encode(b'', wrapcol=76)
"""))
def test_canonical_of_base64_b32hexdecode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32hexdecode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_b32hexdecode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32hexdecode(b'', ignorechars=b'')
"""))
def test_padded_of_base64_b32hexdecode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32hexdecode(b'', padded=True)
"""))
def test_padded_of_base64_b32hexencode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32hexencode(b'', padded=True)
"""))
def test_wrapcol_of_base64_b32hexencode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b32hexencode(b'', wrapcol=76)
"""))
def test_canonical_of_base64_b64decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b64decode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_b64decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b64decode(b'', ignorechars=b'')
"""))
def test_padded_of_base64_b64decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b64decode(b'', padded=True)
"""))
def test_padded_of_base64_b64encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b64encode(b'', padded=True)
"""))
def test_wrapcol_of_base64_b64encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b64encode(b'', wrapcol=76)
"""))
def test_canonical_of_base64_b85decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b85decode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_b85decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b85decode(b'', ignorechars=b'')
"""))
def test_wrapcol_of_base64_b85encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.b85encode(b'', wrapcol=76)
"""))
def test_padded_of_base64_urlsafe_b64decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.urlsafe_b64decode(b'', padded=True)
"""))
def test_wrapcol_of_base64_z85encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.z85encode(b'', wrapcol=76)
"""))
def test_count_of_bytes_replace(self):
self.assertOnlyIn((3, 15),
self.detect("bytes.replace(b'', b'', b'', count=1)"))
def test_count_of_bytearray_replace(self):
self.assertOnlyIn((3, 15),
self.detect(
"bytearray.replace(bytearray(b''), b'', b'', count=1)"))
def test_color_of_ast_dump(self):
self.assertOnlyIn((3, 15),
self.detect("""
import ast
ast.dump(ast.parse('x'), color=True)
"""))
def test_color_of_difflib_unified_diff(self):
self.assertOnlyIn((3, 15),
self.detect("""
import difflib
difflib.unified_diff('a', 'b', color=True)
"""))
def test_padded_of_base64_urlsafe_b64encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.urlsafe_b64encode(b'', padded=True)
"""))
def test_canonical_of_base64_z85decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.z85decode(b'', canonical=True)
"""))
def test_ignorechars_of_base64_z85decode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.z85decode(b'', ignorechars=b'')
"""))
def test_pad_of_base64_z85encode(self):
self.assertOnlyIn((3, 15),
self.detect("""
import base64
base64.z85encode(b'', pad=b' ')
"""))
def test_padded_of_binascii_a2b_base32(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_base32(b'', padded=True)
"""))
def test_alphabet_of_binascii_a2b_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_base64(b'', alphabet=None)
"""))
def test_canonical_of_binascii_a2b_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_base64(b'', canonical=True)
"""))
def test_ignorechars_of_binascii_a2b_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_base64(b'', ignorechars=b'')
"""))
def test_padded_of_binascii_a2b_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_base64(b'', padded=True)
"""))
def test_ignorechars_of_binascii_a2b_hex(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.a2b_hex(b'', ignorechars=b'')
"""))
def test_padded_of_binascii_b2a_base32(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.b2a_base32(b'', padded=True)
"""))
def test_alphabet_of_binascii_b2a_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.b2a_base64(b'', alphabet=None)
"""))
def test_padded_of_binascii_b2a_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.b2a_base64(b'', padded=True)
"""))
def test_wrapcol_of_binascii_b2a_base64(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.b2a_base64(b'', wrapcol=76)
"""))
def test_ignorechars_of_binascii_unhexlify(self):
self.assertOnlyIn((3, 15),
self.detect("""
import binascii
binascii.unhexlify(b'', ignorechars=b'')
"""))
netromdk-vermin-d650a48/tests/lang.py 0000664 0000000 0000000 00000257315 15265463462 0017657 0 ustar 00root root 0000000 0000000 from vermin import BUILTIN_GENERIC_ANNOTATION_TYPES, DICT_UNION_SUPPORTED_TYPES, \
DICT_UNION_MERGE_SUPPORTED_TYPES, dotted_name, Parser, InvalidVersionException
from .testutils import VerminTest, current_version
class VerminLanguageTests(VerminTest):
def test_printv2(self):
# Before 3.4 it just said "invalid syntax" and didn't hint at missing parentheses.
if current_version() >= (3, 4):
self.assertOnlyIn((2, 0), self.detect("print 'hello'"))
source = "print 'hello'"
parser = Parser(source)
(node, mins, _novermin, _err_msg) = parser.detect(self.config)
v = current_version()
if v >= (3, 4):
self.assertEqual(node, None)
self.assertOnlyIn((2, 0), mins)
elif (3, 0) <= v < (3, 4): # pragma: no cover
self.assertEqual(node, None)
self.assertEqual(mins, [(0, 0), (0, 0)])
def test_printv3(self):
"""Allowed in both v2 and v3."""
visitor = self.visit("print('hello')")
v = current_version()
self.assertFalse(visitor.printv2())
self.assertTrue(visitor.printv3())
self.assertIn((v.major, 0), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 4)
def test_print_v2_v3_mixed(self):
"""When using both v2 and v3 style it must return v2 because v3 is allowed in v2."""
# Before 3.4 it just said "invalid syntax" and didn't hint at missing parentheses.
self.assertOnlyIn((2, 0), self.detect("print 'hello'\nprint('hello')"))
def test_format(self):
visitor = self.visit("'hello {}!'.format('world')")
self.assertTrue(visitor.format27())
self.assertOnlyIn(((2, 7), (3, 0)), visitor.minimum_versions())
# "{0}" is py 2.6. "{{}}" simply yields "{}" as a string value.
visitor = self.visit("'{{}} {0}'.format('test')")
self.assertFalse(visitor.format27())
self.assertOnlyIn(((2, 6), (3, 0)), visitor.minimum_versions())
# Ensure regular str formatting is ~2, ~3.
visitor = self.visit("'%x' % 66")
self.assertFalse(visitor.format27())
self.assertFalse(visitor.bytesv3())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_longv2(self):
visitor = self.visit("v = long(42)")
self.assertTrue(visitor.longv2())
self.assertOnlyIn((2, 0), visitor.minimum_versions())
visitor = self.visit("v = 1\nv += long(42)")
self.assertTrue(visitor.longv2())
self.assertOnlyIn((2, 0), visitor.minimum_versions())
visitor = self.visit("isinstance(42, long)")
self.assertTrue(visitor.longv2())
self.assertOnlyIn((2, 0), visitor.minimum_versions())
def test_bytesv3(self):
visitor = self.visit("s = b'hello'")
self.assertTrue(visitor.bytesv3())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
visitor = self.visit("s = B'hello'")
self.assertTrue(visitor.bytesv3())
self.assertEqual([(2, 6), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 6)
def test_fstrings(self):
visitor = self.visit("name = 'world'\nf'hello {name}'")
self.assertTrue(visitor.fstrings())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
visitor = self.visit("f'{f\"{3.1415:.1f}\":*^20}'")
self.assertTrue(visitor.fstrings())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
visitor = self.visit("f'''{\n3\n}'''")
self.assertTrue(visitor.fstrings())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
def test_fstrings_named_expr(self):
if current_version() >= (3, 8):
visitor = self.visit("f'{(x:=1)}'")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.named_expressions())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
if current_version() >= (3, 6):
visitor = self.visit("f'{x:=10}'")
self.assertTrue(visitor.fstrings())
self.assertFalse(visitor.named_expressions())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
def assert_self_doc(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
def assert_not_self_doc(self, source):
visitor = self.visit(source)
self.assertFalse(visitor.fstrings_self_doc())
@VerminTest.skipUnlessVersion(3, 8)
@VerminTest.parameterized_args([
("a = 1\nf'a={a}'",),
("name = 'world'\nf'hello={name}'",),
("a = 1\nf'={a}'",),
("a = 1\nb = 2\nf'={b}={a}'",),
("f'{x:=10}'",),
("f'hello {name!r}'",),
("f'val={val:.2f}'",),
("f'{(a+b)}={x!r}'",),
("a = 1\nf'{{x={a}}}'",),
("f'{x:.2f}'",),
("x = 'x'\ndef foo(shell):pass\nfoo(shell=f'a={x!r}')",),
])
def test_self_doc_not_detected(self, source):
self.config.enable_feature("fstring-self-doc")
self.assert_not_self_doc(source)
@VerminTest.skipUnlessVersion(3, 8)
@VerminTest.parameterized_args([
("a = 1\nf'{a=}'",),
("name = 'world'\nf'hello {name=}'",),
("a = 1\nb = 2\nf'{b=}={a}'",),
("f'{a =}'",),
("f'{ a=}'",),
("f'{a= }'",),
("f'{ a = }'",),
("f'{1+1=}'",),
("f'{a+b=}'",),
("f'{not a=}'",),
("f'{10 % 5=}'",),
("f'{x << y=}'",),
("f'{a or b=}'",),
("f'{(1,2,3)=}'",),
("f'{[1,2,3]=}'",),
("f'{ {1,2,3}=}'",),
("f'{ {1:1, 2:2}=}'",),
("f'{0==1=}'",),
("f'{0<1=}'",),
("f'{0==1!=2=}'",),
("f'{3.14=:10.10}'",),
("f'{3.14=!s:10.10}'",),
("f'{x=!r}'",),
("f'{x=:.2f}'",),
("f'{x=!a:^20}'",),
("f'{d[\"foo\"]=:.2f}'",),
("f'{f\"{3.1415=:.1f}\":*^20}'",),
("f'{f(a=4)=}'",),
("f'{f(a=\"3=\")=}'",),
("f'{C()=!r:*^20}'",),
("f'{delta.days=:,d}'",),
("f'{user=!s} {delta.days=:,d}'",),
("f'{cos(radians(theta))=:.3f}'",),
("f'{(a+b)=}'",),
("f'{d[\"foo\"]=}'",),
("f'i:{i=}'",),
("f'{1 if True else 2=}'",),
("f'{(d[a], None) if 42 != 84 else (1,2,3)=}'",),
("f'expr={ {x: y for x, y in [(1, 2) ]} = }'",),
("f'''{\na=\n}'''",),
("f\"{x = :.2f}\"",),
("f\"{(x) = :.2f}\"",),
# Real-world patterns.
("f\"Expected {provider=} to be a class since {provider_kw=} was\"",),
("f\"Disposition param parsing is not linear: {d1=} vs {d2=}\"",),
("f\"overrun because hit {self.max_length=}\"",),
("f'summary: {save_count=} for {len(frames)=}'",),
# kwarg to a user-defined function.
("x = 1\ndef foo(shell):pass\nfoo(shell=f\"{x=}\")",),
("x = 1\ndef foo(position=None, **kw):pass\nfoo(position=1, shell=f\"{x=}\")",),
])
def test_self_doc_detected(self, source):
self.config.enable_feature("fstring-self-doc")
self.assert_self_doc(source)
@VerminTest.skipUnlessVersion(3, 8)
def test_self_doc_feature_flag(self):
# Enabled by default.
visitor = self.visit("a = 1\nf'{a=}'")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
self.config.clear_features()
visitor = self.visit("a = 1\nf'{a=}'")
self.assertTrue(visitor.fstrings())
self.assertFalse(visitor.fstrings_self_doc())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
self.config.enable_feature("fstring-self-doc")
visitor = self.visit("a = 1\nf'{a=}'")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
def assert_pep701(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
def assert_not_pep701(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.fstrings())
self.assertFalse(visitor.fstrings_pep701())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("f\"{chr(10)}\"",),
("f\"{'#notacomment'}\"",),
("f'hello {name}'",),
("f'''{x}'''",),
("f'''{\n3\n}'''",),
# Mixed triple/single (valid pre-3.12).
('f"""outer {f"inner"}"""',),
# Different-quote nesting (valid pre-3.12).
('f"outer {f\'inner\'}"',),
("f'outer {f\"inner\"}'",),
# Backslash in literal, not expression.
("f'hello\\nworld'",),
])
def test_pep701_not_detected(self, source):
self.config.enable_feature("fstring-pep701")
self.assert_not_pep701(source)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
# Same-quote nesting.
('f"outer {f"inner"}"',),
("f'outer {f'inner'}'",),
('f"""outer {f"""inner"""}"""',),
("f'''outer {f'''inner'''}'''",),
('f"1 {f"2 {f"3"}"}"',),
# Format-spec nesting.
('f"{x:{f".2f"}}"',),
# Single outer with triple inner.
('f"outer {f"""inner"""}"',),
# Multi-line expressions.
('f"{\n1+2\n}"',),
("f\"{\n'''a'''\n}\"",),
# Backslash.
("f\"{'\\n'.join(x)}\"",),
("f\"{r'\\n'}\"",),
('f"{a \\\n}"',),
# Comment.
('f"{x # comment\n}"',),
('f"{\n# comment\n1+2\n}"',),
# String literals reusing the outer quote.
('f"abc {a["x"]} def"',),
("f'ab {a['x']} cd'",),
('f"{x:{"ab"}}"',),
('f"{x:{w["y"]}}"',),
('f"{d["k"]=}"',),
])
def test_pep701_detected(self, source):
self.config.enable_feature("fstring-pep701")
self.assert_pep701(source)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
("'lit' f\"{f\"{x}\"}\"",),
('"""lit""" f"{f"{x}"}"',),
("'''lit''' f\"{f\"{x}\"}\"",),
("f'{\"lit\" f'{x}'}'",),
('f"""{rf"""{x}"""}"""',),
('f"{fr"""{x}"""}"',),
("f'outer {rf'''{x}'''}'",),
('f"{F"é{fr"""{x}"""}config"}"',),
("('lit'\n# comment between\n f\"{f\"{x}\"}\")",),
("'''lit''' f\"{x\n+y}\"",),
('f"""{x # c\n:>3}"""',),
])
def test_pep701_implicit_concat(self, source):
self.config.enable_feature("fstring-pep701")
self.assert_pep701(source)
@VerminTest.skipUnlessVersion(3, 12)
@VerminTest.parameterized_args([
('f"{x\n# comment\n}"',),
('f"""{x\n# comment\n}"""',),
('f"""{x # comment\n}"""',),
('f"""{x # c\n:>3}"""',),
])
def test_pep701_comment_variants(self, source):
self.config.enable_feature("fstring-pep701")
self.assert_pep701(source)
@VerminTest.skipUnlessVersion(3, 12)
def test_pep701_feature_flag(self):
# Enabled by default.
self.config.reset()
visitor = self.visit('f"outer {f"inner"}"')
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
self.config.clear_features()
visitor = self.visit('f"outer {f"inner"}"')
self.assertTrue(visitor.fstrings())
self.assertFalse(visitor.fstrings_pep701())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
self.config.enable_feature("fstring-pep701")
visitor = self.visit('f"outer {f"inner"}"')
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# Ordinary 3.6+ valid fstrings must never be flagged as PEP 701. Especially important on pre-3.12
# interpreters.
@VerminTest.skipUnlessVersion(3, 6)
@VerminTest.parameterized_args([
('f"{x}"',),
('f"{x:10}"',),
('f"{x:#04x}"',),
('f"{x!r}"',),
("f'{x}'",),
("f'{x:10}'",),
("f'{x!s}'",),
('f"{x:>#12}"',),
('f"{x:#x}"',),
('f"{x:{width}}"',),
('f"value: {x:#08x}"',),
('f"hello {name}"',),
# Non-ASCII literal text before a field shifts AST byte-based column offsets away from
# code-point positions. Post-3.12 parsers removed the pinned field positions, exposing the
# format spec `#x` and similar as a false comment or backslash PEP 701 trigger.
('f"é{x}"',),
('f"é{x:#x}"',),
('f"é{x:#04x}"',),
('f"┐{x}"',),
('f"┐{p - 8:#x} ◂"',),
("f'é{x:#x}'",),
('rf"00:0000│\\s+{sp - 8:#x} ◂— 0"',),
('f"euro€ {x:#x} ~"',),
("f''",),
("f'{x}'",),
# Pre-3.12 parsers pin every `FormattedValue` to the whole fused span, with `lineno=1` and
# `end_lineno=N`, which previously read as a multi-line implicit string concat expression.
('s = (f"got {x}: "\n f"done")',),
('s = (f"done"\n f"got {x}: ")',),
('s = (f"{a}"\n f"{b}")',),
('s = (f"{a}"\n "literal")\n',),
('s = (f"done"\n f"done")',),
('s = f"{a}" f"{b}"',),
# `#` inside a format spec is spec filler text, not a comment. Valid since 3.6.
('f"""{x:>3 # c\n}"""',),
('f"""{x:{w} # c\n}"""',),
('f"""{x!r:>3 # c\n}"""',),
# Leading plain literal hides a differently-quoted nested fstring.
('\'pre\' f"{f\'{x}\'}"',),
("'''pre''' f\"{f'{x}'}\"",),
# Format-spec nested fstrings are valid pre-3.12 even when same-quoted.
('f"{x:{f\'{y}\'}}"',),
('f"""{x:{f"{y}"}}"""',),
# Multi-line expression in the triple-quoted trailing part of an implicit concatenation.
('s = f"lit {a}" f"""{b\n+ c}"""',),
# A different quote inside a field is valid since 3.6.
('f"abc {a[\'x\']} def"',),
("f'abc {a[\"x\"]} def'",),
('f"{x:{w[\'y\']}}"',),
('f"{x:>a\'b}"',),
("f'{x:{w[\"y\"]}}'",),
# Triple-quoted f-strings allow reusing their quote character in a literal.
('f"""abc {a["x"]} def"""',),
('f"""abc {a[\'x\']} def"""',),
("f'''abc {a['x']} def'''",),
])
def test_fstrings_pep701_no_false_positives(self, source):
self.config.enable_feature("fstring-pep701")
visitor = self.visit(source)
self.assertFalse(visitor.fstrings_pep701())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 12)
def test_fstrings_self_doc_and_pep701(self):
self.config.enable_feature("fstring-self-doc")
self.config.enable_feature("fstring-pep701")
visitor = self.visit("a = 1\nf'{a=}'")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertFalse(visitor.fstrings_pep701())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit('f"outer {f"inner"}"')
self.assertTrue(visitor.fstrings())
self.assertFalse(visitor.fstrings_self_doc())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# Self-doc inside PEP 701 nested fstring.
visitor = self.visit('f"result: {f"{x=}"}"')
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# Same-quote nesting whose inner field is self-doc, and a backslash-in-expression combined with
# a self-doc marker.
visitor = self.visit('f"normal {f"{a=}"} normal"')
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit("t = f\"{'\\InHere'=}\"")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# The empty-string self-doc form reuses the outer quote for a literal, so it only parses on
# 3.12+ as a same-quote string literal.
visitor = self.visit('f"{""=}"')
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.fstrings_self_doc())
self.assertTrue(visitor.fstrings_pep701())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 6)
def test_await_in_fstring(self):
# From 3.7, `await` may be used in expressions within f-strings.
visitor = self.visit("async def f():\n return f'{await g()}'")
self.assertTrue(visitor.fstrings())
self.assertTrue(visitor.coroutines())
self.assertTrue(visitor.fstrings_await())
self.assertOnlyIn((3, 7), visitor.minimum_versions())
visitor = self.visit("async def f():\n x = [f'{await g()}']")
self.assertTrue(visitor.fstrings_await())
self.assertOnlyIn((3, 7), visitor.minimum_versions())
visitor = self.visit("async def f():\n await g()")
self.assertFalse(visitor.fstrings_await())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
# An f-string without `await` next to one stays at the f-string minimum.
visitor = self.visit("async def f():\n await g()\n return f'{x}'")
self.assertFalse(visitor.fstrings_await())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_coroutines_async(self):
visitor = self.visit("async def func():\n\tpass")
self.assertTrue(visitor.coroutines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_coroutines_await(self):
visitor = self.visit("async def func():\n\tawait something()")
self.assertTrue(visitor.coroutines())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
def test_async_generator(self):
if current_version() >= (3, 6):
visitor = self.visit("async def func():\n"
" yield 42\n"
" await something()")
self.assertTrue(visitor.async_generator())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
visitor = self.visit("async def func():\n"
" yield 42\n"
" async def func2():\n"
" await other()")
self.assertFalse(visitor.async_generator())
# 3.7 = await in comprehension.
if current_version() >= (3, 7):
visitor = self.visit("async def func():\n"
" yield 42\n"
" d = [v for v in await other()]")
self.assertFalse(visitor.async_generator())
self.assertTrue(visitor.await_in_comprehension())
@VerminTest.skipUnlessVersion(3, 7)
def test_async_comprehension(self):
self.assertOnlyIn((3, 7), self.detect("[i async for i in iter() if i % 2]"))
self.assertOnlyIn((3, 10), self.detect("[i async for i in aiter() if i % 2]"))
@VerminTest.skipUnlessVersion(3, 7)
def test_await_in_comprehension(self):
visitor = self.visit("[await fun() for fun in funcs if await condition()]")
self.assertTrue(visitor.await_in_comprehension())
self.assertOnlyIn((3, 7), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_async_for(self):
self.assertOnlyIn((3, 5), self.detect("async def foo():\n\tasync for a in []:pass"))
@VerminTest.skipUnlessVersion(3, 8)
def test_continue_in_finally(self):
visitor = self.visit("try: pass\nfinally: continue")
self.assertTrue(visitor.continue_in_finally())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("for i in range(3):\n"
" try:\n"
" pass\n"
" finally:\n"
" continue")
self.assertTrue(visitor.continue_in_finally())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
visitor = self.visit("for i in range(3):\n"
" try:\n"
" pass\n"
" finally:\n"
" for j in []:\n"
" continue") # Skip due to inline for-loop.
self.assertFalse(visitor.continue_in_finally())
visitor = self.visit("for i in range(3):\n"
" try:\n"
" pass\n"
" finally:\n"
" while i < 2:\n"
" continue") # Skip due to inline while-loop.
self.assertFalse(visitor.continue_in_finally())
visitor = self.visit("for i in range(3):\n"
" try:\n"
" pass\n"
" finally:\n"
" for j in []:\n"
" continue\n" # Skip due to inline for-loop.
" while i < 2:\n"
" continue\n" # Skip due to inline while-loop.
" continue") # Accept this one.
self.assertTrue(visitor.continue_in_finally())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 8)
def test_named_expressions(self):
visitor = self.visit("a = 1\nif (b := a) == 1:\n\tprint(b)")
self.assertTrue(visitor.named_expressions())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
def test_kw_only_args(self):
visitor = self.visit("def foo(a, *, b): return a + b")
self.assertTrue(visitor.kw_only_args())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 8)
def test_pos_only_args(self):
visitor = self.visit("def foo(a, /, b): return a + b")
self.assertTrue(visitor.pos_only_args())
self.assertOnlyIn((3, 8), visitor.minimum_versions())
def test_nonlocal_stmt(self):
visitor = self.visit("def foo():\n\tlong = 1\n\tdef bar():\n\t\tnonlocal long")
self.assertTrue(visitor.nonlocal_stmt())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 3)
def test_yield_from(self):
visitor = self.visit("def foo(x): yield from range(x)")
self.assertTrue(visitor.yield_from())
self.assertOnlyIn((3, 3), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 0)
def test_raise_cause(self):
visitor = self.visit("raise Exception() from ValueError")
self.assertTrue(visitor.raise_cause())
self.assertFalse(visitor.raise_from_none())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 3)
def test_raise_from_none(self):
visitor = self.visit("raise Exception() from None")
self.assertTrue(visitor.raise_cause())
self.assertTrue(visitor.raise_from_none())
self.assertOnlyIn((3, 3), visitor.minimum_versions())
def test_set_literals(self):
visitor = self.visit("{1}")
self.assertTrue(visitor.set_literals())
self.assertEqual([(2, 7), (3, 0)], visitor.minimum_versions())
def test_set_comprehension(self):
visitor = self.visit("{key for ld in lod for key, value in ld.items()}")
self.assertTrue(visitor.set_comprehension())
self.assertEqual([(2, 7), (3, 0)], visitor.minimum_versions())
def test_dict_comprehension(self):
visitor = self.visit("{key: value for ld in lod for key, value in ld.items()}")
self.assertTrue(visitor.dict_comprehension())
self.assertEqual([(2, 7), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_infix_matrix_multiplication(self):
visitor = self.visit("M @ N")
self.assertTrue(visitor.infix_matrix_multiplication())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
def test_str_from_type(self):
visitor = self.visit("\"\".zfill(1)")
self.assertIn("str.zfill", visitor.members())
visitor = self.visit("str().zfill(1)")
self.assertIn("str.zfill", visitor.members())
def test_list_from_type(self):
visitor = self.visit("[].clear()")
self.assertIn("list.clear", visitor.members())
visitor = self.visit("list().clear()")
self.assertIn("list.clear", visitor.members())
def test_dict_from_type(self):
visitor = self.visit("{}.pop()")
self.assertIn("dict.pop", visitor.members())
visitor = self.visit("dict().pop()")
self.assertIn("dict.pop", visitor.members())
def test_set_from_type(self):
visitor = self.visit("{1}.isdisjoint()")
self.assertIn("set.isdisjoint", visitor.members())
visitor = self.visit("set().isdisjoint()")
self.assertIn("set.isdisjoint", visitor.members())
def test_frozenset_from_type(self):
visitor = self.visit("frozenset().isdisjoint()")
self.assertIn("frozenset.isdisjoint", visitor.members())
def test_int_from_type(self):
visitor = self.visit("(1).bit_length()")
self.assertIn("int.bit_length", visitor.members())
visitor = self.visit("int().bit_length()")
self.assertIn("int.bit_length", visitor.members())
def test_float_from_type(self):
visitor = self.visit("(4.2).hex()")
self.assertIn("float.hex", visitor.members())
visitor = self.visit("float().hex()")
self.assertIn("float.hex", visitor.members())
def test_bytes_from_type(self):
visitor = self.visit("b'hello'.hex()")
self.assertIn("bytes.hex", visitor.members())
visitor = self.visit("bytes().hex()")
self.assertIn("bytes.hex", visitor.members())
def test_bytearray_from_type(self):
visitor = self.visit("bytearray(b'hello').hex()")
self.assertIn("bytearray.hex", visitor.members())
visitor = self.visit("bytearray().hex()")
self.assertIn("bytearray.hex", visitor.members())
def test_bool_from_type(self):
visitor = self.visit("bool()")
self.assertIn("bool", visitor.members())
def test_memoryview_from_type(self):
visitor = self.visit("memoryview(b'hello').release()")
self.assertIn("memoryview.release", visitor.members())
@VerminTest.parameterized_args([
["with func():\n pass"],
["with a as (b, c): pass"],
["with a as b:\n\twith c as d:\n\t\tpass"],
])
def test_with_statement(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.with_statement())
self.assertFalse(visitor.multi_withitem())
self.assertFalse(visitor.with_parentheses())
self.assertOnlyIn([(2, 5), (3, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 3) # See `visit_With` for reason for only testing on 3.3+.
@VerminTest.parameterized_args([
["with a, b: pass"],
["with a, b as c: pass"],
["with a as b, c: pass"],
["with a as b, c as d: pass"],
])
def test_multi_withitem(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertFalse(visitor.with_parentheses())
self.assertOnlyIn([(2, 7), (3, 1)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 9)
@VerminTest.parameterized_args([
["with (a, b): pass"],
["with (a, b as c): pass"],
["with (a as b, c): pass"],
["with (a as b, c as d): pass"],
["""with \
(a, b): pass"""],
["""with \
(a, b as c): pass"""],
["""with \
(\
a, b): pass"""],
["""with \
(\
a, b as c): pass"""],
["""with \
\
(a, b): pass"""],
["""with \
\
(a, b as c): pass"""],
["with(a, b): pass"],
["with (a, b): pass"],
])
def test_with_parentheses(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertTrue(visitor.with_parentheses())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 9)
def test_with_parentheses_first_match(self):
self.config.set_verbose(3) # show lines
visitor = self.visit("""with (a as b, c as d): pass
with a as b, c as d: pass""")
self.assertTrue(visitor.with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertTrue(visitor.with_parentheses())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
self.assertEqual(visitor.output_text(), """L1: `with` requires 2.5, 3.0
L1: multiple context expressions in a `with` statement require 2.7, 3.1
L1: multiple context expressions in a `with` statement with parentheses require !2, 3.9
L2: `with` requires 2.5, 3.0
L2: multiple context expressions in a `with` statement require 2.7, 3.1
""")
@VerminTest.skipUnlessVersion(3, 9)
def test_with_parentheses_second_match(self):
self.config.set_verbose(3) # show lines
visitor = self.visit("""with a as b, c as d: pass
with (a as b, c as d): pass""")
self.assertTrue(visitor.with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertTrue(visitor.with_parentheses())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
self.assertEqual(visitor.output_text(), """L1: `with` requires 2.5, 3.0
L1: multiple context expressions in a `with` statement require 2.7, 3.1
L2: `with` requires 2.5, 3.0
L2: multiple context expressions in a `with` statement require 2.7, 3.1
L2: multiple context expressions in a `with` statement with parentheses require !2, 3.9
""")
@VerminTest.skipUnlessVersion(3, 5)
@VerminTest.parameterized_args([
["""async def foo():
async with func(): pass"""],
["""async def foo():
async with a as (b, c): pass"""],
["""async def foo():
async with a as b:
with c as d: pass"""],
])
def test_async_with_statement(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.async_with_statement())
self.assertFalse(visitor.multi_withitem())
self.assertFalse(visitor.with_parentheses())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
@VerminTest.parameterized_args([
["""async def foo():
async with a, b: pass"""],
["""async def foo():
async with a, b as c: pass"""],
["""async def foo():
async with a as b, c: pass"""],
["""async def foo():
async with a as b, c as d: pass"""],
])
def test_async_multi_withitem(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.async_with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertFalse(visitor.with_parentheses())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 9)
@VerminTest.parameterized_args([
["""async def foo():
async with (a, b): pass"""],
["""async def foo():
async with (a, b as c): pass"""],
["""async def foo():
async with (a as b, c): pass"""],
["""async def foo():
async with (a as b, c as d): pass"""],
["""async def foo():
async with \
(a, b): pass"""],
["""async def foo():
async with \
(a, b as c): pass"""],
["""async def foo():
async with \
(\
a, b): pass"""],
["""async def foo():
async with \
(\
a, b as c): pass"""],
["""async def foo():
async with \
\
(a, b): pass"""],
["""async def foo():
async with \
\
(a, b as c): pass"""],
])
def test_async_with_parentheses(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.async_with_statement())
self.assertTrue(visitor.multi_withitem())
self.assertTrue(visitor.with_parentheses())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_generalized_unpacking(self):
if current_version() >= (3, 5):
visitor = self.visit("(*range(4), 4)") # tuple
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(4, *range(4))")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(*range(4),)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(*(1,),)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(*(1, 2),)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(0, *(1, 2))")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(*(1, 2), 3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(0, *(1, 2), 3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("(*(1, 2), *(3, 4))")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*range(4), 4]") # list
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[4, *range(4)]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*range(4)]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*[1]]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*[1, 2]]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[0, *[1, 2]]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*[1, 2], 3]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[0, *[1, 2], 3]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*[1, 2], *[3, 4]]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*range(4), 4}") # set
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{4, *range(4)}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*range(4)}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*{1}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*{1, 2}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{0, *{1, 2}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*{1, 2}, 3}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{0, *{1, 2}, 3}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{*{1, 2}, *{3, 4}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{'x': 1, **{'y': 2}}") # dict
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{**{'y': 2}, 'x': 1}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{**{1: 1}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{**{1: 1, 2: 2}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{0: 0, **{1: 1, 2: 2}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{**{1: 1, 2: 2}, 3: 3}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{0: 0, **{1: 1, 2: 2}, 3: 3}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("{**{1: 1, 2: 2}, **{3: 3, 4: 4}}")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("[*{1,2,3}, *(1,2,3), *[1,2,3], *range(3)]")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("print(*(1,))")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("print(*(1, 2))")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("print(0, *(1, 2))")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("print(*(1, 2), 3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("print(0, *(1, 2), 3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("print(*(1, 2), *(3, 4))")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("dict(**{'b': 1, 'c': 2}, d=3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("dict(a=0, **{'b': 1, 'c': 2}, d=3)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("dict(**{'b': 1, 'c': 2}, **{'d': 3, 'e': 4})")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("foo(0, *(1, 2), 3, a=1, **{'b': 2, 'c': 3})")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("foo(0, *(1, 2), a=1, **{'b': 2, 'c': 3}, d=4)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("function(*arguments, argument)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("function(**kw_arguments, **more_arguments)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("function(**{'x': 42}, arg=84)")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("z = *x, y")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("*x, y = *u, *v")
self.assertTrue(visitor.generalized_unpacking())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
visitor = self.visit("dict(**{'b': 1})")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("dict(**{'b': 1, 'c': 2})")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("dict(a=0, **{'b': 1, 'c': 2})")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("foo(0, *(1, 2), a=1, **{'b': 2, 'c': 3})")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("function(arg=84, **{'x': 42})")
self.assertFalse(visitor.generalized_unpacking())
visitor = self.visit("d = {'a': 'b'}\ndict(**d)")
self.assertFalse(visitor.generalized_unpacking())
@VerminTest.parameterized_args([
["*x, y = [1, 2, 3]"],
["a, *b = 'hello'"],
["([x, *y], z) = ((1, 2), 3)"],
["for *x, in [[1]]: pass"],
["for a, *b in [(1, 2, 3), (4, 5, 6, 7)]: pass"],
["[x for *x, in [[1]]]"],
["{x for *x, in [[1]]}"],
["(x for *x, in [[1]])"],
])
def test_unpacking_assignment(self, source):
# Starred expressions are allowed as assignments targets 3.0+, but generalized unpacking from
# 3.5+.
visitor = self.visit(source)
self.assertTrue(visitor.unpacking_assignment(), msg=source)
self.assertFalse(visitor.generalized_unpacking(), msg=source)
self.assertOnlyIn((3, 0), visitor.minimum_versions(), msg=source)
def test_ellipsis_in_slices(self):
visitor = self.visit('x[...]')
self.assertFalse(visitor.ellipsis_out_of_slices())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit('x[a, ..., b]')
self.assertFalse(visitor.ellipsis_out_of_slices())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
def test_ellipsis_out_of_slices(self):
visitor = self.visit('...')
self.assertTrue(visitor.ellipsis_out_of_slices())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
visitor = self.visit('x[[...]]')
self.assertTrue(visitor.ellipsis_out_of_slices())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 12)
def test_type_alias_statement(self):
visitor = self.visit('type X = int')
self.assertTrue(visitor.type_alias_statement())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit('type Point = tuple[float, float]')
self.assertTrue(visitor.type_alias_statement())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit('type(X)')
self.assertFalse(visitor.type_alias_statement())
# Plain syntax errors.
visitor = self.visit('type "X = int"')
self.assertEqual([(0, 0), (0, 0)], visitor)
visitor = self.visit('type "Point = tuple[float, float]"')
self.assertEqual([(0, 0), (0, 0)], visitor)
visitor = self.visit('type "Po_int = tuple[float, float]"')
self.assertEqual([(0, 0), (0, 0)], visitor)
def test_type_alias_statement_invalid_syntax(self):
"""Prior to 3.12 it would yield SyntaxError: invalid syntax for type alias statements."""
cv = current_version()
if cv.major == 3 and cv.minor <= 11:
self.assertOnlyIn((3, 12), self.detect("type X = int"))
self.assertOnlyIn((3, 12), self.detect("type Point = tuple[float, float]"))
# Plain syntax errors.
self.assertEqual([(0, 0), (0, 0)], self.detect("type 'X = int'"))
self.assertEqual([(0, 0), (0, 0)], self.detect("type 'Point = tuple[float, float]'"))
self.assertEqual([(0, 0), (0, 0)], self.detect("type 'Po_int = tuple[float, float]'"))
@VerminTest.skipUnlessVersion(3, 12)
def test_type_alias_statement_class_scope_lambda(self):
# Type alias not in a class scope.
visitor = self.visit("type Alias = lambda: T")
self.assertTrue(visitor.type_alias_statement())
self.assertFalse(visitor.type_alias_statement_class_scope_lambda())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit("type Alias = [l for l in [lambda: T]]")
self.assertTrue(visitor.type_alias_statement())
self.assertFalse(visitor.type_alias_statement_class_scope_lambda())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# Type alias with lambda not in a class scope but with a nested one without.
visitor = self.visit("""
type Alias = lambda: T
class A[T]:
type Alias = T
""")
self.assertTrue(visitor.type_alias_statement())
self.assertFalse(visitor.type_alias_statement_class_scope_lambda())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
# Type alias in a class scope.
visitor = self.visit("""
class A[T]:
type Alias = lambda: T
""")
self.assertTrue(visitor.type_alias_statement())
self.assertTrue(visitor.type_alias_statement_class_scope_lambda())
self.assertOnlyIn((3, 13), visitor.minimum_versions())
visitor = self.visit("""
class A[T]:
type Alias = [l for l in [lambda: T]]
""")
self.assertTrue(visitor.type_alias_statement())
self.assertTrue(visitor.type_alias_statement_class_scope_lambda())
self.assertOnlyIn((3, 13), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 14)
def test_template_string_literal(self):
visitor = self.visit("t'hello'")
self.assertTrue(visitor.template_string_literal())
self.assertOnlyIn((3, 14), visitor.minimum_versions())
visitor = self.visit("t'hello {var}'")
self.assertTrue(visitor.template_string_literal())
self.assertOnlyIn((3, 14), visitor.minimum_versions())
visitor = self.visit("""
from string.templatelib import Interpolation
def lower_upper(template):
parts = []
for part in template:
if isinstance(part, Interpolation):
parts.append(str(part.value).upper())
else:
parts.append(part.lower())
return ''.join(parts)
name = 'Wenslydale'
template = t'Mister {name}'
assert lower_upper(template) == 'mister WENSLYDALE'
""")
self.assertTrue(visitor.template_string_literal())
self.assertOnlyIn((3, 14), visitor.minimum_versions())
visitor = self.visit("""
attributes = {'src': 'test.jpg', 'alt': 'test test'}
template = t'
'
assert html(template) == '
'
""")
self.assertTrue(visitor.template_string_literal())
self.assertOnlyIn((3, 14), visitor.minimum_versions())
# f-strings are not t-strings
visitor = self.visit("f'hello'")
self.assertFalse(visitor.template_string_literal())
@VerminTest.skipUnlessVersion(3, 15)
@VerminTest.parameterized_args([
("[*x for x in range(10)]",),
("{*x for x in range(10)}",),
("(*x for x in range(10))",),
("{**d for d in items}",),
("[[*y for y in x] for x in z]",),
])
def test_unpacking_in_comprehension(self, source):
visitor = self.visit(source)
self.assertTrue(visitor.unpacking_in_comprehension(), source)
self.assertOnlyIn((3, 15), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
@VerminTest.parameterized_args([
("[print(i, *foo) for i in range(5)]",),
("[f(*x) for x in y]",),
("[x for x in g(*foo)]",),
("[[*a, *b] for x in range(3)]",),
("[x for x in range(10)]",),
])
def test_unpacking_in_comprehension_false_positives(self, source):
visitor = self.visit(source)
self.assertFalse(visitor.unpacking_in_comprehension(), source)
@VerminTest.skipUnlessVersion(3, 15)
def test_lazy_imports(self):
visitor = self.visit("lazy import foo")
self.assertTrue(visitor.lazy_imports())
self.assertOnlyIn((3, 15), visitor.minimum_versions())
visitor = self.visit("lazy from bar import foo")
self.assertTrue(visitor.lazy_imports())
self.assertOnlyIn((3, 15), visitor.minimum_versions())
visitor = self.visit("import foo")
self.assertFalse(visitor.lazy_imports())
def test_lazy_modules(self):
visitor = self.visit("__lazy_modules__ = []")
self.assertTrue(visitor.lazy_modules())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("__all__ = []")
self.assertFalse(visitor.lazy_modules())
def test_lazy_modules_verbose(self):
self.config.set_verbose(3)
visitor = self.visit("__lazy_modules__ = ['json']")
self.assertTrue(visitor.lazy_modules())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Detected and shown, but without a version requirement.
self.assertEqual(visitor.output_text(), """L1: `__lazy_modules__`
""")
def test_slice_subscription(self):
visitor = self.visit("x = slice[1:2:3]")
self.assertTrue(visitor.slice_subscription())
self.assertOnlyIn((3, 15), visitor.minimum_versions())
visitor = self.visit("x = slice(1, 2, 3)")
self.assertFalse(visitor.slice_subscription())
@VerminTest.skipUnlessVersion(3, 5)
def test_bytes_format(self):
visitor = self.visit("b'%x' % 10")
self.assertTrue(visitor.bytes_format())
self.assertOnlyIn(((2, 6), (3, 5)), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 5)
def test_bytearray_format(self):
visitor = self.visit("bytearray(b'%x') % 10")
self.assertTrue(visitor.bytearray_format())
self.assertOnlyIn((3, 5), visitor.minimum_versions())
def test_bytes_directives(self):
visitor = self.visit("b'%b %x'")
self.assertOnlyIn(("b", "x"), visitor.bytes_directives())
visitor = self.visit("b'%4b'")
self.assertOnlyIn(("b",), visitor.bytes_directives())
visitor = self.visit("b'%4b'")
self.assertOnlyIn(("b",), visitor.bytes_directives())
visitor = self.visit("b'%#4b'")
self.assertOnlyIn(("b",), visitor.bytes_directives())
visitor = self.visit("b'%04b'")
self.assertOnlyIn(("b",), visitor.bytes_directives())
visitor = self.visit("b'%.4f'")
self.assertOnlyIn(("f",), visitor.bytes_directives())
visitor = self.visit("b'%-4f'")
self.assertOnlyIn(("f",), visitor.bytes_directives())
visitor = self.visit("b'% f'")
self.assertOnlyIn(("f",), visitor.bytes_directives())
visitor = self.visit("b'%+f'")
self.assertOnlyIn(("f",), visitor.bytes_directives())
def test_detect_raise_members(self):
visitor = self.visit("raise ModuleNotFoundError")
self.assertOnlyIn("ModuleNotFoundError", visitor.members())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
def test_detect_except_members(self):
visitor = self.visit("try: pass\nexcept ModuleNotFoundError: pass")
self.assertOnlyIn("ModuleNotFoundError", visitor.members())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
# Issue 69 example where `file` would get incorrectly seen as Python 2's builtin function
# instead of a name defined in the for-loop. The fix is to only look for members in the type
# branch of exception handlers.
visitor = self.visit("""
for file in ['foo']:
try:
1 / 0
except ZeroDivisionError:
print(file)
""")
self.assertNotIn("file", visitor.members())
def test_dict_union(self):
visitor = self.visit("{'a':1} | {'b':2}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {'a':1}\nb = {'b':2}\na | b")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {'a':1}\na | {'b':2}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {'a':1}\n{'b':2} | a")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("dict() | dict()")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = dict()\nb = dict()\na | b")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = dict()\na | dict()")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = dict()\ndict() | a")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("{} | dict() | {}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("(lambda: {})() | {}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("(lambda: {} | dict())()")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("{} | (1,{},'a')[1]")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("{} | (1,{},'a')[0]")
self.assertFalse(visitor.dict_union())
visitor = self.visit("{} | [1,{},'a'][1]")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("[1,(lambda:{1:2})(),3][1] | {2:3}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
# Builtin types were modified to support "|".
visitor = self.visit("from types import MappingProxyType\nm=MappingProxyType({})\nm|{}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from types import MappingProxyType\nm=MappingProxyType({})\n{}|m")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from types import MappingProxyType\nMappingProxyType({})|{}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from types import MappingProxyType\n{}|MappingProxyType({})")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from types import MappingProxyType as MPT\nMPT({})|{}")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from types import MappingProxyType as MPT\n{}|MPT({})")
self.assertTrue(visitor.dict_union())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
for typ in DICT_UNION_SUPPORTED_TYPES:
names = typ.split(".")
src = "from {} import {} as X\nX() | dict()".format(dotted_name(names[:-1]), names[-1])
visitor = self.visit(src)
self.assertTrue(visitor.dict_union(), msg=src)
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_dict_union_merge(self):
visitor = self.visit("a = {'a':1}\na |= {'b':2}")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {'a':1}\nb = {'b':2}\na |= b")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = dict()\na |= dict()")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = dict()\nb = dict()\na |= b")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {}\nfor b in ({}, {}, {}):\n\ta |= b")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {}\nfor b in [{}, {}, {}]:\n\ta |= b")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {}\nb = {}\nfor c in (b,):\n\ta |= c")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = {}\na |= (lambda:{})()")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("a = 1\nfor a in [{}]:\n\tfor b in ({},):\n\t\ta |= b")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
# Builtin types were modified to also support "|=".
visitor = self.visit("from os import environ\nos.environ |= {'var':'val'}")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from os import environ\ne=os.environ\ne |= {}")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from os import environ as e\ne |= {}")
self.assertTrue(visitor.dict_union_merge())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
for typ in DICT_UNION_MERGE_SUPPORTED_TYPES:
names = typ.split(".")
src = "from {} import {} as X\nx = X()\nx |= dict()".\
format(dotted_name(names[:-1]), names[-1])
visitor = self.visit(src)
self.assertTrue(visitor.dict_union_merge(), msg=src)
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_builtin_generic_type_annotation(self):
# For each type, either use directly if builtin or import and then use. And the fully-qualified
# variant.
# Examples:
# - from re import Match
# Match[str]
# - import re
# re.Match[str]
# - tuple[str]
# The following annotations are only requiring 3.9 when evaluated, which doesn't happen at
# definition time.
# Spot test without annotations evaluation enabled first.
self.config.set_eval_annotations(False)
visitor = self.visit("dict[str, list[int]]")
self.assertFalse(visitor.builtin_generic_type_annotations())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Instruct to eval annotations even though they aren't directly since that is
# what this test is about.
self.config.set_eval_annotations(True)
for typ in BUILTIN_GENERIC_ANNOTATION_TYPES:
names = [typ]
src = ""
if "." in typ:
names = typ.split(".")
src = "from {} import {}\n".format(dotted_name(names[:-1]), names[-1])
src += "{}[str]".format(names[-1])
visitor = self.visit(src)
self.assertTrue(visitor.builtin_generic_type_annotations(), msg=src)
self.assertOnlyIn((3, 9), visitor.minimum_versions())
if len(names) > 1:
src = "import {}\n{}[str]".format(dotted_name(names[:-1]), dotted_name(names))
visitor = self.visit(src)
self.assertTrue(visitor.builtin_generic_type_annotations(), msg=src)
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("class A: pass\nA[str]")
self.assertFalse(visitor.builtin_generic_type_annotations())
# Ignore user-defined types that clash with builtin types.
visitor = self.visit("class dict: pass\ndict[str]")
self.assertFalse(visitor.builtin_generic_type_annotations())
visitor = self.visit("dict[str, list[int]]")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("tuple[int, ...]")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("from collections import ChainMap\nChainMap[str, list[str]]")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("l = list[str]()")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("import types\nisinstance(list[str], types.GenericAlias)")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("l = list\nl[-1]")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
# Not a result because a list instance rather than list type is used.
visitor = self.visit("l = [1,2,3]\nl[-1]")
self.assertFalse(visitor.builtin_generic_type_annotations())
visitor = self.visit("""import collections
collections.ChainMap[str]
""")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("""import collections.abc
collections.abc.Reversible[int]
""")
self.assertTrue(visitor.builtin_generic_type_annotations())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_issue_66_annotations(self):
self.assertOnlyIn((3, 7), self.detect("""
from __future__ import annotations
def foo() -> list[int]:
return [0]
foo()"""))
self.config.set_eval_annotations(True)
self.assertOnlyIn((3, 9), self.detect("""
from __future__ import annotations
import typing
def foo() -> list[int]:
return [0]
typing.get_type_hints(foo)"""))
def test_function_decorators(self):
visitor = self.visit("def foo(): pass")
self.assertFalse(visitor.function_decorators())
visitor = self.visit("@f\ndef foo(): pass")
self.assertTrue(visitor.function_decorators())
self.assertOnlyIn(((2, 4), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@button_0.clicked.connect\ndef foo(): pass")
self.assertTrue(visitor.function_decorators())
self.assertOnlyIn(((2, 4), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@eval('buttons[1].clicked.connect')\ndef foo(): pass")
self.assertTrue(visitor.function_decorators())
self.assertOnlyIn(((2, 4), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@x.y(func)\ndef foo(): pass")
self.assertTrue(visitor.function_decorators())
self.assertOnlyIn(((2, 4), (3, 0)), visitor.minimum_versions())
def test_class_decorators(self):
visitor = self.visit("class A: pass")
self.assertFalse(visitor.class_decorators())
visitor = self.visit("@f\nclass A: pass")
self.assertTrue(visitor.class_decorators())
self.assertOnlyIn(((2, 6), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@button_0.clicked.connect\nclass A: pass")
self.assertTrue(visitor.class_decorators())
self.assertOnlyIn(((2, 6), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@eval('buttons[1].clicked.connect')\nclass A: pass")
self.assertTrue(visitor.class_decorators())
self.assertOnlyIn(((2, 6), (3, 0)), visitor.minimum_versions())
visitor = self.visit("@x.y(func)\nclass A: pass")
self.assertTrue(visitor.class_decorators())
self.assertOnlyIn(((2, 6), (3, 0)), visitor.minimum_versions())
def test_relaxed_decorators(self):
visitor = self.visit("@f\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@button_0.clicked.connect\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@eval('buttons[1].clicked.connect')\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@_(buttons[0].clicked.connect)\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@functools.wraps(func)\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@f\nclass foo: pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@button_0.clicked.connect\nclass foo: pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@eval('buttons[1].clicked.connect')\nclass foo: pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@_(buttons[0].clicked.connect)\nclass foo: pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@functools.wraps(func)\nclass foo: pass")
self.assertFalse(visitor.relaxed_decorators())
if current_version() >= (3, 6):
visitor = self.visit("@f\nasync def foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@button_0.clicked.connect\nasync def foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@eval('buttons[1].clicked.connect')\nasync def foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@_(buttons[0].clicked.connect)\nasync def foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@functools.wraps(func)\nasync def foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
if current_version() >= (3, 9):
visitor = self.visit("@[bax][0]\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@[bax][0] # novm\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("# novm\n@[bax][0]\ndef foo(): pass")
self.assertFalse(visitor.relaxed_decorators())
visitor = self.visit("@x[0]()\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@(lambda x: 1)\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\n@not_relaxed\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@non_relaxed\n@buttons[1].clicked.connect\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit(
"@non_relaxed\n@buttons[1].clicked.connect\n@not_relaxed\ndef foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@[bax][0]\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@x[0]()\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@(lambda x: 1)\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\n@not_relaxed\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@non_relaxed\n@buttons[1].clicked.connect\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit(
"@non_relaxed\n@buttons[1].clicked.connect\n@not_relaxed\nclass foo: pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@[bax][0]\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@x[0]()\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@(lambda x: 1)\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@buttons[1].clicked.connect\n@not_relaxed\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit("@non_relaxed\n@buttons[1].clicked.connect\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
visitor = self.visit(
"@non_relaxed\n@buttons[1].clicked.connect\n@not_relaxed\nasync def foo(): pass")
self.assertTrue(visitor.relaxed_decorators())
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_module_dir_func(self):
visitor = self.visit("def __dir__(): pass", path="__init__.py")
self.assertTrue(visitor.module_dir_func())
visitor = self.visit("def __dir__(): pass")
self.assertFalse(visitor.module_dir_func())
visitor = self.visit("def __dir__(a): pass", path="__init__.py")
self.assertFalse(visitor.module_dir_func())
visitor = self.visit("def __dir__(a, b=1): pass", path="__init__.py")
self.assertFalse(visitor.module_dir_func())
visitor = self.visit("def __dir__(b=1): pass", path="__init__.py")
self.assertFalse(visitor.module_dir_func())
visitor = self.visit("""def foo():
def __dir__(): pass
""", path="__init__.py")
self.assertFalse(visitor.module_dir_func())
def test_module_getattr_func(self):
visitor = self.visit("def __getattr__(name): pass", path="__init__.py")
self.assertTrue(visitor.module_getattr_func())
visitor = self.visit("def __getattr__(a): pass", path="__init__.py")
self.assertTrue(visitor.module_getattr_func())
visitor = self.visit("def __getattr__(name): pass")
self.assertFalse(visitor.module_getattr_func())
visitor = self.visit("def __getattr__(n, b=2): pass", path="__init__.py")
self.assertFalse(visitor.module_getattr_func())
visitor = self.visit("def __getattr__(): pass", path="__init__.py")
self.assertFalse(visitor.module_getattr_func())
visitor = self.visit("""def foo():
def __getattr__(name): pass
""", path="__init__.py")
self.assertFalse(visitor.module_getattr_func())
def test_for_target_ignore_user_def(self):
# unpacking assignment requires !2, 3.0
self.assertEqual([None, (3, 0)], self.detect("""
for a, (*file, c[d+e::f(g)], h.i) in []:
file()
"""))
# The user-def passed out of scope, so match `file` as 2, !3.
self.assertEqual([(2, 0), None], self.detect("""
for a, file, b in []:
pass
file()
"""))
def test_with_items_ignore_user_def(self):
# See `visit_With` for reason for only testing on 3.3+ for first and third test case of this
# function.
# Multiple context expressions in a `with` statement is 2.7, 3.1.
if current_version() >= (3, 3):
self.assertEqual([(2, 7), (3, 1)], self.detect("""
with False as a, True as file, 42 as b:
file()
"""))
self.assertEqual([(2, 5), (3, 0)], self.detect("""
with ctx() as (file,):
file()
"""))
# The user-def passed out of scope, so match `file` as 2, !3 -> 2.7, !3 due to
# multiple context expressions in a `with` statement.
if current_version() >= (3, 3):
self.assertEqual([(2, 7), None], self.detect("""
with False as a, True as file, 42 as b:
pass
file()
"""))
def test_except_handler_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
try:
1 / 0
except ZeroDivisionError as file:
file()
"""))
# The user-def passed out of scope, so match `file` as 2, !3.
self.assertEqual([(2, 0), None], self.detect("""
try:
1 / 0
except ZeroDivisionError as file:
pass
file()
"""))
def test_func_name_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
def file():
file()
"""))
def test_func_arg_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
def foo(a, file, b):
file()
"""))
# The user-def passed out of scope, so match `file` as 2, !3.
self.assertEqual([(2, 0), None], self.detect("""
def foo(a, file, b):
pass
file()
"""))
@VerminTest.skipUnlessVersion(3, 8)
def test_func_posonlyarg_ignore_user_def(self):
self.assertEqual([None, (3, 8)], self.detect("""
def foo(file, /, a="Hello"):
file()
"""))
# The user-def passed out of scope, and exception because `file` requries 2, !3 and posonlyargs
# requires !2, 3.8.
with self.assertRaises(InvalidVersionException):
self.visit("""
def foo(file, /, a="Hello"):
pass
file()
""")
def test_func_kwonlyarg_ignore_user_def(self):
self.assertEqual([None, (3, 0)], self.detect("""
def foo(a, *, file="Hello"):
file()
"""))
# The user-def passed out of scope, and exception because `file` requries 2, !3 and kwonlyargs
# requires !2, 3.
with self.assertRaises(InvalidVersionException):
self.visit("""
def foo(a, *, file="Hello"):
pass
file()
""")
def test_func_vararg_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
def foo(*file):
file()
"""))
def test_func_kwarg_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
def foo(**file):
file()
"""))
def test_lambda_arg_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
(lambda file: file())(print)
"""))
def test_class_name_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
class file:
def __init__(self):
file()
"""))
def test_assign_target_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
file = None
file()
"""))
# unpacking assignment requires !2, 3.0
self.assertEqual([None, (3, 0)], self.detect("""
a, (*file, c[d+e::f(g)], h.i) = [], []
file()
"""))
def test_aug_assign_target_ignore_user_def(self):
# Semantically, this AugAssign cannot be without an initial Assign but this tests that AugAssign
# adds the user-def and not the Assign.
self.assertEqual([(0, 0), (0, 0)], self.detect("""
file += 1
file()
"""))
@VerminTest.skipUnlessVersion(3, 6)
def test_ann_assign_target_ignore_user_def(self):
# variable annotations requires !2, 3.6
self.assertEqual([None, (3, 6)], self.detect("""
file: int = 42
file()
"""))
def test_import_as_target_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
import sys as file
file()
"""))
def test_import_from_as_target_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
from sys import exit as file
file()
"""))
@VerminTest.skipUnlessVersion(3, 8)
def test_named_expr_assign_target_ignore_user_def(self):
# named expressions requires !2, 3.8
self.assertEqual([None, (3, 8)], self.detect("""
(file := 42)
file()
"""))
def test_comprehension_assign_target_ignore_user_def(self):
self.assertEqual([(0, 0), (0, 0)], self.detect("""
[file() for file in [lambda: None]]
"""))
# set comprehension requires 2.7, 3.0
self.assertEqual([(2, 7), (3, 0)], self.detect("""
{file() for file in [lambda: None]}
"""))
# dict comprehension requires 2.7, 3.0
self.assertEqual([(2, 7), (3, 0)], self.detect("""
{file(): 1 for file in [lambda: None]}
"""))
self.assertEqual([(0, 0), (0, 0)], self.detect("""
(file() for file in [lambda: None])
"""))
self.assertEqual([(0, 0), (0, 0)], self.detect("""
[file() for a, file in [1]]
"""))
if current_version() >= (3,):
self.assertEqual([None, (3, 0)], self.detect("""
[file() for a, *file in [1]]
"""))
# After comprehension, `file` rules apply.
self.assertEqual([(2, 0), None], self.detect("""
[file() for a, file in [1]], file()
"""))
# After comprehension, `file` rules apply but unpacking assignment requires !2, 3.
with self.assertRaises(InvalidVersionException):
self.visit("""
[file() for a, *file in [1]], file()
""")
# `file` rules apply because the target is bound in the inner-most comprehension and not the
# outer-most one.
self.assertEqual([(2, 0), None], self.detect("""
[file() for w, x[[file for file in [1]][0]] in [(1, 1)]]
"""))
def test_bare_except_handler(self):
# Support having a bare except handler: `node.type` in `visit_ExceptHandler`.
try:
self.visit("""
try:
pass
except:
pass
""")
except AttributeError:
self.fail("Crashed while parsing bare except handler.")
@VerminTest.skipUnlessVersion(3, 10)
def test_pattern_matching(self):
visitor = self.visit("""
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
""")
self.assertTrue(visitor.pattern_matching())
def test_union_types_enabled(self):
self.config.enable_feature("union-types")
visitor = self.visit("int | float")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("a = 1 | 0")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = {'x':1}
b = {'y':2}
a | b
""")
self.assertFalse(visitor.union_types())
visitor = self.visit('isinstance("", int | str)')
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("issubclass(bool, int | float)")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
a = str
a |= "test"
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = "test"
a |= int
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = str
a |= int
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
class Foo: pass
class Bar: pass
a = Foo() | Bar()
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
class Foo: pass
foo = Foo()
class Bar: pass
bar = Bar()
a = foo | bar
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
class Foo: pass
class Bar: pass
a = Foo | Bar
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
class Foo: pass
class Bar: pass
a = Foo
a |= Bar
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
# Issue 103: Don't judge `|` operator applied to values, and not types, as a union of types.
visitor = self.visit("""
index = 0
c_bitmap = [42]
exec_result = [42]
global_byte = c_bitmap[index]
local_byte = exec_result[index]
if (global_byte | local_byte) != global_byte:
pass
""")
self.assertFalse(visitor.union_types())
if current_version() >= (3, 10):
# Issue 159: Attributes can also be used for union types.
visitor = self.visit("""
def function(argument: ipaddress.IPv4Interface | ipaddress.IPv6Interface):
if isinstance(argument, ipaddress.IPv4Address):
print("We got an IPv4")
elif isinstance(argument, ipaddress.IPv6Address):
print("We got an IPv6")
else:
print(f"We got type {type(argument)}")
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def function(argument: ipaddress.IPv4Interface | None):
pass
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def function(argument: None | ipaddress.IPv4Interface):
pass
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def function(argument: str | ipaddress.IPv4Interface):
pass
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
# Issue 109: When not evaluating annotations, returns annotations must not be visited.
self.config.set_eval_annotations(False)
visitor = self.visit("""
from __future__ import annotations
def b(s: str) -> str | None: # <-- don't visit returns node.
return s
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
from __future__ import annotations
a: str | None = None
def b(s: str) -> str | None: # <-- don't visit returns node.
return s
b(a or '')
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
def square(number) -> int | float:
return number ** 2
""")
self.assertFalse(visitor.union_types())
# Issue 109: When evaluating annotations, visit returns annotations.
self.config.set_eval_annotations(True)
visitor = self.visit("""
from __future__ import annotations
def b(s: str) -> str | None: # <-- visit returns node.
return s
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
from __future__ import annotations
a: str | None = None
def b(s: str) -> str | None: # <-- visit returns node.
return s
b(a or '')
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def square(number) -> int | float:
return number ** 2
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
self.config.set_eval_annotations(False)
visitor = self.visit("""
def square(number: int | float):
return number ** 2
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def square(number: int | float) -> int | float:
return number ** 2
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
self.config.set_eval_annotations(False)
visitor = self.visit("a: int | float = 1")
self.assertFalse(visitor.union_types())
self.assertTrue(visitor.maybe_annotations())
# variable annotations requires !2, 3.6
self.assertOnlyIn((3, 6), visitor.minimum_versions())
self.config.set_eval_annotations(True)
visitor = self.visit("a: int | float = 1")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
self.config.set_eval_annotations(False)
visitor = self.visit("""
a = int
b = str
c: a | b = 1
""")
self.assertFalse(visitor.union_types())
self.assertTrue(visitor.maybe_annotations())
self.assertOnlyIn((3, 6), visitor.minimum_versions())
self.config.set_eval_annotations(True)
visitor = self.visit("""
a = int
b = str
c: a | b = 1
""")
self.assertTrue(visitor.union_types())
self.assertFalse(visitor.maybe_annotations())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("a: int | None")
self.assertTrue(visitor.union_types())
self.assertFalse(visitor.maybe_annotations())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("a: None | int")
self.assertTrue(visitor.union_types())
self.assertFalse(visitor.maybe_annotations())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("a: None | None")
self.assertTrue(visitor.union_types())
self.assertFalse(visitor.maybe_annotations())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
def foo(n: int | None):
return n
""")
self.assertTrue(visitor.union_types())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
visitor = self.visit("""
a = int
b = None
c: a | b = 1 # though in this case `b` is a Name and not Constant.
""")
self.assertTrue(visitor.union_types())
self.assertFalse(visitor.maybe_annotations())
self.assertOnlyIn((3, 10), visitor.minimum_versions())
def test_union_types_disabled(self):
self.assertFalse(self.config.has_feature("union-types"))
# --- Normally true but false because the feature is disabled. ---
visitor = self.visit("int | float")
self.assertFalse(visitor.union_types())
visitor = self.visit('isinstance("", int | str)')
self.assertFalse(visitor.union_types())
visitor = self.visit("issubclass(bool, int | float)")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = str
a |= int
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
class Foo: pass
class Bar: pass
a = Foo | Bar
""")
self.assertFalse(visitor.union_types())
if current_version() >= (3, 10):
# Issue 159: Attributes can also be used for union types.
visitor = self.visit("""
def function(argument: ipaddress.IPv4Interface | ipaddress.IPv6Interface):
if isinstance(argument, ipaddress.IPv4Address):
print("We got an IPv4")
elif isinstance(argument, ipaddress.IPv6Address):
print("We got an IPv6")
else:
print(f"We got type {type(argument)}")
""")
self.assertFalse(visitor.union_types())
# --- False in all cases, disabled or not. ---
visitor = self.visit("a = 1 | 0")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = {'x':1}
b = {'y':2}
a | b
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = str
a |= "test"
""")
self.assertFalse(visitor.union_types())
visitor = self.visit("""
a = "test"
a |= int
""")
self.assertFalse(visitor.union_types())
# Issue 103: Don't judge `|` operator applied to values, and not types, as a union of types.
visitor = self.visit("""
index = 0
c_bitmap = [42]
exec_result = [42]
global_byte = c_bitmap[index]
local_byte = exec_result[index]
if (global_byte | local_byte) != global_byte:
pass
""")
self.assertFalse(visitor.union_types())
def test_super_no_args(self):
# Without arguments, it's v3.0.
visitor = self.visit("""
class Foo:
def test(self):
super()
""")
self.assertTrue(visitor.super_no_args())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
# With arguments, the mininmum of super() is v2.2/3.0.
visitor = self.visit("""
class Foo:
def test(self):
super(Foo, self)
""")
self.assertFalse(visitor.super_no_args())
self.assertOnlyIn(((2, 2), (3, 0)), visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 11)
def test_except_star(self):
visitor = self.visit("""
try:
pass
except* OSError as ex:
pass
""")
self.assertTrue(visitor.except_star())
self.assertOnlyIn((3, 11), visitor.minimum_versions())
visitor = self.visit("""
try:
pass
except * OSError as ex:
pass
""")
self.assertTrue(visitor.except_star())
self.assertOnlyIn((3, 11), visitor.minimum_versions())
visitor = self.visit("""
def foo():
try:
pass
except* OSError as ex:
pass
""")
self.assertTrue(visitor.except_star())
self.assertOnlyIn((3, 11), visitor.minimum_versions())
visitor = self.visit("""
try:
pass
except OSError as ex:
pass
""")
self.assertFalse(visitor.except_star())
def test_False_constant(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("False"))
def test_True_constant(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("True"))
def test_issue_168_keyword_values(self):
visitor = self.visit("""
ret = subparser.add_parser("qemu")
ret.add_argument("--efi", action=argparse.BooleanOptionalAction, help="...")
""")
# `argparse.BooleanOptionalAction` requires !2, 3.9 but the keyword values weren't visited
# before.
self.assertOnlyIn((3, 9), visitor.minimum_versions())
def test_metaclass_class_keyword(self):
visitor = self.visit("""
class Foo(metaclass="foo"):
pass
""")
self.assertTrue(visitor.metaclass_class_keyword())
self.assertOnlyIn((3, 0), visitor.minimum_versions())
visitor = self.visit("""
class Foo(other="foo"):
pass
""")
self.assertFalse(visitor.metaclass_class_keyword())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
visitor = self.visit("class Foo: pass")
self.assertFalse(visitor.metaclass_class_keyword())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
# Py2 variant not using keyword.
visitor = self.visit("""
class Foo:
__metaclass__ = "foo"
""")
self.assertFalse(visitor.metaclass_class_keyword())
self.assertEqual([(0, 0), (0, 0)], visitor.minimum_versions())
@VerminTest.skipUnlessVersion(3, 12)
def test_generic_class_keyword(self):
visitor = self.visit("""
class Foo[T]:
pass
""")
self.assertTrue(visitor.generic_class())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit("""
class Car[Tire]:
def __init__(self, tire: Tire):
self.tire = tire
def change_tire(self, tire: Tire):
self.tire = tire
""")
self.assertTrue(visitor.generic_class())
self.assertOnlyIn((3, 12), visitor.minimum_versions())
visitor = self.visit("""
class Foo:
pass
""")
self.assertFalse(visitor.generic_class())
@VerminTest.skipUnlessVersion(3, 10)
def test_unary_plus_match_pattern(self):
self.assertEqual([None, (3, 15)], self.detect("""
match x:
case +1:
pass
"""))
self.assertEqual([None, (3, 15)], self.detect("""
match x:
case [1, +2]:
pass
"""))
self.assertEqual([None, (3, 15)], self.detect("""
match x:
case +2 - 3j:
pass
"""))
# Binary `+` must not be flagged.
self.assertEqual([None, (3, 10)], self.detect("""
match x:
case 0.25 + 1.75j:
pass
"""))
@VerminTest.skipUnlessVersion(3, 15)
def test_unary_plus_match_pattern_visitor_flag(self):
visitor = self.visit("""
match x:
case +1:
pass
""")
self.assertTrue(visitor.unary_plus_match_pattern())
@VerminTest.skipUnlessVersion(3, 10)
def test_unary_minus_match_pattern_not_flagged(self):
visitor = self.visit("""
match x:
case -1:
pass
""")
self.assertFalse(visitor.unary_plus_match_pattern())
netromdk-vermin-d650a48/tests/maybe_annotations.py 0000664 0000000 0000000 00000001757 15265463462 0022445 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminMaybeAnnotationsTests(VerminTest):
def setUp(self):
self.config.set_eval_annotations(False)
@VerminTest.skipUnlessVersion(3, 6)
def test_ann_assign(self):
visitor = self.visit("a: b = 1")
self.assertTrue(visitor.maybe_annotations())
@VerminTest.skipUnlessVersion(3, 10)
def test_ann_assign_union_type(self):
visitor = self.visit("a: b | c = 1")
self.assertTrue(visitor.maybe_annotations())
@VerminTest.skipUnlessVersion(3, 6)
def test_lit_annotation(self):
visitor = self.visit("a: Literal = 5")
self.assertTrue(visitor.maybe_annotations())
visitor = self.visit("a: Literal[int] = 5")
self.assertTrue(visitor.maybe_annotations())
@VerminTest.skipUnlessVersion(3, 6)
def test_builtin_generic_annotation(self):
visitor = self.visit("dict[str, list[int]]")
self.assertTrue(visitor.maybe_annotations())
visitor = self.visit("l = list[str]()")
self.assertTrue(visitor.maybe_annotations())
netromdk-vermin-d650a48/tests/module.py 0000664 0000000 0000000 00000050161 15265463462 0020211 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminModuleTests(VerminTest):
def test_argparse(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import argparse"))
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("from argparse import *"))
self.assertTrue(self.config.add_backport("argparse"))
self.assertOnlyIn(((2, 3), (3, 1)), self.detect("import argparse"))
def test_abc(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import abc"))
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import abc as ABC"))
def test_annotationlib(self):
self.assertOnlyIn((3, 14), self.detect("import annotationlib"))
def test_multiprocessing(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import multiprocessing"))
def test_md5(self):
self.assertOnlyIn((2, 0), self.detect("import md5"))
def test__winreg(self):
self.assertOnlyIn((2, 0), self.detect("import _winreg"))
def test_winreg(self):
self.assertOnlyIn((3, 0), self.detect("import winreg"))
def test_BaseHTTPServer(self):
self.assertOnlyIn((2, 0), self.detect("import BaseHTTPServer"))
def test_ConfigParser(self):
self.assertOnlyIn((2, 0), self.detect("import ConfigParser"))
def test_configparser(self):
self.assertOnlyIn((3, 0), self.detect("import configparser"))
self.assertTrue(self.config.add_backport("configparser"))
self.assertOnlyIn(((2, 6), (3, 2)), self.detect("import configparser"))
def test_copy_reg(self):
self.assertOnlyIn((2, 0), self.detect("import copy_reg"))
def test_copyreg(self):
self.assertOnlyIn((3, 0), self.detect("import copyreg"))
def test_Queue(self):
self.assertOnlyIn((2, 0), self.detect("import Queue"))
def test_queue(self):
self.assertOnlyIn((3, 0), self.detect("import queue"))
def test_SocketServer(self):
self.assertOnlyIn((2, 0), self.detect("import SocketServer"))
def test_socketserver(self):
self.assertOnlyIn((3, 0), self.detect("import socketserver"))
def test_markupbase(self):
self.assertOnlyIn((2, 0), self.detect("import markupbase"))
def test__markupbase(self):
self.assertOnlyIn((3, 0), self.detect("import _markupbase"))
def test__thread(self):
self.assertOnlyIn((3, 0), self.detect("import _thread"))
def test_random(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import random"))
def test_repr(self):
self.assertOnlyIn((2, 0), self.detect("import repr"))
def test_reprlib(self):
self.assertOnlyIn((3, 0), self.detect("import reprlib"))
def test_dbm_io(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.io"))
def test_dbm_ndbm(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.ndbm"))
def test_dbm_os(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.os"))
def test_dbm_struct(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.struct"))
def test_dbm_sqlite3(self):
self.assertOnlyIn((3, 13), self.detect("import dbm.sqlite3"))
def test_dbm_sys(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.sys"))
def test_dbm_whichdb(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.whichdb"))
def test_dbm_gnu(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.gnu"))
def test_dbm_dumb(self):
self.assertOnlyIn((3, 0), self.detect("import dbm.dumb"))
def test_html(self):
self.assertOnlyIn((3, 0), self.detect("import html"))
def test_HTMLParser(self):
self.assertOnlyIn((2, 2), self.detect("import HTMLParser"))
def test_htmlentitydefs(self):
self.assertOnlyIn((2, 0), self.detect("import htmlentitydefs"))
def test_http(self):
self.assertOnlyIn((3, 0), self.detect("import http"))
def test_tkinter(self):
self.assertOnlyIn((3, 0), self.detect("import tkinter"))
def test_Tkinter(self):
self.assertOnlyIn((2, 0), self.detect("import Tkinter"))
def test_tomllib(self):
self.assertOnlyIn((3, 11), self.detect("import tomllib"))
def test_urllib2(self):
self.assertOnlyIn((2, 0), self.detect("import urllib2"))
def test_xmlrpc(self):
self.assertOnlyIn((3, 0), self.detect("import xmlrpc"))
def test_sets(self):
self.assertOnlyIn((2, 3), self.detect("import sets"))
def test_socket(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import socket"))
def test_new(self):
self.assertOnlyIn((2, 0), self.detect("import new"))
def test___builtin__(self):
self.assertOnlyIn((2, 0), self.detect("import __builtin__"))
def test_builtins(self):
self.assertOnlyIn((3, 0), self.detect("import builtins"))
def test_ast(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ast"))
def test__ast(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import _ast"))
def test_unittest(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import unittest"))
def test_unittest_mock(self):
self.assertOnlyIn((3, 3), self.detect("import unittest.mock"))
def test_secrets(self):
self.assertOnlyIn((3, 6), self.detect("import secrets"))
def test_asyncio(self):
self.assertOnlyIn((3, 4), self.detect("import asyncio"))
self.assertTrue(self.config.add_backport("asyncio"))
self.assertOnlyIn((3, 3), self.detect("import asyncio"))
def test_asyncio_graph(self):
self.assertOnlyIn((3, 14), self.detect("import asyncio.graph"))
def test_asyncore(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import asyncore"))
def test_atexit(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import atexit"))
def test_audioop(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import audioop"))
def test_typing(self):
self.assertOnlyIn((3, 5), self.detect("import typing"))
self.assertTrue(self.config.add_backport("typing"))
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import typing"))
def test_tracemalloc(self):
self.assertOnlyIn((3, 4), self.detect("import tracemalloc"))
def test_hashlib(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import hashlib"))
def test_faulthandler(self):
self.assertOnlyIn((3, 3), self.detect("import faulthandler"))
def test_ipaddress(self):
self.assertOnlyIn((3, 3), self.detect("import ipaddress"))
self.assertTrue(self.config.add_backport("ipaddress"))
self.assertOnlyIn(((2, 6), (3, 2)), self.detect("import ipaddress"))
def test___future__(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import __future__"))
def test_bisect(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import bisect"))
def test_bz2(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import bz2"))
def test_calendar(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import calendar"))
def test_cgitb(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import cgitb"))
def test_collections(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import collections"))
def test_collections_abc(self):
self.assertOnlyIn((3, 3), self.detect("import collections.abc"))
def test_compression(self):
self.assertOnlyIn((3, 14), self.detect("import compression"))
def test_compression_bz2(self):
self.assertOnlyIn((3, 14), self.detect("import compression.bz2"))
def test_compression_gzip(self):
self.assertOnlyIn((3, 14), self.detect("import compression.gzip"))
def test_compression_lzma(self):
self.assertOnlyIn((3, 14), self.detect("import compression.lzma"))
def test_compression_zlib(self):
self.assertOnlyIn((3, 14), self.detect("import compression.zlib"))
def test_compression_zstd(self):
self.assertOnlyIn((3, 14), self.detect("import compression.zstd"))
def test_concurrent_futures(self):
self.assertOnlyIn((3, 2), self.detect("import concurrent.futures"))
def test_concurrent_interpreters(self):
self.assertOnlyIn((3, 14), self.detect("import concurrent.interpreters"))
def test_compileall(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import compileall"))
def test_contextlib(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import contextlib"))
def test_cookielib(self):
self.assertOnlyIn((2, 4), self.detect("import cookielib"))
def test_http_cookiejar(self):
self.assertOnlyIn((3, 0), self.detect("import http.cookiejar"))
def test_http_server(self):
self.assertOnlyIn((3, 0), self.detect("import http.server"))
def test_cProfile(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import cProfile"))
def test_csv(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import csv"))
def test_ctypes(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import ctypes"))
def test_datetime(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import datetime"))
def test_decimal(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import decimal"))
def test_difflib(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import difflib"))
def test_DocXMLRPCServer(self):
self.assertOnlyIn((2, 3), self.detect("import DocXMLRPCServer"))
def test_xmlrpc_server(self):
self.assertOnlyIn((3, 0), self.detect("import xmlrpc.server"))
def test_xmlrpc_client(self):
self.assertOnlyIn((3, 0), self.detect("import xmlrpc.client"))
def test_dummy_thread(self):
self.assertOnlyIn((2, 3), self.detect("import dummy_thread"))
def test__dummy_thread(self):
self.assertOnlyIn((3, 0), self.detect("import _dummy_thread"))
def test_dummy_threading(self):
self.assertOnlyIn((2, 3), self.detect("import dummy_threading"))
def test_email(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email"))
def test_email_header(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email.header"))
def test_email_errors(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import email.errors"))
def test_email_message(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email.message"))
def test_email_parser(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email.parser"))
def test_email_utils(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email.utils"))
def test_email_charset(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import email.charset"))
def test_email_policy(self):
self.assertOnlyIn((3, 3), self.detect("import email.policy"))
def test_email_contentmanager(self):
self.assertOnlyIn((3, 4), self.detect("import email.contentmanager"))
def test_email_headerregistry(self):
self.assertOnlyIn((3, 3), self.detect("import email.headerregistry"))
def test_encodings_idna(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import encodings.idna"))
def test_encodings_utf_8_sig(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import encodings.utf_8_sig"))
def test_fractions(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import fractions"))
def test_functools(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import functools"))
def test_future_builtins(self):
self.assertOnlyIn((2, 6), self.detect("import future_builtins"))
def test_heapq(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import heapq"))
def test_hmac(self):
self.assertOnlyIn(((2, 2), (3, 0)), self.detect("import hmac"))
def test_hotshot(self):
self.assertOnlyIn((2, 2), self.detect("import hotshot"))
def test_imghdr(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import imghdr"))
def test_imp(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import imp"))
def test_importlib(self):
self.assertOnlyIn(((2, 7), (3, 1)), self.detect("import importlib"))
self.assertTrue(self.config.add_backport("importlib"))
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import importlib"))
def test_inspect(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import inspect"))
def test_io(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import io"))
def test_itertools(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import itertools"))
def test_json(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import json"))
def test_locale(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import locale"))
def test_logging(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import logging"))
def test_logging_config(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import logging.config"))
def test_logging_handlers(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import logging.handlers"))
def test_modulefinder(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import modulefinder"))
def test_msilib(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import msilib"))
def test_numbers(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import numbers"))
def test_optparse(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import optparse"))
def test_ossaudiodev(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import ossaudiodev"))
def test_pickletools(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import pickletools"))
def test_pkgutil(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import pkgutil"))
def test_platform(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import platform"))
def test_popen2(self):
self.assertOnlyIn((2, 0), self.detect("import popen2"))
def test_pyclbr(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import pyclbr"))
def test_pydoc(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import pydoc"))
def test_runpy(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import runpy"))
def test_SimpleXMLRPCServer(self):
self.assertOnlyIn((2, 2), self.detect("import SimpleXMLRPCServer"))
def test_spwd(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import spwd"))
def test_sqlite3(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import sqlite3"))
def test_ssl(self):
self.assertOnlyIn(((2, 6), (3, 0)), self.detect("import ssl"))
def test_string_templatelib(self):
self.assertOnlyIn((3, 14), self.detect("import string.templatelib"))
def test_stringprep(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import stringprep"))
def test_subprocess(self):
self.assertOnlyIn(((2, 4), (3, 0)), self.detect("import subprocess"))
def test_sysconfig(self):
self.assertOnlyIn(((2, 7), (3, 2)), self.detect("import sysconfig"))
def test_tarfile(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import tarfile"))
def test_textwrap(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import textwrap"))
def test_timeit(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import timeit"))
def test_uuid(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import uuid"))
def test_warnings(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import warnings"))
def test_weakref(self):
self.assertOnlyIn(((2, 1), (3, 0)), self.detect("import weakref"))
def test_wsgiref(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import wsgiref"))
def test_wsgiref_types(self):
self.assertOnlyIn((3, 11), self.detect("import wsgiref.types"))
def test_xml_dom(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.dom"))
def test_xml_dom_minidom(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.dom.minidom"))
def test_xml_dom_pulldom(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.dom.pulldom"))
def test_xml_etree_ElementTree(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import xml.etree.ElementTree"))
def test_xml_etree_ElementInclude(self):
self.assertOnlyIn(((2, 5), (3, 0)), self.detect("import xml.etree.ElementInclude"))
def test_xml_parsers_expat(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.parsers.expat"))
def test_xml_sax(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.sax"))
def test_xml_sax_handler(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.sax.handler"))
def test_xml_sax_saxutils(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.sax.saxutils"))
def test_xml_sax_xmlreader(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import xml.sax.xmlreader"))
def test_xmlrpclib(self):
self.assertOnlyIn((2, 2), self.detect("import xmlrpclib"))
def test_zipimport(self):
self.assertOnlyIn(((2, 3), (3, 0)), self.detect("import zipimport"))
def test_lzma(self):
self.assertOnlyIn((3, 3), self.detect("import lzma"))
def test_venv(self):
self.assertOnlyIn((3, 3), self.detect("import venv"))
def test_pathlib(self):
self.assertOnlyIn((3, 4), self.detect("import pathlib"))
def test_pathlib_types(self):
self.assertOnlyIn((3, 14), self.detect("import pathlib.types"))
def test_pdb(self):
self.assertOnlyIn(((2, 0), (3, 0)), self.detect("import pdb"))
def test_contextvars(self):
self.assertOnlyIn((3, 7), self.detect("import contextvars"))
self.assertTrue(self.config.add_backport("contextvars"))
self.assertOnlyIn((3, 5), self.detect("import contextvars"))
def test_dataclasses(self):
self.assertOnlyIn((3, 7), self.detect("import dataclasses"))
self.assertTrue(self.config.add_backport("dataclasses"))
self.assertOnlyIn((3, 6), self.detect("import dataclasses"))
def test_importlib_resources(self):
self.assertOnlyIn((3, 7), self.detect("import importlib.resources"))
def test_importlib_resources_abc(self):
self.assertOnlyIn((3, 11), self.detect("import importlib.resources.abc"))
def test_importlib_metadata(self):
self.assertOnlyIn((3, 8), self.detect("import importlib.metadata"))
def test_multiprocessing_pool(self):
self.assertOnlyIn((3, 0), self.detect("import multiprocessing.pool"))
def test_multiprocessing_shared_memory(self):
self.assertOnlyIn((3, 8), self.detect("import multiprocessing.shared_memory"))
def test_statistics(self):
self.assertOnlyIn((3, 4), self.detect("import statistics"))
self.assertTrue(self.config.add_backport("statistics"))
self.assertOnlyIn(((2, 6), (3, 4)), self.detect("import statistics"))
def test_ensurepip(self):
self.assertOnlyIn(((2, 7), (3, 4)), self.detect("import ensurepip"))
def test_enum(self):
self.assertOnlyIn((3, 4), self.detect("import enum"))
self.assertTrue(self.config.add_backport("enum"))
self.assertOnlyIn(((2, 4), (3, 3)), self.detect("import enum"))
def test_selectors(self):
self.assertOnlyIn((3, 4), self.detect("import selectors"))
def test_zipapp(self):
self.assertOnlyIn((3, 5), self.detect("import zipapp"))
def test_urlparse(self):
self.assertOnlyIn((2, 0), self.detect("import urlparse"))
def test_urllib_parse(self):
self.assertOnlyIn((3, 0), self.detect("import urllib.parse"))
def test_zoneinfo(self):
self.assertOnlyIn((3, 9), self.detect("import zoneinfo"))
def test_graphlib(self):
self.assertOnlyIn((3, 9), self.detect("import graphlib"))
def test_test_support_socket_helper(self):
self.assertOnlyIn((3, 9), self.detect("import test.support.socket_helper"))
def test_test_support_bytecode_helper(self):
self.assertOnlyIn((3, 9), self.detect("import test.support.bytecode_helper"))
def test_test_support_threading_helper(self):
self.assertOnlyIn((3, 10), self.detect("import test.support.threading_helper"))
def test_test_support_os_helper(self):
self.assertOnlyIn((3, 10), self.detect("import test.support.os_helper"))
def test_test_support_import_helper(self):
self.assertOnlyIn((3, 10), self.detect("import test.support.import_helper"))
def test_test_support_warnings_helper(self):
self.assertOnlyIn((3, 10), self.detect("import test.support.warnings_helper"))
def test_math_integer(self):
self.assertOnlyIn((3, 15), self.detect("import math.integer"))
def test_profiling(self):
self.assertOnlyIn((3, 15), self.detect("import profiling"))
def test_profiling_sampling(self):
self.assertOnlyIn((3, 15), self.detect("import profiling.sampling"))
def test_profiling_tracing(self):
self.assertOnlyIn((3, 15), self.detect("import profiling.tracing"))
netromdk-vermin-d650a48/tests/strftime_directive.py 0000664 0000000 0000000 00000001334 15265463462 0022615 0 ustar 00root root 0000000 0000000 from .testutils import VerminTest
class VerminStrftimeDirectiveTests(VerminTest):
def test_G_directive(self):
self.assertOnlyIn((3, 6),
self.detect("from datetime import datetime\ndatetime.now().strftime('%G')"))
def test_u_directive(self):
self.assertOnlyIn((3, 6),
self.detect("from datetime import datetime\ndatetime.now().strftime('%u')"))
def test_V_directive(self):
self.assertOnlyIn((3, 6),
self.detect("from datetime import datetime\ndatetime.now().strftime('%V')"))
def test_f_directive(self):
self.assertOnlyIn(((2, 6), (3, 0)),
self.detect("from datetime import datetime\ndatetime.now().strftime('%f')"))
netromdk-vermin-d650a48/tests/testutils.py 0000664 0000000 0000000 00000015357 15265463462 0020774 0 ustar 00root root 0000000 0000000 import unittest
import sys
import os
from contextlib import contextmanager
from os.path import join
from tempfile import NamedTemporaryFile
from vermin import Config, Arguments, detect, visit
def current_version():
return sys.version_info
def touch(fld, name, contents=None):
filename = join(fld, name)
with open(filename, mode="w", encoding="utf-8") as fp:
if contents is not None:
fp.write(contents)
return filename
@contextmanager
def working_dir(path):
prev_wd = os.getcwd()
try:
os.chdir(path)
yield
finally:
os.chdir(prev_wd)
class VerminTest(unittest.TestCase):
"""General test case class for all Vermin tests."""
def __init__(self, methodName):
super().__init__(methodName)
# Allow test diffs of any size (instead of 640 char max).
self.maxDiff = None
# Append additional assertion message to the end of the normal failure message, instead of
# replacing it.
self.longMessage = True
self.config = Config()
def setUp(self):
self.config.reset()
def detect(self, source):
return detect(source, config=self.config)
def visit(self, source, path=None):
return visit(source, config=self.config, path=path)
def parse_args(self, args, detect_path=None):
return Arguments(args).parse(self.config, detect_path)
@staticmethod
def skipUnlessVersion(major_version, minor_version=0):
"""Decorator that only runs test if at least the specified Python version is being used."""
def decorator(func):
def wrapper(self, *args, **kwargs):
if current_version() >= (major_version, minor_version):
func(self, *args, **kwargs)
return wrapper
return decorator
@staticmethod
def skipUnlessPlatform(platform):
"""Decorator that only runs test if executing on specified platform. It checks that the platform
starts with the provided value, like 'win32' or 'darwin'."""
def decorator(func):
def wrapper(self, *args, **kwargs):
if sys.platform.lower().startswith(platform.strip().lower()):
func(self, *args, **kwargs)
return wrapper
return decorator
@staticmethod
def skipPlatform(platform):
"""Decorator that runs test if executing not on specified platform. It checks that the platform
starts with the provided value, like 'win32' or 'darwin'."""
def decorator(func):
def wrapper(self, *args, **kwargs):
if not sys.platform.lower().startswith(platform.strip().lower()):
func(self, *args, **kwargs)
return wrapper
return decorator
@staticmethod
def parameterized_args(tuple_args):
"""Decorator accepting a list of tuples of arguments."""
def decorator(func):
def wrapper(self):
for args in tuple_args:
func(self, *args)
return wrapper
return decorator
@staticmethod
def parameterized_exceptions(tuple_args):
"""Decorator accepting a list of tuples of arguments, where the first must be the exception type
expected to be raised."""
def decorator(func):
def wrapper(self):
for args in tuple_args:
assert len(args) > 1, "Expected tuple: (exception type, test function args..)"
try:
func(self, *args[1:])
except args[0]:
continue
except Exception as ex: # pragma: no cover
raise AssertionError("Raised {} instead of {} for args: {}".
format(type(ex), args[0], args[1:])) from ex
# pragma: no cover
raise AssertionError("Didn't raise {} for args: {}".format(args[0], args[1:]))
return wrapper
return decorator
def assertOnlyIn(self, values, data, msg=None):
"""Assert only value(s) is in data but ignores None and 0 values."""
size = 1
multiple = isinstance(values, (list, tuple))
if multiple:
# Unless it's a tuple of ints, then it's a version and not a multiple.
if all(isinstance(x, int) for x in values):
multiple = False
else:
size = len(values)
self.assertEqual(len(data) - data.count(None) - data.count(0) - data.count((0, 0)), size, msg)
if multiple:
for value in values:
self.assertIn(value, data, msg)
else:
self.assertIn(values, data, msg)
def assertContainsDict(self, dictionary, data, msg=None):
"""Assert data contains all keys and values of dictionary input."""
msg = ", " + msg if msg is not None else ""
for key in dictionary:
self.assertTrue(key in data, msg="Data doesn't have key '{}'{}".format(key, msg))
value = dictionary[key]
value2 = data[key]
self.assertEqual(value, value2,
msg="key={}, value={} != target={}{}".format(key, value, value2, msg))
def assertEmpty(self, data):
self.assertTrue(len(data) == 0,
msg="Input not empty! size={}, '{}'".format(len(data), data))
def assertNotEmpty(self, data):
self.assertTrue(len(data) != 0, msg="Input empty!")
def assertEqualItems(self, expected, actual):
"""Assert that two sequences contain the same elements, regardless of the ordering.
`assertItemsEqual()` is a 2.7 unittest function. In 3.2 it's called `assertCountEqual()`. This
override is made to work for all versions, also 3.0-3.1."""
v = current_version()
if v >= (3, 2):
self.assertCountEqual(expected, actual)
if (2, 7) <= v < (3, 0): # pragma: no cover
self.assertItemsEqual(expected, actual) # pylint: disable=no-member
else:
self.assertEqual(sorted(expected), sorted(actual))
def assertDetectMinVersions(self, source, min_versions):
"""Assert the minimum versions of `source` is `min_versions`."""
res_versions = self.detect(source)
self.assertOnlyIn(min_versions, res_versions, msg="""Minimum versions: {}
Expected: {}
Source:
{}""".format(res_versions, min_versions, source))
def assertParseArgs(self, args, parsed_args):
"""Assert the parsed arguments from input arguments."""
self.assertContainsDict(parsed_args, self.parse_args(args),
msg="args={}".format(args))
class ScopedTemporaryFile:
"""Creates a temporary file that is automatically removed when this instance goes out of scope.
The difference to NamedTemporaryFile is that it isn't deleted when closing the file.
"""
def __init__(self, suffix=".py"):
# pylint: disable=consider-using-with
self.__fp = NamedTemporaryFile(suffix=suffix, delete=False)
def __del__(self):
os.remove(self.path())
def __enter__(self):
return self
def __exit__(self, _exc_type, _exc_val, _exc_tb):
return False
def write(self, data, newline=False):
self.__fp.write(data)
if newline:
self.__fp.write(b"\n")
def writeln(self, data):
self.write(data, newline=True)
def close(self):
self.__fp.close()
def path(self):
return self.__fp.name
netromdk-vermin-d650a48/tests/utility.py 0000664 0000000 0000000 00000003440 15265463462 0020425 0 ustar 00root root 0000000 0000000 from vermin.utility import split_lines
from .testutils import VerminTest
class UtilityTests(VerminTest):
def test_split_lines_lf(self):
lines, offsets = split_lines("a\nb\n")
self.assertEqual(["a", "b"], lines)
self.assertEqual([0, 2, 4], offsets)
def test_split_lines_lf_no_trailing_terminator(self):
lines, offsets = split_lines("a\nb")
self.assertEqual(["a", "b"], lines)
self.assertEqual([0, 2, 3], offsets)
def test_split_lines_crlf(self):
lines, offsets = split_lines("a\r\nb\r\n")
self.assertEqual(["a", "b"], lines)
self.assertEqual([0, 3, 6], offsets)
def test_split_lines_crlf_mixed(self):
lines, offsets = split_lines("a\r\nb\nc\rd")
self.assertEqual(["a", "b", "c", "d"], lines)
self.assertEqual([0, 3, 5, 7, 8], offsets)
def test_split_lines_bare_cr(self):
lines, offsets = split_lines("a\rb\r")
self.assertEqual(["a", "b"], lines)
self.assertEqual([0, 2, 4], offsets)
def test_split_lines_empty(self):
lines, offsets = split_lines("")
self.assertEqual([], lines)
self.assertEqual([0], offsets)
def test_split_lines_only_terminator(self):
self.assertEqual(([""], [0, 1]), split_lines("\n"))
self.assertEqual(([""], [0, 2]), split_lines("\r\n"))
def test_split_lines_consecutive_terminators(self):
lines, offsets = split_lines("a\n\n")
self.assertEqual(["a", ""], lines)
self.assertEqual([0, 2, 3], offsets)
def test_split_lines_no_terminator(self):
lines, offsets = split_lines("single")
self.assertEqual(["single"], lines)
self.assertEqual([0, 6], offsets)
def test_split_lines_parser_separators_not_split(self):
lines, offsets = split_lines("x = \"\v\f\"\nf\"{y}\"\n")
self.assertEqual(["x = \"\v\f\"", "f\"{y}\""], lines)
self.assertEqual([0, 9, 16], offsets)
netromdk-vermin-d650a48/tests/violations.py 0000664 0000000 0000000 00000026627 15265463462 0021125 0 ustar 00root root 0000000 0000000 from vermin import InvalidVersionException
from .testutils import VerminTest
class VerminViolationsTests(VerminTest):
def setUp(self):
self.config.set_only_show_violations(True)
self.config.set_verbose(3) # Verbosity to get output text to validate.
# NOTE: Each test must define one or two targets to test for violations against. Exactness
# doesn't play any role in determiniting violations, only the exit code of the program.
def test_issue_57_example(self):
self.config.add_target((2, 6))
self.config.add_target((3, 2))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
# "(version)" comments mark the results.
visitor = self.visit("""# file 1:
import enum # 2.4, (3.3)
bytes.maketrans() # (!2), 3.1
all() # 2.5, 3.0
# file 2:
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3: 'bytes.maketrans' member requires !2, 3.1
""", visitor.output_text())
def test_v2_3_target(self):
self.config.add_target((2, 3))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, (3.3)
bytes.maketrans() # (!2), 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3: 'bytes.maketrans' member requires !2, 3.1
L4 C0: 'all' member requires 2.5, 3.0
""", visitor.output_text())
def test_v2_3_target_no_v2_incomp(self):
self.config.add_target((2, 3))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, (3.3)
all() # (2.5), 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([(2, 5), (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3 C0: 'all' member requires 2.5, 3.0
""", visitor.output_text())
def test_v2_4_target(self):
self.config.add_target((2, 4))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, 3.3
bytes.maketrans() # (!2), (3.1)
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 3)], visitor.minimum_versions())
self.assertEqual("""L3: 'bytes.maketrans' member requires !2, 3.1
L4 C0: 'all' member requires 2.5, 3.0
""", visitor.output_text())
def test_v2_4_target_no_v2_incomp(self):
self.config.add_target((2, 4))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, 3.3
all() # (2.5), (3.0)
enumerate() # 2.3, 3.0
""")
self.assertEqual([(2, 5), (3, 3)], visitor.minimum_versions())
self.assertEqual("""L3 C0: 'all' member requires 2.5, 3.0
""", visitor.output_text())
def test_v2_1_v3_1_targets(self):
self.config.add_target((2, 1))
self.config.add_target((3, 1))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, (3.3)
bytes.maketrans() # (!2), 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3: 'bytes.maketrans' member requires !2, 3.1
L4 C0: 'all' member requires 2.5, 3.0
L5 C0: 'enumerate' member requires 2.3, 3.0
""", visitor.output_text())
def test_v2_1_v3_1_targets_no_v2_incomp(self):
self.config.add_target((2, 1))
self.config.add_target((3, 1))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # 2.4, (3.3)
all() # (2.5), 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([(2, 5), (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3 C0: 'all' member requires 2.5, 3.0
L4 C0: 'enumerate' member requires 2.3, 3.0
""", visitor.output_text())
def test_v3_1_target(self):
self.config.add_target((3, 1))
self.config.add_backport("enum") # !2, 3.4 -> 2.4, 3.3
visitor = self.visit("""
import enum # (2.4), (3.3)
bytes.maketrans() # !2, 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
""", visitor.output_text())
def test_2_incomp_3_match_show_no_rules(self):
# !2, == 3.4
self.config.add_target((3, 4))
visitor = self.visit("""
import enum # !2, 3.4 <- match version
bytes.maketrans() # !2, 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 4)], visitor.minimum_versions())
self.assertEmpty(visitor.output_text())
def test_2_incomp_above_3_show_violations(self):
# !2, > 3.1
self.config.add_target((3, 1))
visitor = self.visit("""
import enum # !2, 3.4 <- is > 3.1
bytes.maketrans() # !2, 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 4)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires !2, 3.4
""", visitor.output_text())
def test_2_incomp_below_3_show_no_rules(self):
# !2, < 3.5
self.config.add_target((3, 5))
visitor = self.visit("""
import enum # !2, 3.4
bytes.maketrans() # !2, 3.1
all() # 2.5, 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([None, (3, 4)], visitor.minimum_versions())
self.assertEmpty(visitor.output_text())
def test_2_maybe_3_incomp_show_violations(self):
# ~2, !3
self.config.add_target((3, 1))
visitor = self.visit("""
import hotshot # 2.2, !3 <- Incomp with 3.1 requirement
""")
self.assertEqual([(2, 2), None], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'hotshot' module requires 2.2, !3
""", visitor.output_text())
def test_2_incomp_3_incomp_show_incomp(self):
# !2, !3
self.config.add_target((3, 1))
with self.assertRaises(InvalidVersionException):
self.visit("""
import enum # !2, 3.4
import hotshot # 2.2, !3
""")
def test_two_targets_above_both(self):
# >2.3, >3.0
self.config.add_target((2, 3))
self.config.add_target((3, 0))
self.config.add_backport("enum")
visitor = self.visit("""
import enum # 2.4, (3.3)
all() # (2.5), 3.0
enumerate() # 2.3, 3.0
""")
self.assertEqual([(2, 5), (3, 3)], visitor.minimum_versions())
self.assertEqual("""L2 C7: 'enum' module requires 2.4, 3.3
L3 C0: 'all' member requires 2.5, 3.0
""", visitor.output_text())
def test_two_targets_above_2_below_3(self):
# >2.2, <3.1
self.config.add_target((2, 2))
self.config.add_target((3, 1))
visitor = self.visit("""
all() # (2.5), (3.0)
enumerate() # 2.3, 3.0
""")
self.assertEqual([(2, 5), (3, 0)], visitor.minimum_versions())
self.assertEqual("""L2 C0: 'all' member requires 2.5, 3.0
L3 C0: 'enumerate' member requires 2.3, 3.0
""", visitor.output_text())
def test_two_targets_below_2_above_3(self):
# <2.4, >3.0
self.config.add_target((2, 4))
self.config.add_target((3, 0))
self.config.add_backport("argparse")
visitor = self.visit("""
enumerate() # 2.3, 3.0
import argparse # (2.3), (3.1)
""")
self.assertEqual([(2, 3), (3, 1)], visitor.minimum_versions())
self.assertEqual("""L3 C7: 'argparse' module requires 2.3, 3.1
""", visitor.output_text())
def test_two_targets_below_both(self):
# <2.4, <3.3
self.config.add_target((2, 4))
self.config.add_target((3, 3))
self.config.add_backport("argparse")
visitor = self.visit("""
enumerate() # 2.3, 3.0
import argparse # 2.3, 3.1
""")
# All below targets so no violations: no rules shown.
self.assertEqual([(2, 3), (3, 1)], visitor.minimum_versions())
self.assertEmpty(visitor.output_text())
@VerminTest.skipUnlessVersion(3, 6)
def test_violate_variable_annotations(self):
# Violation.
self.config.add_target((3, 5))
code = "x: int"
visitor = self.visit(code)
self.assertEqual("""L1: variable annotations require !2, 3.6
""", visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((3, 6))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
def test_typing_extensions_no_violation_for_3x(self):
# `typing_extensions` with unversioned backport defaults to `((0,0),(0,0))` sentinel. Do not
# treat as a violation when targeting any Python 3.x.
self.config.add_target((3, 8))
visitor = self.visit("import typing_extensions")
self.assertEmpty(visitor.output_text())
self.config.clear_targets()
self.config.add_target((3, 7))
visitor = self.visit("import typing_extensions")
self.assertEmpty(visitor.output_text())
def test_violate_unpacking_assignment(self):
# Violation.
self.config.add_target((2, 7))
code = "*a, b = [1, 2, 3]"
visitor = self.visit(code)
self.assertEqual("""L1: unpacking assignment requires !2, 3.0
""", visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((3, 0))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
@VerminTest.skipUnlessVersion(3, 5)
def test_violate_generalized_unpacking(self):
# Violation.
self.config.add_target((3, 4))
code = "(*range(4), 4)"
visitor = self.visit(code)
self.assertEqual("""L1: generalized unpacking requires !2, 3.5
""", visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((3, 5))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
def test_violate_mod_inv(self):
# Violation.
self.config.add_target((3, 7))
code = "pow(1, -2, 3)"
visitor = self.visit(code)
self.assertEqual("""L1: modular inverse pow() requires !2, 3.8
""", visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((3, 8))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
def test_violate_format27(self):
# Violation.
self.config.add_target((2, 6))
code = "'hello {}!'.format('world')"
txt = """L1: `"..{}..".format(..)` requires 2.7, 3.0
"""
visitor = self.visit(code)
self.assertEqual(txt, visitor.output_text())
self.config.clear_targets()
self.config.add_target((2, 6))
self.config.add_target((3, 0))
visitor = self.visit(code)
self.assertEqual(txt, visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((2, 7))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
self.config.clear_targets()
self.config.add_target((3, 0))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
self.config.clear_targets()
self.config.add_target((2, 7))
self.config.add_target((3, 0))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
def test_violate_bytesv3(self):
# Violation.
self.config.add_target((2, 5))
code = "a = b'42'"
visitor = self.visit(code)
self.assertEqual("""L1: byte string (b'..') or `str` synonym requires 2.6, 3.0
""", visitor.output_text())
# No violation.
self.config.clear_targets()
self.config.add_target((3, 0))
visitor = self.visit(code)
self.assertEmpty(visitor.output_text())
netromdk-vermin-d650a48/vermin.py 0000775 0000000 0000000 00000000127 15265463462 0017062 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
from vermin.main import main
if __name__ == "__main__":
main()
netromdk-vermin-d650a48/vermin/ 0000775 0000000 0000000 00000000000 15265463462 0016505 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/vermin/__init__.py 0000664 0000000 0000000 00000003307 15265463462 0020621 0 ustar 00root root 0000000 0000000 from .main import main
from .detection import detect, visit, detect_paths, detect_paths_incremental, probably_python_file
from .source_visitor import SourceVisitor
from .parser import Parser
from .processor import Processor
from .rules import MOD_REQS, MOD_MEM_REQS, KWARGS_REQS, STRFTIME_REQS, BYTES_REQS, \
ARRAY_TYPECODE_REQS, CODECS_ERROR_HANDLERS, CODECS_ENCODINGS, BUILTIN_GENERIC_ANNOTATION_TYPES, \
DICT_UNION_SUPPORTED_TYPES, DICT_UNION_MERGE_SUPPORTED_TYPES, DECORATOR_USER_FUNCTIONS
from .arguments import Arguments
from .config import Config
from .utility import reverse_range, dotted_name, combine_versions, InvalidVersionException, \
remove_whitespace, sort_line_column, sort_line_column_parsable, version_strings, \
format_title_descs
from .backports import Backports
from .features import Features
from .constants import DEFAULT_PROCESSES, CONFIG_FILE_NAMES, PROJECT_BOUNDARIES
from . import formats
__all__ = [
"ARRAY_TYPECODE_REQS",
"Arguments",
"BUILTIN_GENERIC_ANNOTATION_TYPES",
"BYTES_REQS",
"Backports",
"CODECS_ENCODINGS",
"CODECS_ERROR_HANDLERS",
"CONFIG_FILE_NAMES",
"Config",
"DECORATOR_USER_FUNCTIONS",
"DEFAULT_PROCESSES",
"DICT_UNION_MERGE_SUPPORTED_TYPES",
"DICT_UNION_SUPPORTED_TYPES",
"Features",
"InvalidVersionException",
"KWARGS_REQS",
"MOD_MEM_REQS",
"MOD_REQS",
"PROJECT_BOUNDARIES",
"Parser",
"Processor",
"STRFTIME_REQS",
"SourceVisitor",
"combine_versions",
"detect",
"detect_paths",
"detect_paths_incremental",
"dotted_name",
"format_title_descs",
"formats",
"main",
"probably_python_file",
"remove_whitespace",
"reverse_range",
"sort_line_column",
"sort_line_column_parsable",
"version_strings",
"visit",
]
netromdk-vermin-d650a48/vermin/arguments.py 0000664 0000000 0000000 00000050755 15265463462 0021100 0 ustar 00root root 0000000 0000000 import sys
import os
from .constants import VERSION, DEFAULT_PROCESSES, CONFIG_FILE_NAMES, PROJECT_BOUNDARIES
from .backports import Backports
from .features import Features
from .formats import ParsableFormat
from .config import Config
from .printing import nprint
from . import formats
class Arguments:
def __init__(self, args):
self.__args = args
@staticmethod
def print_usage(full=False):
print("Vermin {}".format(VERSION))
print("Usage: {} [options] ".format(sys.argv[0]))
print("\nConcurrently detect the minimum Python versions needed to run code.")
if not full:
print("\nFor full help and options, use `-h` or `--help`.")
print("\nHeuristics are employed to determine which files to analyze:\n"
" - 'py', 'py3', 'pyw', 'pyj', 'pyi' are always scanned (unless otherwise excluded)\n"
" - 'pyc', 'pyd', 'pxd', 'pyx', 'pyo' are ignored (including various other files)\n"
" - Magic lines with 'python' are accepted, like: #!/usr/bin/env python\n"
" - Files that cannot be opened for reading as text devices are ignored")
print("\nHowever, Vermin will always attempt to parse any file paths directly specified on\n"
"the command line, even without accepted extensions or heuristics, unless otherwise\n"
"excluded.")
print("\nResults interpretation:")
print(" ~2 No known reason it won't work with py2.")
print(" !2 It is known that it won't work with py2.")
print(" 2.5, !3 Works with 2.5+ but it is known it won't work with py3.")
print(" ~2, 3.4 No known reason it won't work with py2, works with 3.4+")
print("\nIncompatible versions notices mean that several files were detected incompatible\n"
"with py2 and py3 simultaneously. In such cases the results might be inconclusive.")
print("\nA config file is automatically tried detected from the current working directory\n"
"where Vermin is run, following parent folders until either the root or project\n"
"boundary files/folders are reached. However, if --config-file is specified, no config\n"
"is auto-detected and loaded.")
if full:
print("\nConfig file names being looked for: {}\n"
"Project boundary files/folders: {}".
format(", ".join(["'{}'".format(fn) for fn in CONFIG_FILE_NAMES]),
", ".join(["'{}'".format(pb) for pb in PROJECT_BOUNDARIES])))
print("\nOptions:")
print(" --quiet | -q\n"
" Quiet mode. If used together with --violations, quiet mode is preserved\n"
" while showing only violations: no descriptive text, tips, or verdicts.\n")
print(" --no-quiet (default)\n"
" Disable quiet mode.\n")
print(" -v.. Verbosity level 1 to 4. -v, -vv, -vvv, and -vvvv shows increasingly more\n"
" information.\n"
" -v will show the individual versions required per file.\n"
" -vv will also show which modules, functions etc. that constitutes\n"
" the requirements.\n"
" -vvv will also show line/col numbers.\n"
" -vvvv will also show user-defined symbols being ignored.\n")
print(" --target=V | -t=V\n"
" Target version that files must abide by. Can be specified once or twice.\n"
" A '-' can be appended to match target version or smaller, like '-t=3.5-'.\n"
" If not met Vermin will exit with code 1. Vermin will only compare target\n"
" versions with the same major version, so if you do not care about Python\n"
" 2, you can just specify one target for Python 3. However, if used in\n"
" conjunction with --violations, and no rules are triggered, it will exit\n"
" with code 0.\n")
print(" --no-target (default)\n"
" Don't expect certain target version(s).\n")
print(" --processes=N | -p=N\n"
" Use N concurrent processes to detect and analyze files. Defaults to all\n"
" cores ({}).\n".format(DEFAULT_PROCESSES))
print(" --ignore | -i\n"
" Ignore incompatible versions and warnings. However, if no compatible\n"
" versions are found then incompatible versions will be shown in the end to\n"
" not have an absence of results.\n")
print(" --no-ignore (default)\n"
" Don't ignore incompatible versions and warnings.\n")
print(" --dump | -d\n"
" Dump AST node visits.\n")
print(" --no-dump (default)\n"
" Don't dump AST node visits.")
print("\n --help | -h\n"
" Shows this information and exits.")
print("\n --version | -V\n"
" Shows version number and exits.")
print("\n --config-file | -c \n"
" Loads config file unless --no-config-file is specified. Any additional\n"
" arguments supplied are applied on top of that config. See configuration\n"
" section above for more information.")
print("\n --no-config-file\n"
" No automatic config file detection and --config-file argument is disallowed.")
print("\n --hidden\n"
" Analyze 'hidden' files and folders starting with '.'.")
print("\n --no-hidden (default)\n"
" Don't analyze hidden files and folders unless specified directly.")
print("\n --versions\n"
" In the end, print all unique versions required by the analysed code.")
print("\n --show-tips (default)\n"
" Show helpful tips at the end, like those relating to backports or usage of\n"
" unevaluated generic/literal annotations.")
print("\n --no-tips\n"
" Don't show tips.")
print("\n --violations | --lint\n"
" Show only results that violate versions described by --target arguments,\n"
" which are required to be specified. Verbosity mode is automatically set to\n"
" at least 2 in order to show violations in output text, but can be increased\n"
" if necessary.\n\n"
" If no rules are triggered while used in conjunction with --target, an exit\n"
" code 0 will still be yielded due to inconclusivity.\n\n"
" Can be used together with --quiet such that only the violations are shown:\n"
" no descriptive text, tips, or verdicts.")
print("\n --no-violations | --no-lint (default)\n"
" Show regular results.")
print("\n --pessimistic\n"
" Pessimistic mode: syntax errors are interpreted as the major Python version\n"
" in use being incompatible.")
print("\n --no-pessimistic (default)\n"
" Disable pessimistic mode.")
print("\n --eval-annotations\n"
" Instructs parser that annotations will be manually evaluated in code, which\n"
" changes minimum versions in certain cases. Otherwise, function and variable\n"
" annotations are not evaluated at definition time. Apply this argument if\n"
" code uses `typing.get_type_hints` or `eval(obj.__annotations__)` or\n"
" otherwise forces evaluation of annotations.")
print("\n --no-eval-annotations (default)\n"
" Disable annotations evaluation.")
print("\n --parse-comments (default)\n"
" Parse for comments to influence exclusion of code for analysis via\n"
" \"# novm\" and \"# novermin\".")
print("\n --no-parse-comments\n"
" Don't parse for comments. Not parsing comments can sometimes yield a speedup\n"
" of 30-40%+.")
print("\n --scan-symlink-folders\n"
" Scan symlinks to folders to include in analysis.")
print("\n --no-symlink-folders (default)\n"
" Don't scan symlinks to folders to include in analysis. Symlinks\n"
" to non-folders or top-level folders will always be scanned.")
print("\n --format | -f \n"
" Format to show results and output in.\n"
" Supported formats:\n{}".format(formats.help_str(10)))
print("\n [--exclude ] ...\n"
" Exclude full names, like 'email.parser.FeedParser', from analysis. Useful to\n"
" ignore conditional logic that can trigger incompatible results.\n\n"
" Examples:\n"
" Exclude 'foo.bar.baz' module/member: --exclude 'foo.bar.baz'\n"
" Exclude 'foo' kwarg: --exclude 'somemodule.func(foo)'\n"
" Exclude 'bar' codecs error handler: --exclude 'ceh=bar'\n"
" Exclude 'baz' codecs encoding: --exclude 'ce=baz'")
print("\n [--exclude-file ] ...\n"
" Exclude full names like --exclude but from a specified file instead. Each\n"
" line constitutes an exclusion with the same format as with --exclude.")
print("\n --no-exclude (default)\n"
" Use no excludes. Clears any excludes specified before this.")
print("\n [--exclude-regex ] ...\n"
" Exclude files from analysis by matching a regex pattern against their\n"
" entire path as expanded from the Vermin command line. Patterns are matched\n"
" using re.search(), so '^' or '$' anchors should be applied as needed.\n\n"
" Examples:\n"
" Exclude any '.pyi' file: --exclude-regex '\\.pyi$'\n\n"
" (Note: the below examples require --no-make-paths-absolute, or prefixing\n"
" the patterns with the regex-escaped path to the current directory.)\n\n"
" Exclude the directory 'a/b/': --exclude-regex '^a/b$'\n"
" (This will also exclude any files under 'a/b'.)\n\n"
" Exclude '.pyi' files under 'a/b/': --exclude-regex '^a/b/.+\\.pyi$'\n"
" Exclude '.pyi' files in exactly 'a/b/': --exclude-regex '^a/b/[^/]+\\.pyi$'")
print("\n --no-exclude-regex (default)\n"
" Use no exclude patterns. Clears any exclude patterns specified before this.")
print("\n --make-paths-absolute (default)\n"
" Convert any relative paths from the command line into absolute paths.\n"
" This affects the path printed to the terminal if a file fails a check,\n"
" and requires --exclude-regex patterns to match absolute paths.")
print("\n --no-make-paths-absolute\n"
" Do not convert relative paths from the command line into absolute paths.")
print("\n [--backport ] ...\n"
" Some features are sometimes backported into packages, in repositories such\n"
" as PyPi, that are widely used but aren't in the standard language. If such a\n"
" backport is specified as being used, the results will reflect that instead.\n"
" Versioned backports are only used when minimum versions change. Unversioned\n"
" backports must be the newest among versioned and unversioned."
"\n\n"
" Supported backports:\n{}".format(Backports.str(10)))
print("\n --no-backport (default)\n"
" Use no backports. Clears any backports specified before this.")
print("\n [--feature ] ...\n"
" Some features are enabled by default. Others must be\n"
" explicitly enabled:\n{}".format(Features.str(10)))
print("\n --no-feature\n"
" Use no features. Disables all features, including those\n"
" that are enabled by default.")
def parse(self, config, detect_folder=None):
assert config is not None
if len(self.__args) == 0:
return {"code": 1, "usage": True, "full": False}
path_pos = 0
versions = False
fmt = None
detected_config = Config.detect_config_file(detect_folder)
argument_config = None
no_config_file = False
# Preparsing step. Help and version arguments quit immediately and config file parsing must be
# done first such that other arguments can override its settings.
for (i, arg) in enumerate(self.__args):
if arg in ("--help", "-h"):
return {"code": 0, "usage": True, "full": True}
if arg in ("--version", "-V"):
print(VERSION)
sys.exit(0)
if arg == "--no-config-file":
no_config_file = True
detected_config = None
if arg in ("--config-file", "-c"):
if (i + 1) >= len(self.__args):
print("Requires config file path! Example: --config-file /path/to/vermin.ini")
return {"code": 1}
argument_config = os.path.abspath(self.__args[i + 1])
if no_config_file and argument_config:
print("--config-file cannot be used together with --no-config-file!")
return {"code": 1}
# Load potential config file if detected or specified as argument, but prefer config by
# argument.
config_candidate = argument_config or detected_config
loaded_config = False
if config_candidate:
c = Config.parse_file(config_candidate)
if c is None:
return {"code": 1}
loaded_config = True
config.override_from(c)
# Main parsing step.
for (i, arg) in enumerate(self.__args):
if arg in ("--config-file", "-c"):
# Config file parsed again only to ensure path position is correctly increased: reaching
# this point means a well-formed config file was specified and parsed.
path_pos += 2
elif arg in ("--quiet", "-q"):
config.set_quiet(True)
path_pos += 1
elif arg == "--no-quiet":
config.set_quiet(False)
path_pos += 1
elif arg.startswith("-v"):
config.set_verbose(arg.count("v"))
path_pos += 1
elif arg.startswith("-t=") or arg.startswith("--target="):
value = arg.split("=")[1]
if not config.add_target(value):
print("Invalid target: {}".format(value))
return {"code": 1}
path_pos += 1
elif arg == "--no-target":
config.clear_targets()
path_pos += 1
elif arg in ("--ignore", "-i"):
config.set_ignore_incomp(True)
path_pos += 1
elif arg == "--no-ignore":
config.set_ignore_incomp(False)
path_pos += 1
elif arg.startswith("-p=") or arg.startswith("--processes="):
value = arg.split("=")[1]
try:
processes = int(value)
if processes <= 0:
print("Non-positive number: {}".format(processes))
return {"code": 1}
config.set_processes(processes)
except ValueError:
print("Invalid value: {}".format(value))
return {"code": 1}
path_pos += 1
elif arg == "--no-dump":
config.set_print_visits(False)
path_pos += 1
elif arg in ("--dump", "-d"):
config.set_print_visits(True)
path_pos += 1
elif arg == "--hidden":
config.set_analyze_hidden(True)
path_pos += 1
elif arg == "--no-hidden":
config.set_analyze_hidden(False)
path_pos += 1
elif arg == "--versions":
versions = True
path_pos += 1
elif arg == "--show-tips":
config.set_show_tips(True)
path_pos += 1
elif arg == "--no-tips":
config.set_show_tips(False)
path_pos += 1
elif arg in ("--format", "-f"):
if (i + 1) >= len(self.__args):
print("Format requires a name! Example: --format parsable")
return {"code": 1}
fmt_str = self.__args[i + 1].lower()
fmt = formats.from_name(fmt_str)
if fmt is None:
print("Unknown format: {}".format(fmt_str))
return {"code": 1}
path_pos += 2
elif arg == "--exclude":
if (i + 1) >= len(self.__args):
print("Exclusion requires a name! Example: --exclude email.parser.FeedParser")
return {"code": 1}
config.add_exclusion(self.__args[i + 1])
path_pos += 2
elif arg == "--exclude-file":
if (i + 1) >= len(self.__args):
print("Exclusion requires a file name! Example: --exclude-file '~/exclusions.txt'")
return {"code": 1}
config.add_exclusion_file(self.__args[i + 1])
path_pos += 2
elif arg == "--no-exclude":
config.clear_exclusions()
path_pos += 1
elif arg == "--exclude-regex":
if (i + 1) >= len(self.__args):
print("Exclusion requires a regex! Example: --exclude-regex '\\.pyi$'")
return {"code": 1}
config.add_exclusion_regex(self.__args[i + 1])
path_pos += 2
elif arg == "--no-exclude-regex":
config.clear_exclusion_regex()
path_pos += 1
elif arg == "--make-paths-absolute":
config.set_make_paths_absolute(True)
path_pos += 1
elif arg == "--no-make-paths-absolute":
config.set_make_paths_absolute(False)
path_pos += 1
elif arg == "--backport":
if (i + 1) >= len(self.__args):
print("Requires a backport name! Example: --backport typing")
return {"code": 1}
name = self.__args[i + 1]
if not config.add_backport(name):
print("Unknown backport: {}".format(name))
backports = Backports.expand_versions(Backports.version_filter(name))
if len(backports) > 0:
print("Did you mean one of the following?")
print(Backports.str(2, backports))
print("Get the full list of backports via `--help`.")
return {"code": 1}
path_pos += 2
elif arg == "--no-backport":
config.clear_backports()
path_pos += 1
elif arg == "--feature":
if (i + 1) >= len(self.__args):
print("Requires a feature name! Example: --feature fstring-self-doc")
return {"code": 1}
name = self.__args[i + 1]
if not config.enable_feature(name):
print("Unknown feature: {}".format(name))
return {"code": 1}
path_pos += 2
elif arg == "--no-feature":
config.clear_features()
path_pos += 1
elif arg == "--pessimistic":
config.set_pessimistic(True)
path_pos += 1
elif arg == "--no-pessimistic":
config.set_pessimistic(False)
path_pos += 1
elif arg == "--eval-annotations":
config.set_eval_annotations(True)
path_pos += 1
elif arg == "--no-eval-annotations":
config.set_eval_annotations(False)
path_pos += 1
elif arg in ("--violations", "--lint"):
config.set_only_show_violations(True)
path_pos += 1
elif arg in ("--no-violations", "--no-lint"):
config.set_only_show_violations(False)
path_pos += 1
elif arg == "--parse-comments":
config.set_parse_comments(True)
path_pos += 1
elif arg == "--no-parse-comments":
config.set_parse_comments(False)
path_pos += 1
elif arg == "--scan-symlink-folders":
config.set_scan_symlink_folders(True)
path_pos += 1
elif arg == "--no-symlink-folders":
config.set_scan_symlink_folders(False)
path_pos += 1
if fmt is not None:
config.set_format(fmt)
if config.only_show_violations():
if len(config.targets()) == 0:
print("Showing violations requires target(s) to be specified!")
return {"code": 1}
# Automatically set minimum verbosity mode 2 for violations mode.
if config.verbose() < 2:
config.set_verbose(2)
if config.quiet() and config.verbose() > 0 and not config.only_show_violations():
print("Cannot use quiet and verbose modes together!")
return {"code": 1}
parsable = isinstance(config.format(), ParsableFormat)
if parsable:
versions = False
if loaded_config and detected_config and not argument_config and not parsable:
nprint("Using detected config: {}".format(detected_config), config)
paths = self.__args[path_pos:]
return {"code": 0,
"paths": paths,
"versions": versions}
netromdk-vermin-d650a48/vermin/backports.py 0000664 0000000 0000000 00000005005 15265463462 0021047 0 ustar 00root root 0000000 0000000 import re
from .utility import format_title_descs, version_strings
VERSIONED_BACKPORT_REGEX = re.compile(r"([\w_\.]+)\=\=.+")
# Versioned backports must be ordered from oldest minimum version to newest and placed before
# unversioned backport.
BACKPORTS = (
("argparse", ["https://pypi.org/project/argparse/"], ((2, 3), (3, 1))),
("asyncio", ["https://pypi.org/project/asyncio/"], (None, (3, 3))),
("configparser", ["https://pypi.org/project/configparser/"], ((2, 6), (3, 2))),
("contextvars", ["https://pypi.org/project/contextvars/"], (None, (3, 5))),
("dataclasses", ["https://pypi.org/project/dataclasses/"], (None, (3, 6))),
("enum", ["https://pypi.org/project/enum34/"], ((2, 4), (3, 3))),
("importlib", ["https://pypi.org/project/importlib/"], ((2, 3), (3, 0))),
("ipaddress", ["https://pypi.org/project/ipaddress/"], ((2, 6), (3, 2))),
("mock", ["https://pypi.org/project/mock/"], (None, (3, 6))),
("statistics", ["https://pypi.org/project/statistics/"], ((2, 6), (3, 4))),
# Notes:
# Although `typing` backport now requires 2.7 or 3.4+, it originally supported 3.2 and 3.3.
# See: https://github.com/python/typing/blob/02c9d79eb7/prototyping/setup.py
("typing", ["https://pypi.org/project/typing/"], ((2, 7), (3, 2))),
("typing_extensions==4.0", ["https://pypi.org/project/typing-extensions/4.0.0/"], (None, (3, 6))),
("typing_extensions==4.3", ["https://pypi.org/project/typing-extensions/4.3.0/"], (None, (3, 7))),
("typing_extensions", ["https://pypi.org/project/typing-extensions/"], (None, (3, 7))),
("zoneinfo", ["https://pypi.org/project/backports.zoneinfo/"], (None, (3, 6))),
)
class Backports:
@staticmethod
def str(indent=0, backports=BACKPORTS):
return format_title_descs(((mod, ["{} ({})".format(link[0], version_strings(mins))])
for (mod, link, mins) in backports), Backports.modules(), indent)
@staticmethod
def modules():
return {mod for (mod, link, mins) in BACKPORTS}
@staticmethod
def is_backport(module):
return module in Backports.modules()
@staticmethod
def version_filter(module):
m = VERSIONED_BACKPORT_REGEX.match(module)
if m:
return m.group(1)
return module
@staticmethod
def unversioned_filter(modules):
return {Backports.version_filter(bp) for bp in modules}
@staticmethod
def expand_versions(module):
lst = [(mod, link, mins) for (mod, link, mins) in BACKPORTS
if Backports.version_filter(mod) == module]
lst.reverse() # Unversioned should come first.
return lst
netromdk-vermin-d650a48/vermin/config.py 0000664 0000000 0000000 00000034013 15265463462 0020325 0 ustar 00root root 0000000 0000000 import io
import sys
import os
import re
from configparser import ConfigParser, ParsingError # novm
from .backports import Backports
from .features import Features
from .formats import Format, DefaultFormat
from .constants import DEFAULT_PROCESSES, CONFIG_FILE_NAMES, CONFIG_SECTION, PROJECT_BOUNDARIES
from .utility import parse_target
from . import formats
class Config:
def __init__(self):
self.reset()
def reset(self):
self.__quiet = False
self.__verbose = 0
self.__print_visits = False
self.__processes = DEFAULT_PROCESSES
self.__ignore_incomp = False
self.__pessimistic = False
self.__show_tips = True
self.__analyze_hidden = False
self.__exclusions = set()
self.__exclusion_regex = set()
self.__make_paths_absolute = True
self.__backports = set()
self.__features = Features.defaults()
self.__targets = []
self.__eval_annotations = False
self.__only_show_violations = False
self.__parse_comments = True
self.__scan_symlink_folders = False
self.set_format(DefaultFormat())
def override_from(self, other_config):
self.__quiet = other_config.quiet()
self.__verbose = other_config.verbose()
self.__print_visits = other_config.print_visits()
self.__processes = other_config.processes()
self.__ignore_incomp = other_config.ignore_incomp()
self.__pessimistic = other_config.pessimistic()
self.__show_tips = other_config.show_tips()
self.__analyze_hidden = other_config.analyze_hidden()
self.__exclusions = set(other_config.exclusions())
self.__exclusion_regex = {re.compile(r) for r in other_config.exclusion_regex()}
self.__make_paths_absolute = other_config.make_paths_absolute()
self.__backports = other_config.backports()
self.__features = other_config.features()
self.__targets = other_config.targets()
self.__eval_annotations = other_config.eval_annotations()
self.__only_show_violations = other_config.only_show_violations()
self.__parse_comments = other_config.parse_comments()
self.__scan_symlink_folders = other_config.scan_symlink_folders()
self.set_format(other_config.format())
def __repr__(self):
return """{}(
quiet = {}
verbose = {}
print_visits = {}
processes = {}
ignore_incomp = {}
pessimistic = {}
show_tips = {}
analyze_hidden = {}
exclusions = {}
exclusion_regex = {}
make_paths_absolute = {}
backports = {}
features = {}
targets = {}
eval_annotations = {}
only_show_violations = {}
parse_comments = {}
scan_symlink_folders = {}
format = {}
)""".format(self.__class__.__name__, self.quiet(), self.verbose(), self.print_visits(),
self.processes(), self.ignore_incomp(), self.pessimistic(), self.show_tips(),
self.analyze_hidden(), self.exclusions(), self.exclusion_regex(),
self.make_paths_absolute(), list(self.backports()), list(self.features()),
self.targets(), self.eval_annotations(), self.only_show_violations(),
self.parse_comments(), self.scan_symlink_folders(), self.format().name())
@staticmethod
def parse_file(path):
try:
with open(path, mode="r", encoding="utf-8") as fp:
return Config.parse_fp(fp, filename=path)
except Exception as ex:
print("Could not load config file: {}".format(path))
print(ex)
return None
@staticmethod
def parse_data(data):
try:
return Config.parse_fp(io.StringIO(data))
except Exception as ex:
print("Could not load config data")
print(ex)
return None
@staticmethod
def parse_fp(fp, filename=None):
filename = filename or "??>"
config = Config()
def encode_list(iterable):
return "\n".join(iterable)
# Parser with default values from initial instance.
args = {
"quiet": str(config.quiet()),
"verbose": str(config.verbose()),
"print_visits": str(config.print_visits()),
"processes": str(config.processes()),
"ignore_incomp": str(config.ignore_incomp()),
"pessimistic": str(config.pessimistic()),
"show_tips": str(config.show_tips()),
"analyze_hidden": str(config.analyze_hidden()),
"exclusions": encode_list(config.exclusions()),
"exclusion_regex": encode_list(config.exclusion_regex()),
"make_paths_absolute": str(config.make_paths_absolute()),
"backports": encode_list(config.backports()),
"features": encode_list(config.features()),
"targets": encode_list(config.targets()),
"eval_annotations": str(config.eval_annotations()),
"only_show_violations": str(config.only_show_violations()),
"parse_comments": str(config.parse_comments()),
"scan_symlink_folders": str(config.scan_symlink_folders()),
"format": config.format().name(),
}
if sys.version_info < (3, 2): # pragma: no cover
parser = ConfigParser(args)
else:
parser = ConfigParser(args, allow_no_value=True) # novm
try:
if sys.version_info < (3, 2): # pragma: no cover
# pylint: disable=deprecated-method disable=no-member # novm
parser.readfp(fp, filename=filename)
else:
# `read_file` supercedes `readfp` since 3.2.
def readline_generator(fp):
line = fp.readline()
while line:
yield line
line = fp.readline()
parser.read_file(readline_generator(fp), source=filename) # novm
except Exception as ex:
print("Could not load config: {}".format(filename))
print(ex)
return None
if not parser.has_section(CONFIG_SECTION):
print("Missing `[{}]` section in config: {}".format(CONFIG_SECTION, filename))
return None
def getbool(option):
try:
return parser.getboolean(CONFIG_SECTION, option)
except ValueError:
return str(True) == parser.defaults()[option]
def getuint(option):
value = parser.get(CONFIG_SECTION, option)
if len(value) == 0:
return int(parser.defaults()[option])
value = int(value)
if value < 0:
raise ValueError("Not a positive integer (0+): {}".format(option))
return value
def getstringlist(option):
keepends = False
return [ln.strip() for ln in
parser.get(CONFIG_SECTION, option).strip().splitlines(keepends) if ln.strip()]
config.set_quiet(getbool("quiet"))
config.set_verbose(getuint("verbose"))
config.set_print_visits(getbool("print_visits"))
config.set_processes(getuint("processes"))
config.set_ignore_incomp(getbool("ignore_incomp"))
config.set_pessimistic(getbool("pessimistic"))
config.set_show_tips(getbool("show_tips"))
config.set_analyze_hidden(getbool("analyze_hidden"))
config.set_eval_annotations(getbool("eval_annotations"))
config.set_only_show_violations(getbool("only_show_violations"))
config.set_parse_comments(getbool("parse_comments"))
config.set_scan_symlink_folders(getbool("scan_symlink_folders"))
for exclusion in getstringlist("exclusions"):
config.add_exclusion(exclusion)
for exclusion_regex in getstringlist("exclusion_regex"):
config.add_exclusion_regex(exclusion_regex)
config.set_make_paths_absolute(getbool("make_paths_absolute"))
for backport in getstringlist("backports"):
if not config.add_backport(backport):
print("Unknown backport: {}".format(backport))
return None
for feature in getstringlist("features"):
if not config.enable_feature(feature):
print("Unknown feature: {}".format(feature))
return None
targets = getstringlist("targets")
for target in targets:
if not config.add_target(target):
print("Invalid target: {}".format(target))
return None
fmt_str = parser.get(CONFIG_SECTION, "format").strip()
fmt = formats.from_name(fmt_str)
if fmt is None:
print("Unknown format: {}".format(fmt_str))
return None
config.set_format(fmt)
return config
@staticmethod
def detect_config_file(init_folder=None):
"""Detects Vermin config file starting from `init_folder` or CWD. It proceeds through parent
folders until root or project boundaries are reached. Each candidate is checked to be an INI with a
`[vermin]` section in it."""
folder = init_folder or os.getcwd()
while True:
for candidate in CONFIG_FILE_NAMES:
look_for = os.path.join(folder, candidate)
if os.path.exists(look_for):
try:
cp = ConfigParser()
parse_success_files = cp.read(look_for) if sys.version_info < (3, 2) \
else cp.read(look_for, encoding="utf-8") # novm
if look_for in parse_success_files and cp.has_section(CONFIG_SECTION):
return look_for
except ParsingError: # pragma: no cover
pass
# Stop if didn't find config and is at project boundary, which means it has ".git/" or
# similar.
stop = False
for boundary in PROJECT_BOUNDARIES:
path = os.path.join(folder, boundary)
if os.path.exists(path):
stop = True
break
if stop:
break
# Go up one level and stop at root.
old_folder = folder
folder = os.path.abspath(os.path.join(folder, ".."))
if folder == old_folder: # pragma: no cover
break
return None
def quiet(self):
return self.__quiet
def set_quiet(self, quiet):
self.__quiet = quiet
def verbose(self):
return self.__verbose
def set_verbose(self, verbose):
self.__verbose = verbose
def print_visits(self):
return self.__print_visits
def set_print_visits(self, enable):
self.__print_visits = enable
def processes(self):
return self.__processes
def set_processes(self, processes):
self.__processes = processes if processes > 0 else DEFAULT_PROCESSES
def ignore_incomp(self):
return self.__ignore_incomp
def set_ignore_incomp(self, ignore):
self.__ignore_incomp = ignore
def add_exclusion(self, name):
self.__exclusions.add(name)
def add_exclusion_regex(self, pattern):
self.__exclusion_regex.add(re.compile(pattern))
def add_exclusion_file(self, filename):
try:
with open(filename, mode="r", encoding="utf-8") as f:
for line in f.readlines():
self.add_exclusion(line.strip())
except Exception as ex:
print(ex)
def clear_exclusions(self):
self.__exclusions.clear()
def clear_exclusion_regex(self):
self.__exclusion_regex.clear()
def exclusions(self):
res = list(self.__exclusions)
res.sort()
return res
def exclusion_regex(self):
res = [p.pattern for p in self.__exclusion_regex]
res.sort()
return res
def is_excluded(self, name):
return name in self.__exclusions
def is_excluded_kwarg(self, function, keyword):
return "{}({})".format(function, keyword) in self.__exclusions
def is_excluded_codecs_error_handler(self, name):
return "ceh={}".format(name) in self.__exclusions
def is_excluded_codecs_encoding(self, name):
return "ce={}".format(name) in self.__exclusions
def is_excluded_by_regex(self, path):
return any(regex.search(path) for regex in self.__exclusion_regex)
def make_paths_absolute(self):
return self.__make_paths_absolute
def set_make_paths_absolute(self, enable):
self.__make_paths_absolute = enable
def add_backport(self, name):
if not Backports.is_backport(name):
return False
self.__backports.add(name)
return True
def clear_backports(self):
self.__backports.clear()
def backports(self):
return self.__backports
def enable_feature(self, name):
if not Features.is_feature(name):
return False
self.__features.add(name)
return True
def has_feature(self, name):
return name in self.__features
def clear_features(self):
self.__features.clear()
def features(self):
return self.__features
def set_format(self, fmt):
assert isinstance(fmt, Format)
fmt.set_config(self)
self.__format = fmt
def format(self):
return self.__format
def set_pessimistic(self, pessimistic):
self.__pessimistic = pessimistic
def pessimistic(self):
return self.__pessimistic
def set_show_tips(self, show_tips):
self.__show_tips = show_tips
def show_tips(self):
return self.__show_tips
def set_analyze_hidden(self, analyze_hidden):
self.__analyze_hidden = analyze_hidden
def analyze_hidden(self):
return self.__analyze_hidden
def add_target(self, target, exact=True):
"""Adds a target. If target is a string it is parsed, otherwise it is required to be exactness
bool and a version tuple: [exact, (x, y)]. But it can also be a version tuple (x, y) in which case
the `exact` argument is supplied for exactness."""
if len(self.targets()) == 2:
print("A maximum of two targets can be specified!")
return False
# Bundle exactness with version for call site convenience especially if exactness is unchanged
# (stays True):
# add_target((x, y)) vs. add_target([exact, (x, y)])
if isinstance(target, tuple) and len(target) == 2:
target = [exact, target]
if isinstance(target, str):
target = parse_target(target)
if target is None:
return False
if len(target) != 2 or not isinstance(target[0], bool) or not isinstance(target[1], tuple) or\
len(target[1]) != 2:
return False
# Add target and sort for target versions, not boolean values.
self.__targets.append(target)
self.__targets.sort(key=lambda t: t[1])
return True
def clear_targets(self):
self.__targets = []
def targets(self):
return self.__targets
def eval_annotations(self):
return self.__eval_annotations
def set_eval_annotations(self, eval_ann):
self.__eval_annotations = eval_ann
def only_show_violations(self):
return self.__only_show_violations
def set_only_show_violations(self, violations):
self.__only_show_violations = violations
def parse_comments(self):
return self.__parse_comments
def set_parse_comments(self, parse):
self.__parse_comments = parse
def scan_symlink_folders(self):
return self.__scan_symlink_folders
def set_scan_symlink_folders(self, scan):
self.__scan_symlink_folders = scan
netromdk-vermin-d650a48/vermin/constants.py 0000664 0000000 0000000 00000000656 15265463462 0021102 0 ustar 00root root 0000000 0000000 from multiprocessing import cpu_count
VERSION = "1.9.2"
DEFAULT_PROCESSES = cpu_count()
CONFIG_FILE_NAMES = ["vermin.ini", "vermin.conf", ".vermin", "setup.cfg"]
CONFIG_SECTION = "vermin"
PROJECT_BOUNDARIES = [
".bzr", # Bazaar
".fslckout", # Fossil
".git", # Git
".hg", # Mercurial
".p4root", # Perforce Helix Core
".pijul", # Pijul
".svn", # Subversion
"_darcs", # Darcs
]
netromdk-vermin-d650a48/vermin/detection.py 0000664 0000000 0000000 00000023624 15265463462 0021044 0 ustar 00root root 0000000 0000000 from stat import S_ISDIR, S_ISREG, S_ISLNK
from os import listdir, stat, lstat
from os.path import abspath, join, splitext
from multiprocessing import Pool, cpu_count
from .parser import Parser
from .source_visitor import SourceVisitor
from .config import Config
from .printing import nprint, vvprint
NOT_PY_CODE_EXTS = {
"3dm",
"3ds",
"3g2",
"3gp",
"7z",
"8svx",
"DS_Store",
"a",
"aac",
"ac",
"adp",
"aff",
"ai",
"aif",
"aifc",
"aiff",
"aix",
"alz",
"am",
"ape",
"apk",
"applescript",
"ar",
"arj",
"as",
"asf",
"asm",
"au",
"avi",
"bak",
"baml",
"bh",
"bin",
"bk",
"bmp",
"btif",
"bz2",
"bzip2",
"c",
"cab",
"caf",
"cat",
"cc",
"cdxml",
"cfg",
"cgm",
"cl",
"class",
"cmx",
"cnf",
"coffee",
"conf",
"coverity",
"cpio",
"cpp",
"cr2",
"crt",
"cs",
"css",
"css_t",
"csv",
"cur",
"cxx",
"d",
"dart",
"dat",
"dcm",
"deb",
"dectest",
"dex",
"dic",
"dict",
"djvu",
"dll",
"dmg",
"dng",
"doc",
"docm",
"docx",
"dot",
"dotm",
"dra",
"dsk",
"dsp",
"dts",
"dtshd",
"dvb",
"dwg",
"dxf",
"ebnf",
"ecelp4800",
"ecelp7470",
"ecelp9600",
"egg",
"el",
"elc",
"eol",
"eot",
"epub",
"erl",
"es",
"exe",
"exr",
"ext",
"f",
"f4v",
"f90",
"fasl",
"fbs",
"fh",
"fla",
"flac",
"fli",
"flv",
"for",
"fpx",
"fs",
"fsi",
"fsscript",
"fst",
"fsx",
"fvt",
"g3",
"gh",
"gif",
"go",
"graffle",
"gz",
"gzip",
"h",
"h261",
"h263",
"h264",
"hdr",
"hdx",
"hh",
"hpp",
"hrl",
"hs",
"html",
"hxx",
"i",
"icns",
"ico",
"idl",
"idx",
"ief",
"img",
"ini",
"ipa",
"iso",
"jar",
"java",
"jl",
"jpeg",
"jpg",
"jpgv",
"jpm",
"js",
"json",
"jxr",
"key",
"kt",
"kts",
"ktx",
"l",
"latex",
"lha",
"lhs",
"lib",
"lisp",
"litcoffee",
"lsp",
"lua",
"lvp",
"lz",
"lzh",
"lzma",
"lzo",
"m",
"m3u",
"m4",
"m4a",
"m4v",
"mak",
"man",
"mar",
"md",
"mdi",
"mht",
"mid",
"midi",
"mj2",
"mka",
"mkv",
"ml",
"mli",
"mm",
"mmr",
"mng",
"mobi",
"mov",
"movie",
"mp3",
"mp4",
"mp4a",
"mpeg",
"mpg",
"mpga",
"mxu",
"nasm",
"nb",
"nef",
"nib",
"npx",
"nsi",
"nsis",
"numbers",
"nupkg",
"nuspec",
"o",
"oga",
"ogg",
"ogv",
"otf",
"pack",
"pages",
"pbm",
"pcx",
"pdb",
"pdf",
"pea",
"pem",
"pgm",
"phar",
"php",
"php-s",
"php3",
"php4",
"php5",
"php7",
"phps",
"pht",
"phtml",
"pic",
"pl",
"plist",
"pm",
"png",
"pnm",
"pod",
"pot",
"potm",
"potx",
"ppa",
"ppam",
"ppm",
"pps",
"ppsm",
"ppsx",
"ppt",
"pptm",
"pptx",
"pro",
"proj",
"ps",
"ps1",
"ps1xml",
"psc1",
"psd",
"psd1",
"psm1",
"pssc",
"pya",
"pyc",
"pyo",
"pyv",
"qt",
"r",
"rar",
"ras",
"raw",
"rb",
"rc",
"rda",
"rdata",
"rds",
"resources",
"rgb",
"rip",
"rlc",
"rlib",
"rmf",
"rmvb",
"rs",
"rst",
"rtf",
"rz",
"s",
"s3m",
"s7z",
"sccd",
"scm",
"scpt",
"scptd",
"scss",
"sgi",
"shar",
"sil",
"sip",
"sketch",
"slk",
"sln",
"sml",
"smv",
"sndt",
"snk",
"so",
"sql",
"srl",
"ss",
"stl",
"stp",
"sub",
"suo",
"supp",
"svg",
"swf",
"swift",
"t",
"tar",
"tbc",
"tbz",
"tbz2",
"tcl",
"tex",
"tga",
"tgz",
"thm",
"thmx",
"tif",
"tiff",
"tlz",
"ttc",
"ttf",
"txt",
"txz",
"udf",
"ui",
"utf8",
"uvh",
"uvi",
"uvm",
"uvp",
"uvs",
"uvu",
"valgrind",
"vb",
"vcxproj",
"viv",
"vob",
"voc",
"war",
"wasm",
"wat",
"wav",
"wax",
"wbmp",
"wdp",
"weba",
"webm",
"webp",
"whl",
"wim",
"wixproj",
"wl",
"wm",
"wma",
"wmv",
"wmx",
"woff",
"woff2",
"wpr",
"wrm",
"wvx",
"wxl",
"wxs",
"xbm",
"xhtml",
"xif",
"xla",
"xlam",
"xls",
"xlsb",
"xlsm",
"xlsx",
"xlt",
"xltm",
"xltx",
"xm",
"xmind",
"xml",
"xpi",
"xpm",
"xs",
"xsl",
"xwd",
"xz",
"yaml",
"yml",
"z",
"zip",
"zipx",
}
def probably_python_file(path):
_, ext = splitext(path.lower())
ext = ext[1:]
# Always scan definite Python files.
if ext in {"py", "py3", "pyw", "pyj", "pyi"}:
return True
# Skip all non-code Python files.
if ext in {"pyc", "pyd", "pxd", "pyx", "pyo"} or ext in NOT_PY_CODE_EXTS:
return False
# Try opening file for reading as a text device.
try:
with open(path, mode="r", encoding="utf-8") as fp:
for _i in range(10):
# A script with a magic line might contain "python".
line = fp.readline().lower().strip()
if line.startswith("#!") and "python" in line:
return True
except Exception:
# Not python if not readable text file.
return False
return False
# Only invoke os.lstat() once per path. Instead of twice via a call to isdir() and isfile() that
# calls os.stat() internally. Unless it is a symlink, then another os.stat() is made to check what
# is pointed to.
def stat_path(path, scan_symlink_folders=False):
try: # pragma: no cover
st = lstat(path) # Don't follow symlink.
if not S_ISLNK(st.st_mode):
return st
# Ignore symlink if pointing to a dir.
st = stat(path) # Follow symlink.
if S_ISDIR(st.st_mode) and not scan_symlink_folders:
return None
return st
except OSError:
return None
# Called concurrently in an iterative fashion. Each invocation will return accepted paths and a list
# of further arguments tuples, if any.
def detect_paths_incremental(args):
(paths, depth, hidden, ignore_chars, scan_symlink_folders, config) = args
assert config is not None
accepted = []
further_args = []
for path in paths:
try:
if any(ic in path for ic in ignore_chars) or config.is_excluded_by_regex(path):
continue # pragma: no cover
if not hidden and path != "." and path[0] == ".":
continue
if config.make_paths_absolute():
path = abspath(path)
# Scan top-level folders, or input folders, in all cases.
st = stat_path(path, True if depth == 0 else scan_symlink_folders)
if st is None:
continue
if S_ISDIR(st.st_mode):
files = [join(path, p) for p in listdir(path) if hidden or p[0] != "."]
further_args.append((files, depth + 1, hidden, ignore_chars, scan_symlink_folders, config))
elif S_ISREG(st.st_mode) and (depth == 0 or probably_python_file(path)):
accepted.append(path)
except OSError as ex:
nprint("Ignoring {}: {}".format(path, ex), config)
continue
return (accepted, further_args)
# Some detected paths might not be python code since not all files use extensions like ".py" and
# ".pyw", for instance. But try directly specified files on CLI, on depth 0, in any case (non-python
# files will be ignored when trying to parse them). Paths containing chars in `ignore_chars` will be
# ignored, as will any file excluded by regex from the config.
def detect_paths(paths, hidden=False, processes=cpu_count(), ignore_chars=None,
scan_symlink_folders=False, config=None):
assert config is not None
if isinstance(paths, str):
paths = [paths]
accept_paths = []
depth = 0
ignore_chars = ignore_chars or []
args = [(paths, depth, hidden, ignore_chars, scan_symlink_folders, config)]
pool = None
try:
# pylint: disable=consider-using-with
pool = Pool(processes=processes) if processes > 1 else None
# Automatically don't use concurrency when only one process is specified to be used.
def act(args):
if processes == 1:
return [detect_paths_incremental(arg) for arg in args] # pragma: no cover
return pool.imap(detect_paths_incremental, args)
while args:
new_args = []
for (acc, further_args) in act(args):
if acc:
accept_paths += acc
if further_args:
new_args += further_args
args = new_args
except RuntimeError as ex:
# Match the specific multiprocessing bootstrap RuntimeError ("An attempt has been made to start
# a new process before the current process has finished its bootstrapping phase."). Any other
# RuntimeError is a real bug and must propagate.
if "before the current process has finished its bootstrapping phase" not in str(ex):
raise
nprint("""RuntimeError: If running `detect_paths()` outside of `if __name__ == \"__main__\":`
it, or the code calling it, must be done within it instead.""", config)
finally:
if pool:
pool.close()
pool.join()
return accept_paths
def visit(source, config=None, path=None):
"""Analyze source code and yield source code visitor instance which can be queried for further
information. A default config will be used if it isn't specified. If path is specified, it will
occur in errors instead of the default ''. If the source cannot be parsed, the minimum
versions required to parse it will be returned instead of a visitor.
"""
if config is None:
config = Config()
parser = Parser(source, path)
(node, mins, novermin, err_msg) = parser.detect(config)
# cannot parse; mins gives minimum version to successfully parse
if node is None:
if err_msg is not None:
vvprint(err_msg, config)
return mins
visitor = SourceVisitor(config=config, path=path, source=source)
visitor.set_no_lines(novermin)
visitor.tour(node)
# Ensure that minimum versions are calculatd such that `output_text()` invocations make sense.
visitor.minimum_versions()
return visitor
def detect(source, config=None, path=None):
"""Analyze and detect minimum versions from source code. A default config will be used if it isn't
specified. If path is specified, it will occur in errors instead of the default ''.
"""
visitor = visit(source, config, path)
if isinstance(visitor, SourceVisitor):
return visitor.minimum_versions()
# cannot parse; mins gives minimum version to successfully parse
return visitor
netromdk-vermin-d650a48/vermin/features.py 0000664 0000000 0000000 00000001625 15265463462 0020701 0 ustar 00root root 0000000 0000000 from .utility import format_title_descs
DEFAULT_FEATURES = ("fstring-self-doc", "fstring-pep701")
FEATURES = (
("fstring-self-doc", [
"Detect self-documenting fstrings. Enabled by default.",
]),
("fstring-pep701", [
"Detect PEP 701 f-string features (3.12+): same-quote",
"nesting and multi-line expressions. Requires running on",
"Python 3.12+. Enabled by default."
]),
("union-types", [
"[Unstable] Detect union types `X | Y`. Can in some cases",
"wrongly report union types due to having to employ heuristics."
]),
)
class Features:
@staticmethod
def defaults():
return set(DEFAULT_FEATURES)
@staticmethod
def str(indent=0):
return format_title_descs(FEATURES, Features.features(), indent)
@staticmethod
def features():
return {name for (name, desc) in FEATURES}
@staticmethod
def is_feature(feature):
return feature in Features.features()
netromdk-vermin-d650a48/vermin/formats/ 0000775 0000000 0000000 00000000000 15265463462 0020160 5 ustar 00root root 0000000 0000000 netromdk-vermin-d650a48/vermin/formats/__init__.py 0000664 0000000 0000000 00000002740 15265463462 0022274 0 ustar 00root root 0000000 0000000 from .format import Format
from .default_format import DefaultFormat
from .parsable_format import ParsableFormat
from .github_format import GitHubFormat
from ..utility import format_title_descs
FORMATS = (
("default", ["Default formatting."]),
("colored", ["Same as default, but prints with ANSI styling."]),
("parsable", [
"Each result is on form 'file:line:column:py2:py3:feature'. The",
"last line has no path or line/column numbers and contains the",
"minimum py2 and py3 versions. Minimum verbosity level is set to",
"3 but can be increased. Tips, hints, incompatible versions, and",
"`--versions` are disabled. File paths containing ':' are ignored."
]),
("github", [
"Same as parsable format, but each result is formatted as a GitHub",
"Actions annotation. Minimum version messages are annotated as",
"errors, and all other verbose messages as notices. The intent is",
"that it be used for linting in a GitHub Actions pipeline."
]),
)
def names():
return {name for (name, desc) in FORMATS}
def from_name(name):
if name == "default":
return DefaultFormat()
if name == "colored":
return DefaultFormat(colored=True)
if name == "parsable":
return ParsableFormat()
if name == "github":
return GitHubFormat()
return None
def help_str(indent=0):
return format_title_descs(FORMATS, names(), indent)
__all__ = [
"DefaultFormat",
"Format",
"ParsableFormat",
"GitHubFormat",
"from_name",
"help_str",
"names",
]
netromdk-vermin-d650a48/vermin/formats/default_format.py 0000664 0000000 0000000 00000003572 15265463462 0023535 0 ustar 00root root 0000000 0000000 from .format import Format
from ..utility import version_strings, sort_line_column
from ..printing import vprint, sgr
class DefaultFormat(Format):
def __init__(self, colored=False):
super().__init__("colored" if colored else "default")
self.colored = colored
"""Whether ANSI colored styling is enabled."""
def __maybe_style(self, msg, violation):
if self.colored:
return sgr(msg, 91 if violation else 92) # bright red or bright green
return msg
@Format.require_config
def skip_output_line(self):
return self.config().quiet()
@Format.require_config
def format_output_line(self, msg, path=None, line=None, col=None,
versions=None, plural=None, violation=False):
if plural is None:
plural = msg.strip().endswith("s")
if self.config().verbose() < 3:
line = None
col = None
line = "L{}".format(line) if line is not None else ""
col = " C{}".format(col) if col is not None else ""
lc = "{}{}".format(line, col)
if len(lc) > 0:
lc += ": "
vers = " require{} {}".format("s" if not plural else "", version_strings(versions)) \
if versions is not None else ""
return self.__maybe_style("{}{}{}".format(lc, msg, vers), violation)
@Format.require_config
def output_result(self, proc_res):
# Indent subtext.
subtext = ""
if len(proc_res.text) > 0:
lines = proc_res.text.splitlines(True)
subtext = "\n " + " ".join(lines)
if not subtext.endswith("\n"):
subtext += "\n" # pragma: no cover
msg = "{:<12} {}{}".format(version_strings(proc_res.mins), proc_res.path, subtext)
vprint(msg, self.config())
@Format.require_config
def sort_output_lines(self, lines):
if self.config().verbose() > 2 and not self.config().print_visits():
lines.sort(key=sort_line_column) # pragma: no cover
else:
lines.sort()
return lines
netromdk-vermin-d650a48/vermin/formats/format.py 0000664 0000000 0000000 00000002642 15265463462 0022026 0 ustar 00root root 0000000 0000000 from abc import ABCMeta, abstractmethod
class Format(metaclass=ABCMeta):
"""Format encapsulates a format for presenting minimum versions and related information during
processing."""
def __init__(self, name):
self.__name = name
self.__config = None
def name(self):
return self.__name
def config(self):
return self.__config
def set_config(self, config):
self.__config = config
@staticmethod
def require_config(funcobj):
"""Decorator that checks config is not None."""
def _require_config(self, *args, **kwargs):
assert self.config() is not None
return funcobj(self, *args, **kwargs)
return _require_config
@abstractmethod
def skip_output_line(self):
"""Whether or not to skip outputting a line."""
@abstractmethod
def format_output_line(self, msg, path=None, line=None, col=None,
versions=None, plural=None, violation=False):
"""Yield formatted output line given file name, line, column, text, minimum versions. The
plurality can be overridden but will otherwise be controlled by ending with 's' or not. The
final violation flag indicates whether the message indicates a version target violation or an
exception during analysis.
"""
@abstractmethod
def output_result(self, proc_res):
"""Output processed result."""
@abstractmethod
def sort_output_lines(self, lines):
"""Sort and return output lines."""
netromdk-vermin-d650a48/vermin/formats/github_format.py 0000664 0000000 0000000 00000006035 15265463462 0023370 0 ustar 00root root 0000000 0000000 import os
import re
from ..utility import bounded_str_hash, version_strings
from .parsable_format import ParsableFormat
def escape(value):
"""Escape special characters in GitHub Actions annotations. Not to be used for messages."""
return (
str(value)
.replace('%', '%25') # must be first
.replace(',', '%2C')
.replace(':', '%3A')
)
class GitHubFormat(ParsableFormat):
"""Variant of ParsableFormat which outputs as Github Actions annotations."""
def __init__(self, name="github"):
super().__init__(name)
self.order = {}
"""cache sort order of lines; SourceVisitor maintains an internal list of outputs from
format_output_line; these are later deduplicated in a set, then passed to sort_output_lines;
so caching their order uses minimal extra memory and avoids a fragile parse of the already
serialized data to extract its sort order
"""
self.cwd = os.getcwd()
"""current working directory, to relativize paths"""
def format_output_line(self, msg, path=None, line=None, col=None,
versions=None, plural=None, violation=False):
# default title is for generic analysis errors/notices
title = "Python version requirement analysis"
level = "error" if violation else "notice"
if versions is not None:
versions = version_strings(versions)
title = "Requires Python {}".format(versions)
if msg is None:
if versions is None:
msg = "user-defined symbols being ignored"
# msg is None when providing a summary
elif path is None:
msg = "Minimum Python version required across all files: {}".format(versions)
else:
msg = "Minimum Python version required for this file: {}".format(versions)
# github actions can't display multiline messages
if msg is not None:
msg = re.sub(r'(\r\n|\r|\n)', ' | ', str(msg))
# relativize path so github can link to it in a PR
if path is not None:
try:
path = os.path.abspath(path)
path = os.path.relpath(path, self.cwd)
except ValueError:
pass
vals = {
"file": path,
"line": line,
"col": col,
"title": title,
}
args = ",".join("{}={}".format(k, escape(v)) for k, v in vals.items() if v is not None)
out = "::{} {}::{}".format(level, args, msg)
# pre-calculate sort order
order = (line or 0) + (float(col or 0) + bounded_str_hash(title + "\n" + msg)) / 1000
self.order[out] = order
return out
def _sort_key(self, line):
"""Uses cached order, falling back to plain hash if not found."""
if line not in self.order:
return bounded_str_hash(line)
return self.order[line]
def sort_output_lines(self, lines):
lines.sort(key=self._sort_key)
# SourceVisitor, which calls this, overwrites its internal list of outputs; so the input
# lines will never be reused; safe to clear the cache here. Only deleting the lines we've
# seen, to handle depth-first AST traversals.
for line in lines:
if line in self.order:
del self.order[line]
return lines
netromdk-vermin-d650a48/vermin/formats/parsable_format.py 0000664 0000000 0000000 00000002631 15265463462 0023675 0 ustar 00root root 0000000 0000000 import sys
from .format import Format
from ..utility import version_strings, sort_line_column_parsable
class ParsableFormat(Format):
def __init__(self, name="parsable"):
super().__init__(name)
def set_config(self, config):
config.set_verbose(max(3, config.verbose()))
config.set_ignore_incomp(True)
config.set_show_tips(False)
super().set_config(config)
def skip_output_line(self):
"""Never skip."""
return False
def format_output_line(self, msg, path=None, line=None, col=None,
versions=None, plural=None, violation=False):
vers = version_strings(versions, ":") if versions is not None else ":"
if msg is None:
msg = ""
msg = msg.replace("\n", "\\n")
path = "" if path is None else path
return "{}:{}:{}:{}:{}".format(path, line if line is not None else "",
col if col is not None else "", vers, msg)
def output_result(self, proc_res):
# Output all findings of the file.
sys.stdout.write(proc_res.text)
# Then output summary of the file with no line/col numbers and no description.
summary = self.format_output_line(msg=None, path=proc_res.path, versions=proc_res.mins,
violation=proc_res.violation)
sys.stdout.write("{}\n".format(summary))
def sort_output_lines(self, lines):
lines.sort(key=sort_line_column_parsable)
return lines
netromdk-vermin-d650a48/vermin/fstring_detector.py 0000664 0000000 0000000 00000064027 15265463462 0022435 0 ustar 00root root 0000000 0000000 import ast
from .utility import split_lines
BACKSLASH = "\\"
HASH = "#"
FSTRING_PREFIX_CHARS = "furb"
STRING_QUOTE_CHARS = "\"'"
NEWLINE = "\n"
OPEN_BRACE = "{"
CLOSE_BRACE = "}"
DOUBLE_BRACE = "{{"
TRIPLE_QUOTE_LEN = 3
SINGLE_QUOTE_LEN = 1
FSTRING_FLAG = "f"
FSTRING_TOKEN_PREFIX_CHARS = "rf" # nosec
UNICODE_NAME_ESCAPE = BACKSLASH + "N"
CLOSING_TRAILERS = ")]"
WS_AND_NEWLINES = " \t\r" + NEWLINE
WS_AND_TRAILERS = WS_AND_NEWLINES + CLOSING_TRAILERS
SELF_DOC_MARKER = "="
SELF_DOC_FOLLOW_CHARS = "!:`}"
REPR_CONVERSION = ord("r")
class FStringDetector:
def __init__(self, source):
self._source = source
if source is None:
self._lines = None
self._line_offsets = [0]
else:
self._lines, self._line_offsets = split_lines(source)
def _codepoint_col(self, lines, lineno, col_offset):
"""Convert an AST byte-based column offset to a code-point column offset. CPython reports
`col_offset`/`end_col_offset` as byte offsets into the UTF-8 encoded source, while slicing
operates on code-point strings, so the two only differ after non-ASCII text on the same line.
"""
if not lines or lineno < 1 or lineno > len(lines) or col_offset <= 0:
return 0
line = lines[lineno - 1]
try:
return len(line.encode("utf-8")[:col_offset].decode("utf-8"))
except UnicodeDecodeError:
return len(line)
def _codepoint_length(self, lines, start_lineno, start_col_offset,
end_lineno, end_col_offset):
start_off = self._span_offset(lines, start_lineno, start_col_offset)
end_off = self._span_offset(lines, end_lineno, end_col_offset)
if start_off is None or end_off is None:
return 0
return max(0, end_off - start_off)
def is_self_doc(self, node):
if not hasattr(node, "values") or self._source is None:
return False
values = node.values
for idx, value in enumerate(values):
if isinstance(value, ast.FormattedValue) and self._is_fstring_self_doc_candidate(values, idx):
return self._self_doc_source_walk(node)
return False
def _is_fstring_self_doc_candidate(self, values, index):
"""Whether the FormattedValue at `index` may be self-documenting. A `{expr=}` field carries
conversion 114 (`ord("r")`), while a `{literal=}` field, like `{3.14=:..}`, folds with
conversion -1 and ends the preceding Constant's text in `=`.
"""
val = values[index]
if val.conversion == REPR_CONVERSION:
return True
return index > 0 and isinstance(values[index - 1], getattr(ast, "Constant")) and \
isinstance(values[index - 1].value, str) and \
values[index - 1].value.rstrip().endswith(SELF_DOC_MARKER)
def _self_doc_source_walk(self, node):
"""Confirm self-doc by locating each `{..}` region in the source."""
source = self._source
lines = self._lines
start = self._span_offset(lines, node.lineno, node.col_offset)
end = self._span_offset(lines, node.end_lineno, node.end_col_offset)
if start is None or end is None:
return False
# Locate the first f-string literal in the fused span. Implicit concat can merge a leading plain
# string part, whose literal braces would otherwise misdirect the `{`-anchor.
pos = self._fstring_opener_end(source, start, end, start)
if pos is None:
return False
for idx, val in enumerate(node.values):
if not isinstance(val, ast.FormattedValue):
continue
# Find the next non-escaped opening brace.
while pos < end:
if source[pos] == OPEN_BRACE:
# Skip escaped `{{`.
if source.startswith(DOUBLE_BRACE, pos):
pos += len(DOUBLE_BRACE)
continue
# Skip to the closing brace of a `\N{..}` unicode name or a `\{` escaped literal.
if (pos >= start + len(UNICODE_NAME_ESCAPE) and
source[pos - len(UNICODE_NAME_ESCAPE):pos] == UNICODE_NAME_ESCAPE) or \
(pos > start and source[pos - 1] == BACKSLASH):
close = source.find(CLOSE_BRACE, pos, end)
pos = close + 1 if close != -1 else end
continue
break # Actual opening brace found.
pos += 1
if pos >= end:
break
# Skip non-candidates and consume region.
if not self._is_fstring_self_doc_candidate(node.values, idx):
close = source.find(CLOSE_BRACE, pos, end)
if close == -1:
break
pos = close + 1
continue
# Nested f-strings get bogus positions on Python 3.8 because inner tokens are pinned to the
# opening quote, so the `{`-anchor cannot locate their fields. A self-doc fold whose text
# appears verbatim in the source with a `{` directly before it is self-locating, its trailing
# `=` the marker.
if idx > 0 and isinstance(node.values[idx - 1], getattr(ast, "Constant")) and \
isinstance(node.values[idx - 1].value, str) and \
node.values[idx - 1].value.rstrip().endswith(SELF_DOC_MARKER) and \
not node.values[idx - 1].value.startswith(OPEN_BRACE):
const_text = node.values[idx - 1].value
match = start - 1
while True:
match = source.find(const_text, match + 1, end)
if match == -1:
break
# Unescaped `{` directly before (not `{{`), and a valid self-doc follow char after `=`.
after = match + len(const_text)
if match - 1 >= start and source[match - 1] == OPEN_BRACE and \
not (match - 2 >= start and source[match - 2] == OPEN_BRACE) and \
(after >= end or source[after] in SELF_DOC_FOLLOW_CHARS):
return True
# Position is lost on 3.8 but the length survives, so the end is derivable.
if not hasattr(val.value, "end_col_offset") or val.value.end_col_offset is None:
return False
# Skip leading whitespace in the field body.
body = pos + 1
while body < end and source[body] in WS_AND_NEWLINES:
body += 1
# Measure the expression via AST positions, then skip closing trailers (parens/brackets).
length = self._codepoint_length(lines, val.value.lineno, val.value.col_offset,
val.value.end_lineno, val.value.end_col_offset)
expr_end = body + length
while expr_end < end and source[expr_end] in CLOSING_TRAILERS:
expr_end += 1
# Skip trailing whitespace and look for the `=` self-doc marker.
probe = expr_end
while probe < end and source[probe] in WS_AND_NEWLINES:
probe += 1
if probe < end and source[probe] == SELF_DOC_MARKER:
return True
# Grouping-paren inclusion differs across node types and versions, so the span may land before
# the actual end. Probe one char further on.
if not (probe < end and source[probe] in SELF_DOC_FOLLOW_CHARS) and \
expr_end + 1 < end:
probe = expr_end + 1
while probe < end and source[probe] in WS_AND_TRAILERS:
probe += 1
if expr_end + 1 < probe < end and source[probe] == SELF_DOC_MARKER:
return True
close = source.find(CLOSE_BRACE, body, end)
if close == -1:
break
pos = close + 1
return False
def pep701_violation(self, node):
"""Return the first PEP 701 construct the JoinedStr `node` triggers, or None. All five are
`SyntaxError` before 3.12.
"""
if self._source is None:
return None
if not hasattr(node, "values") or not hasattr(node, "end_lineno"):
return None
# Pre-3.12 parsers pin internal `FormattedValue` positions to the whole span, so the scan bound
# collapses onto the span start and no quote can be read. The analysis is skipped on such trees.
lines = self._lines
if self._read_fstring_token(node, lines) is None:
return None
contexts, default_context = self._build_field_contexts(node, lines)
for val in node.values:
if not isinstance(val, ast.FormattedValue):
continue
outer = self._resolve_field_context(val, contexts, default_context)
if outer is None:
continue
outer_quote, outer_triple = outer
# Check expression spanning lines in a single/double-quoted f-string. Triple-quoted f-strings
# allow newlines natively (3.6+), and implicit concatenation that merges a triple-quoted part
# (which the parser collapses, losing the triple-quote info in the AST) is excluded too.
if not outer_triple and hasattr(val, "end_lineno") and \
val.end_lineno is not None and hasattr(val, "lineno") and \
val.end_lineno > val.lineno:
return "multi_line"
# Check same-quote nesting. A triple-quoted outer f-string allows a nested single-occurrence
# inner quote natively, but nested triple-quote f-strings using the same character require
# 3.12+.
for inner_js in self._walk_joined_strs(val):
if inner_js.lineno == node.lineno and \
inner_js.col_offset == node.col_offset:
# Pre-3.12 parsers pin inner `JoinedStr` nodes to the outer quote, which would falsely
# read as same-quote nesting with itself.
continue
inner = self._read_fstring_token(inner_js, lines)
if inner is None or inner[0] != outer_quote:
continue
if not outer_triple or inner[1]:
return "nested_same_quote"
# A string literal reusing the outer quote inside a field is only legal from 3.12. A
# triple-quoted f-string natively allows the single-character reuse, so only single/double
# quotes trigger this. The backslash check is ordered first so escaped same-quote literals
# keep their backslash label.
if self._has_pep701_backslash(val, lines):
return "backslash"
if not outer_triple and self._has_same_quote_string(val, outer_quote):
return "same_quote_string"
if self._has_pep701_comment(val, lines):
return "comment"
return None
def _fstring_opener_end(self, source, pos, bound, lower_bound):
"""Return the offset just past the opening quote of the first f-string literal in `[pos,
bound)`, skipping plain strings, comments, and non-f prefixes, or None if there is no f-string.
"""
while pos < bound:
ch = source[pos]
if ch in STRING_QUOTE_CHARS:
if self._match_fstring_quote(source, pos, lower_bound) is None:
next_pos = self._skip_string(source, pos, bound, len(source))
if next_pos >= bound:
# No well-formed plain literal within bounds. Advance past the lone quote and keep
# scanning so the `{`-anchor still finds the fields.
pos += SINGLE_QUOTE_LEN
continue
pos = next_pos
continue
# F-string opener found. Return just past its quote(s).
pos += (TRIPLE_QUOTE_LEN if source.startswith(ch * TRIPLE_QUOTE_LEN, pos)
else SINGLE_QUOTE_LEN)
return pos
if ch == HASH:
pos = self._skip_comment(source, pos, bound)
continue
pos += 1
return None
def _read_fstring_token(self, node, lines):
"""Return `(quote, is_triple)` of the f-string opening at `node`'s span, or None. On 3.12+
implicit-concat, `col_offset` points at the leading part and raw prefixes at the `f`, so the
opener is scanned forward to the first f-string literal. This also stops a nested same-quote
literal like `f"{f'x'}"` from being misread as the opener.
"""
source = self._source
if source is None or lines is None or not lines:
return None
if not hasattr(node, "lineno") or not hasattr(node, "end_lineno") or \
not hasattr(node, "col_offset"):
return None
# Map the byte-based span-start position to a code-point source offset.
src_len = len(source)
start = self._span_offset(lines, node.lineno, node.col_offset)
if start is None:
return None
# Use end-of-source as the span end when the node has no end column.
end = src_len
if hasattr(node, "end_col_offset"):
end = self._span_offset(lines, node.end_lineno, node.end_col_offset)
if end is None:
return None
# Stop scanning at the first field to avoid misreading a nested same-quote literal as the
# opener.
bound = end
for val in node.values:
if not isinstance(val, ast.FormattedValue):
continue
if hasattr(val, "lineno") and hasattr(val, "col_offset"):
offset = self._span_offset(lines, val.lineno, val.col_offset)
if offset is None:
return None
bound = offset
break
# Skip plain strings, comments, and non-f prefix tokens to reach the f-string opener.
pos = start
while pos < bound:
ch = source[pos]
if ch in STRING_QUOTE_CHARS:
pos = self._skip_string(source, pos, bound, src_len)
continue
if ch == HASH:
pos = self._skip_comment(source, pos, bound)
continue
if ch.lower() in FSTRING_TOKEN_PREFIX_CHARS:
prefix_end = pos
while prefix_end < bound and source[prefix_end].lower() in FSTRING_TOKEN_PREFIX_CHARS:
prefix_end += 1
if prefix_end < bound and source[prefix_end] in STRING_QUOTE_CHARS:
if FSTRING_FLAG in source[pos:prefix_end].lower():
quote = source[prefix_end]
is_triple = source.startswith(quote * TRIPLE_QUOTE_LEN, prefix_end)
return (quote, is_triple) # f-string opener found.
# Skip plain non-fstring, like `r"lit"`.
pos = self._skip_string(source, prefix_end, bound, src_len)
continue
pos += 1
return None
def _span_offset(self, lines, lineno, col_offset):
"""Return the source offset of a code-point line/column position, or None."""
if not lines or lineno < 1 or lineno > len(lines):
return None
return self._line_offsets[lineno - 1] + self._codepoint_col(lines, lineno, max(0, col_offset))
def _skip_string(self, source, pos, bound, src_len):
"""Skip a plain string literal starting at the quote at `pos` and return the offset past it."""
quote = source[pos]
is_triple = source.startswith(quote * TRIPLE_QUOTE_LEN, pos)
scan = pos + (TRIPLE_QUOTE_LEN if is_triple else SINGLE_QUOTE_LEN)
while scan < bound and scan < src_len:
ch = source[scan]
if ch == BACKSLASH:
scan += 2
elif is_triple:
if source.startswith(quote * TRIPLE_QUOTE_LEN, scan):
return scan + TRIPLE_QUOTE_LEN # Closing triple quote found.
scan += 1
elif ch == quote:
return scan + SINGLE_QUOTE_LEN
else:
scan += 1
return min(bound, src_len)
def _skip_comment(self, source, pos, bound):
"""Skip `#` comment to the end of its line and return the offset past the newline or `bound`."""
nl_pos = source.find(NEWLINE, pos, bound)
return bound if nl_pos == -1 else nl_pos + 1
def _build_field_contexts(self, node, lines):
"""Map each top-level replacement-field `{` offset to the `(quote, is_triple)` of the f-string
literal that contains it, plus a default context (the first f-string token) used when a field
cannot be attributed. The source is scanned forward over the whole fused span, so leading plain
strings and `#` comments between implicitly-concatenated parts are skipped before a part's quote
is read, and single- and triple-quoted parts each contribute their own context.
"""
source = self._source
src_len = len(source)
contexts = {}
default = None
if not hasattr(node, "end_col_offset"):
return contexts, default
start = self._span_offset(lines, node.lineno, node.col_offset)
end = self._span_offset(lines, node.end_lineno, node.end_col_offset)
if start is None or end is None:
return contexts, default
# Scan the fused span, attributing each `{` to the f-string literal that contains it.
pos = start
while pos < end:
ch = source[pos]
# Record f-string literals' quote and tripleness in their context.
if ch in STRING_QUOTE_CHARS:
fstr = self._match_fstring_quote(source, pos, start)
if fstr is None:
pos = self._skip_string(source, pos, end, src_len)
continue
quote, is_triple = fstr
context = (quote, is_triple)
if default is None:
default = context
pos = self._fstring_body_end(source, pos, end, quote, is_triple, context, contexts)
continue
# Skip escaped/nested braces and map each field to its context.
if ch == OPEN_BRACE:
if source.startswith(DOUBLE_BRACE, pos):
pos += len(DOUBLE_BRACE) # Escaped brace in a literal.
continue
# A `\N{` unicode name or a `\{` escaped literal is not a replacement field.
if (pos >= start + len(UNICODE_NAME_ESCAPE) and
source[pos - len(UNICODE_NAME_ESCAPE):pos] == UNICODE_NAME_ESCAPE) or \
(pos > start and source[pos - 1] == BACKSLASH):
close = source.find(CLOSE_BRACE, pos, end)
pos = close + 1 if close != -1 else end
continue
if default is not None:
contexts[pos] = default
pos = self._field_end(source, pos + 1, end)
continue
# Skip comments between concatenated parts to the end of the line.
if ch == HASH:
pos = self._skip_comment(source, pos, end)
continue
pos += 1
return contexts, default
def _resolve_field_context(self, val, contexts, default_context):
"""Return the `(quote, is_triple)` context of the f-string literal enclosing a field."""
lineno = getattr(val, "lineno", None)
col = getattr(val, "col_offset", None)
if lineno is None or col is None:
return default_context
offset = self._span_offset(self._lines, lineno, col)
field_ctx = contexts.get(offset)
return default_context if field_ctx is None else field_ctx
def _match_fstring_quote(self, source, pos, lower_bound):
"""Return the quote and tripleness if `source[pos]` opens an f-string literal, else None."""
prefix_start = pos - 1
while prefix_start >= lower_bound and source[prefix_start].lower() in FSTRING_PREFIX_CHARS:
prefix_start -= 1
if FSTRING_FLAG not in source[prefix_start + 1:pos].lower():
return None
return (source[pos], source.startswith(source[pos] * TRIPLE_QUOTE_LEN, pos))
def _fstring_body_end(self, source, pos, end, quote, is_triple, context, contexts):
"""Scan one f-string literal's body, starting at its opening quote at `pos`, and return the
offset just past its closing quote. Replacement fields directly under the literal are mapped to
`context` in `contexts` when that mapping is wanted.
"""
pos += TRIPLE_QUOTE_LEN if is_triple else SINGLE_QUOTE_LEN
while pos < end:
ch = source[pos]
# Skip escaped character.
if ch == BACKSLASH:
pos += 2
continue
if ch == OPEN_BRACE:
# Skip escaped `{{`.
if source.startswith(DOUBLE_BRACE, pos):
pos += len(DOUBLE_BRACE)
continue
# Skip `\N{..}` unicode name escape.
if pos >= len(UNICODE_NAME_ESCAPE) and \
source[pos - len(UNICODE_NAME_ESCAPE):pos] == UNICODE_NAME_ESCAPE:
close = source.find(CLOSE_BRACE, pos, end)
pos = close + 1 if close != -1 else end
continue
# Skip a backslash-escaped nested brace.
if pos > 0 and source[pos - 1] == BACKSLASH:
pos += 1
continue
if contexts is not None:
contexts[pos] = context
pos = self._field_end(source, pos + 1, end)
continue
# Closing triple quote found.
if is_triple:
if source.startswith(quote * TRIPLE_QUOTE_LEN, pos):
return pos + TRIPLE_QUOTE_LEN
# Closing single quote found.
elif ch == quote:
return pos + SINGLE_QUOTE_LEN
pos += 1
return end
def _field_end(self, source, pos, end):
"""Scan a replacement field's expression, just after its `{`, and return the offset just past
the matching `}`. Braces, strings, escapes, and nested f-strings inside the expression are
skipped, so the enclosing brace is found even when a nested f-string reuses the same quote.
"""
depth = 1
while pos < end:
ch = source[pos]
if ch in STRING_QUOTE_CHARS:
fstr = self._match_fstring_quote(source, pos, 0)
if fstr is None:
pos = self._skip_string(source, pos, end, len(source))
continue
quote, is_triple = fstr
pos = self._fstring_body_end(source, pos, end, quote, is_triple, None, None)
continue
# Skip escaped character.
if ch == BACKSLASH:
pos += 2
continue
# Nested field/brace.
if ch == OPEN_BRACE:
depth += 1
pos += 1
continue
if ch == CLOSE_BRACE:
depth -= 1
if depth == 0:
return pos + 1 # Matching closing brace found.
pos += 1
return end
def _has_same_quote_string(self, node, outer_quote):
"""Whether a replacement field contains a string literal reusing the outer quote. Reusing the
quote character only became legal within a field in 3.12, so the whole field body, expression
and format spec, is scanned for a bare outer-quote character.
"""
source = self._source
lines = self._lines
if source is None or lines is None or not hasattr(node, "end_lineno") or \
not hasattr(node, "end_col_offset"):
return False
src_len = len(source)
start = self._span_offset(lines, node.lineno, node.col_offset)
end = self._span_offset(lines, node.end_lineno, node.end_col_offset)
if start is None or end is None or end <= start + 2:
return False
# Exclude the enclosing braces, bounding the scan to the field body.
if end > start and source[end - 1] == CLOSE_BRACE:
end -= 1
pos = start + 1
while pos < end:
ch = source[pos]
if ch == outer_quote:
return True
if ch in STRING_QUOTE_CHARS:
pos = self._skip_string(source, pos, end, src_len)
continue
pos += 1
return False
def _walk_joined_strs(self, node):
for child in ast.iter_child_nodes(node):
if isinstance(child, ast.JoinedStr):
yield child
yield from self._walk_joined_strs(child) # novermin
def _has_pep701_backslash(self, node, lines):
"""Whether a FormattedValue expression contains a backslash (PEP 701). Before 3.12, backslashes
were forbidden in f-string expressions.
"""
source = self._source
if source is None or lines is None:
return False
# If the expression ends on a different line than the replacement field, scan the source between
# them for a line-continuation backslash.
expr = node.value
if node.end_lineno != expr.end_lineno:
expr_line = expr.end_lineno
expr_col = self._codepoint_col(lines, expr.end_lineno, expr.end_col_offset)
field_line = node.end_lineno
field_col = self._codepoint_col(lines, node.end_lineno, node.end_col_offset)
gap_parts = []
if expr_line - 1 < len(lines):
gap_parts.append(lines[expr_line - 1][expr_col:])
for line_no in range(expr_line, field_line - 1):
if line_no < len(lines):
gap_parts.append(lines[line_no])
if field_line - 1 < len(lines):
gap_parts.append(lines[field_line - 1][:field_col])
if any(BACKSLASH in part for part in gap_parts):
return True
# Escape sequence in a string literal within the expression. The single-line guard makes the
# ASCII line slice a complete and cheap check, skipping `ast.get_source_segment()`.
if expr.lineno == expr.end_lineno:
line = lines[expr.lineno - 1]
lo = self._codepoint_col(lines, expr.lineno, expr.col_offset)
hi = self._codepoint_col(lines, expr.lineno, expr.end_col_offset)
if BACKSLASH not in line[lo:hi]:
return False
# Tokenize the full expression source to confirm a backslash. Only reachable on Python 3.8+
# because that's when `ast.get_source_segment()` was added
if hasattr(ast, "get_source_segment"):
expr_src = ast.get_source_segment(source, expr) # novermin
if expr_src and BACKSLASH in expr_src:
import tokenize as _tokenize # novermin, pylint: disable=import-outside-toplevel
import io as _io # novermin, pylint: disable=import-outside-toplevel
try:
tokens = list(_tokenize.generate_tokens(
_io.StringIO(expr_src).readline))
for tok in tokens:
if tok.type == _tokenize.STRING and BACKSLASH in tok.string:
return True
except _tokenize.TokenError:
pass
return False
def _has_pep701_comment(self, node, lines):
"""Whether a replacement field contains a comment (PEP 701). Before 3.12, comments were
forbidden inside f-string expressions. The parser strips them, so the region between the opening
`{` and the top-level format spec's `:`, or the closing `}`, is scanned for `#` characters that
are outside string literals. A `#` in the format spec itself, after the `:`, is spec filler text
and is valid since 3.6.
"""
source = self._source
if source is None or lines is None or not hasattr(node, "end_lineno"):
return False
src_len = len(source)
start = self._span_offset(lines, node.lineno, node.col_offset)
if start is None:
return False
# Bound the scan by the format-spec `:` when present, else the closing `}`.
spec = node.format_spec if hasattr(node, "format_spec") else None
if spec is not None and getattr(spec, "lineno", None) is not None:
end = self._span_offset(lines, spec.lineno, spec.col_offset)
else:
end = self._span_offset(lines, node.end_lineno, node.end_col_offset)
if end is not None and end > start and source[end - 1] == CLOSE_BRACE:
end -= 1
if end is None or end <= start:
return False
# Skip the scan below when the region contains no `#` at all.
field = source[start:end]
if HASH not in field:
return False
# Scan the region for `#` outside string literals.
field_len = len(field)
pos = 0
while pos < field_len:
ch = field[pos]
if ch in STRING_QUOTE_CHARS:
pos = self._skip_string(source, start + pos, end, src_len) - start
continue
if ch == HASH:
return True
pos += 1
return False
netromdk-vermin-d650a48/vermin/main.py 0000664 0000000 0000000 00000015327 15265463462 0020013 0 ustar 00root root 0000000 0000000 import sys
from os.path import abspath
from copy import deepcopy
from .config import Config
from .formats import ParsableFormat
from .printing import nprint, vprint
from .detection import detect_paths
from .processor import Processor
from .arguments import Arguments
from .utility import version_strings, dotted_name, compare_requirements
from .backports import Backports
def main():
config = Config()
args = Arguments(sys.argv[1:]).parse(config)
if "usage" in args:
Arguments.print_usage(args["full"])
sys.exit(args["code"])
if args["code"] != 0:
sys.exit(args["code"]) # pragma: no cover
paths = args["paths"]
parsable = isinstance(config.format(), ParsableFormat)
# Detect paths, remove duplicates, and sort for deterministic results.
if not parsable:
vprint("Detecting python files..", config)
if config.make_paths_absolute():
paths = [abspath(p) for p in paths]
# Parsable format ignores paths with ":" in particular because it interferes with the format that
# uses ":" a lot.
ignore_chars = []
if parsable and not sys.platform.startswith("win32"):
ignore_chars = [":", "\n"]
paths = list(set(detect_paths(paths, hidden=config.analyze_hidden(),
processes=config.processes(), ignore_chars=ignore_chars,
scan_symlink_folders=config.scan_symlink_folders(), config=config)))
paths.sort()
amount = len(paths)
if amount == 0:
nprint("No files specified to analyze!", config)
if config.show_tips() and not config.make_paths_absolute() \
and any(p.startswith(".") for p in args["paths"]):
nprint("Tip: Maybe use the --hidden argument to analyze hidden files.", config)
sys.exit(1)
msg = "Analyzing"
if amount > 1:
msg += " {} files".format(amount)
if not parsable:
vprint("{} using {} processes..".format(msg, config.processes()), config)
try:
# In violations mode it is allowed to use quiet mode to show literally only discrepancies and
# nothing else. But the processor must use the original verbosity level and not be quiet!
local_config = deepcopy(config)
if local_config.only_show_violations() and local_config.quiet(): # pragma: no cover
local_config.set_verbose(config.verbose())
local_config.set_quiet(False)
processor = Processor()
(mins, incomp, unique_versions, backports, used_novermin, maybe_annotations) =\
processor.process(paths, local_config, local_config.processes())
except KeyboardInterrupt: # pragma: no cover
nprint("Aborting..", config)
sys.exit(1)
if incomp and not config.ignore_incomp(): # pragma: no cover
nprint("Note: Some files had incompatible versions so the results might not be correct!",
config)
incomps = []
reqs = []
for (i, ver) in enumerate(mins):
if ver is None:
incomps.append(i + 2) # pragma: no cover
elif ver is not None and ver != 0:
reqs.append(ver)
tips = []
if not parsable and (len(reqs) == 0 and len(incomps) == 0): # pragma: no cover
nprint("No known reason found that it will not work with 2+ and 3+.", config)
nprint("Please report if it does not: https://github.com/netromdk/vermin/issues/", config)
if config.show_tips(): # pragma: no cover
if maybe_annotations and not config.eval_annotations():
tips.append([
"Generic or literal annotations might be in use. If so, try using: --eval-annotations",
"But check the caveat section: https://github.com/netromdk/vermin#caveats"
])
# Only look at unversioned backports.
unique_bps = sorted(backports - Backports.unversioned_filter(config.backports()))
if len(unique_bps) > 0:
tips.append([
"You're using potentially backported modules: {}".format(", ".join(unique_bps)),
"If so, try using the following for better results: {}".
format("".join([" --backport {}".format(n) for n in unique_bps]).strip())
])
if not used_novermin and config.parse_comments():
tips.append(["Since '# novm' or '# novermin' weren't used, a speedup can be achieved using: "
"--no-parse-comments"])
if len(tips) > 0:
verbose = config.verbose()
if len(reqs) == 0 or (reqs == [(0, 0), (0, 0)] and verbose > 0) or \
(len(reqs) > 0 and 0 < verbose < 2):
nprint("", config)
nprint("Tips:", config)
for tip in tips:
nprint("- " + "\n ".join(tip), config)
nprint("(disable using: --no-tips)", config)
if len(reqs) > 0:
nprint("", config)
# determine if any targets were unmet
unmet_targets = False
targets = config.targets()
if len(targets) > 0:
# For violations mode, if all findings are inconclusive, like empty files or no rules triggered,
# don't fail wrt. targets.
all_inconclusive = config.only_show_violations() and len(reqs) > 0 and \
all(req == (0, 0) for req in reqs)
unmet_targets = not all_inconclusive and not compare_requirements(reqs, targets)
if parsable: # pragma: no cover
print(config.format()
.format_output_line(msg=None, path=None, versions=mins, violation=unmet_targets))
elif len(reqs) > 0:
nprint("Minimum required versions: {}".format(version_strings(reqs)), config)
if any(req == (0, 0) for req in reqs):
vers = [req.replace("~", "") for req in version_strings(reqs, ",").split(",") if "~" in req]
nprint("Note: Not enough evidence to conclude it won't work with Python {}.".
format(" or ".join(vers)), config)
# Don't show incompatible versions when -i is given, unless there are no non-incompatible versions
# found then we need must show the incompatible versions - nothing will be shown otherwise. That
# case is when both py2 and py3 incompatibilities were found - in which case `incomps = [2, 3]`
# and `reqs = []`. But if `incomps = [2]` and `reqs = [3.4]`, for instance, then it makes sense
# not to show incompatible versions with -i specified.
if len(incomps) > 0 and (not parsable and (not config.ignore_incomp() or len(reqs) == 0)):
# pragma: no cover
# Improve readability by using, for example, (2, 'x') instead of (2,) such that it reports:
# Incompatible versions: 2.x
# Over:
# Incompatible versions: 2
incomps = [(v, 'x') if isinstance(v, int) else v for v in incomps]
nprint("Incompatible versions: {}".format(version_strings(incomps)), config)
if args["versions"] and len(unique_versions) > 0:
nprint("Version range: {}".format(version_strings(unique_versions)), config)
if unmet_targets:
if not parsable:
vers = ["{}{}".format(dotted_name(t), "-" if not e else "") for (e, t) in targets]
nprint("Target versions not met: {}".format(version_strings(vers)), config)
sys.exit(1)
sys.exit(0)
netromdk-vermin-d650a48/vermin/parser.py 0000664 0000000 0000000 00000010726 15265463462 0020361 0 ustar 00root root 0000000 0000000 import ast
import io
import sys
import re
from tokenize import generate_tokens, COMMENT, NEWLINE, NL, STRING
# 'type' identifier [type_params] "=" expression
TYPE_ALIAS_STMT = re.compile(r"type\s+(\w+)\s+(\[.+?\]\s+)?=\s+(.+)")
# 'case' pattern-clause containing a unary '+' before a number literal
UNARY_PLUS_MATCH_PATTERN = re.compile(r"case\s[^:]*\+\s*[0-9.]")
class Parser:
def __init__(self, source, path=None):
self.__source = source
self.__path = "" if path is None else path
def parse(self, parse_comments=True):
"""Parse python source into an AST."""
node = ast.parse(self.__source, filename=self.__path)
novermin = set()
if parse_comments:
novermin = self.comments()
return (node, novermin)
def comments(self):
"""Finds 'novermin' and 'novm' comments and associates to line numbers."""
novermin = set()
src = self.__source
if isinstance(src, bytes):
src = src.decode(errors="ignore")
try:
tokens = generate_tokens(io.StringIO(src).readline)
except Exception: # pragma: no cover
return novermin
def find_comment(comment, lineno, alone):
if comment.startswith("novermin") or comment.startswith("novm"):
# Associate with next line if the comment is "alone" on a line, i.e. '#' starts the line.
novermin.add(lineno + 1 if alone else lineno)
return True
return False
prev_newline = False
multiline_string = None
for token in tokens:
string, lno, lcol, lend = token.string, token.start[0], token.start[1], token.end[0]
if token.type == STRING:
string = string.strip()
if (string.startswith("\"\"\"") and string.endswith("\"\"\"")) or\
(string.startswith("'''") and string.endswith("'''")):
multiline_string = (lno, lend)
elif token.type == COMMENT:
# For multi-line strings, any comment marking starts at the beginning and not at the end.
if multiline_string is not None and multiline_string[1] == lno:
lno = multiline_string[0]
multiline_string = None
# Check each comment segment for "novermin" and "novm", not just the start of the whole
# comment. A comment is alone on a line if the previous token is a newline or the line
# column is zero.
alone = (prev_newline or lcol == 0)
for segment in string[1:].strip().split("#"):
find_comment(segment.strip(), lno, alone)
prev_newline = token.type in (NEWLINE, NL)
return novermin
def detect(self, config):
"""Parse python source into an AST and yield minimum versions."""
assert config is not None
try:
(node, novermin) = self.parse(config.parse_comments())
return (node, [], novermin, None)
except SyntaxError as err:
def format_error(msg, versions):
"""Generate an error message, as would be done by the SourceVisitor."""
return config.format()\
.format_output_line(msg, path=err.filename, line=err.lineno, col=err.offset,
versions=versions, violation=True)
text = err.text.strip() if err.text is not None else ""
lmsg = err.msg.lower() # pylint: disable=no-member
# `print expr` is a Python 2 construct, in v3 it's `print(expr)`.
# NOTE: This is only triggered when running a python 3 on v2 code!
if lmsg.find("missing parentheses in call to 'print'") != -1:
msg = "info: `{}` requires 2.0".format(text)
versions = [(2, 0), None]
return (None, versions, set(), format_error(msg, versions))
# Type alias statements.
# NOTE: This is only triggered with Python 3.11 or older.
if lmsg == "invalid syntax" and TYPE_ALIAS_STMT.match(text) is not None:
msg = "info: type alias statement `{}`".format(text)
versions = [None, (3, 12)]
return (None, versions, set(), format_error(msg, versions))
# Unary `+` in match literal patterns.
# NOTE: This is only triggered with Python 3.14 or older.
if lmsg == "invalid syntax" and UNARY_PLUS_MATCH_PATTERN.search(text) is not None:
msg = "info: unary `+` in match literal pattern `{}`".format(text)
versions = [None, (3, 15)]
return (None, versions, set(), format_error(msg, versions))
min_versions = [(0, 0), (0, 0)]
if config.pessimistic():
min_versions[sys.version_info.major - 2] = None
msg = "error: {}: {}".format(err.msg, text)
return (None, min_versions, set(), format_error(msg, min_versions))
netromdk-vermin-d650a48/vermin/printing.py 0000664 0000000 0000000 00000000746 15265463462 0020720 0 ustar 00root root 0000000 0000000 def nprint(msg, config):
if not config.quiet():
print(msg)
def verbose_print(msg, level, config):
if config.verbose() >= level and not config.quiet():
print(msg)
def vprint(msg, config):
verbose_print(msg, 1, config)
def vvprint(msg, config):
verbose_print(msg, 2, config)
def sgr(msg, *codes):
"""Wrap message in ANSI Select Graphic Rendition codes for console styling."""
codes = ";".join(str(c) for c in codes)
return "\033[{}m{}\033[0m".format(codes, msg)
netromdk-vermin-d650a48/vermin/processor.py 0000664 0000000 0000000 00000013317 15265463462 0021103 0 ustar 00root root 0000000 0000000 import multiprocessing as mp
from .printing import nprint
from .utility import combine_versions, InvalidVersionException
from .parser import Parser
from .source_visitor import SourceVisitor
from .backports import Backports
class ProcessResult:
def __init__(self, path):
self.path = path # Path of processed file.
self.node = None # AST root node.
self.mins = None # Minimum versions detected.
self.text = "" # Output or exception text.
self.novermin = set() # novermin/novm lines.
self.bps = set() # Potential backport modules used.
self.violation = False # Whether a violation was detected.
# Potential generic/literal annotations used.
self.maybe_annotations = False
def __repr__(self):
return """{} at 0x{:x}
path={}
node={}
mins={}
text={}
novermin={}
bps={}
maybe_annotations={}""".format(self.__class__.__name__, id(self), self.path, self.node, self.mins,
self.text, self.novermin, self.bps, self.maybe_annotations)
class Processor:
def process(self, paths, config, processes=mp.cpu_count()):
assert config is not None
unique_versions = set()
all_backports = set()
used_novermin = False
maybe_annotations = False
mins = [(0, 0), (0, 0)]
incomp = False
pool = None
try:
# pylint: disable=consider-using-with
pool = mp.Pool(processes=processes) if processes > 1 else None
def print_incomp(path, text):
if not config.ignore_incomp():
if len(text) > 0:
text = "\n " + text
nprint("File with incompatible versions: {}{}".format(path, text), config)
# Automatically don't use concurrency when only one process is specified to be used.
def act():
if processes == 1:
return [self.process_individual((path, config)) for path in paths] # pragma: no cover
return pool.imap(self.process_individual, ((path, config) for path in paths))
for proc_res in act():
# Ignore paths that didn't contain python code.
if proc_res is None:
continue
if proc_res.mins is None:
incomp = True
print_incomp(proc_res.path, proc_res.text)
continue
all_backports = all_backports | proc_res.bps
for ver in proc_res.mins:
if ver is not None and ver > (0, 0):
unique_versions.add(ver)
used_novermin |= (len(proc_res.novermin) > 0)
maybe_annotations |= proc_res.maybe_annotations
# For violations mode, only show file names and findings if there are any - no empty ones
# that do not violate the input targets. This is especially important when scanning many
# files since it can be hard to spot violations. Otherwise, show as normal.
if not config.only_show_violations() or len(proc_res.text) > 0:
config.format().output_result(proc_res)
try:
mins = combine_versions(mins, proc_res.mins, config)
except InvalidVersionException:
incomp = True
print_incomp(proc_res.path, proc_res.text)
except RuntimeError as ex:
# Match the specific multiprocessing bootstrap RuntimeError ("An attempt has been made to
# start a new process before the current process has finished its bootstrapping phase."). Any
# other RuntimeError is a real bug and must propagate.
if "before the current process has finished its bootstrapping phase" not in str(ex):
raise
nprint("""RuntimeError: If running `Processor.process()` outside of
`if __name__ == \"__main__\":` it, or the code calling it, must be done within it instead.""",
config)
finally:
if pool:
pool.close()
pool.join()
unique_versions = list(unique_versions)
unique_versions.sort()
return (mins, incomp, unique_versions, all_backports, used_novermin, maybe_annotations)
@staticmethod
def process_individual(args):
(path, config) = args
res = ProcessResult(path)
source = None
err_msg = None
try:
with open(path, mode="rb") as fp:
source = fp.read()
parser = Parser(source, path)
(res.node, res.mins, res.novermin, err_msg) = parser.detect(config)
except KeyboardInterrupt: # pragma: no cover
return res
# When input isn't python code, ignore it.
except ValueError:
# source code string cannot contain null bytes
return None
except TypeError: # pragma: no cover
# compile() expected string without null bytes
return None
except Exception as ex: # pragma: no cover
res.mins = [(0, 0), (0, 0)]
res.violation = True
res.text = config.format()\
.format_output_line("{}, {}".format(type(ex), ex), path=path, violation=True)
visitor = SourceVisitor(config, path, source)
visitor.set_no_lines(res.novermin)
if err_msg is not None:
visitor.add_error_message(err_msg)
# node is None if there was a syntax error; we don't process the AST, but we keep all other
# logic so that it logs the syntax exception in the appropriate format
if res.node is not None:
try:
visitor.tour(res.node)
except KeyboardInterrupt: # pragma: no cover
return res
try:
if res.node is not None:
res.mins = visitor.minimum_versions()
for m in visitor.modules():
if Backports.is_backport(m):
res.bps.add(m)
res.maybe_annotations = visitor.maybe_annotations()
res.violation = visitor.found_violation()
res.text = visitor.output_text()
except InvalidVersionException as ex:
res.mins = None
res.violation = True
res.text = config.format().format_output_line(str(ex), path=path, violation=True)
return res
netromdk-vermin-d650a48/vermin/rules.py 0000664 0000000 0000000 00000654030 15265463462 0020221 0 ustar 00root root 0000000 0000000 from .backports import Backports
def bp(name, config):
"""Checking if backport is used."""
return name in config.backports()
def bpv(name, default_mins, config):
"""Checking if backport, or any versioned variant thereof, are used and returns the minimum
versions, and returns default versions otherwise."""
for (name_, _, mins) in Backports.expand_versions(name):
if bp(name_, config):
return mins
return default_mins
# Module requirements: name -> min version per major or None if N.A.
def MOD_REQS(config):
return {
"BaseHTTPServer": ((2, 0), None),
"ConfigParser": ((2, 0), None),
"DocXMLRPCServer": ((2, 3), None),
"HTMLParser": ((2, 2), None),
"Queue": ((2, 0), None),
"SimpleXMLRPCServer": ((2, 2), None),
"SocketServer": ((2, 0), None),
"Tkinter": ((2, 0), None),
"__builtin__": ((2, 0), None),
"__future__": ((2, 1), (3, 0)),
"_ast": ((2, 5), (3, 0)),
"_dummy_thread": (None, (3, 0)),
"_markupbase": (None, (3, 0)),
"_thread": (None, (3, 0)),
"_winreg": ((2, 0), None),
"abc": ((2, 6), (3, 0)),
"annotationlib": (None, (3, 14)),
"argparse": bpv("argparse", ((2, 7), (3, 2)), config),
"ast": ((2, 6), (3, 0)),
"asyncio": bpv("asyncio", (None, (3, 4)), config),
"asyncio.graph": (None, (3, 14)),
"asyncore": ((2, 6), (3, 0)),
"atexit": ((2, 0), (3, 0)),
"audioop": ((2, 5), (3, 0)),
"bisect": ((2, 1), (3, 0)),
"builtins": (None, (3, 0)),
"bz2": ((2, 3), (3, 0)),
"cProfile": ((2, 5), (3, 0)),
"calendar": ((2, 0), (3, 0)),
"cgitb": ((2, 2), (3, 0)),
"collections": ((2, 4), (3, 0)),
"collections.abc": (None, (3, 3)),
"compileall": ((2, 6), (3, 0)),
"compression": (None, (3, 14)),
"compression.bz2": (None, (3, 14)),
"compression.gzip": (None, (3, 14)),
"compression.lzma": (None, (3, 14)),
"compression.zlib": (None, (3, 14)),
"compression.zstd": (None, (3, 14)),
"concurrent.futures": (None, (3, 2)),
"concurrent.interpreters": (None, (3, 14)),
"configparser": bpv("configparser", (None, (3, 0)), config),
"contextlib": ((2, 5), (3, 0)),
"contextvars": bpv("contextvars", (None, (3, 7)), config),
"cookielib": ((2, 4), None),
"copy_reg": ((2, 0), None),
"copyreg": (None, (3, 0)),
"csv": ((2, 3), (3, 0)),
"ctypes": ((2, 5), (3, 0)),
"dataclasses": bpv("dataclasses", (None, (3, 7)), config),
"datetime": ((2, 3), (3, 0)),
"dbm.dumb": (None, (3, 0)),
"dbm.gnu": (None, (3, 0)),
"dbm.io": (None, (3, 0)),
"dbm.ndbm": (None, (3, 0)),
"dbm.os": (None, (3, 0)),
"dbm.sqlite3": (None, (3, 13)),
"dbm.struct": (None, (3, 0)),
"dbm.sys": (None, (3, 0)),
"dbm.whichdb": (None, (3, 0)),
"decimal": ((2, 4), (3, 0)),
"difflib": ((2, 1), (3, 0)),
"dummy_thread": ((2, 3), None),
"dummy_threading": ((2, 3), None),
"email": ((2, 2), (3, 0)),
"email.charset": ((2, 2), (3, 0)),
"email.contentmanager": (None, (3, 4)),
"email.errors": ((2, 4), (3, 0)),
"email.header": ((2, 2), (3, 0)),
"email.headerregistry": (None, (3, 3)),
"email.message": ((2, 2), (3, 0)),
"email.parser": ((2, 2), (3, 0)),
"email.policy": (None, (3, 3)),
"email.utils": ((2, 2), (3, 0)),
"encodings.idna": ((2, 3), (3, 0)),
"encodings.utf_8_sig": ((2, 5), (3, 0)),
"ensurepip": ((2, 7), (3, 4)),
"enum": bpv("enum", (None, (3, 4)), config),
"faulthandler": (None, (3, 3)),
"fractions": ((2, 6), (3, 0)),
"functools": ((2, 5), (3, 0)),
"future_builtins": ((2, 6), None),
"graphlib": (None, (3, 9)),
"hashlib": ((2, 5), (3, 0)),
"heapq": ((2, 3), (3, 0)),
"hmac": ((2, 2), (3, 0)),
"hotshot": ((2, 2), None),
"html": (None, (3, 0)),
"htmlentitydefs": ((2, 0), None),
"http": (None, (3, 0)),
"http.cookiejar": (None, (3, 0)),
"http.server": (None, (3, 0)),
"imghdr": ((2, 5), (3, 0)),
"imp": ((2, 0), (3, 0)),
"importlib": bpv("importlib", ((2, 7), (3, 1)), config),
"importlib.metadata": (None, (3, 8)),
"importlib.resources": (None, (3, 7)),
"importlib.resources.abc": (None, (3, 11)),
"inspect": ((2, 1), (3, 0)),
"io": ((2, 6), (3, 0)),
"ipaddress": bpv("ipaddress", (None, (3, 3)), config),
"itertools": ((2, 3), (3, 0)),
"json": ((2, 6), (3, 0)),
"locale": ((2, 0), (3, 0)),
"logging": ((2, 3), (3, 0)),
"logging.config": ((2, 3), (3, 0)),
"logging.handlers": ((2, 3), (3, 0)),
"lzma": (None, (3, 3)),
"markupbase": ((2, 0), None),
"math.integer": (None, (3, 15)),
"md5": ((2, 0), None),
"modulefinder": ((2, 3), (3, 0)),
"msilib": ((2, 5), (3, 0)),
"multiprocessing": ((2, 6), (3, 0)),
"multiprocessing.pool": (None, (3, 0)),
"multiprocessing.shared_memory": (None, (3, 8)),
"new": ((2, 0), None),
"numbers": ((2, 6), (3, 0)),
"optparse": ((2, 3), (3, 0)),
"ossaudiodev": ((2, 3), (3, 0)),
"pathlib": (None, (3, 4)),
"pathlib.types": (None, (3, 14)),
"pdb": ((2, 0), (3, 0)),
"pickletools": ((2, 3), (3, 0)),
"pkgutil": ((2, 3), (3, 0)),
"platform": ((2, 3), (3, 0)),
"popen2": ((2, 0), None),
"profiling": (None, (3, 15)),
"profiling.sampling": (None, (3, 15)),
"profiling.tracing": (None, (3, 15)),
"pyclbr": ((2, 0), (3, 0)),
"pydoc": ((2, 1), (3, 0)),
"queue": (None, (3, 0)),
"random": ((2, 0), (3, 0)),
"repr": ((2, 0), None),
"reprlib": (None, (3, 0)),
"runpy": ((2, 5), (3, 0)),
"secrets": (None, (3, 6)),
"selectors": (None, (3, 4)),
"sets": ((2, 3), None),
"socket": ((2, 0), (3, 0)),
"socketserver": (None, (3, 0)),
"spwd": ((2, 5), (3, 0)),
"sqlite3": ((2, 5), (3, 0)),
"ssl": ((2, 6), (3, 0)),
"statistics": bpv("statistics", (None, (3, 4)), config),
"string.templatelib": (None, (3, 14)),
"stringprep": ((2, 3), (3, 0)),
"subprocess": ((2, 4), (3, 0)),
"sysconfig": ((2, 7), (3, 2)),
"tarfile": ((2, 3), (3, 0)),
"test.support.bytecode_helper": (None, (3, 9)),
"test.support.import_helper": (None, (3, 10)),
"test.support.os_helper": (None, (3, 10)),
"test.support.socket_helper": (None, (3, 9)),
"test.support.threading_helper": (None, (3, 10)),
"test.support.warnings_helper": (None, (3, 10)),
"textwrap": ((2, 3), (3, 0)),
"timeit": ((2, 3), (3, 0)),
"tkinter": (None, (3, 0)),
"tomllib": (None, (3, 11)),
"tracemalloc": (None, (3, 4)),
"typing": bpv("typing", (None, (3, 5)), config),
"typing_extensions": bpv("typing_extensions", ((0, 0), (0, 0)), config),
"unittest": ((2, 1), (3, 0)),
"unittest.mock": (None, (3, 3)),
"urllib.parse": (None, (3, 0)),
"urllib2": ((2, 0), None),
"urlparse": ((2, 0), None),
"uuid": ((2, 5), (3, 0)),
"venv": (None, (3, 3)),
"warnings": ((2, 1), (3, 0)),
"weakref": ((2, 1), (3, 0)),
"webbrowser": ((2, 0), (3, 0)),
"winreg": (None, (3, 0)),
"wsgiref": ((2, 5), (3, 0)),
"wsgiref.types": (None, (3, 11)),
"xml.dom": ((2, 0), (3, 0)),
"xml.dom.minidom": ((2, 0), (3, 0)),
"xml.dom.pulldom": ((2, 0), (3, 0)),
"xml.etree.ElementInclude": ((2, 5), (3, 0)),
"xml.etree.ElementTree": ((2, 5), (3, 0)),
"xml.parsers.expat": ((2, 0), (3, 0)),
"xml.sax": ((2, 0), (3, 0)),
"xml.sax.handler": ((2, 0), (3, 0)),
"xml.sax.saxutils": ((2, 0), (3, 0)),
"xml.sax.xmlreader": ((2, 0), (3, 0)),
"xmlrpc": (None, (3, 0)),
"xmlrpc.client": (None, (3, 0)),
"xmlrpc.server": (None, (3, 0)),
"xmlrpclib": ((2, 2), None),
"zipapp": (None, (3, 5)),
"zipimport": ((2, 3), (3, 0)),
"zoneinfo": bpv("zoneinfo", (None, (3, 9)), config),
}
# Module member requirements: member -> (module, requirements)
def MOD_MEM_REQS(config):
return {
# Builtin classes
"bool": ((2, 2), (3, 0)),
"bytearray": ((2, 6), (3, 0)),
"frozenset": ((2, 4), (3, 0)),
"memoryview": ((2, 7), (3, 0)),
"object": ((2, 2), (3, 0)),
"set": ((2, 4), (3, 0)),
"dict": ((2, 2), (3, 0)),
"long": ((2, 0), None),
"frozendict": (None, (3, 15)),
"sentinel": (None, (3, 15)),
# Classes
"ConfigParser.ConfigParser": ((2, 3), None),
"ConfigParser.RawConfigParser": ((2, 3), None),
"ConfigParser.SafeConfigParser": ((2, 3), None),
"Queue.LifoQueue": ((2, 6), None),
"Queue.PriorityQueue": ((2, 6), None),
"SimpleXMLRPCServer.CGIXMLRPCRequestHandler": ((2, 3), None),
"abc.ABC": (None, (3, 4)),
"annotationlib.Format": (None, (3, 14)),
"argparse.BooleanOptionalAction": (None, (3, 9)),
"ast.Constant": (None, (3, 6)),
"asyncio.Barrier": (None, (3, 11)),
"asyncio.BufferedProtocol": (None, (3, 7)),
"asyncio.MultiLoopChildWatcher": (None, (3, 8)),
"asyncio.PidfdChildWatcher": (None, (3, 9)),
"asyncio.Runner": (None, (3, 11)),
"asyncio.TaskGroup": (None, (3, 11)),
"asyncio.ThreadedChildWatcher": (None, (3, 8)),
"calendar.Calendar": ((2, 5), (3, 0)),
"calendar.Day": (None, (3, 12)),
"calendar.HTMLCalendar": ((2, 5), (3, 0)),
"calendar.LocaleHTMLCalendar": ((2, 5), (3, 0)),
"calendar.LocaleTextCalendar": ((2, 5), (3, 0)),
"calendar.Month": (None, (3, 12)),
"calendar.TextCalendar": ((2, 5), (3, 0)),
"codecs.IncrementalEncoder": ((2, 5), (3, 0)),
"collections.ChainMap": (None, (3, 3)),
"collections.Counter": ((2, 7), (3, 1)),
"collections.OrderedDict": ((2, 7), (3, 1)),
"collections.UserDict": (None, (3, 0)),
"collections.UserList": (None, (3, 0)),
"collections.UserString": (None, (3, 0)),
"collections.abc.AsyncGenerator": (None, (3, 6)),
"collections.abc.AsyncIterable": (None, (3, 5)),
"collections.abc.AsyncIterator": (None, (3, 5)),
"collections.abc.Awaitable": (None, (3, 5)),
"collections.abc.Buffer": (None, (3, 12)),
"collections.abc.Collection": (None, (3, 6)),
"collections.abc.Coroutine": (None, (3, 5)),
"collections.abc.Generator": (None, (3, 5)),
"collections.abc.Reversible": (None, (3, 6)),
"collections.defaultdict": ((2, 5), (3, 0)),
"collections.deque": ((2, 4), (3, 0)),
"collections.namedtuple": ((2, 6), (3, 0)),
"concurrent.futures.InterpreterPoolExecutor": (None, (3, 14)),
"contextlib.AbstractAsyncContextManager": (None, (3, 7)),
"contextlib.AbstractContextManager": (None, (3, 6)),
"contextlib.AsyncContextDecorator": (None, (3, 10)),
"contextlib.AsyncExitStack": (None, (3, 7)),
"contextlib.ContextDecorator": (None, (3, 2)),
"contextlib.ExitStack": (None, (3, 3)),
"csv.unix_dialect": (None, (3, 2)),
"ctypes.BigEndianUnion": (None, (3, 11)),
"ctypes.LittleEndianUnion": (None, (3, 11)),
"ctypes.c_bool": ((2, 6), (3, 0)),
"ctypes.c_double_complex": (None, (3, 14)),
"ctypes.c_float_complex": (None, (3, 14)),
"ctypes.c_longdouble": ((2, 6), (3, 0)),
"ctypes.c_longdouble_complex": (None, (3, 14)),
"ctypes.c_ssize_t": ((2, 7), (3, 2)),
"datetime.timezone": (None, (3, 2)),
"difflib.HtmlDiff": ((2, 4), (3, 0)),
"dis.Bytecode": (None, (3, 4)),
"dis.Instruction": (None, (3, 4)),
"dis.Positions": (None, (3, 11)),
"doctest.DocTest": ((2, 4), (3, 0)),
"doctest.DocTestFinder": ((2, 4), (3, 0)),
"doctest.DocTestParser": ((2, 4), (3, 0)),
"doctest.DocTestRunner": ((2, 4), (3, 0)),
"doctest.Example": ((2, 4), (3, 0)),
"doctest.OutputChecker": ((2, 4), (3, 0)),
"email.generator.BytesGenerator": (None, (3, 2)),
"email.generator.DecodedGenerator": ((2, 2), (3, 0)),
"email.mime.application.MIMEApplication": ((2, 5), (3, 0)),
"email.mime.multipart.MIMEMultipart": ((2, 2), (3, 0)),
"email.mime.nonmultipart.MIMENonMultipart": ((2, 2), (3, 0)),
"email.parser.BytesFeedParser": (None, (3, 2)),
"email.parser.BytesHeaderParser": (None, (3, 3)),
"email.parser.BytesParser": (None, (3, 2)),
"email.parser.FeedParser": ((2, 4), (3, 0)),
"email.policy.EmailPolicy": (None, (3, 3)),
"enum.EnumCheck": (None, (3, 11)),
"enum.EnumDict": (None, (3, 13)),
"enum.EnumType": (None, (3, 11)),
"enum.Flag": (None, (3, 6)),
"enum.FlagBoundary": (None, (3, 11)),
"enum.IntFlag": (None, (3, 6)),
"enum.ReprEnum": (None, (3, 11)),
"enum.StrEnum": (None, (3, 11)),
"enum.auto": (None, (3, 6)),
"ftplib.FTP_TLS": ((2, 7), (3, 2)),
"functools.partialmethod": (None, (3, 4)),
"http.HTTPMethod": (None, (3, 11)),
"http.HTTPStatus": (None, (3, 5)),
"http.server.HTTPSServer": (None, (3, 14)),
"http.server.ThreadingHTTPSServer": (None, (3, 14)),
"http.server.ThreadingHTTPServer": (None, (3, 7)),
"httplib.HTTPConnection": ((2, 0), None),
"httplib.HTTPResponse": ((2, 0), None),
"httplib.HTTPSConnection": ((2, 0), None),
"imaplib.IMAP4_stream": ((2, 3), (3, 0)),
"imp.NullImporter": ((2, 5), (3, 0)),
"importlib.abc.FileLoader": (None, (3, 3)),
"importlib.abc.MetaPathFinder": (None, (3, 3)),
"importlib.abc.PathEntryFinder": (None, (3, 3)),
"importlib.abc.ResourceReader": (None, (3, 7)),
"importlib.abc.Traversable": (None, (3, 9)),
"importlib.abc.TraversableReader": (None, (3, 9)),
"importlib.abc.TraversableResources": (None, (3, 9)),
"importlib.machinery.ExtensionFileLoader": (None, (3, 3)),
"importlib.machinery.FileFinder": (None, (3, 3)),
"importlib.machinery.ModuleSpec": (None, (3, 4)),
"importlib.machinery.NamespaceLoader": (None, (3, 11)),
"importlib.machinery.SourceFileLoader": (None, (3, 3)),
"importlib.machinery.SourcelessFileLoader": (None, (3, 3)),
"importlib.machinery.WindowsRegistryFinder": (None, (3, 3)),
"importlib.metadata.EntryPoints": (None, (3, 10)),
"importlib.metadata.MetadataNotFound": (None, (3, 15)),
"importlib.util.LazyLoader": (None, (3, 5)),
"inspect.BoundArguments": (None, (3, 3)),
"inspect.BufferFlags": (None, (3, 12)),
"inspect.Parameter": (None, (3, 3)),
"inspect.Signature": (None, (3, 3)),
"io.Reader": (None, (3, 14)),
"io.Writer": (None, (3, 14)),
"logging.LoggerAdapter": ((2, 6), (3, 0)),
"logging.NullHandler": ((2, 7), (3, 1)),
"logging.StreamHandler": ((2, 6), (3, 0)),
"logging.handlers.QueueHandler": (None, (3, 2)),
"logging.handlers.QueueListener": (None, (3, 2)),
"logging.handlers.WatchedFileHandler": ((2, 6), (3, 0)),
"multiprocessing.Barrier": (None, (3, 3)),
"nntplib.NNTP_SSL": (None, (3, 2)),
"os.DirEntry": (None, (3, 5)),
"os.PathLike": (None, (3, 6)),
"os.sched_param": (None, (3, 3)),
"os.terminal_size": (None, (3, 3)),
"pickle.PickleBuffer": (None, (3, 8)),
"pkgutil.ModuleInfo": (None, (3, 6)),
"plistlib.UID": (None, (3, 8)),
"popen2.Popen4": ((2, 0), None),
"poplib.POP3_SSL": ((2, 4), (3, 0)),
"pstats.FunctionProfile": (None, (3, 9)),
"pstats.Stats": ((2, 3), (3, 0)),
"pstats.StatsProfile": (None, (3, 9)),
"py_compile.PycInvalidationMode": (None, (3, 7)),
"queue.SimpleQueue": (None, (3, 7)),
"random.SystemRandom": ((2, 4), (3, 0)),
"selectors.DevpollSelector": (None, (3, 5)),
"signals.Handlers": (None, (3, 5)),
"signals.Sigmasks": (None, (3, 5)),
"signals.Signals": (None, (3, 5)),
"site.StartupState": (None, (3, 15)),
"smtplib.LMTP": ((2, 6), (3, 0)),
"smtplib.SMTP_SSL": ((2, 6), (3, 0)),
"sqlite3.Blob": (None, (3, 11)),
"ssl.AlertDescription": (None, (3, 6)),
"ssl.MemoryBIO": (None, (3, 5)),
"ssl.Options": (None, (3, 6)),
"ssl.SSLContext": ((2, 7), (3, 2)),
"ssl.SSLErrorNumber": (None, (3, 6)),
"ssl.SSLObject": (None, (3, 5)),
"ssl.SSLSession": (None, (3, 6)),
"ssl.TLSVersion": (None, (3, 7)),
"ssl.VerifyFlags": (None, (3, 6)),
"ssl.VerifyMode": (None, (3, 6)),
"statistics.NormalDist": (None, (3, 8)),
"string.Formatter": ((2, 6), (3, 0)),
"string.Template": ((2, 4), (3, 0)),
"string.templatelib.Interpolation": (None, (3, 14)),
"string.templatelib.Template": (None, (3, 14)),
"struct.Struct": ((2, 5), (3, 0)),
"subprocess.CompletedProcess": (None, (3, 5)),
"test.support.EnvironmentVarGuard": ((2, 6), None),
"test.support.TransientResource": ((2, 6), None),
"test.support.WarningsRecorder": ((2, 6), None),
"test.support.os_helper.EnvironmentVarGuard": (None, (3, 10)),
"test.support.socket_helper.TransientResource": (None, (3, 9)),
"test.support.warnings_helper.WarningsRecorder": (None, (3, 10)),
"threading.Barrier": (None, (3, 2)),
"threading.local": ((2, 4), (3, 0)),
"time.struct_time": ((2, 2), (3, 0)),
"traceback.FrameSummary": (None, (3, 5)),
"traceback.StackSummary": (None, (3, 5)),
"traceback.TracebackException": (None, (3, 5)),
"tracemalloc.DomainFilter": (None, (3, 6)),
"types.CapsuleType": (None, (3, 13)),
"types.GenericAlias": (None, (3, 9)),
"types.MappingProxyType": (None, (3, 3)),
"types.SimpleNamespace": (None, (3, 3)),
"typing.AsyncContextManager": (None, (3, 5)),
"typing.AsyncGenerator": (None, (3, 6)),
"typing.AsyncIterable": (None, (3, 5)),
"typing.AsyncIterator": (None, (3, 5)),
"typing.Awaitable": (None, (3, 5)),
# Notes: `typing.ChainMap` relies on `collections.ChainMap`, which is 3.3+.
"typing.ChainMap": (None, (3, 5) if not bp("typing", config) else (3, 3)),
"typing.Collection": (None, (3, 6)),
# Notes:
# `typing.ContextManager` was added in `typing` backport 3.6.2 (which requires 2.7 or 3.3+).
"typing.ContextManager": (None, (3, 5)) if not bp("typing", config) else ((2, 7), (3, 3)),
"typing.Coroutine": (None, (3, 5)),
# Notes: `typing.Counter` was added in `typing` backport 3.6.1 (which requires 2.7 or 3.3+).
"typing.Counter": (None, (3, 5)) if not bp("typing", config) else ((2, 7), (3, 3)),
# Notes: `typing.Deque` was added in `typing` backport 3.6.1 (which requires 2.7 or 3.3+).
"typing.Deque": (None, (3, 5)) if not bp("typing", config) else ((2, 7), (3, 3)),
"typing.ForwardRef": (None, (3, 7)),
"typing.NamedTuple": (None, (3, 5)),
"typing.NoDefault": (None, (3, 13)),
"typing.OrderedDict": (None, (3, 7)),
# Notes:
# `typing.Protocol` is backported to Python 2.7. For Python 3 it goes to `typing_extensions`.
# The same applies for some other rules below.
"typing.Protocol": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"typing.ParamSpec": (None, (3, 10)),
"typing.ReadOnly": (None, (3, 13)),
# Notes: `object.__bytes__` is 3.2+
"typing.SupportsBytes": (None, (3, 5)) if not bp("typing", config) else (None, (3, 2)),
# Notes:
# `typing.SupportsIndex` was added in `typing` backport 3.7.4 (which requires 2.7 or 3.4+).
"typing.SupportsIndex": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 4)),
# Notes: `object.__round__` is 3.0+
"typing.SupportsRound": (None, (3, 5)) if not bp("typing", config) else (None, (3, 2)),
"typing.TypedDict": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"typing.TypeAliasType": (None, (3, 12)),
"typing.TypeForm": (None, (3, 15)),
"typing.TypeIs": (None, (3, 13)),
"unittest.IsolatedAsyncioTestCase": (None, (3, 8)),
"unittest.TextTestResult": ((2, 7), (3, 2)),
"unittest.mock.AsyncMock": bpv("mock", (None, (3, 8)), config),
"urllib.parse.DefragResult": (None, (3, 2)),
"urllib.parse.DefragResultBytes": (None, (3, 2)),
"urllib.parse.ParseResultBytes": (None, (3, 2)),
"urllib.parse.SplitResultBytes": (None, (3, 2)),
"urllib.request.DataHandler": (None, (3, 4)),
"urllib.request.HTTPPasswordMgrWithPriorAuth": (None, (3, 5)),
"urllib2.HTTPCookieProcessor": ((2, 4), None),
"urllib2.HTTPErrorProcessor": ((2, 4), None),
"uuid.SafeUUID": (None, (3, 7)),
"webbrowser.MacOS": (None, (3, 15)),
"warnings.catch_warnings": ((2, 6), (3, 0)),
"weakref.WeakMethod": (None, (3, 4)),
"weakref.WeakSet": ((2, 7), (3, 0)),
"weakref.finalize": (None, (3, 4)),
"wsgiref.handlers.IISCGIHandler": (None, (3, 2)),
"xml.etree.ElementTree.C14NWriterTarget": (None, (3, 8)),
"xml.etree.ElementTree.XMLPullParser": (None, (3, 4)),
"xml.sax.handler.LexicalHandler": (None, (3, 10)),
"xmlrpclib.MultiCall": ((2, 4), None),
"zipfile.Path": (None, (3, 8)),
"zipimport.zipimporter": ((2, 7), (3, 0)),
# Builtin exceptions
"BaseException": ((2, 5), (3, 0)),
"exceptions.BaseException": ((2, 5), None),
"BaseExceptionGroup": (None, (3, 11)),
"BlockingIOError": (None, (3, 3)),
"BrokenPipeError": (None, (3, 3)),
"BytesWarning": ((2, 6), (3, 0)),
"exceptions.BytesWarning": ((2, 6), None),
"ChildProcessError": (None, (3, 3)),
"ConnectionAbortedError": (None, (3, 3)),
"ConnectionError": (None, (3, 3)),
"ConnectionRefusedError": (None, (3, 3)),
"ConnectionResetError": (None, (3, 3)),
"EncodingWarning": (None, (3, 10)),
"ExceptionGroup": (None, (3, 11)),
"FileExistsError": (None, (3, 3)),
"FileNotFoundError": (None, (3, 3)),
"GeneratorExit": ((2, 5), (3, 0)),
"exceptions.GeneratorExit": ((2, 5), None),
"ImportWarning": ((2, 5), (3, 0)),
"exceptions.ImportWarning": ((2, 5), None),
"InterruptedError": (None, (3, 3)),
"IsADirectoryError": (None, (3, 3)),
"ModuleNotFoundError": (None, (3, 6)),
"NotADirectoryError": (None, (3, 3)),
"PermissionError": (None, (3, 3)),
"ProcessLookupError": (None, (3, 3)),
"PythonFinalizationError": (None, (3, 13)),
"RecursionError": (None, (3, 5)),
"ReferenceError": ((2, 2), (3, 0)),
"exceptions.ReferenceError": ((2, 2), None),
"ResourceWarning": (None, (3, 2)),
"StopAsyncIteration": (None, (3, 5)),
"StopIteration": ((2, 2), (3, 0)),
"exceptions.StopIteration": ((2, 2), None),
"TimeoutError": (None, (3, 3)),
"UnicodeDecodeError": ((2, 3), (3, 0)),
"exceptions.UnicodeDecodeError": ((2, 3), None),
"UnicodeEncodeError": ((2, 3), (3, 0)),
"exceptions.UnicodeEncodeError": ((2, 3), None),
"UnicodeTranslateError": ((2, 3), (3, 0)),
"exceptions.UnicodeTranslateError": ((2, 3), None),
"UnicodeWarning": ((2, 5), (3, 0)),
"exceptions.UnicodeWarning": ((2, 5), None),
"UnboundLocalError": ((2, 0), (3, 0)),
"exceptions.UnboundLocalError": ((2, 0), None),
"UnicodeError": ((2, 0), (3, 0)),
"exceptions.UnicodeError": ((2, 0), None),
"WindowsError": ((2, 0), (3, 0)),
"exceptions.WindowsError": ((2, 0), None),
# Exceptions
"ConfigParser.InterpolationMissingOptionError": ((2, 3), None),
"ConfigParser.InterpolationSyntaxError": ((2, 3), None),
"asyncio.BrokenBarrierError": (None, (3, 11)),
"asyncio.QueueShutDown": (None, (3, 13)),
"concurrent.futures.BrokenExecutor": (None, (3, 7)),
"concurrent.futures.InvalidStateError": (None, (3, 8)),
"concurrent.futures.process.BrokenProcessPool": (None, (3, 3)),
"concurrent.futures.thread.BrokenThreadPool": (None, (3, 7)),
"concurrent.interpreters.BrokenInterpreterPool": (None, (3, 14)),
"concurrent.interpreters.ExecutionFailed": (None, (3, 14)),
"configparser.InvalidWriteError": (None, (3, 14)),
"configparser.MultilineContinuationError": (None, (3, 13)),
"configparser.UnnamedSectionDisabledError": (None, (3, 14)),
"ctypes.COMError": (None, (3, 14)),
"email.errors.CloseBoundaryNotFoundDefect": (None, (3, 3)),
"email.errors.FirstHeaderLineIsContinuationDefect": ((2, 4), (3, 0)),
"email.errors.MalformedHeaderDefect": ((2, 4), (3, 0)),
"email.errors.MisplacedEnvelopeHeaderDefect": ((2, 4), (3, 0)),
"email.errors.MissingHeaderBodySeparatorDefect": (None, (3, 3)),
"email.errors.MultipartInvariantViolationDefect": ((2, 4), (3, 0)),
"email.errors.NoBoundaryInMultipartDefect": ((2, 4), (3, 0)),
"email.errors.StartBoundaryNotFoundDefect": ((2, 4), (3, 0)),
"gzip.BadGzipFile": (None, (3, 8)),
"htmllib.HTMLParseError": ((2, 4), None),
"httplib.BadStatusLine": ((2, 0), None),
"httplib.CannotSendHeader": ((2, 0), None),
"httplib.CannotSendRequest": ((2, 0), None),
"httplib.HTTPException": ((2, 0), None),
"httplib.ImproperConnectionState": ((2, 0), None),
"httplib.IncompleteRead": ((2, 0), None),
"httplib.InvalidURL": ((2, 3), None),
"httplib.NotConnected": ((2, 0), None),
"httplib.ResponseNotReady": ((2, 0), None),
"httplib.UnimplementedFileMode": ((2, 0), None),
"httplib.UnknownProtocol": ((2, 0), None),
"httplib.UnknownTransferEncoding": ((2, 0), None),
"json.JSONDecodeError": (None, (3, 5)),
"pathlib.UnsupportedOperation": (None, (3, 13)),
"queue.ShutDown": (None, (3, 13)),
"re.PatternError": (None, (3, 13)),
"sgmllib.SGMLParseError": ((2, 1), None),
"shutil.Error": ((2, 3), (3, 0)),
"shutil.SameFileError": (None, (3, 4)),
"smtplib.SMTPNotSupportedError": (None, (3, 5)),
"socket.timeout": ((2, 3), (3, 0)),
"ssl.SSLCertVerificationError": (None, (3, 7)),
"ssl.SSLEOFError": ((2, 7), (3, 3)),
"ssl.SSLSyscallError": ((2, 7), (3, 3)),
"ssl.SSLWantReadError": ((2, 7), (3, 3)),
"ssl.SSLWantWriteError": ((2, 7), (3, 3)),
"ssl.SSLZeroReturnError": ((2, 7), (3, 3)),
"subprocess.SubprocessError": (None, (3, 3)),
"subprocess.TimeoutExpired": (None, (3, 3)),
"tarfile.HeaderError": ((2, 6), (3, 0)),
"tarfile.LinkFallbackError": (None, (3, 9)), # Backported 3.14->3.13->3.12->3.11->3.10->3.9
"threading.BrokenBarrierError": (None, (3, 2)),
"unittest.SkipTest": ((2, 7), (3, 1)),
"urllib.ContentTooShortError": ((2, 5), None),
"xml.dom.DOMException": ((2, 1), (3, 0)),
"xml.dom.DomstringSizeErr": ((2, 1), (3, 0)),
"xml.dom.HierarchyRequestErr": ((2, 1), (3, 0)),
"xml.dom.IndexSizeErr": ((2, 1), (3, 0)),
"xml.dom.InuseAttributeErr": ((2, 1), (3, 0)),
"xml.dom.InvalidAccessErr": ((2, 1), (3, 0)),
"xml.dom.InvalidCharacterErr": ((2, 1), (3, 0)),
"xml.dom.InvalidModificationErr": ((2, 1), (3, 0)),
"xml.dom.InvalidStateErr": ((2, 1), (3, 0)),
"xml.dom.NamespaceErr": ((2, 1), (3, 0)),
"xml.dom.NoDataAllowedErr": ((2, 1), (3, 0)),
"xml.dom.NoModificationAllowedErr": ((2, 1), (3, 0)),
"xml.dom.NotFoundErr": ((2, 1), (3, 0)),
"xml.dom.NotSupportedErr": ((2, 1), (3, 0)),
"xml.dom.SyntaxErr": ((2, 1), (3, 0)),
"xml.dom.WrongDocumentErr": ((2, 1), (3, 0)),
"zipfile.BadZipFile": (None, (3, 2)),
# Builtin functions
# Notes:
# file() is kept at 2.0 instead of 2.2, where the function was introduced, because file objects
# have existed since 2.0 and we don't do type deduction. Therefore analysis on file objects
# wouldn't be detected, like `open(..).xreadlines()`, but using `file(..).xreadlines()` would
# trigger rule "file.xreadlines" 2.1. So if file() was kept at 2.2 it would introduce conflict.
"aiter": (None, (3, 10)),
"all": ((2, 5), (3, 0)),
"anext": (None, (3, 10)),
"any": ((2, 5), (3, 0)),
"basestring": ((2, 3), None),
"bin": ((2, 6), (3, 0)),
"breakpoint": (None, (3, 7)),
"bytearray.hex": (None, (3, 5)),
"bytearray.isascii": (None, (3, 7)),
"bytearray.maketrans": (None, (3, 1)),
"bytearray.removeprefix": (None, (3, 9)),
"bytearray.removesuffix": (None, (3, 9)),
"bytearray.take_bytes": (None, (3, 15)),
"bytes.hex": (None, (3, 5)),
"bytes.isascii": (None, (3, 7)),
"bytes.maketrans": (None, (3, 1)),
"bytes.removeprefix": (None, (3, 9)),
"bytes.removesuffix": (None, (3, 9)),
"callable": ((2, 0), (3, 2)),
"classmethod": ((2, 2), (3, 0)),
"dict.fromkeys": ((2, 3), (3, 0)),
"dict.has_key": ((2, 2), None),
"dict.iteritems": ((2, 2), None),
"dict.iterkeys": ((2, 2), None),
"dict.itervalues": ((2, 2), None),
"dict.pop": ((2, 3), (3, 0)),
"dict.viewitems": ((2, 7), None),
"dict.viewkeys": ((2, 7), None),
"dict.viewvalues": ((2, 7), None),
"enumerate": ((2, 3), (3, 0)),
"file": ((2, 0), None), # Kept at 2.0 on purpose (see note above).
"file.next": ((2, 3), None),
"file.xreadlines": ((2, 1), None),
"float.as_integer_ratio": ((2, 6), (3, 0)),
"float.fromhex": ((2, 6), (3, 0)),
"float.hex": ((2, 6), (3, 0)),
"float.is_integer": ((2, 6), (3, 0)),
"format": ((2, 6), (3, 0)),
"frozenset.isdisjoint": ((2, 6), (3, 0)),
"help": ((2, 2), (3, 0)),
"int.as_integer_ratio": (None, (3, 8)),
"int.bit_count": (None, (3, 10)),
"int.bit_length": ((2, 7), (3, 1)),
"int.from_bytes": (None, (3, 2)),
"int.is_integer": (None, (3, 12)),
"int.to_bytes": (None, (3, 2)),
"iter": ((2, 2), (3, 0)),
"list.clear": (None, (3, 0)),
"list.copy": (None, (3, 0)),
"long.bit_length": ((2, 7), None),
"memoryview.cast": (None, (3, 3)),
"memoryview.hex": (None, (3, 5)),
"memoryview.release": (None, (3, 2)),
"memoryview.toreadonly": (None, (3, 8)),
"next": ((2, 6), (3, 0)),
"property": ((2, 2), (3, 0)),
"property.__name__": (None, (3, 13)),
"property.deleter": ((2, 6), (3, 0)),
"property.getter": ((2, 6), (3, 0)),
"property.setter": ((2, 6), (3, 0)),
"reversed": ((2, 4), (3, 0)),
"set.isdisjoint": ((2, 6), (3, 0)),
"slice.indices": ((2, 3), (3, 0)),
"sorted": ((2, 4), (3, 0)),
"staticmethod": ((2, 2), (3, 0)),
"str.casefold": (None, (3, 3)),
"str.decode": ((2, 2), None),
"str.encode": ((2, 0), (3, 0)),
"str.format": ((2, 6), (3, 0)),
"str.format_map": (None, (3, 2)),
"str.isascii": (None, (3, 7)),
"str.isdecimal": (None, (3, 0)),
"str.isidentifier": (None, (3, 0)),
"str.isnumeric": (None, (3, 0)),
"str.isprintable": (None, (3, 0)),
"str.maketrans": (None, (3, 0)),
"str.partition": ((2, 5), (3, 0)),
"str.removeprefix": (None, (3, 9)),
"str.removesuffix": (None, (3, 9)),
"str.rpartition": ((2, 5), (3, 0)),
"str.rsplit": ((2, 4), (3, 0)),
"str.zfill": ((2, 2), (3, 0)),
"sum": ((2, 3), (3, 0)),
"super": ((2, 2), (3, 0)),
"type": ((2, 0), (3, 0)),
"unichr": ((2, 0), None),
"unicode": ((2, 0), None),
"unicode.isdecimal": ((2, 0), None),
"unicode.isnumeric": ((2, 0), None),
"zip": ((2, 0), (3, 0)),
# Builtin constants
"memoryview.c_contiguous": (None, (3, 3)),
"memoryview.contiguous": (None, (3, 3)),
"memoryview.f_contiguous": (None, (3, 3)),
"memoryview.nbytes": (None, (3, 3)),
"memoryview.obj": (None, (3, 3)),
# Dict view constants (via `dict.keys()`, `dict.values()`, or `dict.items()`)
"dict.items.mapping": (None, (3, 10)),
"dict.keys.mapping": (None, (3, 10)),
"dict.values.mapping": (None, (3, 10)),
# Functions
"BaseException.__notes__": (None, (3, 11)),
"BaseException.add_note": (None, (3, 11)),
"ConfigParser.SafeConfigParser.set": ((2, 4), None),
"EasyDialogs.GetArgv": ((2, 0), None),
"Queue.Queue.join": ((2, 5), None),
"Queue.Queue.task_done": ((2, 5), None),
"SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET": ((2, 5), None),
"SimpleXMLRPCServer.SimpleXMLRPCServer.register_introspection_functions": ((2, 3), None),
"SocketServer.BaseServer.server_close": ((2, 6), None),
"SocketServer.BaseServer.shutdown": ((2, 6), None),
"Tkinter.Tcl": ((2, 4), None),
"_thread.get_native_id": (None, (3, 8)),
"_winreg.CreateKeyEx": ((2, 7), None),
"_winreg.DeleteKeyEx": ((2, 7), None),
"_winreg.ExpandEnvironmentStrings": ((2, 6), None),
"abc.get_cache_token": (None, (3, 4)),
"abc.update_abstractmethods": (None, (3, 10)),
"argparse.ArgumentParser.parse_intermixed_args": (None, (3, 7)),
"argparse.ArgumentParser.parse_known_intermixed_args": (None, (3, 7)),
"array.array.clear": (None, (3, 13)),
"array.array.frombytes": (None, (3, 2)),
"array.array.tobytes": (None, (3, 2)),
"ast.compare": (None, (3, 14)),
"ast.get_source_segment": (None, (3, 8)),
"ast.unparse": (None, (3, 9)),
"asyncio.AbstractChildWatcher.is_active": (None, (3, 8)),
"asyncio.Future.get_loop": (None, (3, 7)),
"asyncio.Handle.cancelled": (None, (3, 7)),
"asyncio.Queue.shutdown": (None, (3, 13)),
"asyncio.ReadTransport.is_reading": (None, (3, 7)),
"asyncio.Server.abort_clients": (None, (3, 13)),
"asyncio.Server.close_clients": (None, (3, 13)),
"asyncio.Server.get_loop": (None, (3, 9)),
"asyncio.Server.is_serving": (None, (3, 9)),
"asyncio.Server.serve_forever": (None, (3, 9)),
"asyncio.Server.start_serving": (None, (3, 9)),
"asyncio.StreamReader.readuntil": (None, (3, 5)),
"asyncio.StreamWriter.is_closing": (None, (3, 7)),
"asyncio.StreamWriter.start_tls": (None, (3, 11)),
"asyncio.StreamWriter.wait_closed": (None, (3, 7)),
"asyncio.Task.cancelling": (None, (3, 11)),
"asyncio.Task.get_context": (None, (3, 12)),
"asyncio.Task.get_coro": (None, (3, 8)),
"asyncio.Task.get_name": (None, (3, 8)),
"asyncio.Task.set_name": (None, (3, 8)),
"asyncio.Task.uncancel": (None, (3, 11)),
"asyncio.TaskGroup.cancel": (None, (3, 15)),
"asyncio.TimerHandle.when": (None, (3, 7)),
"asyncio.WriteTransport.get_write_buffer_limits": (None, (3, 4)),
"asyncio.all_tasks": (None, (3, 7)),
"asyncio.capture_call_graph": (None, (3, 14)),
"asyncio.create_eager_task_factory": (None, (3, 12)),
"asyncio.create_task": (None, (3, 7)),
"asyncio.current_task": (None, (3, 7)),
"asyncio.eager_task_factory": (None, (3, 12)),
"asyncio.get_running_loop": (None, (3, 7)),
"asyncio.isfuture": (None, (3, 5)),
"asyncio.loop.connect_accepted_socket": (None, (3, 5)),
"asyncio.loop.create_future": (None, (3, 5)),
"asyncio.loop.get_exception_handler": (None, (3, 5)),
"asyncio.loop.sendfile": (None, (3, 7)),
"asyncio.loop.shutdown_asyncgens": (None, (3, 6)),
"asyncio.loop.shutdown_default_executor": (None, (3, 9)),
"asyncio.loop.sock_recv_into": (None, (3, 7)),
"asyncio.loop.sock_recvfrom": (None, (3, 11)),
"asyncio.loop.sock_recvfrom_into": (None, (3, 11)),
"asyncio.loop.sock_sendfile": (None, (3, 7)),
"asyncio.loop.sock_sendto": (None, (3, 11)),
"asyncio.loop.start_tls": (None, (3, 7)),
"asyncio.print_call_graph": (None, (3, 14)),
"asyncio.run": (None, (3, 7)),
"asyncio.run_coroutine_threadsafe": (None, (3, 5)),
"asyncio.timeout": (None, (3, 11)),
"asyncio.timeout_at": (None, (3, 11)),
"asyncio.to_thread": (None, (3, 9)),
"asyncore.dispatcher.handle_accepted": (None, (3, 2)),
"audioop.alaw2lin": ((2, 5), (3, 0)),
"audioop.byteswap": (None, (3, 4)),
"audioop.lin2alaw": ((2, 5), (3, 0)),
"base64.a85decode": (None, (3, 4)),
"base64.a85encode": (None, (3, 4)),
"base64.b32hexdecode": (None, (3, 10)),
"base64.b32hexencode": (None, (3, 10)),
"base64.b85decode": (None, (3, 4)),
"base64.b85encode": (None, (3, 4)),
"base64.decodebytes": (None, (3, 1)),
"base64.encodebytes": (None, (3, 1)),
"base64.z85decode": (None, (3, 13)),
"base64.z85encode": (None, (3, 13)),
"bdb.Bdb.get_bpbynumber": (None, (3, 2)),
"bdb.Breakpoint.bpformat": (None, (3, 2)),
"bdb.Breakpoint.clearBreakpoints": (None, (3, 10)),
"binascii.a2b_ascii85": (None, (3, 15)),
"binascii.a2b_base32": (None, (3, 15)),
"binascii.a2b_base85": (None, (3, 15)),
"binascii.b2a_ascii85": (None, (3, 15)),
"binascii.b2a_base32": (None, (3, 15)),
"binascii.b2a_base85": (None, (3, 15)),
"bz2.BZ2File.fileno": (None, (3, 3)),
"bz2.BZ2File.peek": (None, (3, 3)),
"bz2.BZ2File.read1": (None, (3, 3)),
"bz2.BZ2File.readable": (None, (3, 3)),
"bz2.BZ2File.readinto": (None, (3, 3)),
"bz2.BZ2File.seekable": (None, (3, 3)),
"bz2.BZ2File.writable": (None, (3, 3)),
"bz2.open": (None, (3, 3)),
"calendar.Calendar.itermonthdays3": (None, (3, 7)),
"calendar.Calendar.itermonthdays4": (None, (3, 7)),
"cgi.FieldStorage.getfirst": ((2, 2), (3, 0)),
"cgi.FieldStorage.getlist": ((2, 2), (3, 0)),
"cmath.isclose": (None, (3, 5)),
"cmath.isfinite": (None, (3, 2)),
"cmath.isinf": ((2, 6), (3, 0)),
"cmath.isnan": ((2, 6), (3, 0)),
"cmath.phase": ((2, 6), (3, 0)),
"cmath.polar": ((2, 6), (3, 0)),
"cmath.rect": ((2, 6), (3, 0)),
"codecs.decode": ((2, 4), (3, 0)),
"codecs.encode": ((2, 4), (3, 0)),
"codecs.getincrementaldecoder": ((2, 5), (3, 0)),
"codecs.getincrementalencoder": ((2, 5), (3, 0)),
"codecs.iterdecode": ((2, 5), (3, 0)),
"codecs.iterencode": ((2, 5), (3, 0)),
"codecs.namereplace_errors": (None, (3, 5)),
"codecs.unregister": (None, (3, 10)),
"collections.Counter.__ixor__": (None, (3, 15)),
"collections.Counter.__xor__": (None, (3, 15)),
"collections.Counter.subtract": (None, (3, 2)),
"collections.Counter.total": (None, (3, 10)),
"collections.OrderedDict.move_to_end": (None, (3, 2)),
"collections.UserString.__getnewargs__": (None, (3, 5)),
"collections.UserString.__rmod__": (None, (3, 5)),
"collections.UserString.casefold": (None, (3, 5)),
"collections.UserString.format_map": (None, (3, 5)),
"collections.UserString.isprintable": (None, (3, 5)),
"collections.UserString.maketrans": (None, (3, 5)),
"collections.UserString.removeprefix": (None, (3, 9)),
"collections.UserString.removesuffix": (None, (3, 9)),
"collections.abc.MutableSequence.clear": (None, (3, 3)),
"collections.abc.MutableSequence.copy": (None, (3, 3)),
"collections.deque.copy": (None, (3, 5)),
"collections.deque.count": ((2, 7), (3, 2)),
"collections.deque.index": (None, (3, 5)),
"collections.deque.insert": (None, (3, 5)),
"collections.deque.remove": ((2, 5), (3, 0)),
"collections.deque.reverse": ((2, 7), (3, 2)),
"compileall.compile_file": ((2, 7), (3, 2)),
"concurrent.futures.ProcessPoolExecutor.kill_workers": (None, (3, 14)),
"concurrent.futures.ProcessPoolExecutor.terminate_workers": (None, (3, 14)),
"configparser.ConfigParser.read_dict": bpv("configparser", (None, (3, 2)), config),
"configparser.ConfigParser.read_file": bpv("configparser", (None, (3, 2)), config),
"configparser.ConfigParser.read_string": bpv("configparser", (None, (3, 2)), config),
"configparser.ExtendedInterpolation": bpv("configparser", (None, (3, 2)), config),
"configparser.RawConfigParser.read_dict": bpv("configparser", (None, (3, 2)), config),
"configparser.RawConfigParser.read_file": bpv("configparser", (None, (3, 2)), config),
"configparser.RawConfigParser.read_string": bpv("configparser", (None, (3, 2)), config),
"contextlib.aclosing": (None, (3, 10)),
"contextlib.chdir": (None, (3, 11)),
"contextlib.nullcontext": (None, (3, 7)),
"contextlib.redirect_stderr": (None, (3, 5)),
"contextlib.redirect_stdout": (None, (3, 4)),
"contextlib.suppress": (None, (3, 4)),
"copy.replace": (None, (3, 13)),
"crypt.mksalt": (None, (3, 3)),
"csv.DictWriter.writeheader": ((2, 7), (3, 2)),
"csv.field_size_limit": ((2, 5), (3, 0)),
"ctypes.CopyComPointer": (None, (3, 14)),
"ctypes._CData.from_buffer": ((2, 6), (3, 0)),
"ctypes._CData.from_buffer_copy": ((2, 6), (3, 0)),
"ctypes.get_errno": ((2, 6), (3, 0)),
"ctypes.get_last_error": ((2, 6), (3, 0)),
"ctypes.set_errno": ((2, 6), (3, 0)),
"ctypes.set_last_error": ((2, 6), (3, 0)),
"ctypes.util.dllist": (None, (3, 14)),
"ctypes.util.find_msvcrt": ((2, 6), (3, 0)),
"curses.assume_default_colors": (None, (3, 14)),
"curses.get_escdelay": (None, (3, 9)),
"curses.get_tabsize": (None, (3, 9)),
"curses.has_extended_color_support": (None, (3, 10)),
"curses.memoryview_at": (None, (3, 14)),
"curses.set_escdelay": (None, (3, 9)),
"curses.set_tabsize": (None, (3, 9)),
"curses.unget_wch": (None, (3, 3)),
"curses.update_lines_cols": (None, (3, 5)),
"curses.window.get_wch": (None, (3, 3)),
"dbm.dumb.reorganize": (None, (3, 15)),
"dbm.gdbm.clear": (None, (3, 13)),
"dbm.ndbm.clear": (None, (3, 13)),
"dbm.sqlite3.reorganize": (None, (3, 15)),
"datetime.date.fromisocalendar": (None, (3, 8)),
"datetime.date.fromisoformat": (None, (3, 7)),
"datetime.date.strptime": (None, (3, 14)),
"datetime.datetime.fromisocalendar": (None, (3, 8)),
"datetime.datetime.fromisoformat": (None, (3, 7)),
"datetime.datetime.strptime": ((2, 5), (3, 0)),
"datetime.datetime.timestamp": (None, (3, 3)),
"datetime.time.fromisoformat": (None, (3, 7)),
"datetime.time.strptime": (None, (3, 14)),
"datetime.timedelta.total_seconds": ((2, 7), (3, 2)),
"decimal.Context.clear_traps": (None, (3, 3)),
"decimal.Context.create_decimal_from_float": ((2, 7), (3, 1)),
"decimal.Decimal.as_integer_ratio": (None, (3, 6)),
"decimal.Decimal.canonical": ((2, 6), (3, 0)),
"decimal.Decimal.compare_signal": ((2, 6), (3, 0)),
"decimal.Decimal.compare_total": ((2, 6), (3, 0)),
"decimal.Decimal.compare_total_mag": ((2, 6), (3, 0)),
"decimal.Decimal.conjugate": ((2, 6), (3, 0)),
"decimal.Decimal.copy_abs": ((2, 6), (3, 0)),
"decimal.Decimal.copy_negate": ((2, 6), (3, 0)),
"decimal.Decimal.copy_sign": ((2, 6), (3, 0)),
"decimal.Decimal.exp": ((2, 6), (3, 0)),
"decimal.Decimal.fma": ((2, 6), (3, 0)),
"decimal.Decimal.from_float": ((2, 7), (3, 1)),
"decimal.Decimal.from_number": (None, (3, 14)),
"decimal.Decimal.is_canonical": ((2, 6), (3, 0)),
"decimal.Decimal.is_finite": ((2, 6), (3, 0)),
"decimal.Decimal.is_infinite": ((2, 6), (3, 0)),
"decimal.Decimal.is_nan": ((2, 6), (3, 0)),
"decimal.Decimal.is_normal": ((2, 6), (3, 0)),
"decimal.Decimal.is_qnan": ((2, 6), (3, 0)),
"decimal.Decimal.is_signed": ((2, 6), (3, 0)),
"decimal.Decimal.is_snan": ((2, 6), (3, 0)),
"decimal.Decimal.is_subnormal": ((2, 6), (3, 0)),
"decimal.Decimal.is_zero": ((2, 6), (3, 0)),
"decimal.Decimal.ln": ((2, 6), (3, 0)),
"decimal.Decimal.log10": ((2, 6), (3, 0)),
"decimal.Decimal.logb": ((2, 6), (3, 0)),
"decimal.Decimal.logical_and": ((2, 6), (3, 0)),
"decimal.Decimal.logical_invert": ((2, 6), (3, 0)),
"decimal.Decimal.logical_or": ((2, 6), (3, 0)),
"decimal.Decimal.logical_xor": ((2, 6), (3, 0)),
"decimal.Decimal.max_mag": ((2, 6), (3, 0)),
"decimal.Decimal.min_mag": ((2, 6), (3, 0)),
"decimal.Decimal.next_minus": ((2, 6), (3, 0)),
"decimal.Decimal.next_plus": ((2, 6), (3, 0)),
"decimal.Decimal.next_toward": ((2, 6), (3, 0)),
"decimal.Decimal.number_class": ((2, 6), (3, 0)),
"decimal.Decimal.radix": ((2, 6), (3, 0)),
"decimal.Decimal.rotate": ((2, 6), (3, 0)),
"decimal.Decimal.scaleb": ((2, 6), (3, 0)),
"decimal.Decimal.shift": ((2, 6), (3, 0)),
"decimal.Decimal.to_integral_exact": ((2, 6), (3, 0)),
"decimal.Decimal.to_integral_value": ((2, 6), (3, 0)),
"decimal.IEEEContext": (None, (3, 14)),
"decimal.localcontext": ((2, 5), (3, 0)),
"difflib.SequenceMatcher.get_grouped_opcodes": ((2, 3), (3, 0)),
"difflib.context_diff": ((2, 3), (3, 0)),
"difflib.diff_bytes": (None, (3, 5)),
"difflib.unified_diff": ((2, 3), (3, 0)),
"dis.code_info": (None, (3, 2)),
"dis.get_instructions": (None, (3, 4)),
"dis.hasarg": (None, (3, 12)),
"dis.hasexc": (None, (3, 12)),
"dis.show_code": (None, (3, 2)),
"dis.stack_effect": (None, (3, 4)),
"doctest.DocFileSuite": ((2, 4), (3, 0)),
"doctest.DocTestSuite": ((2, 3), (3, 0)),
"doctest.debug": ((2, 3), (3, 0)),
"doctest.debug_src": ((2, 4), (3, 0)),
"doctest.register_optionflag": ((2, 4), (3, 0)),
"doctest.script_from_examples": ((2, 4), (3, 0)),
"doctest.set_unittest_reportflags": ((2, 4), (3, 0)),
"doctest.testfile": ((2, 4), (3, 0)),
"doctest.testsource": ((2, 3), (3, 0)),
"email.generator.Generator.clone": ((2, 2), (3, 0)),
"email.generator.Generator.flatten": ((2, 2), (3, 0)),
"email.message.EmailMessage.get_content_disposition": (None, (3, 5)),
"email.message.Message.__bytes__": (None, (3, 4)),
"email.message.Message.as_bytes": (None, (3, 4)),
"email.message.Message.del_param": ((2, 2), (3, 0)),
"email.message.Message.get_charset": ((2, 2), (3, 0)),
"email.message.Message.get_content_charset": ((2, 2), (3, 0)),
"email.message.Message.get_content_disposition": (None, (3, 5)),
"email.message.Message.get_content_maintype": ((2, 2), (3, 0)),
"email.message.Message.get_content_subtype": ((2, 2), (3, 0)),
"email.message.Message.get_content_type": ((2, 2), (3, 0)),
"email.message.Message.get_default_type": ((2, 2), (3, 0)),
"email.message.Message.replace_header": ((2, 2), (3, 0)),
"email.message.Message.set_charset": ((2, 2), (3, 0)),
"email.message.Message.set_default_type": ((2, 2), (3, 0)),
"email.message.Message.set_param": ((2, 2), (3, 0)),
"email.message.Message.set_type": ((2, 2), (3, 0)),
"email.message_from_binary_file": (None, (3, 2)),
"email.message_from_bytes": (None, (3, 2)),
"email.utils.format_datetime": (None, (3, 3)),
"email.utils.formatdate": ((2, 4), (3, 0)),
"email.utils.localtime": (None, (3, 3)),
"email.utils.parsedate_to_datetime": (None, (3, 3)),
"enum.Enum._add_alias_": (None, (3, 13)),
"enum.Enum._add_value_alias_": (None, (3, 13)),
"enum.show_flag_values": (None, (3, 11)),
"faulthandler.dump_c_stack": (None, (3, 14)),
"filecmp.clear_cache": (None, (3, 4)),
"fileinput.fileno": ((2, 5), (3, 0)),
"fileinput.hook_compressed": ((2, 5), (3, 0)),
"fileinput.hook_encoded": ((2, 5), (3, 0)),
"fnmatch.filter": ((2, 2), (3, 0)),
"fnmatch.filterfalse": (None, (3, 14)),
"fractions.Fraction.as_integer_ratio": (None, (3, 8)),
"fractions.Fraction.from_number": (None, (3, 14)),
"fractions.Fraction.is_integer": (None, (3, 12)),
"ftplib.FTP.mlsd": (None, (3, 3)),
"ftplib.FTP_TLS.ccc": (None, (3, 3)),
"functools.cmp_to_key": ((2, 7), (3, 2)),
"functools.reduce": ((2, 6), (3, 0)),
"gc.freeze": (None, (3, 7)),
"gc.get_count": ((2, 5), (3, 0)),
"gc.get_freeze_count": (None, (3, 7)),
"gc.get_objects": ((2, 2), (3, 0)),
"gc.get_referents": ((2, 3), (3, 0)),
"gc.get_referrers": ((2, 2), (3, 0)),
"gc.get_stats": (None, (3, 4)),
"gc.is_finalized": (None, (3, 9)),
"gc.is_tracked": ((2, 7), (3, 1)),
"gc.unfreeze": (None, (3, 7)),
"getopt.gnu_getopt": ((2, 3), (3, 0)),
"gettext.GNUTranslations.lgettext": ((2, 4), (3, 0)),
"gettext.GNUTranslations.lngettext": ((2, 4), (3, 0)),
"gettext.GNUTranslations.ngettext": ((2, 3), (3, 0)),
"gettext.GNUTranslations.npgettext": (None, (3, 8)),
"gettext.GNUTranslations.pgettext": (None, (3, 8)),
"gettext.GNUTranslations.ungettext": ((2, 3), None),
"gettext.NullTranslations.lgettext": ((2, 4), (3, 0)),
"gettext.NullTranslations.lngettext": ((2, 4), (3, 0)),
"gettext.NullTranslations.ngettext": ((2, 3), (3, 0)),
"gettext.NullTranslations.npgettext": (None, (3, 8)),
"gettext.NullTranslations.output_charset": ((2, 4), (3, 0)),
"gettext.NullTranslations.pgettext": (None, (3, 8)),
"gettext.NullTranslations.set_output_charset": ((2, 4), (3, 0)),
"gettext.NullTranslations.ungettext": ((2, 3), None),
"gettext.bind_textdomain_codeset": ((2, 4), (3, 0)),
"gettext.dngettext": ((2, 3), (3, 0)),
"gettext.dnpgettext": (None, (3, 8)),
"gettext.dpgettext": (None, (3, 8)),
"gettext.ldgettext": ((2, 4), (3, 0)),
"gettext.ldngettext": ((2, 4), (3, 0)),
"gettext.lgettext": ((2, 4), (3, 0)),
"gettext.lngettext": ((2, 4), (3, 0)),
"gettext.ngettext": ((2, 3), (3, 0)),
"gettext.npgettext": (None, (3, 8)),
"gettext.pgettext": (None, (3, 8)),
"glob.escape": (None, (3, 4)),
"glob.iglob": ((2, 5), (3, 0)),
"glob.translate": (None, (3, 13)),
"gzip.GzipFile.peek": (None, (3, 2)),
"gzip.compress": (None, (3, 2)),
"gzip.decompress": (None, (3, 2)),
"hashlib.blake2b": (None, (3, 6)),
"hashlib.blake2s": (None, (3, 6)),
"hashlib.file_digest": (None, (3, 11)),
"hashlib.pbkdf2_hmac": ((2, 7), (3, 4)),
"hashlib.scrypt": (None, (3, 6)),
"hashlib.sha3_224": (None, (3, 6)),
"hashlib.sha3_256": (None, (3, 6)),
"hashlib.sha3_384": (None, (3, 6)),
"hashlib.sha3_512": (None, (3, 6)),
"hashlib.shake_128": (None, (3, 6)),
"hashlib.shake_256": (None, (3, 6)),
"heapq.heapify_max": (None, (3, 14)),
"heapq.heappop_max": (None, (3, 14)),
"heapq.heappush_max": (None, (3, 14)),
"heapq.heappushpop": ((2, 6), (3, 0)),
"heapq.heappushpop_max": (None, (3, 14)),
"heapq.heapreplace_max": (None, (3, 14)),
"heapq.merge": ((2, 6), (3, 0)),
"heapq.nlargest": ((2, 4), (3, 0)),
"heapq.nsmallest": ((2, 4), (3, 0)),
"hmac.compare_digest": ((2, 7), (3, 3)),
"hmac.digest": (None, (3, 7)),
"html.escape": (None, (3, 2)),
"html.unescape": (None, (3, 4)),
"http.client.HTTPConnection.set_debuglevel": (None, (3, 1)),
"http.client.HTTPConnection.set_tunnel": (None, (3, 2)),
"http.client.HTTPResponse.readinto": (None, (3, 3)),
"http.server.BaseHTTPRequestHandler.flush_headers": (None, (3, 3)),
"http.server.BaseHTTPRequestHandler.handle_expect_100": (None, (3, 2)),
"http.server.BaseHTTPRequestHandler.send_response_only": (None, (3, 2)),
"http.server.SimpleHTTPRequestHandler.default_content_type": (None, (3, 15)),
"httplib.HTTPConnection.set_tunnel": ((2, 7), None),
"httplib.HTTPResponse.getheaders": ((2, 4), None),
"imaplib.IMAP4.deleteacl": ((2, 4), (3, 0)),
"imaplib.IMAP4.enable": (None, (3, 5)),
"imaplib.IMAP4.getannotation": ((2, 5), (3, 0)),
"imaplib.IMAP4.getquota": ((2, 3), (3, 0)),
"imaplib.IMAP4.getquotaroot": ((2, 3), (3, 0)),
"imaplib.IMAP4.idle": (None, (3, 14)),
"imaplib.IMAP4.login_cram_md5": ((2, 3), (3, 0)),
"imaplib.IMAP4.myrights": ((2, 4), (3, 0)),
"imaplib.IMAP4.namespace": ((2, 3), (3, 0)),
"imaplib.IMAP4.proxyauth": ((2, 3), (3, 0)),
"imaplib.IMAP4.setannotation": ((2, 5), (3, 0)),
"imaplib.IMAP4.setquota": ((2, 3), (3, 0)),
"imaplib.IMAP4.starttls": (None, (3, 2)),
"imaplib.IMAP4.thread": ((2, 4), (3, 0)),
"imaplib.IMAP4.unselect": (None, (3, 9)),
"imaplib.Idler.burst": (None, (3, 14)),
"imp.acquire_lock": ((2, 3), (3, 0)),
"imp.cache_from_source": (None, (3, 2)),
"imp.get_tag": (None, (3, 2)),
"imp.release_lock": ((2, 3), (3, 0)),
"imp.source_from_cache": (None, (3, 2)),
"importlib.abc.InspectLoader.exec_module": (None, (3, 4)),
"importlib.abc.InspectLoader.source_to_code": (None, (3, 4)),
"importlib.abc.Loader.create_module": (None, (3, 4)),
"importlib.abc.Loader.exec_module": (None, (3, 4)),
"importlib.abc.Loader.module_repr": (None, (3, 3)),
"importlib.abc.MetaPathFinder.find_spec": (None, (3, 4)),
"importlib.abc.PathEntryFinder.find_spec": (None, (3, 4)),
"importlib.abc.SourceLoader.exec_module": (None, (3, 4)),
"importlib.abc.SourceLoader.path_stats": (None, (3, 3)),
"importlib.find_loader": (None, (3, 3)),
"importlib.invalidate_caches": (None, (3, 3)),
"importlib.machinery.BuiltinImporter.create_module": (None, (3, 5)),
"importlib.machinery.BuiltinImporter.exec_module": (None, (3, 5)),
"importlib.machinery.ExtensionFileLoader.create_module": (None, (3, 5)),
"importlib.machinery.ExtensionFileLoader.exec_module": (None, (3, 5)),
"importlib.machinery.ExtensionFileLoader.get_filename": (None, (3, 4)),
"importlib.machinery.FileFinder.find_spec": (None, (3, 4)),
"importlib.machinery.FrozenImporter.create_module": (None, (3, 4)),
"importlib.machinery.FrozenImporter.exec_module": (None, (3, 4)),
"importlib.machinery.PathFinder.find_spec": (None, (3, 4)),
"importlib.machinery.all_suffixes": (None, (3, 3)),
"importlib.metadata.packages_distributions": (None, (3, 10)),
"importlib.reload": (None, (3, 4)),
"importlib.resources.as_file": (None, (3, 9)),
"importlib.resources.files": (None, (3, 9)),
"importlib.util.cache_from_source": (None, (3, 4)),
"importlib.util.decode_source": (None, (3, 4)),
"importlib.util.find_spec": (None, (3, 4)),
"importlib.util.module_from_spec": (None, (3, 5)),
"importlib.util.resolve_name": (None, (3, 3)),
"importlib.util.source_from_cache": (None, (3, 4)),
"importlib.util.source_hash": (None, (3, 7)),
"importlib.util.spec_from_file_location": (None, (3, 4)),
"importlib.util.spec_from_loader": (None, (3, 4)),
"inspect.BoundArguments.apply_defaults": (None, (3, 5)),
"inspect.Signature.from_callable": (None, (3, 5)),
"inspect.cleandoc": ((2, 6), (3, 0)),
"inspect.get_annotations": (None, (3, 10)),
"inspect.getasyncgenlocals": (None, (3, 12)),
"inspect.getasyncgenstate": (None, (3, 12)),
"inspect.getattr_static": (None, (3, 2)),
"inspect.getcallargs": ((2, 7), (3, 2)),
"inspect.getclosurevars": (None, (3, 3)),
"inspect.getcoroutinelocals": (None, (3, 5)),
"inspect.getcoroutinestate": (None, (3, 5)),
"inspect.getgeneratorlocals": (None, (3, 3)),
"inspect.getgeneratorstate": (None, (3, 2)),
"inspect.getmembers_static": (None, (3, 11)),
"inspect.isabstract": ((2, 6), (3, 0)),
"inspect.isasyncgen": (None, (3, 6)),
"inspect.isasyncgenfunction": (None, (3, 6)),
"inspect.isawaitable": (None, (3, 5)),
"inspect.iscoroutine": (None, (3, 5)),
"inspect.iscoroutinefunction": (None, (3, 5)),
"inspect.isdatadescriptor": ((2, 3), (3, 0)),
"inspect.isgenerator": ((2, 6), (3, 0)),
"inspect.isgeneratorfunction": ((2, 6), (3, 0)),
"inspect.isgetsetdescriptor": ((2, 5), (3, 0)),
"inspect.ismemberdescriptor": ((2, 5), (3, 0)),
"inspect.ismethodwrapper": (None, (3, 11)),
"inspect.ispackage": (None, (3, 14)),
"inspect.markcoroutinefunction": (None, (3, 12)),
"inspect.signature": (None, (3, 3)),
"inspect.unwrap": (None, (3, 4)),
"io.BufferedIOBase.detach": ((2, 7), (3, 1)),
"io.BufferedIOBase.readinto1": (None, (3, 5)),
"io.BytesIO.getbuffer": (None, (3, 2)),
"io.BytesIO.readinto1": (None, (3, 5)),
"io.TextIOBase.detach": ((2, 7), (3, 1)),
"io.TextIOWrapper.reconfigure": (None, (3, 7)),
"io.open_code": (None, (3, 8)),
"io.text_encoding": (None, (3, 10)),
"ipaddress.IPv4Address.__format__": (None, (3, 9)),
"ipaddress.IPv4Network.subnet_of": bpv("ipaddress", (None, (3, 7)), config),
"ipaddress.IPv4Network.supernet_of": bpv("ipaddress", (None, (3, 7)), config),
"ipaddress.IPv6Address.__format__": (None, (3, 9)),
"itertools.accumulate": (None, (3, 2)),
"itertools.batched": (None, (3, 12)),
"itertools.chain.from_iterable": ((2, 6), (3, 0)),
"itertools.combinations": ((2, 6), (3, 0)),
"itertools.combinations_with_replacement": ((2, 7), (3, 1)),
"itertools.compress": ((2, 7), (3, 1)),
"itertools.groupby": ((2, 4), (3, 0)),
"itertools.izip_longest": ((2, 6), None),
"itertools.pairwise": (None, (3, 10)),
"itertools.permutations": ((2, 6), (3, 0)),
"itertools.product": ((2, 6), (3, 0)),
"itertools.tee": ((2, 4), (3, 0)),
"keyword.issoftkeyword": (None, (3, 9)),
"linecache.lazycache": (None, (3, 5)),
"locale.currency": ((2, 5), (3, 0)),
"locale.delocalize": (None, (3, 5)),
"locale.format_string": ((2, 5), (3, 0)),
"locale.getdefaultlocale": ((2, 0), (3, 0)),
"locale.getencoding": (None, (3, 11)),
"locale.getlocale": ((2, 0), (3, 0)),
"locale.getpreferredencoding": ((2, 3), (3, 0)),
"locale.localize": (None, (3, 10)),
"locale.normalize": ((2, 0), (3, 0)),
"locale.resetlocale": ((2, 0), (3, 0)),
"logging.Logger.getChild": ((2, 7), (3, 2)),
"logging.Logger.hasHandlers": (None, (3, 2)),
"logging.LoggerAdapter._log": (None, (3, 6)),
"logging.LoggerAdapter.getEffectiveLevel": (None, (3, 2)),
"logging.LoggerAdapter.hasHandlers": (None, (3, 2)),
"logging.LoggerAdapter.isEnabledFor": ((2, 7), (3, 2)),
"logging.LoggerAdapter.setLevel": (None, (3, 2)),
"logging.StreamHandler.setStream": (None, (3, 7)),
"logging.config.dictConfig": ((2, 7), (3, 2)),
"logging.getLevelNamesMapping": (None, (3, 11)),
"logging.getLogRecordFactory": (None, (3, 2)),
"logging.handlers.BaseRotatingHandler.rotate": (None, (3, 3)),
"logging.handlers.BaseRotatingHandler.rotation_filename": (None, (3, 3)),
"logging.handlers.QueueListener.enqueue_sentinel": (None, (3, 3)),
"logging.handlers.WatchedFileHandler.reopenIfNeeded": (None, (3, 6)),
"logging.setLogRecordFactory": (None, (3, 2)),
"mailbox.Mailbox.get_bytes": (None, (3, 2)),
"math.acosh": ((2, 6), (3, 0)),
"math.asinh": ((2, 6), (3, 0)),
"math.atanh": ((2, 6), (3, 0)),
"math.cbrt": (None, (3, 11)),
"math.comb": (None, (3, 8)),
"math.copysign": ((2, 6), (3, 0)),
"math.dist": (None, (3, 8)),
"math.erf": ((2, 7), (3, 2)),
"math.erfc": ((2, 7), (3, 2)),
"math.exp2": (None, (3, 11)),
"math.expm1": ((2, 7), (3, 2)),
"math.factorial": ((2, 6), (3, 0)),
"math.fma": (None, (3, 13)),
"math.fmax": (None, (3, 15)),
"math.fmin": (None, (3, 15)),
"math.fsum": ((2, 6), (3, 0)),
"math.gamma": ((2, 7), (3, 2)),
"math.gcd": (None, (3, 5)),
"math.isclose": (None, (3, 5)),
"math.isfinite": (None, (3, 2)),
"math.isinf": ((2, 6), (3, 0)),
"math.isnan": ((2, 6), (3, 0)),
"math.isnormal": (None, (3, 15)),
"math.isqrt": (None, (3, 8)),
"math.issubnormal": (None, (3, 15)),
"math.lcm": (None, (3, 9)),
"math.lgamma": ((2, 7), (3, 2)),
"math.log1p": ((2, 6), (3, 0)),
"math.log2": (None, (3, 3)),
"math.nextafter": (None, (3, 9)),
"math.perm": (None, (3, 8)),
"math.prod": (None, (3, 8)),
"math.remainder": (None, (3, 7)),
"math.signbit": (None, (3, 15)),
"math.sumprod": (None, (3, 12)),
"math.trunc": ((2, 6), (3, 0)),
"math.ulp": (None, (3, 9)),
"mimetypes.MimeTypes.read_windows_registry": ((2, 7), (3, 2)),
"mimetypes.MimeTypes.guess_file_type": (None, (3, 13)),
"mimetypes.guess_file_type": (None, (3, 13)),
"mmap.mmap.madvise": (None, (3, 8)),
"mmap.mmap.seekable": (None, (3, 13)),
"mmap.mmap.set_name": (None, (3, 15)),
"msilib.Database.Close": (None, (3, 7)),
"msvcrt.getwch": ((2, 6), (3, 0)),
"msvcrt.getwche": ((2, 6), (3, 0)),
"msvcrt.putwch": ((2, 6), (3, 0)),
"msvcrt.ungetwch": ((2, 6), (3, 0)),
"multiprocessing.Condition.wait_for": (None, (3, 3)),
"multiprocessing.Lock.locked": (None, (3, 14)),
"multiprocessing.Pool.starmap": (None, (3, 3)),
"multiprocessing.Pool.starmap_async": (None, (3, 3)),
"multiprocessing.Process.close": (None, (3, 7)),
"multiprocessing.Process.interrupt": (None, (3, 14)),
"multiprocessing.Process.kill": (None, (3, 7)),
"multiprocessing.RLock.locked": (None, (3, 14)),
"multiprocessing.SimpleQueue.close": (None, (3, 9)),
"multiprocessing.connection.wait": (None, (3, 3)),
"multiprocessing.get_all_start_methods": (None, (3, 4)),
"multiprocessing.get_context": (None, (3, 4)),
"multiprocessing.get_start_method": (None, (3, 4)),
"multiprocessing.managers.SyncManager.Barrier": (None, (3, 3)),
"multiprocessing.managers.SyncManager.Condition.wait_for": (None, (3, 3)),
"multiprocessing.parent_process": (None, (3, 8)),
"multiprocessing.pool.Pool.starmap": (None, (3, 3)),
"multiprocessing.pool.Pool.starmap_async": (None, (3, 3)),
"multiprocessing.set_start_method": (None, (3, 4)),
"nis.get_default_domain": ((2, 5), (3, 0)),
"nntplib.NNTP.description": ((2, 4), (3, 0)),
"nntplib.NNTP.descriptions": ((2, 4), (3, 0)),
"nntplib.NNTP.getcapabilities": (None, (3, 2)),
"nntplib.NNTP.login": (None, (3, 2)),
"nntplib.NNTP.over": (None, (3, 2)),
"nntplib.NNTP.starttls": (None, (3, 2)),
"operator.__call__": (None, (3, 11)),
"operator.__eq__": ((2, 2), (3, 0)),
"operator.__floordiv__": ((2, 2), (3, 0)),
"operator.__ge__": ((2, 2), (3, 0)),
"operator.__gt__": ((2, 2), (3, 0)),
"operator.__iadd__": ((2, 5), (3, 0)),
"operator.__iand__": ((2, 5), (3, 0)),
"operator.__iconcat__": ((2, 5), (3, 0)),
"operator.__idiv__": ((2, 5), None),
"operator.__ifloordiv__": ((2, 5), (3, 0)),
"operator.__ilshift__": ((2, 5), (3, 0)),
"operator.__imatmul__": (None, (3, 5)),
"operator.__imod__": ((2, 5), (3, 0)),
"operator.__imul__": ((2, 5), (3, 0)),
"operator.__index__": ((2, 5), (3, 0)),
"operator.__ior__": ((2, 5), (3, 0)),
"operator.__ipow__": ((2, 5), (3, 0)),
"operator.__irepeat__": ((2, 5), None),
"operator.__irshift__": ((2, 5), (3, 0)),
"operator.__isub__": ((2, 5), (3, 0)),
"operator.__itruediv__": ((2, 5), (3, 0)),
"operator.__ixor__": ((2, 5), (3, 0)),
"operator.__le__": ((2, 2), (3, 0)),
"operator.__lt__": ((2, 2), (3, 0)),
"operator.__matmul__": (None, (3, 5)),
"operator.__ne__": ((2, 2), (3, 0)),
"operator.__pow__": ((2, 3), (3, 0)),
"operator.__repeat__": ((2, 0), None),
"operator.__truediv__": ((2, 2), (3, 0)),
"operator.attrgetter": ((2, 4), (3, 0)),
"operator.call": (None, (3, 11)),
"operator.eq": ((2, 2), (3, 0)),
"operator.floordiv": ((2, 2), (3, 0)),
"operator.ge": ((2, 2), (3, 0)),
"operator.gt": ((2, 2), (3, 0)),
"operator.iadd": ((2, 5), (3, 0)),
"operator.iand": ((2, 5), (3, 0)),
"operator.iconcat": ((2, 5), (3, 0)),
"operator.idiv": ((2, 5), None),
"operator.ifloordiv": ((2, 5), (3, 0)),
"operator.ilshift": ((2, 5), (3, 0)),
"operator.imatmul": (None, (3, 5)),
"operator.imod": ((2, 5), (3, 0)),
"operator.imul": ((2, 5), (3, 0)),
"operator.index": ((2, 5), (3, 0)),
"operator.ior": ((2, 5), (3, 0)),
"operator.ipow": ((2, 5), (3, 0)),
"operator.irepeat": ((2, 5), None),
"operator.irshift": ((2, 5), (3, 0)),
"operator.is_": ((2, 3), (3, 0)),
"operator.is_none": (None, (3, 14)),
"operator.is_not": ((2, 3), (3, 0)),
"operator.is_not_none": (None, (3, 14)),
"operator.isub": ((2, 5), (3, 0)),
"operator.itemgetter": ((2, 4), (3, 0)),
"operator.itruediv": ((2, 5), (3, 0)),
"operator.ixor": ((2, 5), (3, 0)),
"operator.le": ((2, 2), (3, 0)),
"operator.length_hint": (None, (3, 4)),
"operator.lt": ((2, 2), (3, 0)),
"operator.matmul": (None, (3, 5)),
"operator.methodcaller": ((2, 6), (3, 0)),
"operator.ne": ((2, 2), (3, 0)),
"operator.pow": ((2, 3), (3, 0)),
"operator.repeat": ((2, 0), None),
"operator.truediv": ((2, 2), (3, 0)),
"os.DirEntry.is_junction": (None, (3, 12)),
"os.WCOREDUMP": ((2, 3), (3, 0)),
"os.WIFCONTINUED": ((2, 3), (3, 0)),
"os.add_dll_directory": (None, (3, 8)),
"os.chflags": ((2, 6), (3, 0)),
"os.chroot": ((2, 2), (3, 0)),
"os.closerange": ((2, 6), (3, 0)),
"os.copy_file_range": (None, (3, 8)),
"os.cpu_count": (None, (3, 4)),
"os.eventfd": (None, (3, 10)),
"os.eventfd_read": (None, (3, 10)),
"os.eventfd_write": (None, (3, 10)),
"os.fchdir": ((2, 3), (3, 0)),
"os.fchmod": ((2, 6), (3, 0)),
"os.fchown": ((2, 6), (3, 0)),
"os.fsdecode": (None, (3, 2)),
"os.fsencode": (None, (3, 2)),
"os.fspath": (None, (3, 6)),
"os.fwalk": (None, (3, 3)),
"os.get_blocking": (None, (3, 5)),
"os.get_exec_path": (None, (3, 2)),
"os.get_handle_inheritable": (None, (3, 4)),
"os.get_inheritable": (None, (3, 4)),
"os.get_terminal_size": (None, (3, 3)),
"os.getcwdu": ((2, 3), None),
"os.getenvb": (None, (3, 2)),
"os.getgrouplist": (None, (3, 3)),
"os.getloadavg": ((2, 3), (3, 0)),
"os.getpgid": ((2, 3), (3, 0)),
"os.getpriority": (None, (3, 3)),
"os.getrandom": (None, (3, 6)),
"os.getresgid": ((2, 7), (3, 2)),
"os.getresuid": ((2, 7), (3, 2)),
"os.getsid": ((2, 4), (3, 0)),
"os.getxattr": (None, (3, 3)),
"os.grantpt": (None, (3, 13)),
"os.initgroups": ((2, 7), (3, 2)),
"os.lchflags": ((2, 6), (3, 0)),
"os.lchmod": ((2, 6), (3, 0)),
"os.lchown": ((2, 3), (3, 0)),
"os.listdrives": (None, (3, 12)),
"os.listmounts": (None, (3, 12)),
"os.listvolumes": (None, (3, 12)),
"os.listxattr": (None, (3, 3)),
"os.lockf": (None, (3, 3)),
"os.login_tty": (None, (3, 11)),
"os.major": ((2, 3), (3, 0)),
"os.makedev": ((2, 3), (3, 0)),
"os.memfd_create": (None, (3, 8)),
"os.minor": ((2, 3), (3, 0)),
"os.mknod": ((2, 3), (3, 0)),
"os.path.commonpath": (None, (3, 5)),
"os.path.getctime": ((2, 3), (3, 0)),
"os.path.isdevdrive": (None, (3, 12)),
"os.path.isjunction": (None, (3, 12)),
"os.path.ismount": (None, (3, 4)),
"os.path.isreserved": (None, (3, 13)),
"os.path.lexists": ((2, 4), (3, 0)),
"os.path.realpath": ((2, 2), (3, 0)),
"os.path.relpath": ((2, 6), (3, 0)),
"os.path.splitroot": (None, (3, 12)),
"os.pidfd_open": (None, (3, 9)),
"os.pipe2": (None, (3, 3)),
"os.popen2": ((2, 0), None),
"os.popen3": ((2, 0), None),
"os.popen4": ((2, 0), None),
"os.posix_fadvise": (None, (3, 3)),
"os.posix_fallocate": (None, (3, 3)),
"os.posix_openpt": (None, (3, 13)),
"os.posix_spawn": (None, (3, 8)),
"os.posix_spawnp": (None, (3, 8)),
"os.pread": (None, (3, 3)),
"os.preadv": (None, (3, 7)),
"os.process_cpu_count": (None, (3, 13)),
"os.ptsname": (None, (3, 13)),
"os.pwrite": (None, (3, 3)),
"os.pwritev": (None, (3, 7)),
"os.readinto": (None, (3, 14)),
"os.readv": (None, (3, 3)),
"os.register_at_fork": (None, (3, 7)),
"os.reload_environ": (None, (3, 14)),
"os.removexattr": (None, (3, 3)),
"os.replace": (None, (3, 3)),
"os.scandir": (None, (3, 5)),
"os.scandir.close": (None, (3, 6)),
"os.sched_get_priority_max": (None, (3, 3)),
"os.sched_get_priority_min": (None, (3, 3)),
"os.sched_getaffinity": (None, (3, 3)),
"os.sched_getparam": (None, (3, 3)),
"os.sched_getscheduler": (None, (3, 3)),
"os.sched_rr_get_interval": (None, (3, 3)),
"os.sched_setaffinity": (None, (3, 3)),
"os.sched_setparam": (None, (3, 3)),
"os.sched_setscheduler": (None, (3, 3)),
"os.sched_yield": (None, (3, 3)),
"os.sendfile": (None, (3, 3)),
"os.set_blocking": (None, (3, 5)),
"os.set_handle_inheritable": (None, (3, 4)),
"os.set_inheritable": (None, (3, 4)),
"os.setgroups": ((2, 2), (3, 0)),
"os.setns": (None, (3, 12)),
"os.setpriority": (None, (3, 3)),
"os.setresgid": ((2, 7), (3, 2)),
"os.setresuid": ((2, 7), (3, 2)),
"os.setxattr": (None, (3, 3)),
"os.splice": (None, (3, 10)),
"os.startfile": ((2, 0), (3, 0)),
"os.statx": (None, (3, 15)),
"os.sync": (None, (3, 3)),
"os.timerfd_create": (None, (3, 13)),
"os.timerfd_gettime": (None, (3, 13)),
"os.timerfd_gettime_ns": (None, (3, 13)),
"os.timerfd_settime": (None, (3, 13)),
"os.timerfd_settime_ns": (None, (3, 13)),
"os.truncate": (None, (3, 3)),
"os.unlockpt": (None, (3, 13)),
"os.unshare": (None, (3, 12)),
"os.urandom": ((2, 4), (3, 0)),
"os.wait3": ((2, 5), (3, 0)),
"os.wait4": ((2, 5), (3, 0)),
"os.waitid": (None, (3, 3)),
"os.waitstatus_to_exitcode": (None, (3, 9)),
"os.walk": ((2, 3), (3, 0)),
"os.writev": (None, (3, 3)),
"pathlib.Path.copy": (None, (3, 14)),
"pathlib.Path.copy_into": (None, (3, 14)),
"pathlib.Path.expanduser": (None, (3, 5)),
"pathlib.Path.from_uri": (None, (3, 13)),
"pathlib.Path.full_match": (None, (3, 13)),
"pathlib.Path.hardlink_to": (None, (3, 10)),
"pathlib.Path.home": (None, (3, 5)),
"pathlib.Path.is_junction": (None, (3, 12)),
"pathlib.Path.is_mount": (None, (3, 7)),
"pathlib.Path.is_relative_to": (None, (3, 9)),
"pathlib.Path.link_to": (None, (3, 8)),
"pathlib.Path.move": (None, (3, 14)),
"pathlib.Path.move_into": (None, (3, 14)),
"pathlib.Path.parser": (None, (3, 13)),
"pathlib.Path.read_bytes": (None, (3, 5)),
"pathlib.Path.read_text": (None, (3, 5)),
"pathlib.Path.readlink": (None, (3, 9)),
"pathlib.Path.samefile": (None, (3, 5)),
"pathlib.Path.walk": (None, (3, 12)),
"pathlib.Path.with_segments": (None, (3, 12)),
"pathlib.Path.with_stem": (None, (3, 9)),
"pathlib.Path.write_bytes": (None, (3, 5)),
"pathlib.Path.write_text": (None, (3, 5)),
"pathlib.PurePath.full_match": (None, (3, 13)),
"pathlib.PurePath.is_relative_to": (None, (3, 9)),
"pathlib.PurePath.parser": (None, (3, 13)),
"pathlib.PurePath.with_segments": (None, (3, 12)),
"pathlib.PurePath.with_stem": (None, (3, 9)),
"pdb.set_trace_async": (None, (3, 14)),
"pdb.set_default_backend": (None, (3, 14)),
"pdb.get_default_backend": (None, (3, 14)),
"pickle.Pickler.reducer_override": (None, (3, 8)),
"pickletools.optimize": ((2, 6), (3, 0)),
"pkgutil.get_data": ((2, 6), (3, 0)),
"pkgutil.resolve_name": (None, (3, 9)),
"platform.freedesktop_os_release": (None, (3, 10)),
"platform.invalidate_caches": (None, (3, 14)),
"platform.linux_distribution": ((2, 6), (3, 0)),
"platform.python_branch": ((2, 6), (3, 0)),
"platform.python_implementation": ((2, 6), (3, 0)),
"platform.python_revision": ((2, 6), (3, 0)),
"platform.win32_edition": (None, (3, 8)),
"platform.win32_is_iot": (None, (3, 8)),
"plistlib.dump": (None, (3, 4)),
"plistlib.dumps": (None, (3, 4)),
"plistlib.load": (None, (3, 4)),
"plistlib.loads": (None, (3, 4)),
"poplib.POP3.capa": (None, (3, 4)),
"poplib.POP3.stls": (None, (3, 4)),
"poplib.POP3.utf8": (None, (3, 5)),
"pprint.PrettyPrinter.format": ((2, 3), (3, 0)),
"pprint.pp": (None, (3, 8)),
"pstats.Stats.get_stats_profile": (None, (3, 9)),
"queue.Queue.shutdown": (None, (3, 13)),
"random.Random.randbytes": (None, (3, 9)),
"random.binomialvariate": (None, (3, 12)),
"random.choices": (None, (3, 6)),
"random.getrandbits": ((2, 4), (3, 0)),
"random.getstate": ((2, 1), (3, 0)),
"random.jumpahead": ((2, 1), None),
"random.randbytes": (None, (3, 9)),
"random.sample": ((2, 3), (3, 0)),
"random.setstate": ((2, 1), (3, 0)),
"random.triangular": ((2, 6), (3, 0)),
"re.Pattern.fullmatch": (None, (3, 4)),
"re.Pattern.prefixmatch": (None, (3, 15)),
"re.finditer": ((2, 2), (3, 0)),
"re.fullmatch": (None, (3, 4)),
"re.prefixmatch": (None, (3, 15)),
"readline.append_history_file": (None, (3, 5)),
"readline.clear_history": ((2, 4), (3, 0)),
"readline.get_completer": ((2, 3), (3, 0)),
"readline.get_completion_type": ((2, 6), (3, 0)),
"readline.get_current_history_length": ((2, 3), (3, 0)),
"readline.get_history_item": ((2, 3), (3, 0)),
"readline.remove_history_item": ((2, 4), (3, 0)),
"readline.replace_history_item": ((2, 4), (3, 0)),
"readline.set_auto_history": (None, (3, 6)),
"readline.set_completion_display_matches_hook": ((2, 6), (3, 0)),
"readline.set_pre_input_hook": ((2, 3), (3, 0)),
"readline.set_startup_hook": ((2, 3), (3, 0)),
"resource.prlimit": (None, (3, 4)),
"runpy.run_path": ((2, 7), (3, 2)),
"select.devpoll": (None, (3, 3)),
"select.devpoll.close": (None, (3, 4)),
"select.devpoll.fileno": (None, (3, 4)),
"select.epoll": ((2, 6), (3, 0)),
"select.kevent": ((2, 6), (3, 0)),
"select.kqueue": ((2, 6), (3, 0)),
"select.poll.modify": ((2, 6), (3, 0)),
"sgmllib.SGMLParser.convert_charref": ((2, 5), None),
"sgmllib.SGMLParser.convert_codepoint": ((2, 5), None),
"sgmllib.SGMLParser.convert_entityref": ((2, 5), None),
"shelve.Shelf.reorganize": (None, (3, 15)),
"shlex.join": (None, (3, 8)),
"shlex.quote": (None, (3, 3)),
"shlex.shlex.pop_source": ((2, 1), (3, 0)),
"shlex.shlex.push_source": ((2, 1), (3, 0)),
"shlex.split": ((2, 3), (3, 0)),
"shutil.chown": (None, (3, 3)),
"shutil.disk_usage": (None, (3, 3)),
"shutil.get_archive_formats": ((2, 7), (3, 2)),
"shutil.get_terminal_size": (None, (3, 3)),
"shutil.get_unpack_formats": (None, (3, 2)),
"shutil.ignore_patterns": ((2, 6), (3, 0)),
"shutil.make_archive": ((2, 7), (3, 2)),
"shutil.move": ((2, 3), (3, 0)),
"shutil.register_archive_format": ((2, 7), (3, 2)),
"shutil.register_unpack_format": (None, (3, 2)),
"shutil.unpack_archive": (None, (3, 2)),
"shutil.unregister_archive_format": ((2, 7), (3, 2)),
"shutil.unregister_unpack_format": (None, (3, 2)),
"shutil.which": (None, (3, 3)),
"signal.getitimer": ((2, 6), (3, 0)),
"signal.pidfd_send_signal": (None, (3, 9)),
"signal.pthread_kill": (None, (3, 3)),
"signal.pthread_sigmask": (None, (3, 3)),
"signal.raise_signal": (None, (3, 8)),
"signal.set_wakeup_fd": ((2, 6), (3, 0)),
"signal.setitimer": ((2, 6), (3, 0)),
"signal.siginterrupt": ((2, 6), (3, 0)),
"signal.sigpending": (None, (3, 3)),
"signal.sigtimedwait": (None, (3, 3)),
"signal.sigwait": (None, (3, 3)),
"signal.sigwaitinfo": (None, (3, 3)),
"signal.strsignal": (None, (3, 8)),
"signal.valid_signals": (None, (3, 8)),
"site.getsitepackages": ((2, 7), (3, 2)),
"site.getuserbase": ((2, 7), (3, 2)),
"site.getusersitepackages": ((2, 7), (3, 2)),
"smtplib.SMTP.auth": (None, (3, 5)),
"smtplib.SMTP.ehlo_or_helo_if_needed": ((2, 6), (3, 0)),
"smtplib.SMTP.send_message": (None, (3, 2)),
"smtplib.SMTP.starttls": ((2, 6), (3, 0)),
"socket.CMSG_LEN": (None, (3, 3)),
"socket.CMSG_SPACE": (None, (3, 3)),
"socket.close": (None, (3, 7)),
"socket.create_connection": ((2, 6), (3, 0)),
"socket.create_server": (None, (3, 8)),
"socket.fromshare": (None, (3, 3)),
"socket.getaddrinfo": ((2, 2), (3, 0)),
"socket.getdefaulttimeout": ((2, 3), (3, 0)),
"socket.getnameinfo": ((2, 2), (3, 0)),
"socket.has_dualstack_ipv6": (None, (3, 8)),
"socket.if_indextoname": (None, (3, 3)),
"socket.if_nameindex": (None, (3, 3)),
"socket.if_nametoindex": (None, (3, 3)),
"socket.inet_ntop": ((2, 3), (3, 0)),
"socket.inet_pton": ((2, 3), (3, 0)),
"socket.recv_fds": (None, (3, 9)),
"socket.send_fds": (None, (3, 9)),
"socket.setdefaulttimeout": ((2, 3), (3, 0)),
"socket.sethostname": (None, (3, 3)),
"socket.socket.detach": (None, (3, 2)),
"socket.socket.get_inheritable": (None, (3, 4)),
"socket.socket.getblocking": (None, (3, 7)),
"socket.socket.gettimeout": ((2, 3), (3, 0)),
"socket.socket.ioctl": ((2, 6), (3, 0)),
"socket.socket.recv_into": ((2, 5), (3, 0)),
"socket.socket.recvfrom_into": ((2, 5), (3, 0)),
"socket.socket.recvmsg": (None, (3, 3)),
"socket.socket.recvmsg_into": (None, (3, 3)),
"socket.socket.sendfile": (None, (3, 5)),
"socket.socket.sendmsg": (None, (3, 3)),
"socket.socket.sendmsg_afalg": (None, (3, 6)),
"socket.socket.set_inheritable": (None, (3, 4)),
"socket.socket.settimeout": ((2, 3), (3, 0)),
"socket.socket.share": (None, (3, 3)),
"socket.socketpair": ((2, 4), (3, 0)),
"socketserver.BaseServer.service_actions": (None, (3, 3)),
"sysconfig._get_preferred_schemes": (None, (3, 10)),
"sysconfig.get_default_scheme": (None, (3, 10)),
"sysconfig.get_preferred_scheme": (None, (3, 10)),
"sqlite3.Connection.backup": (None, (3, 7)),
"sqlite3.Connection.blobopen": (None, (3, 11)),
"sqlite3.Connection.create_window_function": (None, (3, 11)),
"sqlite3.Connection.deserialize": (None, (3, 11)),
"sqlite3.Connection.enable_load_extension": ((2, 7), (3, 2)),
"sqlite3.Connection.getconfig": (None, (3, 12)),
"sqlite3.Connection.getlimit": (None, (3, 11)),
"sqlite3.Connection.in_transaction": (None, (3, 2)),
"sqlite3.Connection.iter_dump": ((2, 6), (3, 0)),
"sqlite3.Connection.iterdump": ((2, 6), (3, 0)),
"sqlite3.Connection.load_extension": ((2, 7), (3, 2)),
"sqlite3.Connection.serialize": (None, (3, 11)),
"sqlite3.Connection.set_progress_handler": ((2, 6), (3, 0)),
"sqlite3.Connection.set_trace_callback": (None, (3, 3)),
"sqlite3.Connection.setconfig": (None, (3, 12)),
"sqlite3.Connection.setlimit": (None, (3, 11)),
"sqlite3.Row.keys": ((2, 6), (3, 0)),
"ssl.RAND_bytes": (None, (3, 3)),
"ssl.RAND_pseudo_bytes": (None, (3, 3)),
"ssl.SSLContext.cert_store_stats": ((2, 7), (3, 4)),
"ssl.SSLContext.get_ca_certs": ((2, 7), (3, 4)),
"ssl.SSLContext.get_ciphers": (None, (3, 6)),
"ssl.SSLContext.get_groups": (None, (3, 15)),
"ssl.SSLContext.load_default_certs": ((2, 7), (3, 4)),
"ssl.SSLContext.load_dh_params": ((2, 7), (3, 3)),
"ssl.SSLContext.set_alpn_protocols": ((2, 7), (3, 5)),
"ssl.SSLContext.set_ciphersuites": (None, (3, 15)),
"ssl.SSLContext.set_client_sigalgs": (None, (3, 15)),
"ssl.SSLContext.set_ecdh_curve": ((2, 7), (3, 3)),
"ssl.SSLContext.set_groups": (None, (3, 15)),
"ssl.SSLContext.set_npn_protocols": ((2, 7), (3, 3)),
"ssl.SSLContext.set_psk_client_callback": (None, (3, 13)),
"ssl.SSLContext.set_psk_server_callback": (None, (3, 13)),
"ssl.SSLContext.set_server_sigalgs": (None, (3, 15)),
"ssl.SSLContext.set_servername_callback": ((2, 7), (3, 4)),
"ssl.SSLSocket.client_sigalg": (None, (3, 15)),
"ssl.SSLSocket.compression": ((2, 7), (3, 3)),
"ssl.SSLSocket.get_channel_binding": ((2, 7), (3, 3)),
"ssl.SSLSocket.get_unverified_chain": (None, (3, 13)),
"ssl.SSLSocket.get_verified_chain": (None, (3, 13)),
"ssl.SSLSocket.group": (None, (3, 15)),
"ssl.SSLSocket.selected_alpn_protocol": ((2, 7), (3, 5)),
"ssl.SSLSocket.selected_npn_protocol": ((2, 7), (3, 3)),
"ssl.SSLSocket.server_sigalg": (None, (3, 15)),
"ssl.SSLSocket.sendfile": (None, (3, 5)),
"ssl.SSLSocket.shared_ciphers": (None, (3, 5)),
"ssl.SSLSocket.verify_client_post_handshake": (None, (3, 8)),
"ssl.SSLSocket.version": ((2, 7), (3, 5)),
"ssl._https_verify_certificates": ((2, 7), None),
"ssl.create_default_context": ((2, 7), (3, 4)),
"ssl.enum_certificates": ((2, 7), (3, 4)),
"ssl.enum_crls": ((2, 7), (3, 4)),
"ssl.get_default_verify_paths": ((2, 7), (3, 4)),
"ssl.get_sigalgs": (None, (3, 15)),
"ssl.match_hostname": ((2, 7), (3, 2)),
"stat.S_ISDOOR": (None, (3, 4)),
"stat.S_ISPORT": (None, (3, 4)),
"stat.S_ISWHT": (None, (3, 4)),
"stat.filemode": (None, (3, 3)),
"statistics.NormalDist.zscore": (None, (3, 9)),
"statistics.correlation": (None, (3, 10)),
"statistics.covariance": (None, (3, 10)),
"statistics.fmean": (None, (3, 8)),
"statistics.geometric_mean": (None, (3, 8)),
"statistics.harmonic_mean": (None, (3, 6)),
"statistics.kde": (None, (3, 13)),
"statistics.kde_random": (None, (3, 13)),
"statistics.linear_regression": (None, (3, 10)),
"statistics.multimode": (None, (3, 8)),
"statistics.quantiles": (None, (3, 8)),
"string.Template.get_identifiers": (None, (3, 11)),
"string.Template.is_valid": (None, (3, 11)),
"string.rsplit": ((2, 4), None),
"struct.Struct.iter_unpack": (None, (3, 4)),
"struct.iter_unpack": (None, (3, 4)),
"struct.pack_into": ((2, 5), (3, 0)),
"struct.unpack_from": ((2, 5), (3, 0)),
"subprocess.Popen.kill": ((2, 6), (3, 0)),
"subprocess.Popen.send_signal": ((2, 6), (3, 0)),
"subprocess.Popen.terminate": ((2, 6), (3, 0)),
"subprocess.check_call": ((2, 5), (3, 0)),
"subprocess.check_output": ((2, 7), (3, 1)),
"subprocess.run": (None, (3, 5)),
"symtable.Function.get_cells": (None, (3, 15)),
"symtable.Symbol.is_annotated": (None, (3, 6)),
"symtable.Symbol.is_cell": (None, (3, 15)),
"symtable.Symbol.is_comp_cell": (None, (3, 14)),
"symtable.Symbol.is_comp_iter": (None, (3, 14)),
"symtable.Symbol.is_free_class": (None, (3, 14)),
"symtable.Symbol.is_type_parameter": (None, (3, 14)),
"sys._clear_internal_caches": (None, (3, 13)),
"sys._clear_type_cache": ((2, 6), (3, 0)),
"sys._current_frames": ((2, 5), (3, 0)),
"sys._debugmallocstats": (None, (3, 3)),
"sys._enablelegacywindowsfsencoding": (None, (3, 6)),
"sys._is_gil_enabled": (None, (3, 13)),
"sys._is_immortal": (None, (3, 14)),
"sys._is_interned": (None, (3, 13)),
"sys.abi_info": (None, (3, 15)),
"sys.addaudithook": (None, (3, 8)),
"sys.audit": (None, (3, 8)),
"sys.breakpointhook": (None, (3, 7)),
"sys.exc_clear": ((2, 3), None),
"sys.exception": (None, (3, 11)),
"sys.get_asyncgen_hooks": (None, (3, 6)),
"sys.get_coroutine_origin_tracking_depth": (None, (3, 7)),
"sys.get_int_max_str_digits": (None, (3, 11)),
"sys.get_lazy_imports": (None, (3, 15)),
"sys.getallocatedblocks": (None, (3, 4)),
"sys.getandroidapilevel": (None, (3, 7)),
"sys.getcheckinterval": ((2, 3), (3, 0)),
"sys.getdlopenflags": ((2, 2), (3, 0)),
"sys.getfilesystemencodeerrors": (None, (3, 6)),
"sys.getfilesystemencoding": ((2, 3), (3, 0)),
"sys.getprofile": ((2, 6), (3, 0)),
"sys.getsizeof": ((2, 6), (3, 0)),
"sys.getswitchinterval": (None, (3, 2)),
"sys.gettrace": ((2, 6), (3, 0)),
"sys.getwindowsversion": ((2, 3), (3, 0)),
"sys.is_finalizing": (None, (3, 5)),
"sys.remote_exec": (None, (3, 14)),
"sys.set_asyncgen_hooks": (None, (3, 6)),
"sys.set_coroutine_origin_tracking_depth": (None, (3, 7)),
"sys.set_int_max_str_digits": (None, (3, 11)),
"sys.set_lazy_imports": (None, (3, 15)),
"sys.set_lazy_imports_filter": (None, (3, 15)),
"sys.setdefaultencoding": ((2, 0), None),
"sys.setdlopenflags": ((2, 2), (3, 0)),
"sys.setswitchinterval": (None, (3, 2)),
"sys.settscdump": ((2, 4), None),
"sys.unraisablehook": (None, (3, 8)),
"tarfile.TarFile.extractall": ((2, 5), (3, 0)),
"tarfile.TarInfo.fromtarfile": ((2, 6), (3, 0)),
"tarfile.TarInfo.replace": (None, (3, 12)),
"telnetlib.Telnet.read_sb_data": ((2, 3), (3, 0)),
"tempfile.NamedTemporaryFile": ((2, 3), (3, 0)),
"tempfile.SpooledTemporaryFile": ((2, 6), (3, 0)),
"tempfile.TemporaryDirectory": (None, (3, 2)),
"tempfile.gettempdir": ((2, 3), (3, 0)),
"tempfile.gettempdirb": (None, (3, 5)),
"tempfile.gettempprefixb": (None, (3, 5)),
"tempfile.mkdtemp": ((2, 3), (3, 0)),
"tempfile.mkstemp": ((2, 3), (3, 0)),
"termios.tcgetwinsize": (None, (3, 11)),
"termios.tcsetwinsize": (None, (3, 11)),
"test.support.adjust_int_max_str_digits": (None, (3, 11)),
"test.support.captured_stdout": ((2, 6), (3, 0)),
"test.support.catch_threading_exception": (None, (3, 8)),
"test.support.catch_unraisable_exception": (None, (3, 8)),
"test.support.check__all__": (None, (3, 6)),
"test.support.check_disallow_instantiation": (None, (3, 10)),
"test.support.check_py3k_warnings": ((2, 7), None),
"test.support.check_syntax_warning": (None, (3, 8)),
"test.support.check_warnings": ((2, 6), (3, 0)),
"test.support.detect_api_mismatch": (None, (3, 5)),
"test.support.flush_std_streams": (None, (3, 11)),
"test.support.import_fresh_module": ((2, 7), (3, 1)),
"test.support.import_module": ((2, 7), (3, 1)),
"test.support.print_warning": (None, (3, 9)),
"test.support.skip_if_broken_multiprocessing_synchronize": (None, (3, 10)),
"test.support.wait_process": (None, (3, 9)),
"textwrap.indent": (None, (3, 3)),
"textwrap.shorten": (None, (3, 4)),
"thread.interrupt_main": ((2, 3), None),
"thread.stack_size": ((2, 5), None),
"threading.Condition.locked": (None, (3, 14)),
"threading.Condition.notify_all": ((2, 6), (3, 0)),
"threading.Condition.wait_for": (None, (3, 2)),
"threading.Event.is_set": ((2, 6), (3, 0)),
"threading.RLock.locked": (None, (3, 14)),
"threading.Thread.is_alive": ((2, 6), (3, 0)),
"threading.active_count": ((2, 6), (3, 0)),
"threading.concurrent_tee": (None, (3, 15)),
"threading.current_thread": ((2, 6), (3, 0)),
"threading.excepthook": (None, (3, 8)),
"threading.get_ident": (None, (3, 3)),
"threading.get_native_id": (None, (3, 8)),
"threading.getprofile": (None, (3, 10)),
"threading.gettrace": (None, (3, 10)),
"threading.main_thread": (None, (3, 4)),
"threading.serialize_iterator": (None, (3, 15)),
"threading.setprofile": ((2, 3), (3, 0)),
"threading.setprofile_all_threads": (None, (3, 12)),
"threading.settrace": ((2, 3), (3, 0)),
"threading.settrace_all_threads": (None, (3, 12)),
"threading.stack_size": ((2, 5), (3, 0)),
"threading.synchronized_iterator": (None, (3, 15)),
"time.clock_getres": (None, (3, 3)),
"time.clock_gettime": (None, (3, 3)),
"time.clock_gettime_ns": (None, (3, 7)),
"time.clock_settime": (None, (3, 3)),
"time.clock_settime_ns": (None, (3, 7)),
"time.get_clock_info": (None, (3, 3)),
"time.monotonic": (None, (3, 3)),
"time.monotonic_ns": (None, (3, 7)),
"time.perf_counter": (None, (3, 3)),
"time.perf_counter_ns": (None, (3, 7)),
"time.process_time": (None, (3, 3)),
"time.process_time_ns": (None, (3, 7)),
"time.pthread_getcpuclockid": (None, (3, 7)),
"time.thread_time": (None, (3, 7)),
"time.thread_time_ns": (None, (3, 7)),
"time.time_ns": (None, (3, 7)),
"time.tzset": ((2, 3), (3, 0)),
"timeit.Timer.autorange": (None, (3, 6)),
"timeit.repeat": ((2, 6), (3, 0)),
"timeit.timeit": ((2, 6), (3, 0)),
"tkinter.Event.detail": (None, (3, 15)),
"tkinter.Event.user_data": (None, (3, 15)),
"tkinter.Text.search_all": (None, (3, 15)),
"tkinter.grid_content": (None, (3, 15)),
"tkinter.info_patchlevel": (None, (3, 11)),
"tkinter.pack_content": (None, (3, 15)),
"tkinter.place_content": (None, (3, 15)),
"tkinter.ttk": (None, (3, 1)),
"tokenize.generate_tokens": ((2, 2), (3, 0)),
"tokenize.open": (None, (3, 2)),
"tokenize.untokenize": ((2, 5), (3, 0)),
"traceback.StackSummary.format_frame_summary": (None, (3, 11)),
"traceback.TracebackException.print": (None, (3, 11)),
"traceback.clear_frames": (None, (3, 4)),
"traceback.format_exc": ((2, 4), (3, 0)),
"traceback.walk_stack": (None, (3, 5)),
"traceback.walk_tb": (None, (3, 5)),
"tracemalloc.reset_peak": (None, (3, 9)),
"turtle.fill": (None, (3, 14)),
"turtle.no_animation": (None, (3, 14)),
"turtle.poly": (None, (3, 14)),
"turtle.save": (None, (3, 14)),
"types.CodeType.replace": (None, (3, 8)),
"types.DynamicClassAttribute": (None, (3, 4)),
"types.FrameType.clear": (None, (3, 4)),
"types.coroutine": (None, (3, 5)),
"types.get_original_bases": (None, (3, 12)),
"types.new_class": (None, (3, 3)),
"types.prepare_class": (None, (3, 3)),
"types.FrameLocalsProxyType": (None, (3, 15)),
"types.LazyImportType": (None, (3, 15)),
"types.resolve_bases": (None, (3, 7)),
"typing.ParamSpec.evaluate_default": (None, (3, 14)),
"typing.ParamSpec.has_default": (None, (3, 13)),
"typing.TypeAliasType.evaluate_value": (None, (3, 14)),
"typing.TypeVar.evaluate_bound": (None, (3, 14)),
"typing.TypeVar.evaluate_constraints": (None, (3, 14)),
"typing.TypeVar.evaluate_default": (None, (3, 14)),
"typing.TypeVar.has_default": (None, (3, 13)),
"typing.TypeVarTuple.evaluate_default": (None, (3, 14)),
"typing.TypeVarTuple.has_default": (None, (3, 13)),
"typing.assert_never": (None, (3, 11)),
"typing.assert_type": (None, (3, 11)),
"typing.clear_overloads": (None, (3, 11)),
"typing.evaluate_forward_ref": (None, (3, 14)),
"typing.get_args": (None, (3, 8)),
"typing.get_origin": (None, (3, 8)),
"typing.get_overloads": (None, (3, 11)),
"typing.get_protocol_members": (None, (3, 13)),
"typing.is_protocol": (None, (3, 13)),
"typing.is_typeddict": (None, (3, 10)),
"typing.reveal_type": (None, (3, 11)),
"unicodedata.block": (None, (3, 15)),
"unicodedata.east_asian_width": ((2, 4), (3, 0)),
"unicodedata.extended_pictographic": (None, (3, 15)),
"unicodedata.grapheme_cluster_break": (None, (3, 15)),
"unicodedata.indic_conjunct_break": (None, (3, 15)),
"unicodedata.iter_graphemes": (None, (3, 15)),
"unicodedata.is_normalized": (None, (3, 8)),
"unicodedata.isxidcontinue": (None, (3, 15)),
"unicodedata.isxidstart": (None, (3, 15)),
"unicodedata.normalize": ((2, 3), (3, 0)),
"unittest.IsolatedAsyncioTestCase.enterAsyncContext": (None, (3, 11)),
"unittest.TestCase.addClassCleanup": (None, (3, 8)),
"unittest.TestCase.addCleanup": ((2, 7), (3, 1)),
"unittest.TestCase.addTypeEqualityFunc": ((2, 7), (3, 1)),
"unittest.TestCase.assertCountEqual": (None, (3, 2)),
"unittest.TestCase.assertDictContainsSubset": ((2, 7), (3, 1)),
"unittest.TestCase.assertDictEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertEndsWith": (None, (3, 14)),
"unittest.TestCase.assertGreater": ((2, 7), (3, 1)),
"unittest.TestCase.assertGreaterEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertHasAttr": (None, (3, 14)),
"unittest.TestCase.assertIn": ((2, 7), (3, 1)),
"unittest.TestCase.assertIs": ((2, 7), (3, 1)),
"unittest.TestCase.assertIsInstance": ((2, 7), (3, 2)),
"unittest.TestCase.assertIsNone": ((2, 7), (3, 1)),
"unittest.TestCase.assertIsNot": ((2, 7), (3, 1)),
"unittest.TestCase.assertIsNotNone": ((2, 7), (3, 1)),
"unittest.TestCase.assertIsSubclass": (None, (3, 14)),
"unittest.TestCase.assertItemsEqual": ((2, 7), None),
"unittest.TestCase.assertLess": ((2, 7), (3, 1)),
"unittest.TestCase.assertLessEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertListEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertLogs": (None, (3, 4)),
"unittest.TestCase.assertMultiLineEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertNoLogs": (None, (3, 10)),
"unittest.TestCase.assertNotEndsWith": (None, (3, 14)),
"unittest.TestCase.assertNotHasAttr": (None, (3, 14)),
"unittest.TestCase.assertNotIn": ((2, 7), (3, 1)),
"unittest.TestCase.assertNotIsInstance": ((2, 7), (3, 2)),
"unittest.TestCase.assertNotIsSubclass": (None, (3, 14)),
"unittest.TestCase.assertNotRegex": (None, (3, 2)),
"unittest.TestCase.assertNotRegexpMatches": ((2, 7), (3, 5)),
"unittest.TestCase.assertNotStartsWith": (None, (3, 14)),
"unittest.TestCase.assertRaisesRegex": (None, (3, 2)),
"unittest.TestCase.assertRaisesRegexp": ((2, 7), (3, 1)),
"unittest.TestCase.assertRegex": (None, (3, 2)),
"unittest.TestCase.assertRegexpMatches": ((2, 7), (3, 1)),
"unittest.TestCase.assertSequenceEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertSetEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertStartsWith": (None, (3, 14)),
"unittest.TestCase.assertTupleEqual": ((2, 7), (3, 1)),
"unittest.TestCase.assertWarns": (None, (3, 2)),
"unittest.TestCase.assertWarnsRegex": (None, (3, 2)),
"unittest.TestCase.doClassCleanups": (None, (3, 8)),
"unittest.TestCase.doCleanups": ((2, 7), (3, 1)),
"unittest.TestCase.enterClassContext": (None, (3, 11)),
"unittest.TestCase.enterContext": (None, (3, 11)),
"unittest.TestCase.setUpClass": ((2, 7), (3, 2)),
"unittest.TestCase.skipTest": ((2, 7), (3, 1)),
"unittest.TestCase.subTest": (None, (3, 4)),
"unittest.TestCase.tearDownClass": ((2, 7), (3, 2)),
"unittest.TestLoader.discover": ((2, 7), (3, 2)),
"unittest.TestResult.addSubTest": (None, (3, 4)),
"unittest.TestResult.startTestRun": ((2, 7), (3, 1)),
"unittest.TestResult.stopTestRun": ((2, 7), (3, 1)),
"unittest.addModuleCleanup": (None, (3, 8)),
"unittest.doModuleCleanups": (None, (3, 11)),
"unittest.enterModuleContext": (None, (3, 11)),
"unittest.installHandler": ((2, 7), (3, 2)),
"unittest.mock.Mock.assert_called": (None, (3, 6)),
"unittest.mock.Mock.assert_called_once": (None, (3, 6)),
"unittest.mock.Mock.assert_not_called": (None, (3, 5)),
"unittest.mock.seal": bpv("mock", (None, (3, 7)), config),
"unittest.registerResult": ((2, 7), (3, 2)),
"unittest.removeHandler": ((2, 7), (3, 2)),
"unittest.removeResult": ((2, 7), (3, 2)),
"urllib.request.HTTPRedirectHandler.http_error_308": (None, (3, 11)),
"urllib.request.Request.remove_header": (None, (3, 4)),
"urllib.robotparser.RobotFileParser.crawl_delay": (None, (3, 6)),
"urllib.robotparser.RobotFileParser.request_rate": (None, (3, 6)),
"urllib.robotparser.RobotFileParser.site_maps": (None, (3, 8)),
"urllib.urlopen.getcode": ((2, 6), None),
"urllib2.Request.add_unredirected_header": ((2, 4), None),
"urllib2.Request.has_header": ((2, 4), None),
"urlparse.ParseResult.geturl": ((2, 5), None),
"urlparse.parse_qs": ((2, 6), None),
"urlparse.parse_qsl": ((2, 6), None),
"urlparse.urlsplit": ((2, 2), None),
"urlparse.urlunsplit": ((2, 2), None),
"uuid.uuid6": (None, (3, 14)),
"uuid.uuid7": (None, (3, 14)),
"uuid.uuid8": (None, (3, 14)),
"venv.EnvBuilder.create_git_ignore_file": (None, (3, 13)),
"venv.EnvBuilder.upgrade_dependencies": (None, (3, 9)),
"venv.create": (None, (3, 3)),
"warnings.warnpy3k": ((2, 6), None),
"weakref.WeakKeyDictionary.iterkeyrefs": ((2, 5), None),
"weakref.WeakKeyDictionary.keyrefs": ((2, 5), (3, 0)),
"weakref.WeakValueDictionary.itervaluerefs": ((2, 5), None),
"weakref.WeakValueDictionary.valuerefs": ((2, 5), (3, 0)),
"wave.Wave_read.getformat": (None, (3, 15)),
"wave.Wave_write.getformat": (None, (3, 15)),
"wave.Wave_write.setformat": (None, (3, 15)),
"wave.Wave_write.setparams": (None, (3, 15)),
"webbrowser.controller.open_new_tab": ((2, 5), (3, 0)),
"webbrowser.open_new_tab": ((2, 5), (3, 0)),
"winreg.CreateKeyEx": (None, (3, 2)),
"winreg.DeleteKeyEx": (None, (3, 2)),
"winsound.MessageBeep": ((2, 3), (3, 0)),
"wsgiref.handlers.read_environ": (None, (3, 2)),
"xml.dom.Node.normalize": ((2, 1), (3, 0)),
"xml.dom.minidom.Node.toprettyxml": ((2, 1), (3, 0)),
"xml.etree.ElementTree.Element.extend": ((2, 7), (3, 2)),
"xml.etree.ElementTree.Element.iter": ((2, 7), (3, 2)),
"xml.etree.ElementTree.Element.iterfind": ((2, 7), (3, 2)),
"xml.etree.ElementTree.Element.itertext": ((2, 7), (3, 2)),
"xml.etree.ElementTree.ElementTree.iterfind": ((2, 7), (3, 2)),
"xml.etree.ElementTree.TreeBuilder.comment": (None, (3, 8)),
"xml.etree.ElementTree.TreeBuilder.doctype": ((2, 7), (3, 2)),
"xml.etree.ElementTree.TreeBuilder.end_ns": (None, (3, 8)),
"xml.etree.ElementTree.TreeBuilder.pi": (None, (3, 8)),
"xml.etree.ElementTree.TreeBuilder.start_ns": (None, (3, 8)),
"xml.etree.ElementTree.XMLParser.flush": (None, (3, 13)),
"xml.etree.ElementTree.XMLPullParser.flush": (None, (3, 13)),
"xml.etree.ElementTree.canonicalize": (None, (3, 8)),
"xml.etree.ElementTree.fromstringlist": ((2, 7), (3, 2)),
"xml.etree.ElementTree.indent": (None, (3, 9)),
"xml.etree.ElementTree.register_namespace": ((2, 7), (3, 2)),
"xml.etree.ElementTree.tostringlist": ((2, 7), (3, 2)),
"xml.parsers.expat.xmlparser.EntityDeclHandler": ((2, 1), (3, 0)),
"xml.parsers.expat.xmlparser.GetInputContext": ((2, 1), (3, 0)),
"xml.parsers.expat.xmlparser.SetAllocTrackerActivationThreshold": (None, (3, 14)),
"xml.parsers.expat.xmlparser.SetAllocTrackerMaximumAmplification": (None, (3, 14)),
"xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtection"
"ActivationThreshold": (None, (3, 15)),
"xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtection"
"MaximumAmplification": (None, (3, 15)),
"xml.parsers.expat.xmlparser.UseForeignDTD": ((2, 3), (3, 0)),
"xml.parsers.expat.xmlparser.XmlDeclHandler": ((2, 1), (3, 0)),
"xml.parsers.expat.xmlparser.buffer_size": ((2, 3), (3, 0)),
"xml.parsers.expat.xmlparser.buffer_text": ((2, 3), (3, 0)),
"xml.parsers.expat.xmlparser.buffer_used": ((2, 3), (3, 0)),
"xml.parsers.expat.xmlparser.ordered_attributes": ((2, 1), (3, 0)),
"xml.parsers.expat.xmlparser.specified_attributes": ((2, 1), (3, 0)),
"xml.sax.saxutils.quoteattr": ((2, 2), (3, 0)),
"xml.sax.saxutils.unescape": ((2, 3), (3, 0)),
"xml.is_valid_name": (None, (3, 15)),
"xml.is_valid_text": (None, (3, 15)),
"xmlrpc.server.SimpleXMLRPCServer.register_introspection_functions": (None, (3, 0)),
"zipfile.ZipFile.extract": ((2, 6), (3, 0)),
"zipfile.ZipFile.extractall": ((2, 6), (3, 0)),
"zipfile.ZipFile.mkdir": (None, (3, 11)),
"zipfile.ZipFile.open": ((2, 6), (3, 0)),
"zipfile.ZipFile.setpassword": ((2, 6), (3, 0)),
"zipfile.ZipInfo._for_archive": (None, (3, 14)),
"zipfile.ZipInfo.from_file": (None, (3, 6)),
"zipfile.ZipInfo.is_dir": (None, (3, 6)),
"zipimport.zipimporter.create_module": (None, (3, 10)),
"zipimport.zipimporter.exec_module": (None, (3, 10)),
"zipimport.zipimporter.find_spec": (None, (3, 10)),
"zipimport.zipimporter.get_filename": ((2, 7), (3, 1)),
"zipimport.zipimporter.invalidate_caches": (None, (3, 10)),
"zlib.adler32_combine": (None, (3, 15)),
"zlib.Compress.copy": ((2, 5), (3, 0)),
"zlib.crc32_combine": (None, (3, 15)),
"zlib.Decompress.copy": ((2, 5), (3, 0)),
# Variables and Constants
"AttributeError.name": (None, (3, 10)),
"AttributeError.obj": (None, (3, 10)),
"BaseException.__suppress_context__": (None, (3, 3)),
"BaseHTTPServer.BaseHTTPRequestHandler.error_content_type": ((2, 6), None),
"Cookie.Morsel.httponly": ((2, 6), None),
"ImportError.name": (None, (3, 3)),
"ImportError.path": (None, (3, 3)),
"NameError.name": (None, (3, 10)),
"OSError.filename2": (None, (3, 4)),
"SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.encode_threshold": ((2, 7), None),
"SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.rpc_paths": ((2, 5), None),
"StopIteration.value": (None, (3, 3)),
"SyntaxError.end_lineno": (None, (3, 10)),
"SyntaxError.end_offset": (None, (3, 10)),
"__future__.absolute_import": ((2, 5), (3, 0)),
"__future__.annotations": (None, (3, 7)),
"__future__.division": ((2, 2), (3, 0)),
"__future__.generator_stop": (None, (3, 5)),
"__future__.generators": ((2, 2), (3, 0)),
"__future__.nested_scopes": ((2, 1), (3, 0)),
"__future__.print_function": ((2, 6), (3, 0)),
"__future__.unicode_literals": ((2, 6), (3, 0)),
"__future__.with_statement": ((2, 5), (3, 0)),
"_thread.TIMEOUT_MAX": (None, (3, 2)),
"annotationlib.Format.FORWARDREF": (None, (3, 14)),
"annotationlib.Format.STRING": (None, (3, 14)),
"annotationlib.Format.VALUE": (None, (3, 14)),
"annotationlib.Format.VALUE_WITH_FAKE_GLOBALS": (None, (3, 14)),
"ast.AST._field_types": (None, (3, 13)),
"ast.PyCF_ALLOW_TOP_LEVEL_AWAIT": (None, (3, 8)),
"ast.PyCF_OPTIMIZED_AST": (None, (3, 13)),
"ast.PyCF_TYPE_COMMENTS": (None, (3, 8)),
"bz2.BZ2Decompressor.eof": (None, (3, 3)),
"bz2.BZ2Decompressor.needs_input": (None, (3, 5)),
"bz2.BZ2File.mode": (None, (3, 13)),
"bz2.BZ2File.name": (None, (3, 13)),
"calendar.HTMLCalendar.cssclass_month": (None, (3, 7)),
"calendar.HTMLCalendar.cssclass_month_head": (None, (3, 7)),
"calendar.HTMLCalendar.cssclass_noday": (None, (3, 7)),
"calendar.HTMLCalendar.cssclass_year": (None, (3, 7)),
"calendar.HTMLCalendar.cssclass_year_head": (None, (3, 7)),
"calendar.HTMLCalendar.cssclasses_weekday_head": (None, (3, 7)),
"calendar.Day.FRIDAY": (None, (3, 12)),
"calendar.Day.MONDAY": (None, (3, 12)),
"calendar.Day.SATURDAY": (None, (3, 12)),
"calendar.Day.SUNDAY": (None, (3, 12)),
"calendar.Day.THURSDAY": (None, (3, 12)),
"calendar.Day.TUESDAY": (None, (3, 12)),
"calendar.Day.WEDNESDAY": (None, (3, 12)),
"calendar.FRIDAY": (None, (3, 10)),
"calendar.MONDAY": (None, (3, 10)),
"calendar.SATURDAY": (None, (3, 10)),
"calendar.THURSDAY": (None, (3, 10)),
"calendar.TUESDAY": (None, (3, 10)),
"calendar.WEDNESDAY": (None, (3, 10)),
"calendar.SUNDAY": (None, (3, 10)),
"calendar.Month.JANUARY": (None, (3, 12)),
"calendar.Month.FEBRUARY": (None, (3, 12)),
"calendar.Month.MARCH": (None, (3, 12)),
"calendar.Month.APRIL": (None, (3, 12)),
"calendar.Month.MAY": (None, (3, 12)),
"calendar.Month.JUNE": (None, (3, 12)),
"calendar.Month.JULY": (None, (3, 12)),
"calendar.Month.AUGUST": (None, (3, 12)),
"calendar.Month.SEPTEMBER": (None, (3, 12)),
"calendar.Month.OCTOBER": (None, (3, 12)),
"calendar.Month.NOVEMBER": (None, (3, 12)),
"calendar.Month.DECEMBER": (None, (3, 12)),
"calendar.JANUARY": (None, (3, 12)),
"calendar.FEBRUARY": (None, (3, 12)),
"calendar.MARCH": (None, (3, 12)),
"calendar.APRIL": (None, (3, 12)),
"calendar.MAY": (None, (3, 12)),
"calendar.JUNE": (None, (3, 12)),
"calendar.JULY": (None, (3, 12)),
"calendar.AUGUST": (None, (3, 12)),
"calendar.SEPTEMBER": (None, (3, 12)),
"calendar.OCTOBER": (None, (3, 12)),
"calendar.NOVEMBER": (None, (3, 12)),
"calendar.DECEMBER": (None, (3, 12)),
"classmethod.__wrapped__": (None, (3, 10)),
"cmath.inf": (None, (3, 6)),
"cmath.infj": (None, (3, 6)),
"cmath.nan": (None, (3, 6)),
"cmath.nanj": (None, (3, 6)),
"cmath.tau": (None, (3, 6)),
"collections.deque.maxlen": ((2, 7), (3, 1)),
"collections.namedtuple._field_defaults": (None, (3, 7)),
"configparser.DuplicateSectionError.lineno": bpv("configparser", (None, (3, 2)), config),
"configparser.DuplicateSectionError.source": bpv("configparser", (None, (3, 2)), config),
"configparser.ParsingError.source": bpv("configparser", (None, (3, 2)), config),
"cookielib.Cookie.rfc2109": ((2, 5), None),
"cookielib.DefaultCookiePolicy.rfc2109_as_netscape": ((2, 5), None),
"crypt.METHOD_BLOWFISH": (None, (3, 7)),
"crypt.METHOD_CRYPT": (None, (3, 3)),
"crypt.METHOD_MD5": (None, (3, 3)),
"crypt.METHOD_SHA256": (None, (3, 3)),
"crypt.METHOD_SHA512": (None, (3, 3)),
"crypt.methods": (None, (3, 3)),
"csv.QUOTE_NOTNULL": (None, (3, 12)),
"csv.QUOTE_STRINGS": (None, (3, 12)),
"csv.csvreader.fieldnames": ((2, 6), (3, 0)),
"csv.csvreader.line_num": ((2, 5), (3, 0)),
"ctypes.Structure._align_": (None, (3, 13)),
"curses.A_ITALIC": (None, (3, 7)),
"curses.ncurses_version": (None, (3, 8)),
"curses.window.encoding": (None, (3, 3)),
"dataclasses.KW_ONLY": (None, (3, 10)),
"datetime.UTC": (None, (3, 11)),
"datetime.datetime.fold": (None, (3, 6)),
"datetime.time.fold": (None, (3, 6)),
"decimal.HAVE_CONTEXTVAR": (None, (3, 7)), # Backported from 3.9 -> 3.8 -> 3.7
"difflib.SequenceMatcher.bjunk": (None, (3, 2)),
"difflib.SequenceMatcher.bpopular": (None, (3, 2)),
"dis.Instruction.positions": (None, (3, 11)),
"dis.Instruction.start_offset": (None, (3, 13)),
"dis.Instruction.cache_offset": (None, (3, 13)),
"dis.Instruction.end_offset": (None, (3, 13)),
"dis.Instruction.baseopname": (None, (3, 13)),
"dis.Instruction.baseopcode": (None, (3, 13)),
"dis.Instruction.jump_target": (None, (3, 13)),
"dis.Instruction.oparg": (None, (3, 13)),
"dis.Instruction.line_number": (None, (3, 13)),
"dis.Instruction.cache_info": (None, (3, 13)),
"doctest.COMPARISON_FLAGS": ((2, 4), (3, 0)),
"doctest.DONT_ACCEPT_BLANKLINE": ((2, 4), (3, 0)),
"doctest.ELLIPSIS": ((2, 4), (3, 0)),
"doctest.FAIL_FAST": (None, (3, 4)),
"doctest.IGNORE_EXCEPTION_DETAIL": ((2, 4), (3, 0)),
"doctest.NORMALIZE_WHITESPACE": ((2, 4), (3, 0)),
"doctest.REPORTING_FLAGS": ((2, 4), (3, 0)),
"doctest.REPORT_CDIFF": ((2, 4), (3, 0)),
"doctest.REPORT_NDIFF": ((2, 4), (3, 0)),
"doctest.REPORT_ONLY_FIRST_FAILURE": ((2, 4), (3, 0)),
"doctest.REPORT_UDIFF": ((2, 4), (3, 0)),
"doctest.SKIP": ((2, 5), (3, 0)),
"doctest.DocTestRunner.skips": (None, (3, 13)),
"doctest.DocTestRunner.skipped": (None, (3, 13)),
"email.message.Message.defects": ((2, 4), (3, 0)),
"email.policy.EmailPolicy.content_manager": (None, (3, 4)),
"email.policy.EmailPolicy.utf8": (None, (3, 5)),
"email.policy.Policy.message_factory": (None, (3, 6)),
"email.policy.Policy.verify_generated_headers": (None, (3, 13)),
"errno.EHWPOISON": (None, (3, 14)),
"errno.EQFULL": (None, (3, 11)),
"fcntl.F_ADD_SEALS": (None, (3, 8)),
"fcntl.F_DUP2FD": (None, (3, 11)),
"fcntl.F_DUP2FD_CLOEXEC": (None, (3, 11)),
"fcntl.F_GETPATH": (None, (3, 9)),
"fcntl.F_GETPIPE_SZ": (None, (3, 10)),
"fcntl.F_GET_SEALS": (None, (3, 8)),
"fcntl.F_OFD_GETLK": (None, (3, 9)),
"fcntl.F_OFD_SETLK": (None, (3, 9)),
"fcntl.F_OFD_SETLKW": (None, (3, 9)),
"fcntl.F_SEAL_GROW": (None, (3, 8)),
"fcntl.F_SEAL_SEAL": (None, (3, 8)),
"fcntl.F_SEAL_SHRINK": (None, (3, 8)),
"fcntl.F_SEAL_WRITE": (None, (3, 8)),
"fcntl.F_SETPIPE_SZ": (None, (3, 10)),
"file.encoding": ((2, 3), None),
"file.errors": ((2, 6), None),
"filecmp.DEFAULT_IGNORES": (None, (3, 4)),
"functools.Placeholder": (None, (3, 14)),
"gc.callbacks": (None, (3, 3)),
"gzip.GzipFile.mtime": (None, (3, 1)),
"hashlib.algorithms": ((2, 7), None),
"hashlib.algorithms_available": ((2, 7), (3, 2)),
"hashlib.algorithms_guaranteed": ((2, 7), (3, 2)),
"hashlib.hash.name": (None, (3, 4)),
"hmac.HMAC.block_size": (None, (3, 4)),
"hmac.HMAC.name": (None, (3, 4)),
"html.entities.html5": (None, (3, 3)),
"htmlentitydefs.codepoint2name": ((2, 3), None),
"htmlentitydefs.name2codepoint": ((2, 3), None),
"http.HTTPStatus.EARLY_HINTS": (None, (3, 9)),
"http.HTTPStatus.IM_A_TEAPOT": (None, (3, 9)),
"http.HTTPStatus.MISDIRECTED_REQUEST": (None, (3, 7)),
"http.HTTPStatus.TOO_EARLY": (None, (3, 9)),
"http.HTTPStatus.UNAVAILABLE_FOR_LEGAL_REASONS": (None, (3, 8)),
"http.client.HTTPConnection.blocksize": (None, (3, 7)),
"httplib.responses": ((2, 5), None),
"imaplib.IMAP4.utf8_enabled": (None, (3, 5)),
"importlib.machinery.BYTECODE_SUFFIXES": (None, (3, 3)),
"importlib.machinery.DEBUG_BYTECODE_SUFFIXES": (None, (3, 3)),
"importlib.machinery.EXTENSION_SUFFIXES": (None, (3, 3)),
"importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES": (None, (3, 3)),
"importlib.machinery.SOURCE_SUFFIXES": (None, (3, 3)),
"importlib.metadata.metadata.json": (None, (3, 10)),
"importlib.util.MAGIC_NUMBER": (None, (3, 4)),
"inspect.CO_ASYNC_GENERATOR": (None, (3, 6)),
"inspect.CO_COROUTINE": (None, (3, 5)),
"inspect.CO_HAS_DOCSTRING": (None, (3, 14)),
"inspect.CO_ITERABLE_COROUTINE": (None, (3, 5)),
"inspect.CO_METHOD": (None, (3, 14)),
"inspect.Parameter.kind.description": (None, (3, 8)),
"io.SEEK_CUR": ((2, 7), (3, 1)),
"io.SEEK_END": ((2, 7), (3, 1)),
"io.SEEK_SET": ((2, 7), (3, 1)),
"io.TextIOWrapper.write_through": (None, (3, 7)),
"ipaddress.IPv4Address.ipv6_mapped": bpv("ipaddress", (None, (3, 13)), config),
"ipaddress.IPv4Address.is_global": bpv("ipaddress", (None, (3, 4)), config),
"ipaddress.IPv4Address.reverse_pointer": bpv("ipaddress", (None, (3, 5)), config),
"ipaddress.IPv6Address.is_global": bpv("ipaddress", (None, (3, 4)), config),
"keyword.softkwlist": (None, (3, 9)),
"logging.Formatter.default_msec_format": (None, (3, 3)),
"logging.Formatter.default_time_format": (None, (3, 3)),
"logging.LogRecord.funcName": ((2, 5), (3, 0)),
"logging.LogRecord.processName": ((2, 6), (3, 0)),
"logging.LoggerAdapter.manager": (None, (3, 6)),
"logging.StreamHandler.terminator": (None, (3, 2)),
"logging.handlers.BaseRotatingHandler.namer": (None, (3, 3)),
"logging.handlers.BaseRotatingHandler.rotator": (None, (3, 3)),
"logging.lastResort": (None, (3, 2)),
"lzma.LZMADecompressor.needs_input": (None, (3, 5)),
"lzma.LZMAFile.mode": (None, (3, 13)),
"lzma.LZMAFile.name": (None, (3, 13)),
"marshal.version": ((2, 4), (3, 0)),
"math.inf": (None, (3, 5)),
"math.nan": (None, (3, 5)),
"math.tau": (None, (3, 6)),
"mmap.ACCESS_DEFAULT": (None, (3, 7)),
"mmap.MADV_AUTOSYNC": (None, (3, 8)),
"mmap.MADV_CORE": (None, (3, 8)),
"mmap.MADV_DODUMP": (None, (3, 8)),
"mmap.MADV_DOFORK": (None, (3, 8)),
"mmap.MADV_DONTDUMP": (None, (3, 8)),
"mmap.MADV_DONTFORK": (None, (3, 8)),
"mmap.MADV_DONTNEED": (None, (3, 8)),
"mmap.MADV_FREE": (None, (3, 8)),
"mmap.MADV_FREE_REUSABLE": (None, (3, 8)),
"mmap.MADV_FREE_REUSE": (None, (3, 8)),
"mmap.MADV_HUGEPAGE": (None, (3, 8)),
"mmap.MADV_HWPOISON": (None, (3, 8)),
"mmap.MADV_MERGEABLE": (None, (3, 8)),
"mmap.MADV_NOCORE": (None, (3, 8)),
"mmap.MADV_NOHUGEPAGE": (None, (3, 8)),
"mmap.MADV_NORMAL": (None, (3, 8)),
"mmap.MADV_NOSYNC": (None, (3, 8)),
"mmap.MADV_PROTECT": (None, (3, 8)),
"mmap.MADV_RANDOM": (None, (3, 8)),
"mmap.MADV_REMOVE": (None, (3, 8)),
"mmap.MADV_SEQUENTIAL": (None, (3, 8)),
"mmap.MADV_SOFT_OFFLINE": (None, (3, 8)),
"mmap.MADV_UNMERGEABLE": (None, (3, 8)),
"mmap.MADV_WILLNEED": (None, (3, 8)),
"mmap.MAP_32BIT": (None, (3, 13)),
"mmap.MAP_HASSEMAPHORE": (None, (3, 13)),
"mmap.MAP_JIT": (None, (3, 13)),
"mmap.MAP_NOCACHE": (None, (3, 13)),
"mmap.MAP_NOEXTEND": (None, (3, 13)),
"mmap.MAP_NORESERVE": (None, (3, 13)),
"mmap.MAP_POPULATE": (None, (3, 10)),
"mmap.MAP_RESILIENT_CODESIGN": (None, (3, 13)),
"mmap.MAP_RESILIENT_MEDIA": (None, (3, 13)),
"mmap.MAP_STACK": (None, (3, 11)),
"mmap.MAP_TPRO": (None, (3, 13)),
"mmap.MAP_TRANSLATED_ALLOW_EXECUTE": (None, (3, 13)),
"mmap.MAP_UNIX03": (None, (3, 13)),
"mmap.mmap.closed": (None, (3, 2)),
"multiprocessing.Process.sentinel": (None, (3, 3)),
"nntplib.NNTP.nntp_implementation": (None, (3, 2)),
"nntplib.NNTP.nntp_version": (None, (3, 2)),
"object.__match_args__": (None, (3, 10)),
"os.CLD_CONTINUED": (None, (3, 3)),
"os.CLD_DUMPED": (None, (3, 3)),
"os.CLD_EXITED": (None, (3, 3)),
"os.CLD_KILLED": (None, (3, 9)),
"os.CLD_STOPPED": (None, (3, 9)),
"os.CLD_TRAPPED": (None, (3, 3)),
"os.EFD_CLOEXEC": (None, (3, 10)),
"os.EFD_NONBLOCK": (None, (3, 10)),
"os.EFD_SEMAPHORE": (None, (3, 10)),
"os.EX_CANTCREAT": ((2, 3), (3, 0)),
"os.EX_CONFIG": ((2, 3), (3, 0)),
"os.EX_DATAERR": ((2, 3), (3, 0)),
"os.EX_IOERR": ((2, 3), (3, 0)),
"os.EX_NOHOST": ((2, 3), (3, 0)),
"os.EX_NOINPUT": ((2, 3), (3, 0)),
"os.EX_NOPERM": ((2, 3), (3, 0)),
"os.EX_NOTFOUND": ((2, 3), (3, 0)),
"os.EX_NOUSER": ((2, 3), (3, 0)),
"os.EX_OK": ((2, 3), (3, 0)),
"os.EX_OSERR": ((2, 3), (3, 0)),
"os.EX_OSFILE": ((2, 3), (3, 0)),
"os.EX_PROTOCOL": ((2, 3), (3, 0)),
"os.EX_SOFTWARE": ((2, 3), (3, 0)),
"os.EX_TEMPFAIL": ((2, 3), (3, 0)),
"os.EX_UNAVAILABLE": ((2, 3), (3, 0)),
"os.EX_USAGE": ((2, 3), (3, 0)),
"os.F_LOCK": (None, (3, 3)),
"os.F_TEST": (None, (3, 3)),
"os.F_TLOCK": (None, (3, 3)),
"os.F_ULOCK": (None, (3, 3)),
"os.GRND_NONBLOCK": (None, (3, 6)),
"os.GRND_RANDOM": (None, (3, 6)),
"os.MFD_ALLOW_SEALING": (None, (3, 8)),
"os.MFD_CLOEXEC": (None, (3, 8)),
"os.MFD_HUGETLB": (None, (3, 8)),
"os.MFD_HUGE_16GB": (None, (3, 8)),
"os.MFD_HUGE_16MB": (None, (3, 8)),
"os.MFD_HUGE_1GB": (None, (3, 8)),
"os.MFD_HUGE_1MB": (None, (3, 8)),
"os.MFD_HUGE_256MB": (None, (3, 8)),
"os.MFD_HUGE_2GB": (None, (3, 8)),
"os.MFD_HUGE_2MB": (None, (3, 8)),
"os.MFD_HUGE_32MB": (None, (3, 8)),
"os.MFD_HUGE_512KB": (None, (3, 8)),
"os.MFD_HUGE_512MB": (None, (3, 8)),
"os.MFD_HUGE_64KB": (None, (3, 8)),
"os.MFD_HUGE_8MB": (None, (3, 8)),
"os.MFD_HUGE_MASK": (None, (3, 8)),
"os.MFD_HUGE_SHIFT": (None, (3, 8)),
"os.O_CLOEXEC": (None, (3, 3)),
"os.O_EVTONLY": (None, (3, 10)),
"os.O_FSYNC": (None, (3, 10)),
"os.O_NOFOLLOW_ANY": (None, (3, 10)),
"os.O_PATH": (None, (3, 4)),
"os.O_SYMLINK": (None, (3, 10)),
"os.O_TMPFILE": (None, (3, 4)),
"os.PIDFD_NONBLOCK": (None, (3, 12)),
"os.POSIX_FADV_DONTNEED": (None, (3, 3)),
"os.POSIX_FADV_NOREUSE": (None, (3, 3)),
"os.POSIX_FADV_NORMAL": (None, (3, 3)),
"os.POSIX_FADV_RANDOM": (None, (3, 3)),
"os.POSIX_FADV_SEQUENTIAL": (None, (3, 3)),
"os.POSIX_FADV_WILLNEED": (None, (3, 3)),
"os.POSIX_SPAWN_CLOSE": (None, (3, 8)),
"os.POSIX_SPAWN_DUP2": (None, (3, 8)),
"os.POSIX_SPAWN_OPEN": (None, (3, 8)),
"os.PRIO_DARWIN_BG": (None, (3, 12)),
"os.PRIO_DARWIN_NONUI": (None, (3, 12)),
"os.PRIO_DARWIN_PROCESS": (None, (3, 12)),
"os.PRIO_DARWIN_THREAD": (None, (3, 12)),
"os.PRIO_PGRP": (None, (3, 3)),
"os.PRIO_PROCESS": (None, (3, 3)),
"os.PRIO_USER": (None, (3, 3)),
"os.P_ALL": (None, (3, 3)),
"os.P_PGID": (None, (3, 3)),
"os.P_PID": (None, (3, 3)),
"os.P_PIDFD": (None, (3, 9)),
"os.RTLD_DEEPBIND": (None, (3, 3)),
"os.RTLD_GLOBAL": (None, (3, 3)),
"os.RTLD_LAZY": (None, (3, 3)),
"os.RTLD_LOCAL": (None, (3, 3)),
"os.RTLD_NODELETE": (None, (3, 3)),
"os.RTLD_NOLOAD": (None, (3, 3)),
"os.RTLD_NOW": (None, (3, 3)),
"os.RWF_APPEND": (None, (3, 10)),
"os.RWF_DSYNC": (None, (3, 7)),
"os.RWF_HIPRI": (None, (3, 7)),
"os.RWF_NOWAIT": (None, (3, 7)),
"os.RWF_SYNC": (None, (3, 7)),
"os.SCHED_BATCH": (None, (3, 3)),
"os.SCHED_DEADLINE": (None, (3, 14)),
"os.SCHED_FIFO": (None, (3, 3)),
"os.SCHED_IDLE": (None, (3, 3)),
"os.SCHED_NORMAL": (None, (3, 14)),
"os.SCHED_OTHER": (None, (3, 3)),
"os.SCHED_RESET_ON_FORK": (None, (3, 3)),
"os.SCHED_RR": (None, (3, 3)),
"os.SCHED_SPORADIC": (None, (3, 3)),
"os.SEEK_CUR": ((2, 5), (3, 0)),
"os.SEEK_DATA": (None, (3, 3)),
"os.SEEK_END": ((2, 5), (3, 0)),
"os.SEEK_HOLE": (None, (3, 3)),
"os.SEEK_SET": ((2, 5), (3, 0)),
"os.SF_MNOWAIT": (None, (3, 3)),
"os.SF_NOCACHE": (None, (3, 11)),
"os.SF_NODISKIO": (None, (3, 3)),
"os.SF_SYNC": (None, (3, 3)),
"os.SPLICE_F_MORE": (None, (3, 10)),
"os.SPLICE_F_MOVE": (None, (3, 10)),
"os.SPLICE_F_NONBLOCK": (None, (3, 10)),
"os.ST_APPEND": (None, (3, 4)),
"os.ST_IMMUTABLE": (None, (3, 4)),
"os.ST_MANDLOCK": (None, (3, 4)),
"os.ST_NOATIME": (None, (3, 4)),
"os.ST_NODEV": (None, (3, 4)),
"os.ST_NODIRATIME": (None, (3, 4)),
"os.ST_NOEXEC": (None, (3, 4)),
"os.ST_NOSUID": (None, (3, 2)),
"os.ST_RDONLY": (None, (3, 2)),
"os.ST_RELATIME": (None, (3, 4)),
"os.ST_SYNCHRONOUS": (None, (3, 4)),
"os.ST_WRITE": (None, (3, 4)),
"os.TFD_CLOEXEC": (None, (3, 13)),
"os.TFD_NONBLOCK": (None, (3, 13)),
"os.TFD_TIMER_ABSTIME": (None, (3, 13)),
"os.TFD_TIMER_CANCEL_ON_SET": (None, (3, 13)),
"os.WCONTINUED": ((2, 3), (3, 0)),
"os.WEXITED": (None, (3, 3)),
"os.WNOWAIT": (None, (3, 3)),
"os.WSTOPPED": (None, (3, 3)),
"os.WUNTRACED": ((2, 3), (3, 0)),
"os.XATTR_CREATE": (None, (3, 3)),
"os.XATTR_REPLACE": (None, (3, 3)),
"os.XATTR_SIZE_MAX": (None, (3, 3)),
"os._COPYFILE_ACL": (None, (3, 11)),
"os._COPYFILE_STAT": (None, (3, 11)),
"os._COPYFILE_XATTR": (None, (3, 11)),
"os.devnull": ((2, 4), (3, 0)),
"os.environb": (None, (3, 2)),
"os.extsep": ((2, 2), (3, 0)),
"os.killpg": ((2, 3), (3, 0)),
"os.path.ALLOW_MISSING": (None, (3, 14)),
"os.path.supports_unicode_filenames": ((2, 3), (3, 0)),
"os.stat.st_atime": ((2, 2), (3, 0)),
"os.stat.st_atime_ns": (None, (3, 3)),
"os.stat.st_attrs": ((2, 2), (3, 0)),
"os.stat.st_birthtime": ((2, 5), (3, 0)),
"os.stat.st_birthtime_ns": (None, (3, 12)),
"os.stat.st_blksize": ((2, 2), (3, 0)),
"os.stat.st_blocks": ((2, 2), (3, 0)),
"os.stat.st_ctime": ((2, 2), (3, 0)),
"os.stat.st_ctime_ns": (None, (3, 3)),
"os.stat.st_dev": ((2, 2), (3, 0)),
"os.stat.st_file_attributes": (None, (3, 5)),
"os.stat.st_flags": ((2, 2), (3, 0)),
"os.stat.st_ftype": ((2, 2), (3, 0)),
"os.stat.st_gen": ((2, 5), (3, 0)),
"os.stat.st_gid": ((2, 2), (3, 0)),
"os.stat.st_ino": ((2, 2), (3, 0)),
"os.stat.st_mode": ((2, 2), (3, 0)),
"os.stat.st_mtime": ((2, 2), (3, 0)),
"os.stat.st_mtime_ns": (None, (3, 3)),
"os.stat.st_nlink": ((2, 2), (3, 0)),
"os.stat.st_obtype": ((2, 2), (3, 0)),
"os.stat.st_rdev": ((2, 2), (3, 0)),
"os.stat.st_reparse_tag": (None, (3, 8)),
"os.stat.st_size": ((2, 2), (3, 0)),
"os.stat.st_uid": ((2, 2), (3, 0)),
"os.statvfs.f_bavail": ((2, 2), (3, 0)),
"os.statvfs.f_bfree": ((2, 2), (3, 0)),
"os.statvfs.f_blocks": ((2, 2), (3, 0)),
"os.statvfs.f_bsize": ((2, 2), (3, 0)),
"os.statvfs.f_favail": ((2, 2), (3, 0)),
"os.statvfs.f_ffree": ((2, 2), (3, 0)),
"os.statvfs.f_files": ((2, 2), (3, 0)),
"os.statvfs.f_flag": ((2, 2), (3, 0)),
"os.statvfs.f_frsize": ((2, 2), (3, 0)),
"os.statvfs.f_fsid": (None, (3, 7)),
"os.statvfs.f_namemax": ((2, 2), (3, 0)),
"os.supports_bytes_environ": (None, (3, 2)),
"os.supports_dir_fd": (None, (3, 3)),
"os.supports_effective_ids": (None, (3, 3)),
"os.supports_fd": (None, (3, 3)),
"os.supports_follow_symlinks": (None, (3, 3)),
"pathlib.info": (None, (3, 14)),
"pickle.HIGHEST_PROTOCOL": ((2, 3), (3, 0)),
"pickle.Pickler.dispatch_table": (None, (3, 3)),
"plistlib.FMT_BINARY": (None, (3, 4)),
"plistlib.FMT_XML": (None, (3, 4)),
"pstats.SortKey": (None, (3, 7)),
"pyclbr.Class.children": (None, (3, 7)),
"pyclbr.Class.end_lineno": (None, (3, 10)),
"pyclbr.Class.parent": (None, (3, 7)),
"pyclbr.Function.children": (None, (3, 7)),
"pyclbr.Function.end_lineno": (None, (3, 10)),
"pyclbr.Function.is_async": (None, (3, 10)),
"pyclbr.Function.parent": (None, (3, 7)),
"range.start": (None, (3, 3)),
"range.step": (None, (3, 3)),
"range.stop": (None, (3, 3)),
"re.NOFLAG": (None, (3, 11)),
"re.U": ((2, 0), (3, 0)),
"re.UNICODE": ((2, 0), (3, 0)),
"re.error.colno": (None, (3, 5)),
"re.error.lineno": (None, (3, 5)),
"re.error.msg": (None, (3, 5)),
"re.error.pattern": (None, (3, 5)),
"re.error.pos": (None, (3, 5)),
"repr.Repr.maxfrozenset": ((2, 4), None),
"repr.Repr.maxset": ((2, 4), None),
"reprlib.Repr.fillvalue": (None, (3, 11)),
"resource.RLIMIT_KQUEUES": (None, (3, 10)),
"resource.RLIMIT_MSGQUEUE": (None, (3, 4)),
"resource.RLIMIT_NICE": (None, (3, 4)),
"resource.RLIMIT_NPTS": (None, (3, 4)),
"resource.RLIMIT_RTPRIO": (None, (3, 4)),
"resource.RLIMIT_RTTIME": (None, (3, 4)),
"resource.RLIMIT_SBSIZE": (None, (3, 4)),
"resource.RLIMIT_SIGPENDING": (None, (3, 4)),
"resource.RLIMIT_SWAP": (None, (3, 4)),
"resource.RLIMIT_NTHR": (None, (3, 15)),
"resource.RLIMIT_THREADS": (None, (3, 15)),
"resource.RLIMIT_UMTXP": (None, (3, 15)),
"resource.RLIM_SAVED_CUR": (None, (3, 15)),
"resource.RLIM_SAVED_MAX": (None, (3, 15)),
"resource.RUSAGE_THREAD": (None, (3, 2)),
"resource.getrusage.ru_idrss": ((2, 3), (3, 0)),
"resource.getrusage.ru_inblock": ((2, 3), (3, 0)),
"resource.getrusage.ru_isrss": ((2, 3), (3, 0)),
"resource.getrusage.ru_ixrss": ((2, 3), (3, 0)),
"resource.getrusage.ru_majflt": ((2, 3), (3, 0)),
"resource.getrusage.ru_maxrss": ((2, 3), (3, 0)),
"resource.getrusage.ru_minflt": ((2, 3), (3, 0)),
"resource.getrusage.ru_msgrcv": ((2, 3), (3, 0)),
"resource.getrusage.ru_msgsnd": ((2, 3), (3, 0)),
"resource.getrusage.ru_nivcsw": ((2, 3), (3, 0)),
"resource.getrusage.ru_nsignals": ((2, 3), (3, 0)),
"resource.getrusage.ru_nswap": ((2, 3), (3, 0)),
"resource.getrusage.ru_nvcsw": ((2, 3), (3, 0)),
"resource.getrusage.ru_oublock": ((2, 3), (3, 0)),
"resource.getrusage.ru_stime": ((2, 3), (3, 0)),
"resource.getrusage.ru_utime": ((2, 3), (3, 0)),
"sched.scheduler.queue": ((2, 6), (3, 0)),
"select.EPOLLEXCLUSIVE": (None, (3, 6)),
"select.PIPE_BUF": ((2, 7), (3, 2)),
"select.devpoll.closed": (None, (3, 4)),
"shlex.shlex.eof": ((2, 3), (3, 0)),
"shlex.shlex.escape": ((2, 3), (3, 0)),
"shlex.shlex.escapedquotes": ((2, 3), (3, 0)),
"shlex.shlex.punctuation_chars": (None, (3, 6)),
"shlex.shlex.whitespace_split": ((2, 3), (3, 0)),
"shutil.rmtree.avoids_symlink_attacks": (None, (3, 3)),
"signal.CTRL_BREAK_EVENT": ((2, 7), (3, 2)),
"signal.CTRL_C_EVENT": ((2, 7), (3, 2)),
"signal.SIGSTKFLT": (None, (3, 11)),
"signal.SIG_BLOCK": (None, (3, 3)),
"signal.SIG_SETMASK": (None, (3, 3)),
"signal.SIG_UNBLOCK": (None, (3, 3)),
"site.ENABLE_USER_SITE": ((2, 6), (3, 0)),
"site.PREFIXES": ((2, 6), (3, 0)),
"site.USER_BASE": ((2, 6), (3, 0)),
"site.USER_SITE": ((2, 6), (3, 0)),
"socket.AF_ALG": (None, (3, 6)),
"socket.AF_CAN": (None, (3, 3)),
"socket.AF_LINK": (None, (3, 4)),
"socket.AF_QIPCRTR": (None, (3, 8)),
"socket.AF_RDS": (None, (3, 3)),
"socket.AF_TIPC": ((2, 6), (3, 0)),
"socket.AF_VSOCK": (None, (3, 7)),
"socket.ALG_OP_DECRYPT": (None, (3, 6)),
"socket.ALG_OP_ENCRYPT": (None, (3, 6)),
"socket.ALG_OP_SIGN": (None, (3, 6)),
"socket.ALG_OP_VERIFY": (None, (3, 6)),
"socket.ALG_SET_AEAD_ASSOCLEN": (None, (3, 6)),
"socket.ALG_SET_AEAD_AUTHSIZE": (None, (3, 6)),
"socket.ALG_SET_IV": (None, (3, 6)),
"socket.ALG_SET_KEY": (None, (3, 6)),
"socket.ALG_SET_OP": (None, (3, 6)),
"socket.ALG_SET_PUBKEY": (None, (3, 6)),
"socket.BDADDR_BREDR": (None, (3, 14)),
"socket.BDADDR_LE_PUBLIC": (None, (3, 14)),
"socket.BDADDR_LE_RANDOM": (None, (3, 14)),
"socket.BT_CHANNEL_POLICY": (None, (3, 14)),
"socket.BT_CHANNEL_POLICY_BREDR_ONLY": (None, (3, 14)),
"socket.BT_CHANNEL_POLICY_BREDR_PREFERRED": (None, (3, 14)),
"socket.BT_CODEC": (None, (3, 14)),
"socket.BT_DEFER_SETUP": (None, (3, 14)),
"socket.BT_FLUSHABLE": (None, (3, 14)),
"socket.BT_FLUSHABLE_OFF": (None, (3, 14)),
"socket.BT_FLUSHABLE_ON": (None, (3, 14)),
"socket.BT_ISO_QOS": (None, (3, 14)),
"socket.BT_MODE": (None, (3, 14)),
"socket.BT_MODE_BASIC": (None, (3, 14)),
"socket.BT_MODE_ERTM": (None, (3, 14)),
"socket.BT_MODE_EXT_FLOWCTL": (None, (3, 14)),
"socket.BT_MODE_LE_FLOWCTL": (None, (3, 14)),
"socket.BT_MODE_STREAMING": (None, (3, 14)),
"socket.BT_PHY": (None, (3, 14)),
"socket.BT_PHY_BR_1M_1SLOT": (None, (3, 14)),
"socket.BT_PHY_BR_1M_3SLOT": (None, (3, 14)),
"socket.BT_PHY_BR_1M_5SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_2M_1SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_2M_3SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_2M_5SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_3M_1SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_3M_3SLOT": (None, (3, 14)),
"socket.BT_PHY_EDR_3M_5SLOT": (None, (3, 14)),
"socket.BT_PHY_LE_1M_RX": (None, (3, 14)),
"socket.BT_PHY_LE_1M_TX": (None, (3, 14)),
"socket.BT_PHY_LE_2M_RX": (None, (3, 14)),
"socket.BT_PHY_LE_2M_TX": (None, (3, 14)),
"socket.BT_PHY_LE_CODED_RX": (None, (3, 14)),
"socket.BT_PHY_LE_CODED_TX": (None, (3, 14)),
"socket.BT_PKT_STATUS": (None, (3, 14)),
"socket.BT_POWER": (None, (3, 14)),
"socket.BT_POWER_FORCE_ACTIVE_OFF": (None, (3, 14)),
"socket.BT_POWER_FORCE_ACTIVE_ON": (None, (3, 14)),
"socket.BT_RCVMTU": (None, (3, 14)),
"socket.BT_SECURITY": (None, (3, 14)),
"socket.BT_SECURITY_FIPS": (None, (3, 14)),
"socket.BT_SECURITY_HIGH": (None, (3, 14)),
"socket.BT_SECURITY_LOW": (None, (3, 14)),
"socket.BT_SECURITY_MEDIUM": (None, (3, 14)),
"socket.BT_SECURITY_SDP": (None, (3, 14)),
"socket.BT_SNDMTU": (None, (3, 14)),
"socket.BT_VOICE": (None, (3, 14)),
"socket.BT_VOICE_CVSD_16BIT": (None, (3, 14)),
"socket.BT_VOICE_TRANSPARENT": (None, (3, 14)),
"socket.CAN_BCM": (None, (3, 4)),
"socket.CAN_BCM_CAN_FD_FRAME": (None, (3, 4)),
"socket.CAN_BCM_RX_ANNOUNCE_RESUME": (None, (3, 4)),
"socket.CAN_BCM_RX_CHANGED": (None, (3, 4)),
"socket.CAN_BCM_RX_CHECK_DLC": (None, (3, 4)),
"socket.CAN_BCM_RX_DELETE": (None, (3, 4)),
"socket.CAN_BCM_RX_FILTER_ID": (None, (3, 4)),
"socket.CAN_BCM_RX_NO_AUTOTIMER": (None, (3, 4)),
"socket.CAN_BCM_RX_READ": (None, (3, 4)),
"socket.CAN_BCM_RX_RTR_FRAME": (None, (3, 4)),
"socket.CAN_BCM_RX_SETUP": (None, (3, 4)),
"socket.CAN_BCM_RX_STATUS": (None, (3, 4)),
"socket.CAN_BCM_RX_TIMEOUT": (None, (3, 4)),
"socket.CAN_BCM_SETTIMER": (None, (3, 4)),
"socket.CAN_BCM_STARTTIMER": (None, (3, 4)),
"socket.CAN_BCM_TX_ANNOUNCE": (None, (3, 4)),
"socket.CAN_BCM_TX_COUNTEVT": (None, (3, 4)),
"socket.CAN_BCM_TX_CP_CAN_ID": (None, (3, 4)),
"socket.CAN_BCM_TX_DELETE": (None, (3, 4)),
"socket.CAN_BCM_TX_EXPIRED": (None, (3, 4)),
"socket.CAN_BCM_TX_READ": (None, (3, 4)),
"socket.CAN_BCM_TX_RESET_MULTI_IDX": (None, (3, 4)),
"socket.CAN_BCM_TX_SEND": (None, (3, 4)),
"socket.CAN_BCM_TX_SETUP": (None, (3, 4)),
"socket.CAN_BCM_TX_STATUS": (None, (3, 4)),
"socket.CAN_EFF_FLAG": (None, (3, 3)),
"socket.CAN_EFF_MASK": (None, (3, 3)),
"socket.CAN_ERR_FLAG": (None, (3, 3)),
"socket.CAN_ERR_MASK": (None, (3, 3)),
"socket.CAN_ISOTP": (None, (3, 7)),
"socket.CAN_J1939": (None, (3, 9)),
"socket.CAN_RAW": (None, (3, 3)),
"socket.CAN_RAW_ERR_FILTER": (None, (3, 3)),
"socket.CAN_RAW_FD_FRAMES": (None, (3, 5)),
"socket.CAN_RAW_FILTER": (None, (3, 3)),
"socket.CAN_RAW_JOIN_FILTERS": (None, (3, 9)),
"socket.CAN_RAW_LOOPBACK": (None, (3, 3)),
"socket.CAN_RAW_RECV_OWN_MSGS": (None, (3, 3)),
"socket.CAN_RTR_FLAG": (None, (3, 3)),
"socket.CAN_SFF_MASK": (None, (3, 3)),
"socket.HCI_CHANNEL_CONTROL": (None, (3, 14)),
"socket.HCI_CHANNEL_LOGGING": (None, (3, 14)),
"socket.HCI_CHANNEL_MONITOR": (None, (3, 14)),
"socket.HCI_CHANNEL_RAW": (None, (3, 14)),
"socket.HCI_CHANNEL_USER": (None, (3, 14)),
"socket.HCI_DEV_NONE": (None, (3, 14)),
"socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID": (None, (3, 7)),
"socket.IPPROTO_MPTCP": (None, (3, 10)),
"socket.IPPROTO_UDPLITE": (None, (3, 9)),
"socket.IP_RECVTOS": (None, (3, 10)),
"socket.L2CAP_LM": (None, (3, 14)),
"socket.L2CAP_LM_AUTH": (None, (3, 14)),
"socket.L2CAP_LM_ENCRYPT": (None, (3, 14)),
"socket.L2CAP_LM_MASTER": (None, (3, 14)),
"socket.L2CAP_LM_RELIABLE": (None, (3, 14)),
"socket.L2CAP_LM_SECURE": (None, (3, 14)),
"socket.L2CAP_LM_TRUSTED": (None, (3, 14)),
"socket.LOCAL_CREDS": (None, (3, 11)),
"socket.LOCAL_CREDS_PERSISTENT": (None, (3, 11)),
"socket.PF_CAN": (None, (3, 3)),
"socket.PF_RDS": (None, (3, 3)),
"socket.RCVALL_IPLEVEL": ((2, 6), (3, 0)),
"socket.RCVALL_MAX": ((2, 6), (3, 0)),
"socket.RCVALL_OFF": ((2, 6), (3, 0)),
"socket.RCVALL_ON": ((2, 6), (3, 0)),
"socket.RCVALL_SOCKETLEVELONLY": ((2, 6), (3, 0)),
"socket.RDS_CANCEL_SENT_TO": (None, (3, 3)),
"socket.RDS_CMSG_RDMA_ARGS": (None, (3, 3)),
"socket.RDS_CMSG_RDMA_DEST": (None, (3, 3)),
"socket.RDS_CMSG_RDMA_MAP": (None, (3, 3)),
"socket.RDS_CMSG_RDMA_STATUS": (None, (3, 3)),
"socket.RDS_CMSG_RDMA_UPDATE": (None, (3, 3)),
"socket.RDS_CONG_MONITOR": (None, (3, 3)),
"socket.RDS_FREE_MR": (None, (3, 3)),
"socket.RDS_GET_MR": (None, (3, 3)),
"socket.RDS_GET_MR_FOR_DEST": (None, (3, 3)),
"socket.RDS_RDMA_DONTWAIT": (None, (3, 3)),
"socket.RDS_RDMA_FENCE": (None, (3, 3)),
"socket.RDS_RDMA_INVALIDATE": (None, (3, 3)),
"socket.RDS_RDMA_NOTIFY_ME": (None, (3, 3)),
"socket.RDS_RDMA_READWRITE": (None, (3, 3)),
"socket.RDS_RDMA_SILENT": (None, (3, 3)),
"socket.RDS_RDMA_USE_ONCE": (None, (3, 3)),
"socket.RDS_RECVERR": (None, (3, 3)),
"socket.SCM_CREDS2": (None, (3, 11)),
"socket.SIO_KEEPALIVE_VALS": ((2, 6), (3, 0)),
"socket.SIO_LOOPBACK_FAST_PATH": (None, (3, 6)),
"socket.SIO_RCVALL": ((2, 6), (3, 0)),
"socket.SOCK_CLOEXEC": (None, (3, 2)),
"socket.SOCK_NONBLOCK": (None, (3, 2)),
"socket.SOL_ALG": (None, (3, 6)),
"socket.SOL_BLUETOOTH": (None, (3, 14)),
"socket.SOL_CAN_BASE": (None, (3, 3)),
"socket.SOL_CAN_RAW": (None, (3, 3)),
"socket.SOL_HCI": (None, (3, 14)),
"socket.SOL_L2CAP": (None, (3, 14)),
"socket.SOL_RDS": (None, (3, 3)),
"socket.SOL_RFCOMM": (None, (3, 14)),
"socket.SOL_SCO": (None, (3, 14)),
"socket.SOL_TIPC": ((2, 6), (3, 0)),
"socket.SO_DOMAIN": (None, (3, 6)),
"socket.SO_HCI_EVT_FILTER": (None, (3, 14)),
"socket.SO_HCI_PKT_FILTER": (None, (3, 14)),
"socket.SO_INCOMING_CPU": (None, (3, 11)),
"socket.SO_PASSSEC": (None, (3, 6)),
"socket.SO_PEERSEC": (None, (3, 6)),
"socket.SO_PROTOCOL": (None, (3, 6)),
"socket.SO_REUSEPORT_LB": (None, (3, 14)),
"socket.SO_VM_SOCKETS_BUFFER_MAX_SIZE": (None, (3, 7)),
"socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE": (None, (3, 7)),
"socket.SO_VM_SOCKETS_BUFFER_SIZE": (None, (3, 7)),
"socket.TCP_CONGESTION": (None, (3, 6)),
"socket.TCP_CONNECTION_INFO": (None, (3, 11)),
"socket.TCP_KEEPALIVE": (None, (3, 10)),
"socket.TCP_NOTSENT_LOWAT": (None, (3, 7)),
"socket.TCP_USER_TIMEOUT": (None, (3, 6)),
"socket.TIPC_ADDR_ID": ((2, 6), (3, 0)),
"socket.TIPC_ADDR_NAME": ((2, 6), (3, 0)),
"socket.TIPC_ADDR_NAMESEQ": ((2, 6), (3, 0)),
"socket.TIPC_CFG_SRV": ((2, 6), (3, 0)),
"socket.TIPC_CLUSTER_SCOPE": ((2, 6), (3, 0)),
"socket.TIPC_CONN_TIMEOUT": ((2, 6), (3, 0)),
"socket.TIPC_CRITICAL_IMPORTANCE": ((2, 6), (3, 0)),
"socket.TIPC_DEST_DROPPABLE": ((2, 6), (3, 0)),
"socket.TIPC_HIGH_IMPORTANCE": ((2, 6), (3, 0)),
"socket.TIPC_IMPORTANCE": ((2, 6), (3, 0)),
"socket.TIPC_LOW_IMPORTANCE": ((2, 6), (3, 0)),
"socket.TIPC_MEDIUM_IMPORTANCE": ((2, 6), (3, 0)),
"socket.TIPC_NODE_SCOPE": ((2, 6), (3, 0)),
"socket.TIPC_PUBLISHED": ((2, 6), (3, 0)),
"socket.TIPC_SRC_DROPPABLE": ((2, 6), (3, 0)),
"socket.TIPC_SUBSCR_TIMEOUT": ((2, 6), (3, 0)),
"socket.TIPC_SUB_CANCEL": ((2, 6), (3, 0)),
"socket.TIPC_SUB_PORTS": ((2, 6), (3, 0)),
"socket.TIPC_SUB_SERVICE": ((2, 6), (3, 0)),
"socket.TIPC_TOP_SRV": ((2, 6), (3, 0)),
"socket.TIPC_WAIT_FOREVER": ((2, 6), (3, 0)),
"socket.TIPC_WITHDRAWN": ((2, 6), (3, 0)),
"socket.TIPC_ZONE_SCOPE": ((2, 6), (3, 0)),
"socket.VMADDR_CID_ANY": (None, (3, 7)),
"socket.VMADDR_CID_HOST": (None, (3, 7)),
"socket.VMADDR_PORT_ANY": (None, (3, 7)),
"socket.has_ipv6": ((2, 3), (3, 0)),
"socket.socket.family": ((2, 5), (3, 0)),
"socket.socket.proto": ((2, 5), (3, 0)),
"socket.socket.type": ((2, 5), (3, 0)),
"socketserver.ForkingMixIn.block_on_close": (None, (3, 7)),
"socketserver.ThreadingMixIn.block_on_close": (None, (3, 7)),
"sqlite3.Connection.autocommit": (None, (3, 12)),
"sqlite3.Error.sqlite_errorcode": (None, (3, 11)),
"sqlite3.Error.sqlite_errorname": (None, (3, 11)),
"sqlite3.SQLITE_DBCONFIG_DEFENSIVE": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_DQS_DDL": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_DQS_DML": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_FKEY": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_QPSG": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_TRIGGER": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_ENABLE_VIEW": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_RESET_DATABASE": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_TRIGGER_EQP": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_TRUSTED_SCHEMA": (None, (3, 12)),
"sqlite3.SQLITE_DBCONFIG_WRITABLE_SCHEMA": (None, (3, 12)),
"ssl.ALERT_DESCRIPTION_ACCESS_DENIED": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_BAD_CERTIFICATE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_BAD_RECORD_MAC": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_CERTIFICATE_EXPIRED": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_CERTIFICATE_REVOKED": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_CLOSE_NOTIFY": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_DECODE_ERROR": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_DECOMPRESSION_FAILURE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_DECRYPT_ERROR": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_HANDSHAKE_FAILURE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_ILLEGAL_PARAMETER": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_INSUFFICIENT_SECURITY": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_INTERNAL_ERROR": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_NO_RENEGOTIATION": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_PROTOCOL_VERSION": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_RECORD_OVERFLOW": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNEXPECTED_MESSAGE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNKNOWN_CA": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNRECOGNIZED_NAME": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION": ((2, 7), (3, 4)),
"ssl.ALERT_DESCRIPTION_USER_CANCELLED": ((2, 7), (3, 4)),
"ssl.CHANNEL_BINDING_TYPES": ((2, 7), (3, 3)),
"ssl.HAS_ALPN": ((2, 7), (3, 5)),
"ssl.HAS_ECDH": ((2, 7), (3, 3)),
"ssl.HAS_NEVER_CHECK_COMMON_NAME": (None, (3, 7)),
"ssl.HAS_NPN": ((2, 7), (3, 3)),
"ssl.HAS_PHA": (None, (3, 14)),
"ssl.HAS_PSK": (None, (3, 13)),
"ssl.HAS_PSK_TLS13": (None, (3, 15)),
"ssl.HAS_SNI": ((2, 7), (3, 2)),
"ssl.HAS_SSLv2": (None, (3, 7)),
"ssl.HAS_SSLv3": (None, (3, 7)),
"ssl.HAS_TLSv1": (None, (3, 7)),
"ssl.HAS_TLSv1_1": (None, (3, 7)),
"ssl.HAS_TLSv1_2": (None, (3, 7)),
"ssl.HAS_TLSv1_3": ((2, 7), (3, 7)),
"ssl.OPENSSL_VERSION": ((2, 7), (3, 2)),
"ssl.OPENSSL_VERSION_INFO": ((2, 7), (3, 2)),
"ssl.OPENSSL_VERSION_NUMBER": ((2, 7), (3, 2)),
"ssl.OP_ALL": ((2, 7), (3, 2)),
"ssl.OP_CIPHER_SERVER_PREFERENCE": ((2, 7), (3, 3)),
"ssl.OP_ENABLE_MIDDLEBOX_COMPAT": ((2, 7), (3, 8)),
"ssl.OP_IGNORE_UNEXPECTED_EOF": (None, (3, 10)),
"ssl.OP_NO_COMPRESSION": ((2, 7), (3, 3)),
"ssl.OP_NO_RENEGOTIATION": (None, (3, 7)),
"ssl.OP_NO_SSLv2": ((2, 7), (3, 2)),
"ssl.OP_NO_SSLv3": ((2, 7), (3, 2)),
"ssl.OP_NO_TICKET": (None, (3, 6)),
"ssl.OP_NO_TLSv1": ((2, 7), (3, 2)),
"ssl.OP_NO_TLSv1_1": ((2, 7), (3, 4)),
"ssl.OP_NO_TLSv1_2": ((2, 7), (3, 4)),
"ssl.OP_NO_TLSv1_3": ((2, 7), (3, 7)),
"ssl.OP_SINGLE_DH_USE": ((2, 7), (3, 3)),
"ssl.OP_SINGLE_ECDH_USE": ((2, 7), (3, 3)),
"ssl.PROTOCOL_TLS": ((2, 7), (3, 6)),
"ssl.PROTOCOL_TLS_CLIENT": (None, (3, 6)),
"ssl.PROTOCOL_TLS_SERVER": (None, (3, 6)),
"ssl.PROTOCOL_TLSv1_1": ((2, 7), (3, 4)),
"ssl.PROTOCOL_TLSv1_2": ((2, 7), (3, 4)),
"ssl.Purpose.CLIENT_AUTH": ((2, 7), (3, 4)),
"ssl.Purpose.SERVER_AUTH": ((2, 7), (3, 4)),
"ssl.SSLContext.check_hostname": (None, (3, 4)),
"ssl.SSLContext.hostname_checks_common_name": (None, (3, 7)),
"ssl.SSLContext.keylog_filename": (None, (3, 8)),
"ssl.SSLContext.maximum_version": (None, (3, 7)),
"ssl.SSLContext.minimum_version": (None, (3, 7)),
"ssl.SSLContext.num_tickets": (None, (3, 8)),
"ssl.SSLContext.post_handshake_auth": (None, (3, 8)),
"ssl.SSLContext.security_level": (None, (3, 10)),
"ssl.SSLContext.sni_callback": (None, (3, 7)),
"ssl.SSLContext.sslobject_class": (None, (3, 7)),
"ssl.SSLContext.sslsocket_class": (None, (3, 7)),
"ssl.SSLContext.verify_flags": (None, (3, 4)),
"ssl.SSLError.library": ((2, 7), (3, 3)),
"ssl.SSLError.reason": ((2, 7), (3, 3)),
"ssl.SSLSocket.context": ((2, 7), (3, 2)),
"ssl.SSLSocket.server_hostname": (None, (3, 2)),
"ssl.SSLSocket.server_side": (None, (3, 2)),
"ssl.SSLSocket.session": (None, (3, 6)),
"ssl.SSLSocket.session_reused": (None, (3, 6)),
"ssl.VERIFY_ALLOW_PROXY_CERTS": (None, (3, 10)),
"ssl.VERIFY_CRL_CHECK_CHAIN": ((2, 7), (3, 4)),
"ssl.VERIFY_CRL_CHECK_LEAF": ((2, 7), (3, 4)),
"ssl.VERIFY_DEFAULT": ((2, 7), (3, 4)),
"ssl.VERIFY_X509_PARTIAL_CHAIN": (None, (3, 10)),
"ssl.VERIFY_X509_STRICT": ((2, 7), (3, 4)),
"ssl.VERIFY_X509_TRUSTED_FIRST": ((2, 7), (3, 4)),
"stat.FILE_ATTRIBUTE_ARCHIVE": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_COMPRESSED": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_DEVICE": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_DIRECTORY": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_ENCRYPTED": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_HIDDEN": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_INTEGRITY_STREAM": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_NORMAL": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_NO_SCRUB_DATA": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_OFFLINE": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_READONLY": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_REPARSE_POINT": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_SPARSE_FILE": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_SYSTEM": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_TEMPORARY": (None, (3, 5)),
"stat.FILE_ATTRIBUTE_VIRTUAL": (None, (3, 5)),
"stat.IO_REPARSE_TAG_APPEXECLINK": (None, (3, 8)),
"stat.IO_REPARSE_TAG_MOUNT_POINT": (None, (3, 8)),
"stat.IO_REPARSE_TAG_SYMLINK": (None, (3, 8)),
"stat.S_IFDOOR": (None, (3, 4)),
"stat.S_IFPORT": (None, (3, 4)),
"stat.S_IFWHT": (None, (3, 4)),
"staticmethod.__wrapped__": (None, (3, 10)),
"string.Template.braceidpattern": (None, (3, 7)),
"string.Template.flags": (None, (3, 2)),
"string.letters": ((2, 0), None),
"string.lowercase": ((2, 0), None),
"string.uppercase": ((2, 0), None),
"subprocess.ABOVE_NORMAL_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.BELOW_NORMAL_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.CREATE_BREAKAWAY_FROM_JOB": (None, (3, 7)),
"subprocess.CREATE_DEFAULT_ERROR_MODE": (None, (3, 7)),
"subprocess.CREATE_NO_WINDOW": (None, (3, 7)),
"subprocess.CalledProcessError.stderr": (None, (3, 5)),
"subprocess.CalledProcessError.stdout": (None, (3, 5)),
"subprocess.DETACHED_PROCESS": (None, (3, 7)),
"subprocess.DEVNULL": (None, (3, 3)),
"subprocess.HIGH_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.IDLE_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.NORMAL_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.Popen.args": (None, (3, 3)),
"subprocess.REALTIME_PRIORITY_CLASS": (None, (3, 7)),
"subprocess.STARTF_FORCEOFFFEEDBACK": (None, (3, 13)),
"subprocess.STARTF_FORCEONFEEDBACK": (None, (3, 13)),
"subprocess.STARTUPINFO.lpAttributeList": (None, (3, 7)),
"subprocess.TimeoutExpired.stderr": (None, (3, 5)),
"subprocess.TimeoutExpired.stdout": (None, (3, 5)),
"sys.__breakpointhook__": (None, (3, 7)),
"sys.__interactivehook__": (None, (3, 4)),
"sys.__unraisablehook__": (None, (3, 8)),
"sys._emscripten_info": (None, (3, 11)),
"sys._jit": (None, (3, 14)),
"sys._xoptions": (None, (3, 2)),
"sys.abiflags": (None, (3, 2)),
"sys.activate_stack_trampoline": (None, (3, 12)),
"sys.api_version": ((2, 3), (3, 0)),
"sys.base_exec_prefix": (None, (3, 3)),
"sys.base_prefix": (None, (3, 3)),
"sys.deactivate_stack_trampoline": (None, (3, 12)),
"sys.dont_write_bytecode": ((2, 6), (3, 0)),
"sys.flags": ((2, 6), (3, 0)),
"sys.flags.context_aware_warnings": (None, (3, 14)),
"sys.flags.dev_mode": (None, (3, 7)),
"sys.flags.gil": (None, (3, 13)),
"sys.flags.hash_randomization": ((2, 7), (3, 2)),
"sys.flags.int_max_str_digits": (None, (3, 11)),
"sys.flags.isolated": (None, (3, 4)),
"sys.flags.quiet": (None, (3, 2)),
"sys.flags.safe_path": (None, (3, 11)),
"sys.flags.thread_inherit_context": (None, (3, 14)),
"sys.flags.utf8_mode": (None, (3, 7)),
"sys.flags.warn_default_encoding": (None, (3, 10)),
"sys.float_info": ((2, 6), (3, 0)),
"sys.float_repr_style": ((2, 7), (3, 1)),
"sys.getunicodeinternedsize": (None, (3, 12)),
"sys.getwindowsversion.build": ((2, 7), (3, 0)),
"sys.getwindowsversion.major": ((2, 7), (3, 0)),
"sys.getwindowsversion.minor": ((2, 7), (3, 0)),
"sys.getwindowsversion.platform": ((2, 7), (3, 0)),
"sys.getwindowsversion.product_type": ((2, 7), (3, 0)),
"sys.getwindowsversion.service_pack": ((2, 7), (3, 0)),
"sys.getwindowsversion.service_pack_major": ((2, 7), (3, 0)),
"sys.getwindowsversion.service_pack_minor": ((2, 7), (3, 0)),
"sys.getwindowsversion.suite_mask": ((2, 7), (3, 0)),
"sys.hash_info": (None, (3, 2)),
"sys.hash_info.algorithm": (None, (3, 4)),
"sys.hash_info.hash_bits": (None, (3, 4)),
"sys.hash_info.seed_bits": (None, (3, 4)),
"sys.implementation": (None, (3, 3)),
"sys.int_info": (None, (3, 1)),
"sys.is_stack_trampoline_active": (None, (3, 12)),
"sys.last_exc": (None, (3, 12)),
"sys.long_info": ((2, 7), None),
"sys.monitoring": (None, (3, 12)),
"sys.orig_argv": (None, (3, 10)),
"sys.platlibdir": (None, (3, 9)),
"sys.py3kwarning": ((2, 6), None),
"sys.pycache_prefix": (None, (3, 8)),
"sys.stdlib_module_names": (None, (3, 10)),
"sys.subversion": ((2, 5), (3, 0)),
"sys.thread_info": (None, (3, 3)),
"sys.version_info": ((2, 0), (3, 0)),
"sys.version_info.major": ((2, 7), (3, 0)),
"sys.version_info.micro": ((2, 7), (3, 0)),
"sys.version_info.minor": ((2, 7), (3, 0)),
"sys.version_info.releaselevel": ((2, 7), (3, 0)),
"tarfile.DEFAULT_FORMAT": ((2, 6), (3, 0)),
"tarfile.GNU_FORMAT": ((2, 6), (3, 0)),
"tarfile.PAX_FORMAT": ((2, 6), (3, 0)),
"tarfile.TarFile.extraction_filter": (None, (3, 12)),
"tarfile.TarFile.pax_headers": ((2, 6), (3, 0)),
"tarfile.TarInfo.pax_headers": ((2, 6), (3, 0)),
"tarfile.USTAR_FORMAT": ((2, 6), (3, 0)),
"textwrap.TextWrapper.break_on_hyphens": ((2, 6), (3, 0)),
"textwrap.TextWrapper.drop_whitespace": ((2, 6), (3, 0)),
"textwrap.TextWrapper.max_lines": (None, (3, 4)),
"textwrap.TextWrapper.placeholder": (None, (3, 4)),
"textwrap.TextWrapper.tabsize": (None, (3, 3)),
"threading.TIMEOUT_MAX": (None, (3, 2)),
"threading.Thread.daemon": ((2, 6), (3, 0)),
"threading.Thread.ident": ((2, 6), (3, 0)),
"threading.Thread.name": ((2, 6), (3, 0)),
"threading.Thread.native_id": (None, (3, 8)),
"threading.__excepthook__": (None, (3, 10)),
"time.CLOCK_BOOTTIME": (None, (3, 7)),
"time.CLOCK_HIGHRES": (None, (3, 3)),
"time.CLOCK_MONOTONIC": (None, (3, 3)),
"time.CLOCK_MONOTONIC_RAW": (None, (3, 3)),
"time.CLOCK_MONOTONIC_RAW_APPROX": (None, (3, 13)),
"time.CLOCK_PROCESS_CPUTIME_ID": (None, (3, 3)),
"time.CLOCK_PROF": (None, (3, 7)),
"time.CLOCK_REALTIME": (None, (3, 3)),
"time.CLOCK_TAI": (None, (3, 9)),
"time.CLOCK_THREAD_CPUTIME_ID": (None, (3, 3)),
"time.CLOCK_UPTIME": (None, (3, 7)),
"time.CLOCK_UPTIME_RAW": (None, (3, 8)),
"time.CLOCK_UPTIME_RAW_APPROX": (None, (3, 13)),
"time.struct_time.tm_gmtoff": (None, (3, 3)),
"time.struct_time.tm_zone": (None, (3, 3)),
"token.ASYNC": (None, (3, 5)),
"token.AWAIT": (None, (3, 5)),
"token.COLONEQUAL": (None, (3, 8)),
"token.COMMENT": (None, (3, 7)),
"token.ENCODING": (None, (3, 7)),
"token.NL": (None, (3, 7)),
"token.TYPE_COMMENT": (None, (3, 8)),
"token.TYPE_IGNORE": (None, (3, 8)),
"traceback.TracebackException.__notes__": (None, (3, 11)),
"traceback.TracebackException.exc_type_str": (None, (3, 13)),
"tracemalloc.Filter.domain": (None, (3, 6)),
"tracemalloc.Trace.domain": (None, (3, 6)),
"tracemalloc.Traceback.total_nframe": (None, (3, 9)),
"types.AsyncGeneratorType": (None, (3, 6)),
"types.BooleanType": ((2, 3), None),
"types.CellType": (None, (3, 8)),
"types.ClassMethodDescriptorType": (None, (3, 7)),
"types.CoroutineType": (None, (3, 5)),
"types.EllipsisType": ((2, 0), (3, 10)),
"types.GeneratorType": ((2, 2), (3, 0)),
"types.GetSetDescriptorType": ((2, 5), (3, 0)),
"types.MemberDescriptorType": ((2, 5), (3, 0)),
"types.MethodDescriptorType": (None, (3, 7)),
"types.MethodWrapperType": (None, (3, 7)),
"types.ModuleType.__spec__": (None, (3, 4)),
"types.NoneType": ((2, 0), (3, 10)),
"types.NotImplementedType": ((2, 5), (3, 10)),
"types.StringTypes": ((2, 2), None),
"types.UnionType": (None, (3, 10)),
"types.WrapperDescriptorType": (None, (3, 7)),
"typing.Annotated": (None, (3, 9)),
"typing.Concatenate": (None, (3, 10)),
# Notes: `typing.NoReturn` was added in `typing` backport 3.6.2 (which requires 2.7 or 3.3+).
"typing.NoReturn": (None, (3, 5)) if not bp("typing", config) else ((2, 7), (3, 3)),
"typing.Final": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"typing.Literal": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"typing.ParamSpecArgs": (None, (3, 10)),
"typing.ParamSpecKwargs": (None, (3, 10)),
"typing.LiteralString": (None, (3, 11)),
"typing.Never": (None, (3, 11)),
"typing.NotRequired": (None, (3, 11)),
"typing.Required": (None, (3, 11)),
"typing.Self": (None, (3, 11)),
"typing.TypeAlias": (None, (3, 10)),
"typing.TypeGuard": (None, (3, 10)),
"typing.TypeVarTuple": (None, (3, 11)),
"typing.Unpack": (None, (3, 11)),
"unicodedata.ucd_3_2_0": ((2, 5), (3, 0)),
"unicodedata.unidata_version": ((2, 3), (3, 0)),
"unittest.TestCase.longMessage": ((2, 7), (3, 1)),
"unittest.TestCase.maxDiff": ((2, 7), (3, 2)),
"unittest.TestLoader.errors": (None, (3, 5)),
"unittest.TestLoader.testNamePatterns": (None, (3, 7)),
"unittest.TestResult.buffer": ((2, 7), (3, 2)),
"unittest.TestResult.failfast": ((2, 7), (3, 2)),
"unittest.TestResult.skipped": ((2, 7), (3, 1)),
"unittest.TestResult.tb_locals": (None, (3, 5)),
"unittest.mock.Mock.call_args.args": bpv("mock", (None, (3, 8)), config),
"unittest.mock.Mock.call_args.kwargs": bpv("mock", (None, (3, 8)), config),
"urllib.error.HTTPError.headers": (None, (3, 4)),
"urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE": (None, (3, 10)),
"urllib.request.Request.method": (None, (3, 3)),
"urllib.response.addinfourl.status": (None, (3, 9)),
"urlparse.urlparse.fragment": ((2, 5), None),
"urlparse.urlparse.hostname": ((2, 5), None),
"urlparse.urlparse.netloc": ((2, 5), None),
"urlparse.urlparse.params": ((2, 5), None),
"urlparse.urlparse.password": ((2, 5), None),
"urlparse.urlparse.path": ((2, 5), None),
"urlparse.urlparse.port": ((2, 5), None),
"urlparse.urlparse.query": ((2, 5), None),
"urlparse.urlparse.scheme": ((2, 5), None),
"urlparse.urlparse.username": ((2, 5), None),
"urlparse.urlsplit.fragment": ((2, 5), None),
"urlparse.urlsplit.hostname": ((2, 5), None),
"urlparse.urlsplit.netloc": ((2, 5), None),
"urlparse.urlsplit.password": ((2, 5), None),
"urlparse.urlsplit.path": ((2, 5), None),
"urlparse.urlsplit.port": ((2, 5), None),
"urlparse.urlsplit.query": ((2, 5), None),
"urlparse.urlsplit.scheme": ((2, 5), None),
"urlparse.urlsplit.username": ((2, 5), None),
"uuid.MAX": (None, (3, 14)),
"uuid.NIL": (None, (3, 14)),
"uuid.UUID.is_safe": (None, (3, 7)),
"weakref.ref.__callback__": (None, (3, 4)),
"winreg.REG_QWORD": (None, (3, 6)),
"winreg.REG_QWORD_LITTLE_ENDIAN": (None, (3, 6)),
"xml.dom.DOMSTRING_SIZE_ERR": ((2, 1), (3, 0)),
"xml.dom.EMPTY_NAMESPACE": ((2, 2), (3, 0)),
"xml.dom.HIERARCHY_REQUEST_ERR": ((2, 1), (3, 0)),
"xml.dom.INDEX_SIZE_ERR": ((2, 1), (3, 0)),
"xml.dom.INUSE_ATTRIBUTE_ERR": ((2, 1), (3, 0)),
"xml.dom.INVALID_ACCESS_ERR": ((2, 1), (3, 0)),
"xml.dom.INVALID_CHARACTER_ERR": ((2, 1), (3, 0)),
"xml.dom.INVALID_MODIFICATION_ERR": ((2, 1), (3, 0)),
"xml.dom.INVALID_STATE_ERR": ((2, 1), (3, 0)),
"xml.dom.NAMESPACE_ERR": ((2, 1), (3, 0)),
"xml.dom.NOT_FOUND_ERR": ((2, 1), (3, 0)),
"xml.dom.NOT_SUPPORTED_ERR": ((2, 1), (3, 0)),
"xml.dom.NO_DATA_ALLOWED_ERR": ((2, 1), (3, 0)),
"xml.dom.NO_MODIFICATION_ALLOWED_ERR": ((2, 1), (3, 0)),
"xml.dom.SYNTAX_ERR": ((2, 1), (3, 0)),
"xml.dom.WRONG_DOCUMENT_ERR": ((2, 1), (3, 0)),
"xml.dom.XHTML_NAMESPACE": ((2, 2), (3, 0)),
"xml.dom.XMLNS_NAMESPACE": ((2, 2), (3, 0)),
"xml.dom.XML_NAMESPACE": ((2, 2), (3, 0)),
"xml.parsers.expat.ExpatError.code": ((2, 1), (3, 0)),
"xml.parsers.expat.ExpatError.lineno": ((2, 1), (3, 0)),
"xml.parsers.expat.ExpatError.offset": ((2, 1), (3, 0)),
"xml.parsers.expat.SetAllocTrackerActivationThreshold": (None, (3, 15)),
"xml.parsers.expat.SetAllocTrackerMaximumAmplification": (None, (3, 15)),
"xml.parsers.expat.XMLParserType.CurrentByteIndex": ((2, 4), (3, 0)),
"xml.parsers.expat.XMLParserType.CurrentColumnNumber": ((2, 4), (3, 0)),
"xml.parsers.expat.XMLParserType.CurrentLineNumber": ((2, 4), (3, 0)),
"xml.parsers.expat.XMLParserType.buffer_size": ((2, 3), (3, 0)),
"xml.parsers.expat.XMLParserType.buffer_text": ((2, 3), (3, 0)),
"xml.parsers.expat.XMLParserType.buffer_used": ((2, 3), (3, 0)),
"xml.parsers.expat.XMLParserType.ordered_attributes": ((2, 1), (3, 0)),
"xml.parsers.expat.XMLParserType.returns_unicode": ((2, 0), None),
"xml.parsers.expat.XMLParserType.specified_attributes": ((2, 1), (3, 0)),
"xml.parsers.expat.errors.codes": (None, (3, 2)),
"xml.parsers.expat.errors.messages": (None, (3, 2)),
"xmlrpc.server.SimpleXMLRPCRequestHandler.rpc_paths": (None, (3, 0)),
"zipfile.Path.stem": (None, (3, 11)),
"zipfile.Path.suffix": (None, (3, 11)),
"zipfile.Path.suffixes": (None, (3, 11)),
"zipfile.ZIP_BZIP2": (None, (3, 3)),
"zipfile.ZIP_LZMA": (None, (3, 3)),
"zipfile.ZIP_ZSTANDARD": (None, (3, 14)),
"zlib.Decompress.eof": (None, (3, 3)),
"zlib.ZLIB_RUNTIME_VERSION": (None, (3, 3)),
# Decorators
"abc.abstractclassmethod": (None, (3, 2)),
"abc.abstractstaticmethod": (None, (3, 2)),
"contextlib.asynccontextmanager": (None, (3, 7)),
"enum.global_enum": (None, (3, 11)),
"enum.member": (None, (3, 11)),
"enum.nonmember": (None, (3, 11)),
"enum.property": (None, (3, 11)),
"enum.verify": (None, (3, 11)),
"functools.cache": (None, (3, 9)),
"functools.cached_property": (None, (3, 8)),
"functools.lru_cache": (None, (3, 2)),
"functools.singledispatch": (None, (3, 4)),
"functools.singledispatchmethod": (None, (3, 8)),
"functools.total_ordering": ((2, 7), (3, 2)),
"reprlib.recursive_repr": (None, (3, 2)),
"typing.dataclass_transform": (None, (3, 11)),
"typing.disjoint_base": (None, (3, 15)),
"typing.final": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"typing.override": (None, (3, 12)),
"typing.runtime_checkable": (None, (3, 8)) if not bp("typing", config) else ((2, 7), (3, 8)),
"unittest.expectedFailure": ((2, 7), (3, 1)),
"unittest.skip": ((2, 7), (3, 1)),
"unittest.skipIf": ((2, 7), (3, 1)),
"unittest.skipUnless": ((2, 7), (3, 1)),
"warnings.deprecated": (None, (3, 13)),
}
# Keyword arguments requirements: (function, keyword argument) -> (requirements)
# Notes:
# `bytes.decode(encoding, errors)` and `bytearray.decode(encoding, errors)`
# are documented to be in 3.1 but they do not actually work, they work on 3.2+
def KWARGS_REQS(config):
return {
("BaseHTTPServer.BaseHTTPRequestHandler.date_time_string", "timestamp"): ((2, 5), None),
("ConfigParser.ConfigParser", "allow_no_value"): ((2, 6), None),
("ConfigParser.ConfigParser", "dict_type"): ((2, 6), None),
("ConfigParser.RawConfigParser", "allow_no_value"): ((2, 6), None),
("ConfigParser.RawConfigParser", "dict_type"): ((2, 6), None),
("ConfigParser.SafeConfigParser", "allow_no_value"): ((2, 6), None),
("ConfigParser.SafeConfigParser", "dict_type"): ((2, 6), None),
("ImportError", "name"): (None, (3, 3)),
("ImportError", "path"): (None, (3, 3)),
("OSError", "filename2"): (None, (3, 4)),
("Queue.Queue.get", "timeout"): ((2, 3), None),
("Queue.Queue.put", "timeout"): ((2, 3), None),
("SimpleXMLRPCServer.CGIXMLRPCRequestHandler", "allow_none"): ((2, 5), None),
("SimpleXMLRPCServer.CGIXMLRPCRequestHandler", "encoding"): ((2, 5), None),
("SimpleXMLRPCServer.SimpleXMLRPCServer", "allow_none"): ((2, 5), None),
("SimpleXMLRPCServer.SimpleXMLRPCServer", "bind_and_activate"): ((2, 6), None),
("SimpleXMLRPCServer.SimpleXMLRPCServer", "encoding"): ((2, 5), None),
("SimpleXMLRPCServer.SimpleXMLRPCServer.register_instance", "allow_dotted_names"):
((2, 3), None),
("Tkinter.Tk", "useTk"): ((2, 4), None),
("__import__", "level"): ((2, 5), (3, 0)),
("_thread.lock.acquire", "timeout"): (None, (3, 2)),
("argparse.ArgumentParser", "allow_abbrev"): (None, (3, 5)),
("argparse.ArgumentParser", "color"): (None, (3, 14)),
("argparse.ArgumentParser", "exit_on_error"): (None, (3, 9)),
("argparse.ArgumentParser", "suggest_on_error"): (None, (3, 14)),
("argparse.ArgumentParser.add_argument", "deprecated"): (None, (3, 13)),
("argparse.ArgumentParser.add_parser", "deprecated"): (None, (3, 13)),
("argparse.ArgumentParser.add_subparsers", "required"): (None, (3, 7)),
("argparse.FileType", "encoding"): (None, (3, 4)),
("argparse.FileType", "errors"): (None, (3, 4)),
("ast.dump", "color"): (None, (3, 15)),
("ast.dump", "indent"): (None, (3, 9)),
("ast.dump", "show_empty"): (None, (3, 13)),
("ast.parse", "feature_version"): (None, (3, 8)),
("ast.parse", "module"): (None, (3, 15)),
("ast.parse", "type_comments"): (None, (3, 8)),
("ast.parse", "optimize"): (None, (3, 13)),
("asyncio.Future.add_done_callback", "context"): (None, (3, 7)),
("asyncio.Future.cancel", "msg"): (None, (3, 9)),
("asyncio.Task", "context"): (None, (3, 11)),
("asyncio.Task", "eager_start"): (None, (3, 12)),
("asyncio.Task", "name"): (None, (3, 8)),
("asyncio.Task.cancel", "msg"): (None, (3, 9)),
("asyncio.create_task", "context"): (None, (3, 11)),
("asyncio.create_task", "eager_start"): (None, (3, 14)),
("asyncio.create_task", "name"): (None, (3, 8)),
("asyncio.loop.call_at", "context"): (None, (3, 7)),
("asyncio.loop.call_later", "context"): (None, (3, 7)),
("asyncio.loop.call_soon", "context"): (None, (3, 7)),
("asyncio.loop.call_soon_threadsafe", "context"): (None, (3, 7)),
("asyncio.loop.connect_accepted_socket", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.loop.connect_accepted_socket", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.loop.create_connection", "happy_eyeballs_delay"): (None, (3, 8)),
("asyncio.loop.create_connection", "interleave"): (None, (3, 8)),
("asyncio.loop.create_connection", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.loop.create_connection", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.loop.create_datagram_endpoint", "allow_broadcast"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "family"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "flags"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "proto"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "reuse_address"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "reuse_port"): (None, (3, 4)),
("asyncio.loop.create_datagram_endpoint", "sock"): (None, (3, 4)),
("asyncio.loop.create_server", "ssl_handshake_timeout"): (None, (3, 6)),
("asyncio.loop.create_server", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.loop.create_server", "start_serving"): (None, (3, 6)),
("asyncio.loop.create_task", "context"): (None, (3, 11)),
("asyncio.loop.create_task", "name"): (None, (3, 8)),
("asyncio.loop.create_unix_connection", "path"): (None, (3, 7)),
("asyncio.loop.create_unix_connection", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.loop.create_unix_connection", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.loop.create_unix_server", "path"): (None, (3, 7)),
("asyncio.loop.create_unix_server", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.loop.create_unix_server", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.loop.create_unix_server", "start_serving"): (None, (3, 7)),
("asyncio.loop.start_tls", "ssl_shutdown_timeout"): (None, (3, 11)),
("asyncio.open_connection", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.open_unix_connection", "path"): (None, (3, 7)),
("asyncio.open_unix_connection", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.run", "loop_factory"): (None, (3, 12)),
("asyncio.start_server", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.start_server", "start_serving"): (None, (3, 7)),
("asyncio.start_unix_server", "path"): (None, (3, 7)),
("asyncio.start_unix_server", "ssl_handshake_timeout"): (None, (3, 7)),
("asyncio.start_unix_server", "start_serving"): (None, (3, 7)),
("base64.a85decode", "canonical"): (None, (3, 15)),
("base64.b16decode", "ignorechars"): (None, (3, 15)),
("base64.b16encode", "wrapcol"): (None, (3, 15)),
("base64.b32decode", "canonical"): (None, (3, 15)),
("base64.b32decode", "ignorechars"): (None, (3, 15)),
("base64.b32decode", "padded"): (None, (3, 15)),
("base64.b32encode", "padded"): (None, (3, 15)),
("base64.b32encode", "wrapcol"): (None, (3, 15)),
("base64.b32hexdecode", "canonical"): (None, (3, 15)),
("base64.b32hexdecode", "ignorechars"): (None, (3, 15)),
("base64.b32hexdecode", "padded"): (None, (3, 15)),
("base64.b32hexencode", "padded"): (None, (3, 15)),
("base64.b32hexencode", "wrapcol"): (None, (3, 15)),
("base64.b64decode", "canonical"): (None, (3, 15)),
("base64.b64decode", "ignorechars"): (None, (3, 15)),
("base64.b64decode", "padded"): (None, (3, 15)),
("base64.b64encode", "padded"): (None, (3, 15)),
("base64.b64encode", "wrapcol"): (None, (3, 15)),
("base64.b85decode", "canonical"): (None, (3, 15)),
("base64.b85decode", "ignorechars"): (None, (3, 15)),
("base64.b85encode", "wrapcol"): (None, (3, 15)),
("base64.urlsafe_b64decode", "padded"): (None, (3, 15)),
("base64.urlsafe_b64encode", "padded"): (None, (3, 15)),
("base64.z85decode", "canonical"): (None, (3, 15)),
("base64.z85decode", "ignorechars"): (None, (3, 15)),
("base64.z85encode", "pad"): (None, (3, 15)),
("base64.z85encode", "wrapcol"): (None, (3, 15)),
("bdb.Bdb", "skip"): ((2, 7), (3, 1)),
("binascii.a2b_base32", "padded"): (None, (3, 15)),
("binascii.a2b_base64", "alphabet"): (None, (3, 15)),
("binascii.a2b_base64", "canonical"): (None, (3, 15)),
("binascii.a2b_base64", "ignorechars"): (None, (3, 15)),
("binascii.a2b_base64", "padded"): (None, (3, 15)),
("binascii.a2b_base64", "strict_mode"): (None, (3, 11)),
("binascii.a2b_hex", "ignorechars"): (None, (3, 15)),
("binascii.b2a_base32", "padded"): (None, (3, 15)),
("binascii.b2a_base64", "alphabet"): (None, (3, 15)),
("binascii.b2a_base64", "newline"): (None, (3, 6)),
("binascii.b2a_base64", "padded"): (None, (3, 15)),
("binascii.b2a_base64", "wrapcol"): (None, (3, 15)),
("binascii.b2a_hex", "bytes_per_sep"): (None, (3, 8)),
("binascii.b2a_hex", "sep"): (None, (3, 8)),
("binascii.b2a_uu", "backtick"): (None, (3, 7)),
("binascii.hexlify", "bytes_per_sep"): (None, (3, 8)),
("binascii.hexlify", "sep"): (None, (3, 8)),
("binascii.unhexlify", "ignorechars"): (None, (3, 15)),
("bisect.bisect", "key"): (None, (3, 10)),
("bisect.bisect_left", "key"): (None, (3, 10)),
("bisect.bisect_right", "key"): (None, (3, 10)),
("bisect.insort", "key"): (None, (3, 10)),
("bisect.insort_left", "key"): (None, (3, 10)),
("bisect.insort_right", "key"): (None, (3, 10)),
("bytearray.decode", "encoding"): (None, (3, 2)),
("bytearray.decode", "errors"): (None, (3, 2)),
("bytearray.hex", "bytes_per_sep"): (None, (3, 8)),
("bytearray.hex", "sep"): (None, (3, 8)),
("bytearray.translate", "delete"): (None, (3, 6)),
("bytes.decode", "encoding"): (None, (3, 2)),
("bytes.decode", "errors"): (None, (3, 2)),
("bytes.replace", "count"): (None, (3, 15)),
("bytearray.replace", "count"): (None, (3, 15)),
("bytes.hex", "bytes_per_sep"): (None, (3, 8)),
("bytes.hex", "sep"): (None, (3, 8)),
("bytes.translate", "delete"): (None, (3, 6)),
("bz2.BZ2Decompressor.decompress", "max_length"): (None, (3, 5)),
# Security fix backported to 3.6.13+, 3.7.10+, 3.8.8+, 3.9.2+, 3.10+
("cgi.parse", "separator"): (None, (3, 6)),
("cgi.parse_multipart", "encoding"): (None, (3, 7)),
("cgi.parse_multipart", "errors"): (None, (3, 7)),
# Security fix backported to 3.6.13+, 3.7.10+, 3.8.8+, 3.9.2+, 3.10+
("cgi.parse_multipart", "separator"): (None, (3, 6)),
("cgi.parse_qs", "max_num_fields"): ((2, 7), None),
("cgi.parse_qsl", "max_num_fields"): ((2, 7), None),
("cmath.log", "base"): ((2, 4), (3, 0)),
("cmd.Cmd", "stdin"): ((2, 3), (3, 0)),
("cmd.Cmd", "stdout"): ((2, 3), (3, 0)),
("code.interact", "exitmsg"): (None, (3, 6)),
("codecs.StreamReader.read", "chars"): ((2, 4), (3, 0)),
("codecs.StreamReader.read", "firstline"): ((2, 4), (3, 0)),
("codecs.StreamReader.readline", "keepends"): ((2, 4), (3, 0)),
("collections.ChainMap.new_child", "m"): (None, (3, 4)),
("collections.abc.ByteString.index", "start"): (None, (3, 5)),
("collections.abc.ByteString.index", "stop"): (None, (3, 5)),
("collections.abc.MutableSequence.index", "start"): (None, (3, 5)),
("collections.abc.MutableSequence.index", "stop"): (None, (3, 5)),
("collections.abc.Sequence.index", "start"): (None, (3, 5)),
("collections.abc.Sequence.index", "stop"): (None, (3, 5)),
("collections.deque", "maxlen"): ((2, 6), (3, 0)),
("collections.namedtuple", "defaults"): (None, (3, 7)),
("collections.namedtuple", "module"): (None, (3, 6)),
("collections.namedtuple", "rename"): ((2, 7), (3, 1)),
("compile", "dont_inherit"): ((2, 3), (3, 0)),
("compile", "flags"): ((2, 3), (3, 0)),
("compile", "module"): (None, (3, 15)),
("compile", "optimize"): (None, (3, 2)),
("compileall.compile_dir", "hardlink_dupes"): (None, (3, 9)),
("compileall.compile_dir", "invalidation_mode"): (None, (3, 7)),
("compileall.compile_dir", "legacy"): (None, (3, 2)),
("compileall.compile_dir", "limit_sl_dest"): (None, (3, 9)),
("compileall.compile_dir", "optimize"): (None, (3, 2)),
("compileall.compile_dir", "prependdir"): (None, (3, 9)),
("compileall.compile_dir", "stripdir"): (None, (3, 9)),
("compileall.compile_dir", "workers"): (None, (3, 5)),
("compileall.compile_file", "hardlink_dupes"): (None, (3, 9)),
("compileall.compile_file", "invalidation_mode"): (None, (3, 7)),
("compileall.compile_file", "limit_sl_dest"): (None, (3, 9)),
("compileall.compile_file", "prependdir"): (None, (3, 9)),
("compileall.compile_file", "stripdir"): (None, (3, 9)),
("compileall.compile_path", "invalidation_mode"): (None, (3, 7)),
("compileall.compile_path", "legacy"): (None, (3, 2)),
("compileall.compile_path", "optimize"): (None, (3, 2)),
("concurrent.futures.Executor.map", "buffersize"): (None, (3, 14)),
("concurrent.futures.Executor.map", "chunksize"): (None, (3, 5)),
("concurrent.futures.Executor.shutdown", "cancel_futures"): (None, (3, 9)),
("concurrent.futures.ProcessPoolExecutor", "initargs"): (None, (3, 7)),
("concurrent.futures.ProcessPoolExecutor", "initializer"): (None, (3, 7)),
("concurrent.futures.ProcessPoolExecutor", "max_tasks_per_child"): (None, (3, 11)),
("concurrent.futures.ProcessPoolExecutor", "mp_context"): (None, (3, 7)),
("concurrent.futures.ThreadPoolExecutor", "initargs"): (None, (3, 7)),
("concurrent.futures.ThreadPoolExecutor", "initializer"): (None, (3, 7)),
("concurrent.futures.ThreadPoolExecutor", "thread_name_prefix"): (None, (3, 6)),
("configparser.ConfigParser", "allow_no_value"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser", "allow_unnamed_section"):
bpv("configparser", (None, (3, 13)), config),
("configparser.ConfigParser", "comment_prefixes"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser", "converters"): bpv("configparser", (None, (3, 5)), config),
("configparser.ConfigParser", "default_section"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser", "delimiters"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser", "empty_lines_in_values"): bpv("configparser", (None, (3, 2)),
config),
("configparser.ConfigParser", "interpolation"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser", "strict"): bpv("configparser", (None, (3, 2)), config),
("configparser.ConfigParser.read", "encoding"): bpv("configparser", (None, (3, 2)), config),
("configparser.RawConfigParser", "allow_no_value"): bpv("configparser", (None, (3, 2)), config),
("configparser.RawConfigParser", "allow_unnamed_section"):
bpv("configparser", (None, (3, 13)), config),
("configparser.RawConfigParser", "comment_prefixes"): bpv("configparser", (None, (3, 2)),
config),
("configparser.RawConfigParser", "converters"): bpv("configparser", (None, (3, 5)), config),
("configparser.RawConfigParser", "default_section"): bpv("configparser", (None, (3, 2)),
config),
("configparser.RawConfigParser", "delimiters"): bpv("configparser", (None, (3, 2)), config),
("configparser.RawConfigParser", "empty_lines_in_values"): bpv("configparser", (None, (3, 2)),
config),
("configparser.RawConfigParser", "interpolation"): bpv("configparser", (None, (3, 2)), config),
("configparser.RawConfigParser", "strict"): bpv("configparser", (None, (3, 2)), config),
("configparser.RawConfigParser.read", "encoding"): bpv("configparser", (None, (3, 2)), config),
("configparser.DuplicateSectionError", "lineno"): bpv("configparser", (None, (3, 2)), config),
("configparser.DuplicateSectionError", "source"): bpv("configparser", (None, (3, 2)), config),
("configparser.ParsingError", "source"): bpv("configparser", (None, (3, 2)), config),
("crypt.mksalt", "rounds"): (None, (3, 7)),
("ctypes.CDLL", "use_errno"): ((2, 6), (3, 0)),
("ctypes.CDLL", "use_last_error"): ((2, 6), (3, 0)),
("ctypes.CDLL", "winmode"): (None, (3, 8)),
("ctypes.CFUNCTYPE", "use_errno"): ((2, 6), (3, 0)),
("ctypes.CFUNCTYPE", "use_last_error"): ((2, 6), (3, 0)),
("ctypes.OleDLL", "use_errno"): ((2, 6), (3, 0)),
("ctypes.OleDLL", "use_last_error"): ((2, 6), (3, 0)),
("ctypes.OleDLL", "winmode"): (None, (3, 8)),
("ctypes.WinDLL", "use_errno"): ((2, 6), (3, 0)),
("ctypes.WinDLL", "use_last_error"): ((2, 6), (3, 0)),
("ctypes.WinDLL", "winmode"): (None, (3, 8)),
("dataclasses.dataclass", "kw_only"): (None, (3, 10)),
("dataclasses.dataclass", "match_args"): (None, (3, 10)),
("dataclasses.dataclass", "slots"): (None, (3, 10)),
("dataclasses.field", "kw_only"): (None, (3, 10)),
("datetime.datetime", "fold"): (None, (3, 6)),
("datetime.datetime.combine", "tzinfo"): (None, (3, 6)),
("datetime.datetime.isoformat", "timespec"): (None, (3, 6)),
("datetime.datetime.replace", "fold"): (None, (3, 6)),
("datetime.time.isoformat", "timespec"): (None, (3, 6)),
("datetime.time.replace", "fold"): (None, (3, 6)),
("difflib.HtmlDiff.make_file", "charset"): (None, (3, 5)),
("difflib.SequenceMatcher", "autojunk"): ((2, 7), (3, 2)),
("difflib.unified_diff", "color"): (None, (3, 15)),
("dis.Bytecode", "show_caches"): (None, (3, 11)),
("dis.Bytecode", "show_offsets"): (None, (3, 13)),
("dis.Bytecode", "show_positions"): (None, (3, 14)),
("dis.dis", "depth"): (None, (3, 7)),
("dis.dis", "file"): (None, (3, 4)),
("dis.dis", "show_caches"): (None, (3, 11)),
("dis.dis", "show_positions"): (None, (3, 14)),
("dis.disassemble", "file"): (None, (3, 4)),
("dis.disassemble", "show_caches"): (None, (3, 11)),
("dis.disassemble", "show_offsets"): (None, (3, 13)),
("dis.disco", "file"): (None, (3, 4)),
("dis.disco", "show_caches"): (None, (3, 11)),
("dis.disco", "show_positions"): (None, (3, 14)),
("dis.distb", "file"): (None, (3, 4)),
("dis.distb", "show_caches"): (None, (3, 11)),
("dis.distb", "show_offsets"): (None, (3, 13)),
("dis.distb", "show_positions"): (None, (3, 14)),
("dis.get_instructions", "show_caches"): (None, (3, 11)),
("dis.show_code", "file"): (None, (3, 4)),
("dis.stack_effect", "jump"): (None, (3, 8)),
("doctest.DocFileSuite", "encoding"): ((2, 5), (3, 0)),
("doctest.DocTestSuite", "extraglobs"): ((2, 4), (3, 0)),
("doctest.DocTestSuite", "globs"): ((2, 4), (3, 0)),
("doctest.DocTestSuite", "optionflags"): ((2, 4), (3, 0)),
("doctest.DocTestSuite", "setUp"): ((2, 4), (3, 0)),
("doctest.DocTestSuite", "tearDown"): ((2, 4), (3, 0)),
("doctest.DocTestSuite", "test_finder"): ((2, 4), (3, 0)),
("doctest.debug", "pm"): ((2, 4), (3, 0)),
("doctest.testfile", "encoding"): ((2, 5), (3, 0)),
("doctest.testmod", "exclude_empty"): ((2, 4), (3, 0)),
("doctest.testmod", "extraglobs"): ((2, 4), (3, 0)),
("doctest.testmod", "optionflags"): ((2, 3), (3, 0)),
("doctest.testmod", "raise_on_error"): ((2, 4), (3, 0)),
("email.generator.BytesGenerator", "policy"): (None, (3, 3)),
("email.generator.Generator", "policy"): (None, (3, 3)),
("email.generator.Generator.flatten", "linesep"): (None, (3, 2)),
("email.header.Header.encode", "linesep"): (None, (3, 2)),
("email.message.EmailMessage.set_param", "replace"): (None, (3, 4)),
("email.message.Message", "policy"): (None, (3, 3)),
("email.message.Message.as_string", "policy"): (None, (3, 4)),
("email.message.Message.get_param", "unquote"): ((2, 2), (3, 0)),
("email.message.Message.get_params", "unquote"): ((2, 2), (3, 0)),
("email.message.Message.set_param", "replace"): (None, (3, 4)),
("email.message.Message.set_payload", "charset"): ((2, 2), (3, 0)),
("email.message_from_binary_file", "policy"): (None, (3, 3)),
("email.message_from_bytes", "policy"): (None, (3, 3)),
("email.message_from_file", "policy"): (None, (3, 3)),
("email.message_from_file", "strict"): ((2, 2), (3, 0)),
("email.message_from_string", "policy"): (None, (3, 3)),
("email.message_from_string", "strict"): ((2, 2), (3, 0)),
("email.mime.application.MIMEApplication", "policy"): (None, (3, 6)),
("email.mime.audio.MIMEAudio", "policy"): (None, (3, 6)),
("email.mime.base.MIMEBase", "policy"): (None, (3, 6)),
("email.mime.image.MIMEImage", "policy"): (None, (3, 6)),
("email.mime.message.MIMEMessage", "policy"): (None, (3, 6)),
("email.mime.multipart.MIMEMultipart", "policy"): (None, (3, 6)),
("email.mime.text.MIMEText", "policy"): (None, (3, 6)),
("email.parser.BytesFeedParser", "policy"): (None, (3, 3)),
("email.parser.BytesParser", "policy"): (None, (3, 3)),
("email.parser.FeedParser", "policy"): (None, (3, 3)),
("email.parser.Parser", "policy"): (None, (3, 3)),
("email.parser.Parser.parse", "headersonly"): ((2, 2), (3, 0)),
("email.parser.Parser.parsestr", "headersonly"): ((2, 2), (3, 0)),
("email.policy.Policy", "mangle_from_"): (None, (3, 5)),
("email.utils.getaddresses", "strict"): (None, (3, 13)),
("email.utils.formataddr", "charset"): (None, (3, 3)),
("email.utils.make_msgid", "domain"): (None, (3, 2)),
("email.utils.parseaddr", "strict"): (None, (3, 13)),
("enum.Enum", "start"): bpv("enum", (None, (3, 5)), config),
("enumerate", "start"): ((2, 6), (3, 0)),
("exec", "closure"): (None, (3, 11)),
("exec", "globals"): (None, (3, 13)),
("exec", "locals"): (None, (3, 13)),
("eval", "globals"): (None, (3, 13)),
("eval", "locals"): (None, (3, 13)),
("faulthandler.dump_traceback", "max_threads"): (None, (3, 15)),
("faulthandler.dump_traceback_later", "max_threads"): (None, (3, 15)),
("faulthandler.enable", "max_threads"): (None, (3, 15)),
("faulthandler.register", "max_threads"): (None, (3, 15)),
("fileinput.FileInput", "encoding"): (None, (3, 10)),
("fileinput.FileInput", "errors"): (None, (3, 10)),
("fileinput.FileInput", "mode"): ((2, 5), (3, 0)),
("fileinput.FileInput", "openhook"): ((2, 5), (3, 0)),
("fileinput.hook_compressed", "encoding"): (None, (3, 10)),
("fileinput.hook_compressed", "errors"): (None, (3, 10)),
("fileinput.hook_encoded", "errors"): (None, (3, 6)),
("fileinput.input", "encoding"): (None, (3, 10)),
("fileinput.input", "errors"): (None, (3, 10)),
("fileinput.input", "mode"): ((2, 5), (3, 0)),
("fileinput.input", "openhook"): ((2, 5), (3, 0)),
("ftplib.FTP", "encoding"): (None, (3, 9)),
("ftplib.FTP", "source_address"): (None, (3, 3)),
("ftplib.FTP", "timeout"): ((2, 6), (3, 0)),
("ftplib.FTP.connect", "source_address"): (None, (3, 3)),
("ftplib.FTP.connect", "timeout"): ((2, 6), (3, 0)),
("ftplib.FTP.storbinary", "callback"): ((2, 6), (3, 0)),
("ftplib.FTP.storbinary", "rest"): ((2, 7), (3, 2)),
("ftplib.FTP.storlines", "callback"): ((2, 6), (3, 0)),
("ftplib.FTP_TLS", "context"): ((2, 7), (3, 2)),
("ftplib.FTP_TLS", "encoding"): (None, (3, 9)),
("ftplib.FTP_TLS", "source_address"): (None, (3, 3)),
("functools.reduce", "initial"): (None, (3, 14)),
("functools.lru_cache", "typed"): (None, (3, 3)),
# ("functools.lru_cache", "user_function"): (None, (3, 8)), # See DECORATOR_USER_FUNCTIONS
("gc.collect", "generation"): ((2, 5), (3, 0)),
("gc.get_objects", "generation"): (None, (3, 8)),
("getpass.getpass", "echo_char"): (None, (3, 14)),
("getpass.getpass", "stream"): ((2, 5), (3, 0)),
("gettext.NullTranslations.install", "names"): ((2, 5), (3, 0)),
("gettext.install", "codeset"): ((2, 4), (3, 0)),
("gettext.install", "names"): ((2, 5), (3, 0)),
("gettext.translation", "codeset"): ((2, 4), (3, 0)),
("glob.glob", "dir_fd"): (None, (3, 10)),
("glob.glob", "include_hidden"): (None, (3, 11)),
("glob.glob", "recursive"): (None, (3, 5)),
("glob.glob", "root_dir"): (None, (3, 10)),
("glob.iglob", "dir_fd"): (None, (3, 10)),
("glob.iglob", "include_hidden"): (None, (3, 11)),
("glob.iglob", "recursive"): (None, (3, 5)),
("glob.iglob", "root_dir"): (None, (3, 10)),
("gzip.GzipFile", "mtime"): ((2, 7), (3, 1)),
("gzip.compress", "mtime"): (None, (3, 8)),
("gzip.open", "encoding"): (None, (3, 3)),
("gzip.open", "errors"): (None, (3, 3)),
("gzip.open", "newline"): (None, (3, 3)),
("hashlib.blake2b", "usedforsecurity"): (None, (3, 9)),
("hashlib.blake2s", "usedforsecurity"): (None, (3, 9)),
("hashlib.md5", "usedforsecurity"): (None, (3, 9)),
("hashlib.new", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha1", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha224", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha256", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha384", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha3_224", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha3_256", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha3_384", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha3_512", "usedforsecurity"): (None, (3, 9)),
("hashlib.sha512", "usedforsecurity"): (None, (3, 9)),
("hashlib.shake_128", "usedforsecurity"): (None, (3, 9)),
("hashlib.shake_256", "usedforsecurity"): (None, (3, 9)),
("heapq.merge", "key"): (None, (3, 5)),
("heapq.merge", "reverse"): (None, (3, 5)),
("heapq.nlargest", "key"): ((2, 5), (3, 0)),
("heapq.nsmallest", "key"): ((2, 5), (3, 0)),
("html.parser.HTMLParser", "convert_charrefs"): (None, (3, 4)),
("http.client.HTTPConnection", "blocksize"): (None, (3, 7)),
("http.client.HTTPConnection", "max_response_headers"): (None, (3, 15)),
("http.client.HTTPConnection", "source_address"): (None, (3, 2)),
("http.client.HTTPConnection.endheaders", "encode_chunked"): (None, (3, 6)),
("http.client.HTTPConnection.request", "encode_chunked"): (None, (3, 6)),
("http.client.HTTPSConnection", "check_hostname"): (None, (3, 2)),
("http.client.HTTPSConnection", "context"): (None, (3, 2)),
("http.client.HTTPSConnection", "max_response_headers"): (None, (3, 15)),
("http.client.HTTPSConnection", "source_address"): (None, (3, 2)),
("http.server.BaseHTTPRequestHandler.send_error", "explain"): (None, (3, 4)),
("http.server.SimpleHTTPRequestHandler", "directory"): (None, (3, 7)),
("http.server.SimpleHTTPRequestHandler", "extra_response_headers"): (None, (3, 15)),
("httplib.HTTPConnection", "source_address"): ((2, 7), None),
("httplib.HTTPConnection", "timeout"): ((2, 6), None),
("httplib.HTTPConnection.endheaders", "message_body"): ((2, 7), None),
("httplib.HTTPConnection.putrequest", "skip_accept_encoding"): ((2, 4), None),
("httplib.HTTPSConnection", "context"): ((2, 7), None),
("httplib.HTTPSConnection", "source_address"): ((2, 7), None),
("httplib.HTTPSConnection", "timeout"): ((2, 6), None),
("imaplib.IMAP4", "timeout"): (None, (3, 9)),
("imaplib.IMAP4.open", "timeout"): (None, (3, 9)),
("imaplib.IMAP4_SSL", "ssl_context"): (None, (3, 3)),
("imaplib.IMAP4_SSL", "timeout"): (None, (3, 9)),
("importlib.abc.InspectLoader.source_to_code", "fullname"): (None, (3, 15)),
("importlib.util.cache_from_source", "optimization"): (None, (3, 5)),
("inspect.Signature.format", "quote_annotation_strings"): (None, (3, 14)),
("inspect.Signature.from_callable", "globals"): (None, (3, 10)),
("inspect.Signature.from_callable", "locals"): (None, (3, 10)),
("inspect.getdoc", "fallback_to_class_doc"): (None, (3, 15)),
("inspect.getdoc", "inherit_class_doc"): (None, (3, 15)),
("inspect.signature", "annotation_format"): (None, (3, 14)),
("inspect.signature", "eval_str"): (None, (3, 10)),
("inspect.signature", "follow_wrapped"): (None, (3, 5)),
("inspect.signature", "globals"): (None, (3, 10)),
("inspect.signature", "locals"): (None, (3, 10)),
("io.FileIO", "opener"): (None, (3, 3)),
("io.TextIOWrapper", "write_through"): (None, (3, 3)),
("io.TextIOWrapper.reconfigure", "encoding"): (None, (3, 11)),
("io.open", "opener"): (None, (3, 3)),
("itertools.accumulate", "func"): (None, (3, 3)),
("itertools.accumulate", "initial"): (None, (3, 8)),
("itertools.batched", "strict"): (None, (3, 13)),
("itertools.count", "step"): ((2, 7), (3, 1)),
("json.JSONDecoder", "object_pairs_hook"): ((2, 7), (3, 1)),
("json.load", "array_hook"): (None, (3, 15)),
("json.load", "object_pairs_hook"): ((2, 7), (3, 1)),
("json.loads", "array_hook"): (None, (3, 15)),
("linecache.getline", "module_globals"): ((2, 5), (3, 0)),
("locale.format", "monetary"): ((2, 5), (3, 0)),
("locale.format_string", "monetary"): (None, (3, 7)),
("logging.FileHandler", "delay"): ((2, 6), (3, 0)),
("logging.FileHandler", "errors"): (None, (3, 9)),
("logging.Formatter", "defaults"): (None, (3, 10)),
("logging.Formatter", "style"): (None, (3, 2)),
("logging.Formatter", "validate"): (None, (3, 8)),
("logging.LogRecord", "func"): ((2, 5), (3, 0)),
("logging.Logger.critical", "stack_info"): (None, (3, 2)),
("logging.Logger.critical", "stacklevel"): (None, (3, 8)),
("logging.Logger.debug", "stack_info"): (None, (3, 2)),
("logging.Logger.debug", "stacklevel"): (None, (3, 8)),
("logging.Logger.error", "stack_info"): (None, (3, 2)),
("logging.Logger.error", "stacklevel"): (None, (3, 8)),
("logging.Logger.exception", "stack_info"): (None, (3, 2)),
("logging.Logger.exception", "stacklevel"): (None, (3, 8)),
("logging.Logger.info", "stack_info"): (None, (3, 2)),
("logging.Logger.info", "stacklevel"): (None, (3, 8)),
("logging.Logger.log", "stack_info"): (None, (3, 2)),
("logging.Logger.log", "stacklevel"): (None, (3, 8)),
("logging.Logger.makeRecord", "extra"): ((2, 5), (3, 0)),
("logging.Logger.makeRecord", "func"): ((2, 5), (3, 0)),
("logging.Logger.warn", "stack_info"): (None, (3, 2)),
("logging.Logger.warn", "stacklevel"): (None, (3, 8)),
("logging.Logger.warning", "stack_info"): (None, (3, 2)),
("logging.Logger.warning", "stacklevel"): (None, (3, 8)),
("logging.basicConfig", "datefmt"): ((2, 4), (3, 0)),
("logging.basicConfig", "encoding"): (None, (3, 9)),
("logging.basicConfig", "errors"): (None, (3, 9)),
("logging.basicConfig", "filemode"): ((2, 4), (3, 0)),
("logging.basicConfig", "filename"): ((2, 4), (3, 0)),
("logging.basicConfig", "force"): (None, (3, 8)),
("logging.basicConfig", "format"): ((2, 4), (3, 0)),
("logging.basicConfig", "handlers"): (None, (3, 3)),
("logging.basicConfig", "level"): ((2, 4), (3, 0)),
("logging.basicConfig", "stream"): ((2, 4), (3, 0)),
("logging.basicConfig", "style"): (None, (3, 2)),
("logging.config.fileConfig", "disable_existing_loggers"): ((2, 6), (3, 0)),
("logging.config.fileConfig", "encoding"): (None, (3, 10)),
("logging.config.listen", "verify"): (None, (3, 4)),
("logging.critical", "extra"): ((2, 5), (3, 0)),
("logging.critical", "stack_info"): (None, (3, 2)),
("logging.critical", "stacklevel"): (None, (3, 8)),
("logging.debug", "extra"): ((2, 5), (3, 0)),
("logging.debug", "stack_info"): (None, (3, 2)),
("logging.debug", "stacklevel"): (None, (3, 8)),
("logging.error", "extra"): ((2, 5), (3, 0)),
("logging.error", "stack_info"): (None, (3, 2)),
("logging.error", "stacklevel"): (None, (3, 8)),
("logging.exception", "extra"): ((2, 5), (3, 0)),
("logging.exception", "stack_info"): (None, (3, 2)),
("logging.exception", "stacklevel"): (None, (3, 8)),
("logging.handlers.HTTPHandler", "context"): (None, (3, 5)),
("logging.handlers.MemoryHandler", "flushOnClose"): (None, (3, 6)),
("logging.handlers.QueueListener", "respect_handler_level"): (None, (3, 5)),
("logging.handlers.RotatingFileHandler", "delay"): ((2, 6), (3, 0)),
("logging.handlers.RotatingFileHandler", "errors"): (None, (3, 9)),
("logging.handlers.SMTPHandler", "credentials"): ((2, 6), (3, 0)),
("logging.handlers.SMTPHandler", "secure"): ((2, 7), (3, 0)),
("logging.handlers.SMTPHandler", "timeout"): (None, (3, 3)),
("logging.handlers.SysLogHandler", "socktype"): ((2, 7), (3, 2)),
("logging.handlers.SysLogHandler", "timeout"): (None, (3, 14)),
("logging.handlers.TimedRotatingFileHandler", "atTime"): (None, (3, 4)),
("logging.handlers.TimedRotatingFileHandler", "delay"): ((2, 6), (3, 0)),
("logging.handlers.TimedRotatingFileHandler", "errors"): (None, (3, 9)),
("logging.handlers.TimedRotatingFileHandler", "utc"): ((2, 6), (3, 0)),
("logging.handlers.WatchedFileHandler", "errors"): (None, (3, 9)),
("logging.info", "extra"): ((2, 5), (3, 0)),
("logging.info", "stack_info"): (None, (3, 2)),
("logging.info", "stacklevel"): (None, (3, 8)),
("logging.log", "extra"): ((2, 5), (3, 0)),
("logging.log", "stack_info"): (None, (3, 2)),
("logging.log", "stacklevel"): (None, (3, 8)),
("logging.warn", "stack_info"): (None, (3, 2)),
("logging.warn", "stacklevel"): (None, (3, 8)),
("logging.warning", "extra"): ((2, 5), (3, 0)),
("logging.warning", "stack_info"): (None, (3, 2)),
("logging.warning", "stacklevel"): (None, (3, 8)),
("lzma.LZMADecompressor.decompress", "max_length"): (None, (3, 5)),
("marshal.dump", "allow_code"): (None, (3, 13)),
("marshal.dumps", "allow_code"): (None, (3, 13)),
("marshal.load", "allow_code"): (None, (3, 13)),
("marshal.loads", "allow_code"): (None, (3, 13)),
("math.log", "base"): ((2, 3), (3, 0)),
("math.nextafter", "steps"): (None, (3, 12)),
("max", "default"): (None, (3, 4)),
("max", "key"): ((2, 5), (3, 0)),
("memoryview.hex", "bytes_per_sep"): (None, (3, 8)),
("memoryview.hex", "sep"): (None, (3, 8)),
("min", "default"): (None, (3, 4)),
("min", "key"): ((2, 5), (3, 0)),
("mmap.mmap", "trackfd"): (None, (3, 13)),
("multiprocessing.Pool", "maxtasksperchild"): ((2, 7), (3, 2)),
("multiprocessing.Process", "daemon"): (None, (3, 3)),
("multiprocessing.managers.BaseManager", "shutdown_timeout"): (None, (3, 11)),
("multiprocessing.pool.Pool", "context"): (None, (3, 4)),
("multiprocessing.pool.Pool", "maxtasksperchild"): (None, (3, 2)),
("nis.cat", "domain"): ((2, 5), (3, 0)),
("nis.maps", "domain"): ((2, 5), (3, 0)),
("nis.match", "domain"): ((2, 5), (3, 0)),
("nntplib.NNTP", "usenetrc"): ((2, 4), (3, 0)),
("nntplib.NNTP.list", "group_pattern"): (None, (3, 2)),
("open", "closefd"): (None, (3, 0)),
("open", "encoding"): (None, (3, 0)),
("open", "errors"): (None, (3, 0)),
("open", "newline"): (None, (3, 0)),
("open", "opener"): (None, (3, 3)),
("os.access", "dir_fd"): (None, (3, 3)),
("os.access", "effective_ids"): (None, (3, 3)),
("os.access", "follow_symlinks"): (None, (3, 3)),
("os.chflags", "follow_symlinks"): (None, (3, 3)),
("os.chmod", "dir_fd"): (None, (3, 3)),
("os.chmod", "follow_symlinks"): (None, (3, 3)),
("os.chown", "dir_fd"): (None, (3, 3)),
("os.chown", "follow_symlinks"): (None, (3, 3)),
("os.dup2", "inheritable"): (None, (3, 4)),
("os.link", "dst_dir_fd"): (None, (3, 3)),
("os.link", "follow_symlinks"): (None, (3, 3)),
("os.link", "src_dir_fd"): (None, (3, 3)),
("os.lstat", "dir_fd"): (None, (3, 3)),
("os.makedirs", "exist_ok"): (None, (3, 2)),
("os.makedirs", "parent_mode"): (None, (3, 15)),
("os.mkdir", "dir_fd"): (None, (3, 3)),
("os.mkfifo", "dir_fd"): (None, (3, 3)),
("os.mknod", "dir_fd"): (None, (3, 3)),
("os.open", "dir_fd"): (None, (3, 3)),
("os.path.realpath", "strict"): (None, (3, 10)),
("os.readlink", "dir_fd"): (None, (3, 3)),
("os.remove", "dir_fd"): (None, (3, 3)),
("os.rename", "dst_dir_fd"): (None, (3, 3)),
("os.rename", "src_dir_fd"): (None, (3, 3)),
("os.rmdir", "dir_fd"): (None, (3, 3)),
("os.sendfile", "in_fd"): (None, (3, 9)),
("os.sendfile", "out_fd"): (None, (3, 9)),
("os.startfile", "arguments"): (None, (3, 10)),
("os.startfile", "cwd"): (None, (3, 10)),
("os.startfile", "operation"): ((2, 5), (3, 0)),
("os.startfile", "show_cmd"): (None, (3, 10)),
("os.stat", "dir_fd"): (None, (3, 3)),
("os.stat", "follow_symlinks"): (None, (3, 3)),
("os.symlink", "dir_fd"): (None, (3, 3)),
("os.unlink", "dir_fd"): (None, (3, 3)),
("os.utime", "dir_fd"): (None, (3, 3)),
("os.utime", "follow_symlinks"): (None, (3, 3)),
("os.utime", "ns"): (None, (3, 3)),
("os.walk", "followlinks"): ((2, 6), (3, 0)),
("pathlib.Path.chmod", "follow_symlinks"): (None, (3, 10)),
("pathlib.Path.exists", "follow_symlinks"): (None, (3, 12)),
("pathlib.Path.glob", "case_sensitive"): (None, (3, 12)),
("pathlib.Path.glob", "recurse_symlinks"): (None, (3, 13)),
("pathlib.Path.group", "follow_symlinks"): (None, (3, 13)),
("pathlib.Path.is_dir", "follow_symlinks"): (None, (3, 13)),
("pathlib.Path.is_file", "follow_symlinks"): (None, (3, 13)),
("pathlib.Path.match", "case_sensitive"): (None, (3, 12)),
("pathlib.Path.mkdir", "exist_ok"): (None, (3, 5)),
("pathlib.Path.mkdir", "parent_mode"): (None, (3, 15)),
("pathlib.Path.owner", "follow_symlinks"): (None, (3, 13)),
("pathlib.Path.read_text", "newline"): (None, (3, 13)),
("pathlib.Path.relative_to", "walk_up"): (None, (3, 12)),
("pathlib.Path.resolve", "strict"): (None, (3, 6)),
("pathlib.Path.rglob", "case_sensitive"): (None, (3, 12)),
("pathlib.Path.rglob", "recurse_symlinks"): (None, (3, 13)),
("pathlib.Path.stat", "follow_symlinks"): (None, (3, 10)),
("pathlib.Path.unlink", "missing_ok"): (None, (3, 8)),
("pathlib.Path.write_text", "newline"): (None, (3, 10)),
("pathlib.PurePath.match", "case_sensitive"): (None, (3, 12)),
("pathlib.PurePath.relative_to", "walk_up"): (None, (3, 12)),
("pdb.Pdb", "backend"): (None, (3, 14)),
("pdb.Pdb", "colorize"): (None, (3, 14)),
("pdb.Pdb", "mode"): (None, (3, 14)),
("pdb.Pdb", "nosigint"): (None, (3, 2)),
("pdb.Pdb", "readrc"): (None, (3, 6)),
("pdb.Pdb", "skip"): ((2, 7), (3, 1)),
("pdb.set_trace", "commands"): (None, (3, 14)),
("pdb.set_trace", "header"): (None, (3, 7)),
("pickle.Pickler", "buffer_callback"): (None, (3, 8)),
("pickle.Pickler", "protocol"): ((2, 3), (3, 0)),
("pickle.Unpickler", "buffers"): (None, (3, 8)),
("pickle.Unpickler", "encoding"): (None, (3, 0)),
("pickle.Unpickler", "errors"): (None, (3, 0)),
("pickle.dump", "buffer_callback"): (None, (3, 8)),
("pickle.dump", "protocol"): ((2, 3), (3, 0)),
("pickle.dumps", "buffer_callback"): (None, (3, 8)),
("pickle.dumps", "protocol"): ((2, 3), (3, 0)),
("pickle.load", "buffers"): (None, (3, 8)),
("pickle.load", "encoding"): (None, (3, 0)),
("pickle.load", "errors"): (None, (3, 0)),
("pickle.loads", "buffers"): (None, (3, 8)),
("pickle.loads", "encoding"): (None, (3, 0)),
("pickle.loads", "errors"): (None, (3, 0)),
("pickletools.dis", "annotate"): (None, (3, 2)),
("poplib.POP3", "timeout"): ((2, 6), (3, 0)),
("poplib.POP3_SSL", "context"): (None, (3, 2)),
("pow", "base"): (None, (3, 8)),
("pow", "exp"): (None, (3, 8)),
("pow", "mod"): (None, (3, 8)),
("pprint.PrettyPrinter", "compact"): (None, (3, 4)),
("pprint.PrettyPrinter", "expand"): (None, (3, 15)),
("pprint.PrettyPrinter", "sort_dicts"): (None, (3, 8)),
("pprint.PrettyPrinter", "underscore_numbers"): (None, (3, 10)),
("pprint.pformat", "compact"): (None, (3, 4)),
("pprint.pformat", "depth"): ((2, 4), (3, 0)),
("pprint.pformat", "expand"): (None, (3, 15)),
("pprint.pformat", "indent"): ((2, 4), (3, 0)),
("pprint.pformat", "sort_dicts"): (None, (3, 8)),
("pprint.pformat", "underscore_numbers"): (None, (3, 10)),
("pprint.pformat", "width"): ((2, 4), (3, 0)),
("pprint.pp", "expand"): (None, (3, 15)),
("pprint.pprint", "compact"): (None, (3, 4)),
("pprint.pprint", "depth"): ((2, 4), (3, 0)),
("pprint.pprint", "expand"): (None, (3, 15)),
("pprint.pprint", "indent"): ((2, 4), (3, 0)),
("pprint.pprint", "sort_dicts"): (None, (3, 8)),
("pprint.pprint", "underscore_numbers"): (None, (3, 10)),
("pprint.pprint", "width"): ((2, 4), (3, 0)),
("print", "flush"): (None, (3, 3)),
("py_compile.compile", "invalidation_mode"): (None, (3, 7)),
("py_compile.compile", "optimize"): (None, (3, 2)),
("py_compile.compile", "quiet"): (None, (3, 8)),
("pyclbr.Class", "end_lineno"): (None, (3, 10)),
("pyclbr.Class", "parent"): (None, (3, 7)),
("pyclbr.Function", "end_lineno"): (None, (3, 10)),
("pyclbr.Function", "is_async"): (None, (3, 10)),
("pyclbr.Function", "parent"): (None, (3, 7)),
("random.sample", "counts"): (None, (3, 9)),
("re.findall", "flags"): ((2, 4), (3, 0)),
("re.finditer", "flags"): ((2, 4), (3, 0)),
("re.split", "flags"): ((2, 7), (3, 1)),
("re.sub", "flags"): ((2, 7), (3, 1)),
("re.subn", "flags"): ((2, 7), (3, 1)),
("sched.scheduler.enter", "kwargs"): (None, (3, 3)),
("sched.scheduler.enterabs", "kwargs"): (None, (3, 3)),
("sched.scheduler.run", "blocking"): (None, (3, 3)),
("select.epoll", "flags"): (None, (3, 3)),
("select.kqueue.control", "timeout"): (None, (3, 0)),
("shelve.Shelf", "keyencoding"): (None, (3, 2)),
("shelve.Shelf", "protocol"): ((2, 3), (3, 0)),
("shelve.open", "protocol"): ((2, 3), (3, 0)),
("shlex.shlex", "punctuation_chars"): (None, (3, 6)),
("shlex.split", "posix"): ((2, 6), (3, 0)),
("shutil.chown", "dir_fd"): (None, (3, 13)),
("shutil.chown", "follow_symlinks"): (None, (3, 13)),
("shutil.copy", "follow_symlinks"): (None, (3, 3)),
("shutil.copy2", "follow_symlinks"): (None, (3, 3)),
("shutil.copyfile", "follow_symlinks"): (None, (3, 3)),
("shutil.copymode", "follow_symlinks"): (None, (3, 3)),
("shutil.copystat", "follow_symlinks"): (None, (3, 3)),
("shutil.copytree", "copy_function"): (None, (3, 2)),
("shutil.copytree", "dirs_exist_ok"): (None, (3, 8)),
("shutil.copytree", "ignore"): ((2, 6), (3, 0)),
("shutil.copytree", "ignore_dangling_symlinks"): (None, (3, 2)),
("shutil.move", "copy_function"): (None, (3, 5)),
("shutil.rmtree", "dir_fd"): (None, (3, 11)),
("shutil.rmtree", "onexc"): (None, (3, 12)),
("shutil.unpack_archive", "filter"): (None, (3, 12)),
("signal.set_wakeup_fd", "warn_on_full_buffer"): (None, (3, 7)),
("smtpd.SMTPChannel", "decode_data"): (None, (3, 5)),
("smtpd.SMTPChannel", "enable_SMTPUTF8"): (None, (3, 5)),
("smtpd.SMTPServer", "decode_data"): (None, (3, 5)),
("smtpd.SMTPServer", "enable_SMTPUTF8"): (None, (3, 5)),
("smtpd.SMTPServer", "map"): (None, (3, 4)),
("smtplib.LMTP", "timeout"): (None, (3, 9)),
("smtplib.SMTP", "source_address"): (None, (3, 3)),
("smtplib.SMTP", "timeout"): ((2, 6), (3, 0)),
("smtplib.SMTP.login", "initial_response_ok"): (None, (3, 5)),
("smtplib.SMTP.starttls", "context"): (None, (3, 3)),
("smtplib.SMTP_SSL", "context"): (None, (3, 3)),
("smtplib.SMTP_SSL", "source_address"): (None, (3, 3)),
("socket.create_connection", "all_errors"): (None, (3, 11)),
("socket.create_connection", "source_address"): ((2, 7), (3, 2)),
("socket.setsockopt", "optlen"): (None, (3, 6)),
("sorted", "key"): ((2, 4), (3, 0)),
("sorted", "reverse"): ((2, 4), (3, 0)),
("sqlite3.Connection.create_function", "deterministic"): (None, (3, 8)),
("sqlite3.Connection.iterdump", "filter"): (None, (3, 13)),
("sqlite3.Connection.load_extension", "entrypoint"): (None, (3, 12)),
("sqlite3.connect", "autocommit"): (None, (3, 12)),
("sqlite3.connect", "uri"): (None, (3, 4)),
("ssl.SSLContext.load_cert_chain", "password"): (None, (3, 3)),
("ssl.SSLContext.load_verify_locations", "cadata"): (None, (3, 4)),
("ssl.SSLContext.wrap_bio", "session"): (None, (3, 6)),
("ssl.SSLContext.wrap_socket", "session"): (None, (3, 6)),
("ssl.get_server_certificate", "timeout"): (None, (3, 10)),
("ssl.wrap_socket", "ciphers"): ((2, 7), (3, 2)),
("statistics.fmean", "weights"): (None, (3, 11)),
("statistics.harmonic_mean", "weights"): (None, (3, 10)),
("statistics.linear_regression", "proportional"): (None, (3, 11)),
("str.decode", "encoding"): ((2, 7), None),
("str.decode", "errors"): ((2, 7), None),
("str.encode", "encoding"): ((2, 7), (3, 1)),
("str.encode", "errors"): ((2, 7), (3, 1)),
("str.replace", "count"): (None, (3, 13)),
("string.lstrip", "chars"): ((2, 3), None),
("string.rstrip", "chars"): ((2, 3), None),
("string.strip", "chars"): ((2, 3), None),
# Notes:
# Creating keyword argument rules for the `subprocess` module is tricky. Newly added arguments
# may only be documented in `subprocess.Popen`. But the new arguments are actually also
# supported by `subprocess.run`, `subprocess.call`, `subprocess.check_call` and
# `subprocess.check_output` (we can see `**other_popen_kwargs` in the documentation, the kwargs
# are passed through). Therefore, whenever a new argument is added, we need to add rules for
# all the 5 functions mentioned above.
("subprocess.Popen", "encoding"): (None, (3, 6)),
("subprocess.Popen", "errors"): (None, (3, 6)),
("subprocess.Popen", "extra_groups"): (None, (3, 9)),
("subprocess.Popen", "group"): (None, (3, 9)),
("subprocess.Popen", "pass_fds"): (None, (3, 2)),
("subprocess.Popen", "pipesize"): (None, (3, 10)),
("subprocess.Popen", "process_group"): (None, (3, 11)),
("subprocess.Popen", "restore_signals"): (None, (3, 2)),
("subprocess.Popen", "start_new_session"): (None, (3, 2)),
("subprocess.Popen", "text"): (None, (3, 7)),
("subprocess.Popen", "umask"): (None, (3, 9)),
("subprocess.Popen", "user"): (None, (3, 9)),
("subprocess.Popen.communicate", "timeout"): (None, (3, 3)),
("subprocess.Popen.wait", "timeout"): (None, (3, 3)),
("subprocess.CalledProcessError", "stderr"): (None, (3, 5)),
("subprocess.STARTUPINFO", "lpAttributeList"): (None, (3, 7)),
("subprocess.TimeoutExpired", "stderr"): (None, (3, 5)),
("subprocess.call", "encoding"): (None, (3, 6)),
("subprocess.call", "errors"): (None, (3, 6)),
("subprocess.call", "extra_groups"): (None, (3, 9)),
("subprocess.call", "group"): (None, (3, 9)),
("subprocess.call", "pass_fds"): (None, (3, 2)),
("subprocess.call", "pipesize"): (None, (3, 10)),
("subprocess.call", "process_group"): (None, (3, 11)),
("subprocess.call", "restore_signals"): (None, (3, 2)),
("subprocess.call", "start_new_session"): (None, (3, 2)),
("subprocess.call", "text"): (None, (3, 7)),
("subprocess.call", "timeout"): (None, (3, 3)),
("subprocess.call", "umask"): (None, (3, 9)),
("subprocess.call", "user"): (None, (3, 9)),
("subprocess.check_call", "encoding"): (None, (3, 6)),
("subprocess.check_call", "errors"): (None, (3, 6)),
("subprocess.check_call", "extra_groups"): (None, (3, 9)),
("subprocess.check_call", "group"): (None, (3, 9)),
("subprocess.check_call", "pass_fds"): (None, (3, 2)),
("subprocess.check_call", "pipesize"): (None, (3, 10)),
("subprocess.check_call", "process_group"): (None, (3, 11)),
("subprocess.check_call", "restore_signals"): (None, (3, 2)),
("subprocess.check_call", "start_new_session"): (None, (3, 2)),
("subprocess.check_call", "text"): (None, (3, 7)),
("subprocess.check_call", "timeout"): (None, (3, 3)),
("subprocess.check_call", "umask"): (None, (3, 9)),
("subprocess.check_call", "user"): (None, (3, 9)),
("subprocess.check_output", "encoding"): (None, (3, 6)),
("subprocess.check_output", "errors"): (None, (3, 6)),
("subprocess.check_output", "extra_groups"): (None, (3, 9)),
("subprocess.check_output", "group"): (None, (3, 9)),
("subprocess.check_output", "input"): (None, (3, 4)),
("subprocess.check_output", "pass_fds"): (None, (3, 2)),
("subprocess.check_output", "pipesize"): (None, (3, 10)),
("subprocess.check_output", "process_group"): (None, (3, 11)),
("subprocess.check_output", "restore_signals"): (None, (3, 2)),
("subprocess.check_output", "start_new_session"): (None, (3, 2)),
("subprocess.check_output", "text"): (None, (3, 7)),
("subprocess.check_output", "timeout"): (None, (3, 3)),
("subprocess.check_output", "umask"): (None, (3, 9)),
("subprocess.check_output", "user"): (None, (3, 9)),
("subprocess.getoutput", "encoding"): (None, (3, 11)),
("subprocess.getoutput", "errors"): (None, (3, 11)),
("subprocess.getstatusoutput", "encoding"): (None, (3, 11)),
("subprocess.getstatusoutput", "errors"): (None, (3, 11)),
("subprocess.run", "capture_output"): (None, (3, 7)),
("subprocess.run", "encoding"): (None, (3, 6)),
("subprocess.run", "errors"): (None, (3, 6)),
("subprocess.run", "extra_groups"): (None, (3, 9)),
("subprocess.run", "group"): (None, (3, 9)),
("subprocess.run", "pipesize"): (None, (3, 10)),
("subprocess.run", "text"): (None, (3, 7)),
("subprocess.run", "umask"): (None, (3, 9)),
("subprocess.run", "user"): (None, (3, 9)),
("sum", "start"): (None, (3, 8)),
("symtable.symtable", "module"): (None, (3, 15)),
("sys.getwindowsversion", "platform_version"): (None, (3, 6)),
("tarfile.TarFile", "encoding"): ((2, 6), (3, 0)),
("tarfile.TarFile", "errors"): ((2, 6), (3, 0)),
("tarfile.TarFile", "format"): ((2, 6), (3, 0)),
("tarfile.TarFile", "pax_headers"): ((2, 6), (3, 0)),
("tarfile.TarFile", "stream"): (None, (3, 13)),
("tarfile.TarFile", "tarinfo"): ((2, 6), (3, 0)),
("tarfile.TarFile.add", "exclude"): ((2, 6), (3, 0)),
("tarfile.TarFile.add", "filter"): ((2, 7), (3, 2)),
("tarfile.TarFile.extract", "filter"): (None, (3, 12)),
("tarfile.TarFile.extract", "numeric_owner"): (None, (3, 5)),
("tarfile.TarFile.extract", "set_attrs"): (None, (3, 2)),
("tarfile.TarFile.extractall", "filter"): (None, (3, 12)),
("tarfile.TarFile.extractall", "numeric_owner"): (None, (3, 5)),
("tarfile.TarFile.list", "members"): (None, (3, 5)),
("tarfile.TarInfo.tobuf", "encoding"): ((2, 6), (3, 0)),
("tarfile.TarInfo.tobuf", "errors"): ((2, 6), (3, 0)),
("tarfile.TarInfo.tobuf", "format"): ((2, 6), (3, 0)),
("telnetlib.Telnet", "timeout"): ((2, 6), (3, 0)),
("telnetlib.Telnet.open", "timeout"): ((2, 6), (3, 0)),
("tempfile.NamedTemporaryFile", "delete"): ((2, 6), (3, 0)),
("tempfile.NamedTemporaryFile", "errors"): (None, (3, 8)),
("tempfile.NamedTemporaryFile", "delete_on_close"): (None, (3, 12)),
("tempfile.SpooledTemporaryFile", "errors"): (None, (3, 8)),
("tempfile.SpooledTemporaryFile.truncate", "size"): (None, (3, 3)),
("tempfile.TemporaryDirectory", "delete"): (None, (3, 12)),
("tempfile.TemporaryDirectory", "ignore_cleanup_errors"): (None, (3, 10)),
("tempfile.TemporaryFile", "errors"): (None, (3, 8)),
("test.support.check_warnings", "quiet"): ((2, 7), (3, 2)),
("threading.Lock.acquire", "blocking"): (None, (3, 0)),
("threading.Lock.acquire", "timeout"): (None, (3, 2)),
("threading.RLock.acquire", "blocking"): (None, (3, 0)),
("threading.RLock.acquire", "timeout"): (None, (3, 2)),
("threading.Semaphore.acquire", "timeout"): (None, (3, 2)),
("threading.Semaphore.release", "n"): (None, (3, 9)),
("threading.Thread", "context"): (None, (3, 14)),
("threading.Thread", "daemon"): (None, (3, 3)),
("tkinter.Text.search", "nolinestop"): (None, (3, 15)),
("tkinter.Text.search", "strictlimits"): (None, (3, 15)),
("timeit.Timer", "globals"): (None, (3, 5)),
("timeit.Timer.autorange", "target_time"): (None, (3, 15)),
("timeit.repeat", "globals"): (None, (3, 5)),
("timeit.timeit", "globals"): (None, (3, 5)),
("tkinter.font.nametofont", "root"): (None, (3, 10)),
("traceback.TracebackException", "compact"): (None, (3, 10)),
("traceback.TracebackException.format_exception_only", "show_group"): (None, (3, 13)),
("tracemalloc.Filter", "domain"): (None, (3, 6)),
("typing.get_type_hints", "include_extras"): (None, (3, 9)),
("unittest.TestCase.assertAlmostEqual", "delta"): ((2, 7), (3, 2)),
("unittest.TestCase.assertLogs", "formatter"): (None, (3, 15)),
("unittest.TestCase.assertNotAlmostEqual", "delta"): ((2, 7), (3, 2)),
("unittest.TestCase.assertRaises", "msg"): (None, (3, 3)),
("unittest.TestCase.assertRaisesRegex", "msg"): (None, (3, 3)),
("unittest.TestCase.assertWarns", "msg"): (None, (3, 3)),
("unittest.TestCase.assertWarnsRegex", "msg"): (None, (3, 3)),
("unittest.TestLoader.loadTestsFromModule", "pattern"): (None, (3, 5)),
("unittest.TextTestRunner", "tb_locals"): (None, (3, 5)),
("unittest.TextTestRunner", "warnings"): (None, (3, 2)),
("unittest.main", "buffer"): ((2, 7), (3, 2)),
("unittest.main", "catchbreak"): ((2, 7), (3, 2)),
("unittest.main", "exit"): ((2, 7), (3, 1)),
("unittest.main", "failfast"): ((2, 7), (3, 2)),
("unittest.main", "verbosity"): ((2, 7), (3, 2)),
("unittest.main", "warnings"): (None, (3, 2)),
("unittest.mock.Mock", "unsafe"): (None, (3, 5)),
("unittest.mock.Mock.reset_mock", "return_value"): (None, (3, 6)),
("unittest.mock.Mock.reset_mock", "side_effect"): (None, (3, 6)),
("urllib.URLopener", "context"): ((2, 7), None),
("urllib.parse.parse_qs", "encoding"): (None, (3, 2)),
("urllib.parse.parse_qs", "errors"): (None, (3, 2)),
# Security fix backported to 3.6.8+, 3.7.2+, 3.8+
("urllib.parse.parse_qs", "max_num_fields"): (None, (3, 6)),
# Security fix backported to 3.6.13+, 3.7.10+, 3.8.8+, 3.9.2+, 3.10+
("urllib.parse.parse_qs", "separator"): (None, (3, 6)),
("urllib.parse.parse_qsl", "encoding"): (None, (3, 2)),
("urllib.parse.parse_qsl", "errors"): (None, (3, 2)),
# Security fix backported to 3.6.8+, 3.7.2+, 3.8+
("urllib.parse.parse_qsl", "max_num_fields"): (None, (3, 6)),
# Security fix backported to 3.6.13+, 3.7.10+, 3.8.8+, 3.9.2+, 3.10+
("urllib.parse.parse_qsl", "separator"): (None, (3, 6)),
("urllib.parse.urldefrag", "missing_as_none"): (None, (3, 15)),
("urllib.parse.urlencode", "quote_via"): (None, (3, 5)),
("urllib.parse.urlparse", "missing_as_none"): (None, (3, 15)),
("urllib.parse.urlsplit", "missing_as_none"): (None, (3, 15)),
("urllib.parse.urlunparse", "keep_empty"): (None, (3, 15)),
("urllib.parse.urlunsplit", "keep_empty"): (None, (3, 15)),
("urllib.request.HTTPSHandler", "check_hostname"): (None, (3, 2)),
("urllib.request.HTTPSHandler", "context"): (None, (3, 2)),
("urllib.request.Request", "method"): (None, (3, 3)),
("urllib.request.urlopen", "cadefault"): (None, (3, 3)),
("urllib.request.urlopen", "cafile"): (None, (3, 2)),
("urllib.request.urlopen", "capath"): (None, (3, 2)),
("urllib.request.urlopen", "context"): (None, (3, 4)),
("urllib.request.pathname2url", "add_scheme"): (None, (3, 14)),
("urllib.request.url2pathname", "require_scheme"): (None, (3, 14)),
("urllib.request.url2pathname", "resolve_host"): (None, (3, 14)),
("urllib.urlopen", "context"): ((2, 7), None),
("urllib.urlopen", "proxies"): ((2, 3), None),
("urllib.urlretrieve", "context"): ((2, 7), None),
("urllib2.HTTPSHandler", "context"): ((2, 7), None),
("urllib2.OpenerDirector.open", "timeout"): ((2, 6), None),
("urllib2.urlopen", "cadefault"): ((2, 7), None),
("urllib2.urlopen", "cafile"): ((2, 7), None),
("urllib2.urlopen", "capth"): ((2, 7), None),
("urllib2.urlopen", "context"): ((2, 7), None),
("urllib2.urlopen", "timeout"): ((2, 6), None),
("urlparse.parse_qs", "max_num_fields"): ((2, 7), None),
("urlparse.parse_qsl", "max_num_fields"): ((2, 7), None),
("uu.encode", "backtick"): (None, (3, 7)),
("venv.EnvBuilder", "prompt"): (None, (3, 6)),
("venv.EnvBuilder", "scm_ignore_files"): (None, (3, 13)),
("venv.EnvBuilder", "upgrade_deps"): (None, (3, 9)),
("venv.EnvBuilder", "with_pip"): (None, (3, 4)),
("venv.create", "prompt"): (None, (3, 6)),
("venv.create", "scm_ignore_files"): (None, (3, 13)),
("venv.create", "upgrade_deps"): (None, (3, 9)),
("venv.create", "with_pip"): (None, (3, 4)),
("warnings.catch_warnings", "action"): (None, (3, 11)),
("warnings.catch_warnings", "append"): (None, (3, 11)),
("warnings.catch_warnings", "category"): (None, (3, 11)),
("warnings.catch_warnings", "lineno"): (None, (3, 11)),
("warnings.formatwarning", "line"): ((2, 6), (3, 0)),
("warnings.showwarning", "line"): ((2, 7), (3, 0)),
("warnings.warn", "source"): (None, (3, 6)),
("warnings.warn_explicit", "module_globals"): ((2, 5), (3, 0)),
("warnings.warn_explicit", "source"): (None, (3, 6)),
("webbrowser.register", "preferred"): (None, (3, 7)),
("winreg.OpenKey", "access"): (None, (3, 2)),
("winreg.OpenKey", "key"): (None, (3, 2)),
("winreg.OpenKey", "reserved"): (None, (3, 2)),
("winreg.OpenKey", "sub_key"): (None, (3, 2)),
("winreg.OpenKeyEx", "access"): (None, (3, 2)),
("winreg.OpenKeyEx", "key"): (None, (3, 2)),
("winreg.OpenKeyEx", "reserved"): (None, (3, 2)),
("winreg.OpenKeyEx", "sub_key"): (None, (3, 2)),
("xml.dom.minidom.Document.writexml", "encoding"): ((2, 3), (3, 0)),
("xml.dom.minidom.Node.toprettyxml", "encoding"): ((2, 3), (3, 0)),
("xml.dom.minidom.Node.toprettyxml", "standalone"): (None, (3, 9)),
("xml.dom.minidom.Node.toxml", "encoding"): ((2, 3), (3, 0)),
("xml.dom.minidom.Node.toxml", "standalone"): (None, (3, 9)),
("xml.dom.minidom.Node.writexml", "addindent"): ((2, 1), (3, 0)),
("xml.dom.minidom.Node.writexml", "encoding"): (None, (3, 0)),
("xml.dom.minidom.Node.writexml", "indent"): ((2, 1), (3, 0)),
("xml.dom.minidom.Node.writexml", "newl"): ((2, 1), (3, 0)),
("xml.dom.minidom.Node.writexml", "standalone"): (None, (3, 9)),
("xml.etree.ElementInclude.include", "base_url"): (None, (3, 9)),
("xml.etree.ElementInclude.include", "max_depth"): (None, (3, 9)),
("xml.etree.ElementTree.ElementTree.write", "short_empty_elements"): (None, (3, 4)),
("xml.etree.ElementTree.tostring", "default_namespace"): (None, (3, 8)),
("xml.etree.ElementTree.tostring", "short_empty_elements"): (None, (3, 4)),
("xml.etree.ElementTree.tostring", "xml_declaration"): (None, (3, 8)),
("xml.etree.ElementTree.tostringlist", "default_namespace"): (None, (3, 8)),
("xml.etree.ElementTree.tostringlist", "short_empty_elements"): (None, (3, 4)),
("xml.etree.ElementTree.tostringlist", "xml_declaration"): (None, (3, 8)),
("xml.etree.ElementTree.write", "short_empty_elements"): (None, (3, 4)),
("xml.sax.saxutils.XMLGenerator", "short_empty_elements"): (None, (3, 2)),
("xmlrpc.client.ServerProxy", "context"): (None, (3, 4)),
("xmlrpc.client.ServerProxy", "headers"): (None, (3, 8)),
("xmlrpc.client.ServerProxy", "use_builtin_types"): (None, (3, 3)),
("xmlrpc.client.loads", "use_builtin_types"): (None, (3, 3)),
("xmlrpc.server.CGIXMLRPCRequestHandler", "use_builtin_types"): (None, (3, 3)),
("xmlrpc.server.DocXMLRPCServer", "use_builtin_types"): (None, (3, 3)),
("xmlrpc.server.SimpleXMLRPCServer", "use_builtin_types"): (None, (3, 3)),
("xmlrpclib.ServerProxy", "context"): ((2, 7), None),
("xmlrpclib.ServerProxy", "use_datetime"): ((2, 5), None),
("xmlrpclib.loads", "use_datetime"): ((2, 5), None),
("zip", "strict"): (None, (3, 10)),
("zipapp.create_archive", "compressed"): (None, (3, 7)),
("zipapp.create_archive", "filter"): (None, (3, 7)),
("zipfile.PyZipFile", "optimize"): (None, (3, 2)),
("zipfile.PyZipFile.writepy", "filterfunc"): (None, (3, 4)),
("zipfile.ZipFile", "compresslevel"): (None, (3, 7)),
("zipfile.ZipFile", "metadata_encoding"): (None, (3, 11)),
("zipfile.ZipFile", "strict_timestamps"): (None, (3, 8)),
("zipfile.ZipFile.read", "pwd"): ((2, 6), (3, 0)),
("zipfile.ZipFile.writestr", "compress_type"): ((2, 7), (3, 2)),
("zipfile.ZipInfo.from_file", "strict_timestamps"): (None, (3, 8)),
("zlib.Decompress.decompress", "max_length"): (None, (3, 6)),
("zlib.compress", "level"): (None, (3, 6)),
("zlib.compress", "wbits"): (None, (3, 11)),
("zlib.compressobj", "zdict"): (None, (3, 3)),
("zlib.decompress", "bufsize"): (None, (3, 6)),
("zlib.decompress", "wbits"): (None, (3, 6)),
("zlib.decompressobj", "zdict"): (None, (3, 3)),
}
# datetime+time strftime/strptime requirements: directive -> requirements
STRFTIME_REQS = {
"G": (None, (3, 6)),
"V": (None, (3, 6)),
"f": ((2, 6), (3, 0)),
"u": (None, (3, 6)),
}
# bytes/bytearray (and str for 2 compatibility) requirements: directive -> requirements
BYTES_REQS = {
"a": (None, (3, 5)),
"b": (None, (3, 5)),
"r": ((2, 7), (3, 5)),
}
# array.array typecode requirements: typecode -> requirements
ARRAY_TYPECODE_REQS = {
"q": (None, (3, 3)),
"Q": (None, (3, 3)),
"w": (None, (3, 13)),
"e": (None, (3, 15)),
"Zf": (None, (3, 15)),
"Zd": (None, (3, 15)),
}
# codecs error handler requirements: error name -> requirements
CODECS_ERROR_HANDLERS = {
"surrogateescape": (None, (3, 1)),
"surrogatepass": (None, (3, 1)),
"namereplace": (None, (3, 5)),
}
# Correlate the value of kwarg "errors" of the following functions/constructors with
# CODECS_ERROR_HANDLERS: function -> argument index
CODECS_ERRORS_INDICES = {
"codecs.encode": 2,
"codecs.decode": 2,
"codecs.open": 3,
"codecs.EncodedFile": 3,
"codecs.iterencode": 2,
"codecs.iterdecode": 2,
"codecs.IncrementalEncoder": 0,
"codecs.IncrementalDecoder": 0,
"codecs.StreamWriter": 1,
"codecs.StreamReader": 1,
"codecs.StreamReaderWriter": 3,
"codecs.StreamRecoder": 5,
}
# codecs encodings and aliases -> requirements
# Checks case-insensitively.
CODECS_ENCODINGS = {
# German
("cp273", "273", "ibm273", "csibm273"): (None, (3, 4)),
# Ukrainian
("cp1125", "1125", "ibm1125", "cp866u", "ruscii"): (None, (3, 4)),
# Windows UTF-8 (CP_UTF8)
("cp65001",): (None, (3, 3)),
# Tajik
("koi8_t",): (None, (3, 5)),
# Kazakh
("kz1048", "kz_1048", "strk1048_2002", "kz-1048", "strk1048-2002", "rk1048"): (None, (3, 5)),
# Windows OEM
("oem",): (None, (3, 6)),
# == Binary transforms ==
("base64_codec", "base64-codec"): (None, (3, 2)),
("base64", "base_64", "base-64"): (None, (3, 4)),
("bz2_codec", "bz2-codec"): (None, (3, 2)),
("bz2",): (None, (3, 4)),
("hex_codec", "hex-codec"): (None, (3, 2)),
("hex",): (None, (3, 4)),
("quopri_codec", "quopri-codec"): (None, (3, 2)),
("quopri", "quotedprintable", "quoted_printable", "quoted-printable"): (None, (3, 4)),
("uu_codec", "uu-codec"): (None, (3, 2)),
("uu",): (None, (3, 4)),
("zip", "zlib"): (None, (3, 4)),
# == Text transforms ==
# Caesar cipher
("rot_13", "rot-13"): (None, (3, 2)),
("rot13",): (None, (3, 4)),
}
# Correlate the value of kwarg "encoding", "file_encoding", "data_encoding" of the following
# functions with CODECS_ENCODINGS: function -> set of argument indices
CODECS_ENCODINGS_INDICES = {
"codecs.encode": (1,),
"codecs.decode": (1,),
"codecs.lookup": (0,),
"codecs.getencoder": (0,),
"codecs.getdecoder": (0,),
"codecs.getincrementalencoder": (0,),
"codecs.getincrementaldecoder": (0,),
"codecs.getreader": (0,),
"codecs.getwriter": (0,),
"codecs.open": (2,),
"codecs.EncodedFile": (1, 2),
"codecs.iterencode": (2,),
"codecs.iterdecode": (2,),
}
# Builtin types that work as annotation types from 3.9+
# The list is taken from https://github.com/python/cpython/blob/master/Lib/test/test_genericalias.py
BUILTIN_GENERIC_ANNOTATION_TYPES = (
"collections.ChainMap",
"collections.Counter",
"collections.OrderedDict",
"collections.UserDict",
"collections.UserList",
"collections.abc.AsyncGenerator",
"collections.abc.AsyncIterable",
"collections.abc.AsyncIterator",
"collections.abc.Awaitable",
"collections.abc.ByteString",
"collections.abc.Callable",
"collections.abc.Collection",
"collections.abc.Container",
"collections.abc.Coroutine",
"collections.abc.Generator",
"collections.abc.ItemsView",
"collections.abc.Iterable",
"collections.abc.Iterator",
"collections.abc.KeysView",
"collections.abc.Mapping",
"collections.abc.MappingView",
"collections.abc.MutableMapping",
"collections.abc.MutableSequence",
"collections.abc.MutableSet",
"collections.abc.Reversible",
"collections.abc.Sequence",
"collections.abc.Set",
"collections.abc.ValuesView",
"collections.defaultdict",
"collections.deque",
"concurrent.futures.Future",
"concurrent.futures.thread._WorkItem",
"contextlib.AbstractAsyncContextManager",
"contextlib.AbstractContextManager",
"contextvars.ContextVar",
"contextvars.Token",
"ctypes.Array",
"ctypes.LibraryLoader",
"dataclasses.Field",
"dict",
"difflib.SequenceMatcher",
"enumerate",
"filecmp.dircmp",
"fileinput.FileInput",
"frozenset",
"functools.cached_property",
"functools.partial",
"functools.partialmethod",
"graphlib.TopologicalSorter",
"http.cookies.Morsel",
"itertools.chain",
"list",
"logging.LoggerAdapter",
"logging.StreamHandler",
"mailbox.Mailbox",
"mailbox._PartialFile",
"multiprocessing.managers.ValueProxy",
"multiprocessing.pool.ApplyResult",
"multiprocessing.queues.SimpleQueue",
"multiprocessing.shared_memory.ShareableList",
"os.DirEntry",
"queue.Queue",
"queue.SimpleQueue",
"re.Match",
"re.Pattern",
"set",
"tempfile.SpooledTemporaryFile",
"tempfile.TemporaryDirectory",
"tuple",
"type",
"types.AsyncGeneratorType",
"types.MappingProxyType",
"unittest.case._AssertRaisesContext",
"urllib.parse.ParseResult",
"urllib.parse.SplitResult",
"weakref.ReferenceType",
"weakref.WeakSet",
"weakref.ref",
)
# Types that support dictionary union operator | (3.9).
DICT_UNION_SUPPORTED_TYPES = (
"collections.ChainMap",
"collections.OrderedDict",
"collections.UserDict",
"collections.defaultdict",
"os.environ",
"os.environb",
"types.MappingProxyType",
"weakref.WeakKeyDictionary",
"weakref.WeakValueDictionary",
)
# Types that support dictionary union merge operator |= (3.9).
DICT_UNION_MERGE_SUPPORTED_TYPES = (
"collections.ChainMap",
"collections.OrderedDict",
"collections.UserDict",
"collections.defaultdict",
"os.environ",
"os.environb",
"weakref.WeakKeyDictionary",
"weakref.WeakValueDictionary",
)
# Certain decorators allow being used not as function calls, where they instead apply directly to
# the "user function".
# Ref: https://docs.python.org/3/library/functools.html#functools.lru_cache
DECORATOR_USER_FUNCTIONS = {
"functools.lru_cache": (None, (3, 8)),
"functools.cache": (None, (3, 9)),
}
netromdk-vermin-d650a48/vermin/source_state.py 0000664 0000000 0000000 00000013542 15265463462 0021564 0 ustar 00root root 0000000 0000000 import sys
import os
from collections import deque
from .formats import ParsableFormat
from .rules import MOD_REQS, MOD_MEM_REQS, KWARGS_REQS
class SourceState:
"""Source file visitation state."""
def __init__(self, config, path=None, source=None):
assert config is not None, "Config must be specified!"
self.config = config
self.parsable = isinstance(config.format(), ParsableFormat)
self.path = "" if path is None else path
if isinstance(source, bytes):
self.source = source.decode(errors="replace")
else:
self.source = source
if self.parsable and not sys.platform.startswith("win32"):
for c in (":", "\n"):
assert c not in self.path, "Path '{}' cannot contain '{}'".format(self.path, c)
self.is_init_file = os.path.basename(self.path) == "__init__.py"
self.depth = 0
self.line = 1
self.lines = None
# List of lines of output text.
self.output_text = []
# Set of (msg, versions, entity) fingerprints to avoid duplicate output lines.
self.output_seen = set()
# Whether violations were found while visiting
self.found_violation = False
# Line/column of entities for vvv-printing.
self.line_col_entities = {}
self.modules = []
self.members = []
self.printv2 = False
self.printv3 = False
self.format27 = False # If format is used so that it requires 2.7+, like '{}' etc.
self.longv2 = False
self.bytesv3 = False
self.fstrings = False
self.fstrings_self_doc = False
self.fstrings_pep701 = False
self.fstrings_await = False
self.bool_const = False
self.annotations = False
self.var_annotations = False
self.final_annotations = False
self.literal_annotations = False
self.coroutines = False
self.async_generator = False
self.async_comprehension = False
self.async_for = False
self.seen_yield = 0
self.seen_await = 0
self.await_in_comprehension = False
self.named_exprs = False
self.kw_only_args = False
self.pos_only_args = False
self.nonlocal_stmt = False
self.yield_from = False
self.raise_cause = False
self.raise_from_none = False
self.set_literals = False
self.set_comp = False
self.dict_comp = False
self.mat_mult = False
self.continue_in_finally = False
self.seen_for = 0
self.seen_while = 0
self.seen_class = 0
self.try_finally = []
self.mod_inverse_pow = False
self.function_name = None
self.function_name_stack = deque()
self.kwargs = []
self.user_func_decorators = []
self.strftime_directives = []
self.bytes_directives = []
self.codecs_error_handlers = []
self.codecs_encodings = []
self.with_statement = False
self.async_with_statement = False
self.multi_withitem = False
self.with_parentheses = False
self.generalized_unpacking = False
self.unpacking_assignment = False
self.ellipsis_out_of_slices = False
self.bytes_format = False
self.bytearray_format = False
self.dict_union = False
self.dict_union_merge = False
self.builtin_generic_type_annotations = False
self.function_decorators = False
self.class_decorators = False
self.relaxed_decorators = False
self.module_dir_func = False
self.module_getattr_func = False
self.pattern_matching = False
self.union_types = False
self.builtin_types = {"dict", "set", "list", "unicode", "str", "int", "float", "long", "bytes",
"bytearray", "frozenset", "tuple", "bool", "memoryview"}
self.codecs_encodings_kwargs = ("encoding", "data_encoding", "file_encoding")
self.super_no_args = False
self.except_star = False
self.metaclass_class_keyword = False
# `type X = SomeType`.
self.type_alias_statement = False
# `type X = SomeType` with lambda or comprehension in `SomeType` with the annotation being
# defined in a class scope.
self.type_alias_statement_class_scope_lambda = False
# `class C[T]: ...`
self.generic_class = False
# `t'text {var}'`
self.template_string_literal = False
# `*x` unpacking in comprehension value expressions (PEP 798).
self.unpacking_in_comprehension = False
# `lazy import` statement (PEP 810).
self.lazy_imports = False
# `__lazy_modules__` module attribute.
self.lazy_modules = False
# `slice` type subscript support, e.g. `slice[1:2:3]`.
self.slice_subscription = False
# Unary `+` in match literal patterns, e.g. `case +1:`.
self.unary_plus_match_pattern = False
# Imported members of modules, like "exc_clear" of "sys".
self.import_mem_mod = {}
# Name -> name resolutions.
self.name_res = {}
# Name -> type resolutions. Is a dictionary of sets.
self.name_res_type = {}
# User-defined symbols to be ignored.
self.user_defs = set()
# Typecodes for use with `array.array(typecode, [init..])`.
self.array_typecodes = []
# Module as-name -> name.
self.module_as_name = {}
# Lines that should be ignored if they have the comment "novermin" or "novm".
self.no_lines = set()
self.fstring_self_doc_enabled = self.config.has_feature("fstring-self-doc")
self.fstrings_pep701_enabled = self.config.has_feature("fstring-pep701")
# Default to disabling union types detection because it sometimes fails to report it correctly
# due to using heuristics.
self.union_types_enabled = self.config.has_feature("union-types")
# Used for incompatible versions texts.
self.info_versions = {}
# Keep track of all Ellipsis nodes in slices for detecting Ellipsis out of slices.
self.ellipsis_nodes_in_slices = set()
# Might be using generic/literal annotations that require `--eval-annotations` to work.
self.maybe_annotations = False
self.mod_rules = MOD_REQS(self.config)
self.mod_mem_reqs_rules = MOD_MEM_REQS(self.config)
self.kwargs_reqs_rules = KWARGS_REQS(self.config)
netromdk-vermin-d650a48/vermin/source_visitor.py 0000664 0000000 0000000 00000260054 15265463462 0022145 0 ustar 00root root 0000000 0000000 import ast
import re
from collections import deque
import sys
from .source_state import SourceState
from .fstring_detector import FStringDetector
from .rules import STRFTIME_REQS, BYTES_REQS, ARRAY_TYPECODE_REQS, CODECS_ERROR_HANDLERS, \
CODECS_ERRORS_INDICES, CODECS_ENCODINGS, CODECS_ENCODINGS_INDICES, \
BUILTIN_GENERIC_ANNOTATION_TYPES, DICT_UNION_SUPPORTED_TYPES, DICT_UNION_MERGE_SUPPORTED_TYPES, \
DECORATOR_USER_FUNCTIONS
from .utility import dotted_name, reverse_range, combine_versions, compare_requirements
STRFTIME_DIRECTIVE_REGEX = re.compile(r"%(?:[-\.\d#\s\+])*(\w)")
BYTES_DIRECTIVE_REGEX = STRFTIME_DIRECTIVE_REGEX
STR_27_FORMAT_REGEX = re.compile(r"(?= (3, 8):
return (isinstance(node, getattr(ast, "Constant")) and isinstance(node.value, int)) or \
(isinstance(node, ast.UnaryOp) and isinstance(node.operand, getattr(ast, "Constant")) and
isinstance(node.operand.value, int))
return (isinstance(node, ast.Num) and isinstance(node.n, int)) or \
(isinstance(node, ast.UnaryOp) and isinstance(node.operand, ast.Num) and
isinstance(node.operand.n, int))
def is_neg_int_node(node):
if sys.version_info >= (3, 8):
return (isinstance(node, getattr(ast, "Constant")) and
isinstance(node.value, int) and node.value < 0) or \
(isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub) and
isinstance(node.operand, getattr(ast, "Constant")) and isinstance(node.operand.value, int))
return (isinstance(node, ast.Num) and isinstance(node.n, int) and node.n < 0) or \
(isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub) and
isinstance(node.operand, ast.Num) and isinstance(node.operand.n, int))
def is_none_node(node): # pragma: no cover
if isinstance(node, ast.Name) and node.id == 'None':
return True
if sys.version_info >= (3, 8):
if isinstance(node, getattr(ast, "Constant")) and node.value is None:
return True
elif sys.version_info >= (3, 4):
if isinstance(node, ast.NameConstant) and node.value is None:
return True
return False
def is_ellipsis_node(node): # pragma: no cover
if sys.version_info >= (3, 8):
return isinstance(node, getattr(ast, "Constant")) and isinstance(node.value, type(Ellipsis))
return hasattr(ast, 'Ellipsis') and isinstance(node, ast.Ellipsis)
# Generalized unpacking, or starred expressions, are allowed when used with assignment targets prior
# to 3.5. That means that generalized unpacking expressions are only on the right-hand side of the
# assignment, they're ctx=ast.Load for 3.5+ but ctx=ast.Store are allowed prior to 3.5.
def is_valid_star_unpack(node):
return hasattr(ast, "Starred") and isinstance(node, ast.Starred) and\
isinstance(node.ctx, ast.Load)
def assign_target_walk(node):
"""Walker used for determining assignment target nodes. It ignores all `ast.Subscript` and
`ast.Attribute` nodes.
"""
todo = deque([node])
while todo:
node = todo.popleft()
if not isinstance(node, (ast.Subscript, ast.Attribute)):
todo.extend(ast.iter_child_nodes(node))
yield node
class SourceVisitor(ast.NodeVisitor):
def __init__(self, config, path=None, source=None):
super().__init__()
self.__s = SourceState(config, path, source)
self.__fstr = FStringDetector(self.__s.source)
def modules(self):
return self.__s.modules
def members(self):
return self.__s.members
def printv2(self):
return self.__s.printv2
def printv3(self):
return self.__s.printv3
def format27(self):
return self.__s.format27
def longv2(self):
return self.__s.longv2
def bytesv3(self):
return self.__s.bytesv3
def fstrings(self):
return self.__s.fstrings
def fstrings_self_doc(self):
return self.__s.fstrings_self_doc
def fstrings_pep701(self):
return self.__s.fstrings_pep701
def fstrings_await(self):
return self.__s.fstrings_await
def bool_const(self):
return self.__s.bool_const
def named_expressions(self):
return self.__s.named_exprs
def kwargs(self):
return self.__s.kwargs
def user_function_decorators(self):
return self.__s.user_func_decorators
def annotations(self):
return self.__s.annotations
def var_annotations(self):
return self.__s.var_annotations
def final_annotations(self):
return self.__s.final_annotations
def literal_annotations(self):
return self.__s.literal_annotations
def coroutines(self):
return self.__s.coroutines
def async_generator(self):
return self.__s.async_generator
def async_comprehension(self):
return self.__s.async_comprehension
def await_in_comprehension(self):
return self.__s.await_in_comprehension
def async_for(self):
return self.__s.async_for
def kw_only_args(self):
return self.__s.kw_only_args
def pos_only_args(self):
return self.__s.pos_only_args
def nonlocal_stmt(self):
return self.__s.nonlocal_stmt
def strftime_directives(self):
return self.__s.strftime_directives
def bytes_directives(self):
return self.__s.bytes_directives
def user_defined(self):
return list(self.__s.user_defs)
def array_typecodes(self):
return self.__s.array_typecodes
def codecs_error_handlers(self):
return self.__s.codecs_error_handlers
def codecs_encodings(self):
return self.__s.codecs_encodings
def yield_from(self):
return self.__s.yield_from
def raise_cause(self):
return self.__s.raise_cause
def raise_from_none(self):
return self.__s.raise_from_none
def set_literals(self):
return self.__s.set_literals
def set_comprehension(self):
return self.__s.set_comp
def dict_comprehension(self):
return self.__s.dict_comp
def infix_matrix_multiplication(self):
return self.__s.mat_mult
def continue_in_finally(self):
return self.__s.continue_in_finally
def modular_inverse_pow(self):
return self.__s.mod_inverse_pow
def with_statement(self):
return self.__s.with_statement
def async_with_statement(self):
return self.__s.async_with_statement
def multi_withitem(self):
return self.__s.multi_withitem
def with_parentheses(self):
return self.__s.with_parentheses
def generalized_unpacking(self):
return self.__s.generalized_unpacking
def unpacking_assignment(self):
return self.__s.unpacking_assignment
def ellipsis_out_of_slices(self):
return self.__s.ellipsis_out_of_slices
def type_alias_statement(self):
return self.__s.type_alias_statement
def type_alias_statement_class_scope_lambda(self):
return self.__s.type_alias_statement_class_scope_lambda
def template_string_literal(self):
return self.__s.template_string_literal
def bytes_format(self):
return self.__s.bytes_format
def bytearray_format(self):
return self.__s.bytearray_format
def dict_union(self):
return self.__s.dict_union
def dict_union_merge(self):
return self.__s.dict_union_merge
def builtin_generic_type_annotations(self):
return self.__s.builtin_generic_type_annotations
def function_decorators(self):
return self.__s.function_decorators
def class_decorators(self):
return self.__s.class_decorators
def relaxed_decorators(self):
return self.__s.relaxed_decorators
def module_dir_func(self):
return self.__s.module_dir_func
def module_getattr_func(self):
return self.__s.module_getattr_func
def union_types(self):
return self.__s.union_types
def pattern_matching(self):
return self.__s.pattern_matching
def super_no_args(self):
return self.__s.super_no_args
def maybe_annotations(self):
return self.__s.maybe_annotations
def metaclass_class_keyword(self):
return self.__s.metaclass_class_keyword
def generic_class(self):
return self.__s.generic_class
def unpacking_in_comprehension(self):
return self.__s.unpacking_in_comprehension
def lazy_imports(self):
return self.__s.lazy_imports
def lazy_modules(self):
return self.__s.lazy_modules
def slice_subscription(self):
return self.__s.slice_subscription
def unary_plus_match_pattern(self):
return self.__s.unary_plus_match_pattern
def __get_source_line(self, line, col=0):
if self.__s.source is None:
return None # pragma: no cover
if self.__s.lines is None:
self.__s.lines = self.__s.source.splitlines()
if 0 < line <= len(self.__s.lines):
cur = self.__s.lines[line - 1]
if col >= 0:
return cur[col:]
return cur # pragma: no cover
return None
def __get_source_lines(self, line_begin, amount):
res = []
for line in range(line_begin, line_begin + amount + 1):
value = self.__get_source_line(line)
if value is not None:
res.append(value)
return "\n".join(res)
def except_star(self):
return self.__s.except_star
def __is_violation(self, versions):
"""Check if versions violate targets. Versions being None indicates a verbose message, and
version violations are not checked.
"""
# versions none indicates verbose message, not that no compatible versions found
if versions is None:
return False
# If all version entries are sentinels or `None`, no real constraints exist.
if all(v is None or v == (0, 0) for v in versions):
return False
# compare_requirements considers violation if no targets, which we don't want
targets = self.__s.config.targets()
if not targets:
return False
# exactness only relevant after performing a min-reduction across all found requirements
violation = not compare_requirements(versions, targets, ignore_exact=True)
if violation:
self.__s.found_violation = True
return violation
def found_violation(self):
"""Whether any violations were found during the visit."""
return self.__s.found_violation
def __show_analysis(self, violation):
"""Whether to show analysis results. We only show violations in show-only-violations mode."""
return violation or not self.__s.config.only_show_violations()
def __add_versions_entity(self, mins, versions, info=None, vvprint=False, entity=None,
plural=None):
# Whether to show verbose print/version info
violation = self.__is_violation(versions)
show = self.__show_analysis(violation)
if show and info is not None:
if versions in self.__s.info_versions:
self.__s.info_versions[versions].append(info)
else:
self.__s.info_versions[versions] = [info]
if vvprint:
self.__vvprint(info, entity=entity, versions=versions, plural=plural, violation=violation)
return combine_versions(mins, versions, self.__s.config, self.__s.info_versions)
def minimum_versions(self):
mins = [(0, 0), (0, 0)]
if self.printv2():
# Must be like this, not `combine_versions(2.0, None)`, since in py2 all print statements call
# `visit_Print()` but in py3 it's just a regular function via
# `Call(func=Name(id="print"..)..)`. Otherwise it will say not compatible with 3 when run on
# py3. The reason for now using `combine_versions(2.0, 3.0)` is that in py2 we cannot
# distinguish `print x` from `print(x)` - the first fails in py3 but not the second form.
mins[0] = (2, 0) # pragma: no cover
if self.printv3():
# print() is used so often that we only want to show it once, and with no line.
self.__vvprint("print(expr)", line=-1, versions=[(2, 0), (3, 0)])
mins = self.__add_versions_entity(mins, ((2, 0), (3, 0)))
if self.format27():
mins = self.__add_versions_entity(mins, ((2, 7), (3, 0)), "`\"..{}..\".format(..)`")
if self.longv2():
# `long` is also in `MOD_MEM_REQS`, which means it will trigger below, so we don't put an
# entity description here.
mins = self.__add_versions_entity(mins, ((2, 0), None))
if self.bytesv3():
# Since byte strings are a `str` synonym as of 2.6+, (2, 6) is returned instead of None.
# Ref: https://github.com/netromdk/vermin/issues/32
mins = self.__add_versions_entity(mins, ((2, 6), (3, 0)), "'bytes' type")
if self.fstrings():
mins = self.__add_versions_entity(mins, (None, (3, 6)), "f-strings")
if self.fstrings_self_doc():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "self-documenting f-strings")
if self.fstrings_pep701():
mins = self.__add_versions_entity(mins, (None, (3, 12)), "f-strings (PEP 701)")
if self.fstrings_await():
mins = self.__add_versions_entity(mins, (None, (3, 7)), "`await` in f-string")
if self.bool_const(): # pragma: no cover
mins = self.__add_versions_entity(mins, ((2, 3), (3, 0)), "'bool' constant")
if self.annotations():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "annotations")
if self.var_annotations():
mins = self.__add_versions_entity(mins, (None, (3, 6)), "variable annotations")
if self.final_annotations():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "Final annotations")
if self.literal_annotations():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "Literal annotations")
if self.coroutines():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "coroutines")
if self.async_generator():
mins = self.__add_versions_entity(mins, (None, (3, 6)), "async generators")
# NOTE: While async comprehensions and await in comprehensions should be in 3.6, they were first
# put into 3.7 for some reason!
if self.async_comprehension():
mins = self.__add_versions_entity(mins, (None, (3, 7)), "async comprehensions")
if self.await_in_comprehension():
mins = self.__add_versions_entity(mins, (None, (3, 7)), "await in comprehension")
if self.async_for():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "async for-loop")
if self.named_expressions():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "named expressions")
if self.kw_only_args():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "keyword-only arguments")
if self.pos_only_args():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "position only arguments")
if self.nonlocal_stmt():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "'nonlocal' statement")
if self.yield_from():
mins = self.__add_versions_entity(mins, (None, (3, 3)), "yield from")
if self.raise_cause():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "exception cause")
if self.raise_from_none():
mins = self.__add_versions_entity(mins, (None, (3, 3)), "raise ... from None")
if self.set_literals():
mins = self.__add_versions_entity(mins, ((2, 7), (3, 0)), "set literals")
if self.set_comprehension():
mins = self.__add_versions_entity(mins, ((2, 7), (3, 0)), "set comprehension")
if self.dict_comprehension():
mins = self.__add_versions_entity(mins, ((2, 7), (3, 0)), "dict comprehension")
if self.infix_matrix_multiplication():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "infix matrix multiplication")
if self.continue_in_finally():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "'continue' in 'finally'")
if self.modular_inverse_pow():
mins = self.__add_versions_entity(mins, (None, (3, 8)), "modular inverse 'pow()'")
if self.with_statement():
mins = self.__add_versions_entity(mins, ((2, 5), (3, 0)), "'with' statement")
if self.async_with_statement():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "'async with' statement")
if self.multi_withitem():
mins = self.__add_versions_entity(mins, ((2, 7), (3, 1)),
"multiple context expressions in a 'with' statement",
plural=True)
if self.with_parentheses():
msg = "multiple context expressions in a `with` statement with parentheses"
mins = self.__add_versions_entity(mins, (None, (3, 9)), msg)
if self.generalized_unpacking():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "generalized unpacking")
if self.unpacking_assignment():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "unpacking assignment")
if self.ellipsis_out_of_slices():
mins = self.__add_versions_entity(mins, (None, (3, 0)),
"ellipsis literal (`...`) out of slices", plural=False)
if self.type_alias_statement():
mins = self.__add_versions_entity(mins, (None, (3, 12)),
"type alias statement (`type X = SomeType`)", plural=False)
if self.type_alias_statement_class_scope_lambda():
mins = self.__add_versions_entity(mins, (None, (3, 13)),
"type alias statement using lambda/comp in class scope",
plural=False)
if self.template_string_literal():
mins = self.__add_versions_entity(mins, (None, (3, 14)),
"template string literal (`t'text {var}'`)",
plural=False)
if self.bytes_format():
# Since byte strings are a `str` synonym as of 2.6+, and thus also supports `%` formatting,
# (2, 6) is returned instead of None.
mins = self.__add_versions_entity(mins, ((2, 6), (3, 5)), "bytes format")
if self.bytearray_format():
mins = self.__add_versions_entity(mins, (None, (3, 5)), "bytearray format")
if self.dict_union():
mins = self.__add_versions_entity(mins, (None, (3, 9)), "dict union")
if self.dict_union_merge():
mins = self.__add_versions_entity(mins, (None, (3, 9)), "dict union merge")
if self.builtin_generic_type_annotations():
mins = self.__add_versions_entity(mins, (None, (3, 9)), "builtin generic type annotations")
if self.function_decorators():
mins = self.__add_versions_entity(mins, ((2, 4), (3, 0)), "function decorators")
if self.class_decorators():
mins = self.__add_versions_entity(mins, ((2, 6), (3, 0)), "class decorators")
if self.relaxed_decorators():
mins = self.__add_versions_entity(mins, (None, (3, 9)), "relaxed decorators")
if self.pattern_matching():
mins = self.__add_versions_entity(mins, (None, (3, 10)), "pattern matching")
if self.union_types():
mins = self.__add_versions_entity(mins, (None, (3, 10)), "union types as `X | Y`",
plural=True)
if self.super_no_args():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "super() without arguments",
plural=False)
if self.except_star():
mins = self.__add_versions_entity(mins, (None, (3, 11)), "`except*`")
if self.metaclass_class_keyword():
mins = self.__add_versions_entity(mins, (None, (3, 0)), "'metaclass' class keyword")
if self.generic_class():
mins = self.__add_versions_entity(mins, (None, (3, 12)), "generic class `class C[T]: ...`")
if self.unpacking_in_comprehension():
mins = self.__add_versions_entity(mins, (None, (3, 15)),
"unpacking in comprehension (PEP 798)")
if self.lazy_imports():
mins = self.__add_versions_entity(mins, (None, (3, 15)),
"lazy imports (PEP 810)")
if self.slice_subscription():
mins = self.__add_versions_entity(mins, (None, (3, 15)),
"slice subscription")
if self.unary_plus_match_pattern():
mins = self.__add_versions_entity(mins, (None, (3, 15)),
"unary `+` in match literal pattern")
for directive in self.strftime_directives():
if directive in STRFTIME_REQS:
vers = STRFTIME_REQS[directive]
mins = self.__add_versions_entity(mins, vers, "strftime directive '{}'".format(directive),
vvprint=True, entity=directive)
for directive in self.bytes_directives():
if directive in BYTES_REQS:
vers = BYTES_REQS[directive]
mins = self.__add_versions_entity(mins, vers, "bytes directive '{}'".format(directive),
vvprint=True, entity=directive)
for typecode in self.array_typecodes():
if typecode in ARRAY_TYPECODE_REQS:
vers = ARRAY_TYPECODE_REQS[typecode]
mins = self.__add_versions_entity(mins, vers, "array typecode '{}'".format(typecode),
vvprint=True, entity=typecode)
for name in self.codecs_error_handlers():
if name in CODECS_ERROR_HANDLERS:
vers = CODECS_ERROR_HANDLERS[name]
mins = self.__add_versions_entity(mins, vers, "codecs error handler name '{}'".format(name),
vvprint=True, entity=name)
for encoding in self.codecs_encodings():
for (encs, vers) in CODECS_ENCODINGS.items():
if encoding.lower() in encs:
mins = self.__add_versions_entity(mins, vers, "codecs encoding '{}'".format(encoding),
vvprint=True, entity=encoding)
mods = self.modules()
for mod in mods:
if mod in self.__s.mod_rules:
vers = self.__s.mod_rules[mod]
mins = self.__add_versions_entity(mins, vers, "'{}' module".format(mod), vvprint=True,
entity=mod)
mems = self.members()
for mem in mems:
if mem in self.__s.mod_mem_reqs_rules:
vers = self.__s.mod_mem_reqs_rules[mem]
mins = self.__add_versions_entity(mins, vers, "'{}' member".format(mem), vvprint=True,
entity=mem)
kwargs = self.kwargs()
for fn_kw in kwargs:
if fn_kw in self.__s.kwargs_reqs_rules:
vers = self.__s.kwargs_reqs_rules[fn_kw]
mins = self.__add_versions_entity(mins, vers, "'{}({})'".format(fn_kw[0], fn_kw[1]),
vvprint=True, entity=fn_kw)
for user_func_deco in self.user_function_decorators():
if user_func_deco in DECORATOR_USER_FUNCTIONS:
vers = DECORATOR_USER_FUNCTIONS[user_func_deco]
mins = self.__add_versions_entity(mins, vers, "'{}' user function decorator".
format(user_func_deco), vvprint=True,
entity=user_func_deco)
return mins
def output_text(self):
# Sort the output lines.
text = self.__s.output_text
self.__s.output_text = self.__s.config.format().sort_output_lines(text)
text = "\n".join(self.__s.output_text)
if len(text) > 0:
text += "\n"
return text
def add_error_message(self, line):
"""Manually add an error message line to the output text."""
# treat as a violation
self.__s.found_violation = True
self.__s.output_text.append(line)
def set_no_lines(self, lines):
self.__no_lines = lines
def no_lines(self):
return self.__no_lines
def __nprint(self, msg):
if not self.__s.config.quiet(): # pragma: no cover
self.__s.output_text.append(msg)
# pragma: no cover
def __verbose_print(self, msg, level, entity=None, line=None,
versions=None, plural=None, violation=None):
"""Violation bool is inferred if not provided."""
if violation is None:
violation = self.__is_violation(versions)
if not self.__show_analysis(violation):
return
fmt = self.__s.config.format()
config_level = self.__s.config.verbose()
if fmt.skip_output_line() or config_level < level:
return
col = None
# Line/column numbers start at level 3+ or for parsable format.
entity = entity if config_level > 2 else None
if entity is not None and entity in self.__s.line_col_entities:
(line, col) = self.__s.line_col_entities[entity]
if line == -1:
line = None
elif line is None and config_level > 2:
line = self.__s.line
msg = fmt.format_output_line(msg, self.__s.path, line, col, versions, plural, violation)
# Deduplicate output by feature identity to avoid same feature producing multiple lines.
versions_key = None
if versions is not None:
versions_key = tuple(tuple(v) if v is not None else None for v in versions)
fingerprint = (msg, versions_key, entity)
if fingerprint in self.__s.output_seen:
return
self.__s.output_seen.add(fingerprint)
self.__s.output_text.append(msg)
def __vvprint(self, msg, entity=None, line=None,
versions=None, plural=None, violation=None): # pragma: no cover
self.__verbose_print(msg, 2, entity, line, versions, plural=plural, violation=violation)
def __vvvprint(self, msg, entity=None, line=None,
versions=None, plural=None, violation=None): # pragma: no cover
self.__verbose_print(msg, 3, entity, line, versions, plural=plural, violation=violation)
# pragma: no cover
def __vvvvprint(self, msg, entity=None, line=None,
versions=None, plural=None, violation=None):
self.__verbose_print(msg, 4, entity, line, versions, plural=plural, violation=violation)
def __add_module(self, module, line=None, col=None):
if module in self.__s.user_defs: # pragma: no cover
self.__vvvvprint("Ignoring module '{}' because it's user-defined!".format(module))
return
if self.__s.config.is_excluded(module):
self.__vvprint("Excluding module: {}".format(module))
return
if module not in self.__s.modules:
self.__s.modules.append(module)
self.__add_line_col(module, line, col)
def __add_member(self, member, line=None, col=None):
"""Add member if fully-qualified name is known."""
if member in self.__s.user_defs:
self.__vvvvprint("Ignoring member '{}' because it's user-defined!".format(member))
return
if self.__s.config.is_excluded(member):
self.__vvprint("Excluding member: {}".format(member))
return
if member in self.__s.mod_mem_reqs_rules:
self.__s.members.append(member)
self.__add_line_col(member, line, col)
def __add_kwargs(self, function, keyword, line=None, col=None):
if function in self.__s.user_defs: # pragma: no cover
self.__vvvvprint("Ignoring function '{}' because it's user-defined!".format(function))
return False
if self.__s.config.is_excluded_kwarg(function, keyword):
self.__vvprint("Excluding kwarg: {}({})".format(function, keyword))
return None
fn_kw = (function, keyword)
if fn_kw not in self.__s.kwargs:
self.__s.kwargs.append(fn_kw)
self.__add_line_col(fn_kw, line, col)
return True
def __add_user_func_deco(self, ufd, line=None, col=None):
if ufd in self.__s.user_defs: # pragma: no cover
self.__vvvvprint("Ignoring user function decorator '{}' because it's user-defined!".
format(ufd))
return
if self.__s.config.is_excluded(ufd): # pragma: no cover
self.__vvprint("Excluding user function decorator: {}".format(ufd))
return
if ufd in DECORATOR_USER_FUNCTIONS:
self.__s.user_func_decorators.append(ufd)
self.__add_line_col(ufd, line, col)
def __add_strftime_directive(self, group, line=None, col=None):
self.__s.strftime_directives.append(group)
self.__add_line_col(group, line, col)
def __add_bytes_directive(self, group, line=None, col=None):
self.__s.bytes_directives.append(group)
self.__add_line_col(group, line, col)
def __add_codecs_error_handler(self, func, node):
if func in CODECS_ERRORS_INDICES:
idx = CODECS_ERRORS_INDICES[func]
# Check indexed arguments.
if 0 <= idx < len(node.args):
arg = node.args[idx]
name = None
if sys.version_info >= (3, 8) and isinstance(arg, getattr(ast, "Constant")):
name = arg.value
elif hasattr(arg, "s"):
name = arg.s
if name is not None:
if self.__s.config.is_excluded_codecs_error_handler(name):
self.__vvprint("Excluding codecs error handler: {}".format(name))
else:
self.__s.codecs_error_handlers.append(name)
self.__add_line_col(name, node.lineno)
# Check for "errors" keyword arguments.
for kw in node.keywords:
if kw.arg == "errors":
if sys.version_info >= (3, 8) and isinstance(kw.value, getattr(ast, "Constant")):
name = kw.value.value
elif hasattr(kw.value, "s"):
name = kw.value.s
else:
continue
if self.__s.config.is_excluded_codecs_error_handler(name):
self.__vvprint("Excluding codecs error handler: {}".format(name))
continue
self.__s.codecs_error_handlers.append(name)
self.__add_line_col(name, node.lineno)
def __add_codecs_encoding(self, func, node):
if func in CODECS_ENCODINGS_INDICES:
for idx in CODECS_ENCODINGS_INDICES[func]:
# Check indexed arguments.
if 0 <= idx < len(node.args):
arg = node.args[idx]
if sys.version_info >= (3, 8) and isinstance(arg, getattr(ast, "Constant")):
name = arg.value
elif hasattr(arg, "s"):
name = arg.s
else:
continue
if self.__s.config.is_excluded_codecs_encoding(name):
self.__vvprint("Excluding codecs encoding: {}".format(name))
continue
self.__s.codecs_encodings.append(name)
self.__add_line_col(name, node.lineno)
# Check for "encoding", "data_encoding", "file_encoding" keyword arguments.
for kw in node.keywords:
if kw.arg in self.__s.codecs_encodings_kwargs:
if sys.version_info >= (3, 8) and isinstance(kw.value, getattr(ast, "Constant")):
name = kw.value.value
elif hasattr(kw.value, "s"):
name = kw.value.s
else:
continue
if self.__s.config.is_excluded_codecs_encoding(name):
self.__vvprint("Excluding codecs encoding: {}".format(name))
continue
self.__s.codecs_encodings.append(name)
self.__add_line_col(name, node.lineno)
def __check_codecs_function(self, func, node):
self.__add_codecs_error_handler(func, node)
self.__add_codecs_encoding(func, node)
def __add_user_def(self, name):
self.__s.user_defs.add(name)
def __add_user_def_node(self, node):
if isinstance(node, ast.Name) and isinstance(node.ctx, (ast.Store, ast.Param)):
self.__add_user_def(node.id)
elif isinstance(node, str):
self.__add_user_def(node)
def __add_name_res(self, source, target):
self.__s.name_res[source] = target
def __add_name_res_type(self, source, target):
"""Keep source -> target in a dictionary. If source already exists then convert target to a set
and add the new target value to it (if different).
"""
if source not in self.__s.name_res_type:
self.__s.name_res_type[source] = {target}
else:
self.__s.name_res_type[source].add(target)
def __is_builtin_type(self, name):
return name in self.__s.builtin_types
def __resolve_module_name(self, name):
return self.__s.module_as_name[name] if name in self.__s.module_as_name else name
def __get_attribute_name(self, node):
"""Retrieve full attribute name path, like ["ipaddress", "IPv4Address"] from:
`Attribute(value=Name(id='ipaddress', ctx=Load()), attr='IPv4Address', ctx=Load())`
Or ["Fraction", "as_integer_ratio"] from:
`Attribute(value=Call(func=Name(id='Fraction', ctx=Load()), args=[Num(n=42)], keywords=[]),
attr='as_integer_ratio', ctx=Load())`
"""
full_name = []
primi_type = False
for attr in ast.walk(node):
if len(full_name) > 0 and self.__is_builtin_type(full_name[0]):
primi_type = True
if isinstance(attr, ast.Attribute):
if hasattr(attr, "attr"):
full_name.append(attr.attr)
if hasattr(attr, "value") and hasattr(attr.value, "id"):
full_name.append(self.__resolve_module_name(attr.value.id))
elif isinstance(attr, ast.Call):
if hasattr(attr, "func") and hasattr(attr.func, "id"):
full_name.append(attr.func.id)
elif not primi_type:
if isinstance(attr, ast.Dict):
if len(full_name) == 0 or (full_name[0] != "dict" and full_name[-1] != "dict"):
full_name.append("dict")
elif isinstance(attr, ast.Set):
if len(full_name) == 0 or (full_name[0] != "set" and full_name[-1] != "set"):
full_name.append("set")
elif isinstance(attr, ast.List):
if len(full_name) == 0 or (full_name[0] != "list" and full_name[-1] != "list"):
full_name.append("list")
elif sys.version_info >= (3, 8):
if isinstance(attr, getattr(ast, "Constant")):
if isinstance(attr.value, str):
name = "str"
if len(full_name) == 0 or (full_name[0] != name and len(full_name) == 1):
full_name.append(name)
elif isinstance(attr.value, (int, float)):
name = "int" if isinstance(attr.value, int) else "float"
if name is not None and (len(full_name) == 0 or
(full_name[0] != name and len(full_name) == 1)):
full_name.append(name)
elif isinstance(attr.value, bytes):
if len(full_name) == 0 or (full_name[0] != "bytes" and len(full_name) == 1):
full_name.append("bytes")
else:
if isinstance(attr, ast.Str):
name = "str"
if len(full_name) == 0 or (full_name[0] != name and len(full_name) == 1):
full_name.append(name)
elif isinstance(attr, ast.Num):
t = type(attr.n)
name = None
if t is int:
name = "int"
elif t is float:
name = "float"
if name is not None and (len(full_name) == 0 or
(full_name[0] != name and len(full_name) == 1)):
full_name.append(name)
elif hasattr(ast, "Bytes") and isinstance(attr, ast.Bytes):
if len(full_name) == 0 or (full_name[0] != "bytes" and len(full_name) == 1):
full_name.append("bytes")
full_name.reverse()
return full_name
def __add_name_res_assign_node(self, node):
if not hasattr(node, "value"):
return # pragma: no cover
value_name = None
type_name = None
# If rvalue is a Call.
if isinstance(node.value, ast.Call):
if isinstance(node.value.func, ast.Name):
value_name = node.value.func.id
elif isinstance(node.value.func, ast.Attribute):
value_name = dotted_name(self.__get_attribute_name(node.value.func))
# If rvalue is an Attribute list
elif isinstance(node.value, ast.Attribute):
value_name = dotted_name(self.__get_attribute_name(node.value))
elif isinstance(node.value, ast.Dict):
value_name = "dict"
elif isinstance(node.value, ast.Set):
value_name = "set"
elif isinstance(node.value, ast.List):
value_name = "list"
# If rvalue is None
elif sys.version_info >= (3, 8) and \
isinstance(node.value, getattr(ast, "Constant")) and node.value.value is None:
type_name = "None"
elif ((3, 8) > sys.version_info >= (3, 4)) and \
isinstance(node.value, ast.NameConstant) and node.value.value is None:
type_name = "None"
elif ((3, 4) > sys.version_info) and \
isinstance(node.value, ast.Name) and node.value.id == "None":
type_name = "None"
# When a type name is used, and not a type instance.
elif isinstance(node.value, ast.Name):
type_name = node.value.id
elif sys.version_info >= (3, 8):
if isinstance(node.value, getattr(ast, "Constant")):
v = node.value.value
if isinstance(v, str):
value_name = "str"
elif isinstance(v, int):
value_name = "int"
elif isinstance(v, float):
value_name = "float"
elif isinstance(v, bytes):
value_name = "bytes"
else:
if isinstance(node.value, ast.Str):
value_name = "str"
elif isinstance(node.value, ast.Num):
n = node.value.n
if isinstance(n, int):
value_name = "int"
elif isinstance(n, float):
value_name = "float"
elif hasattr(ast, "Bytes") and isinstance(node.value, ast.Bytes):
value_name = "bytes"
if value_name is None and type_name is None:
return
targets = []
if hasattr(node, "targets"):
targets = node.targets
elif hasattr(node, "target"):
targets.append(node.target)
for target in targets:
if isinstance(target, ast.Name):
target_name = target.id
if value_name is not None:
self.__add_name_res(target_name, value_name)
elif type_name is not None:
self.__add_name_res_type(target_name, type_name)
def __add_line_col(self, entity, line, col=None):
if line is not None:
self.__s.line_col_entities[entity] = (line, col)
def __add_array_typecode(self, typecode, line=None, col=None):
if typecode not in self.__s.array_typecodes:
self.__s.array_typecodes.append(typecode)
self.__add_line_col(typecode, line, col)
def __is_no_line(self, line):
return line in self.__no_lines
def __check_unpacking_in_comprehension(self, value):
# Via PEP 798, check for `*x`/`**x` as the leading value expr of a comprehension. Dict `**`
# comprehensions are represented with `value=None`.
if value is None or isinstance(value, ast.Starred):
if not self.__s.unpacking_in_comprehension:
self.__s.unpacking_in_comprehension = True
self.__vvprint("unpacking in comprehension (PEP 798)", versions=[None, (3, 15)])
def __after_visit_all(self):
# Remove any modules and members that were added before any known user-definitions. Do it in
# reverse so the indices are kept while traversing!
for ud in self.__s.user_defs:
for i in reverse_range(self.__s.modules):
if self.__s.modules[i] == ud: # pragma: no cover
self.__vvvvprint("Ignoring module '{}' because it's user-defined!".format(ud))
del self.__s.modules[i]
for i in reverse_range(self.__s.members):
if self.__s.members[i] == ud: # pragma: no cover
self.__vvvvprint("Ignoring member '{}' because it's user-defined!".format(ud))
del self.__s.members[i]
# Entry point of source visitor.
def tour(self, node):
self.visit(node)
self.__after_visit_all()
def generic_visit(self, node):
if hasattr(node, "lineno"):
self.__s.line = node.lineno
self.__s.depth += 1
if self.__s.config.print_visits():
self.__nprint("| " * self.__s.depth + ast.dump(node)) # pragma: no cover
super().generic_visit(node)
self.__s.depth -= 1
def visit_Import(self, node):
if self.__is_no_line(node.lineno):
return
# PEP 810: `lazy import` (3.15+).
if hasattr(node, "is_lazy") and node.is_lazy:
self.__s.lazy_imports = True
self.__vvprint("lazy imports (PEP 810)", line=node.lineno,
versions=[None, (3, 15)])
for name in node.names:
line = node.lineno
col = node.col_offset + 7 # "import" = 6 + 1
self.__add_module(name.name, line, col)
self.__add_member(name.name, line, col)
if hasattr(name, "asname") and name.asname is not None:
self.__s.module_as_name[name.asname] = name.name
self.__add_user_def(name.asname)
def visit_ImportFrom(self, node):
if node.module is None:
return # pragma: no cover
# Ignore modules that aren't top-level, such as `.typing` and `..typing` that are relative and
# might be files in local packages.
if hasattr(node, "level") and node.level > 0:
return
if self.__is_no_line(node.lineno):
return
# PEP 810: `lazy from ... import` (3.15+).
if hasattr(node, "is_lazy") and node.is_lazy:
self.__s.lazy_imports = True
self.__vvprint("lazy imports (PEP 810)", line=node.lineno,
versions=[None, (3, 15)])
from_col = 5 # "from" = 4 + 1
self.__add_module(node.module, node.lineno, node.col_offset + from_col)
# Remember module members and full module paths, like "ABC" member of module "abc" and "abc.ABC"
# module.
for name in node.names:
if name.name == "*":
# Ignore star import.
pass
elif name.name is not None:
self.__s.import_mem_mod[name.name] = node.module
comb_name = "{}.{}".format(node.module, name.name)
line = node.lineno
col = node.col_offset + from_col
self.__add_module(comb_name, line, col)
self.__add_member(comb_name, line, col)
self.__add_member(name.name, line, col)
if hasattr(name, "asname") and name.asname is not None:
self.__s.module_as_name[name.asname] = node.module + "." + name.name
self.__add_user_def(name.asname)
def visit_Name(self, node):
if node.id == "long":
if self.__s.config.is_excluded("long"):
self.__vvprint("Excluding long type")
elif "long" in self.__s.user_defs:
self.__vvvvprint("Ignoring member 'long' because it's user-defined!")
else:
self.__s.longv2 = True
self.__vvprint("long is a v2 feature")
elif node.id in ("True", "False"):
self.__s.bool_const = True
self.__vvvprint("True/False constant", versions=[(2, 3), (3, 0)])
elif node.id == "__lazy_modules__":
# Detected but no version requirement because earlier Python versions ignore it.
self.__s.lazy_modules = True
self.__vvprint("`__lazy_modules__`", line=node.lineno)
def visit_Print(self, node): # pragma: no cover
self.__s.printv2 = True
self.generic_visit(node)
def visit_Starred(self, node):
# Unpacking assignment is when a starred expression `*` is used on the left-hand side of an
# assignment, like `*a, b = [1, 2, 3]`.
if isinstance(node.ctx, ast.Store):
self.__s.unpacking_assignment = True
self.__vvprint("unpacking assignment", versions=[None, (3, 0)])
self.generic_visit(node)
def __check_generalized_unpacking(self, node):
def has_gen_unp():
self.__s.generalized_unpacking = True
self.__vvprint("generalized unpacking", versions=[None, (3, 5)])
# Call arguments and keywords: Check if more than one unpacking is used or if unpacking is used
# before the end. This is so because in 3.4, unpacking in function call parameter list is only
# allowed at the end of the parameter list, and only one unpacking is allowed.
if isinstance(node, ast.Call):
def check_gen_unp(pos, total):
val = len(pos) > 1 or any(p < total - 1 for p in pos)
if val:
has_gen_unp()
return val
if hasattr(node, "args") and hasattr(ast, "Starred"):
total = len(node.args)
pos = []
for i in range(total):
if is_valid_star_unpack(node.args[i]):
pos.append(i)
if check_gen_unp(pos, total):
return
if hasattr(node, "keywords"):
total = len(node.keywords)
pos = []
for i in range(total):
kw = node.keywords[i]
if kw.arg is None and kw.value is not None:
pos.append(i)
if check_gen_unp(pos, total):
return
# Any unpacking in tuples, sets, or lists is generalized unpacking.
elif isinstance(node, (ast.Tuple, ast.Set, ast.List)) and hasattr(ast, "Starred"):
if any(is_valid_star_unpack(elt) for elt in node.elts):
has_gen_unp()
return
# Any unpacking in dicts is generalized unpacking.
elif isinstance(node, ast.Dict):
if any(key is None and value is not None
for (key, value) in zip(node.keys, node.values)):
has_gen_unp()
def __push_function_name(self, name):
self.__s.function_name = name
self.__s.function_name_stack.append(name)
def __pop_function_name(self):
self.__s.function_name = self.__s.function_name_stack.pop() \
if len(self.__s.function_name_stack) > 0 else None
def visit_Call(self, node):
if self.__is_no_line(node.lineno):
return
if hasattr(node, "func"):
func = node.func
if hasattr(func, "id"):
self.__push_function_name(func.id)
self.__add_member(func.id, node.lineno, node.col_offset)
if func.id in self.__s.import_mem_mod:
name = self.__s.import_mem_mod[func.id] + "." + func.id
self.__check_codecs_function(name, node)
elif func.id in self.__s.module_as_name:
name = self.__s.module_as_name[func.id]
self.__check_codecs_function(name, node)
if func.id == "print":
self.__s.printv3 = True
elif func.id == "array" or\
(func.id in self.__s.module_as_name and
self.__s.module_as_name[func.id] == "array.array"):
for arg in node.args:
if sys.version_info >= (3, 8):
if isinstance(arg, getattr(ast, "Constant")) and isinstance(arg.value, str):
# "array" = 5 + 1 = 6
self.__add_array_typecode(arg.value, node.lineno, node.col_offset + 6)
else:
if isinstance(arg, ast.Str) and hasattr(arg, "s"):
# "array" = 5 + 1 = 6
self.__add_array_typecode(arg.s, node.lineno, node.col_offset + 6)
elif func.id == "pow" and len(node.args) == 3:
# Check if the second of three arguments of pow() is negative.
if is_int_node(node.args[0]) and is_neg_int_node(node.args[1]) and \
is_int_node(node.args[2]):
self.__s.mod_inverse_pow = True
self.__vvprint("modular inverse pow()", versions=[None, (3, 8)])
elif func.id == "super" and len(node.args) == 0:
self.__s.super_no_args = True
self.__vvprint("super() without arguments", versions=[None, (3, 0)], plural=False)
elif hasattr(func, "attr"):
attr = func.attr
if (sys.version_info >= (3, 8) and attr == "format" and hasattr(func, "value") and
isinstance(func.value, getattr(ast, "Constant")) and
isinstance(func.value.value, str) and
"{}" in func.value.value) \
or \
(sys.version_info < (3, 8) and attr == "format" and hasattr(func, "value") and
isinstance(func.value, ast.Str) and
"{}" in func.value.s):
# There cannot be "{" before or "}" after an occurrence of "{}" since "{{}}" means simply
# an escaped "{}" and won't be replaced.
if (sys.version_info >= (3, 8) and
STR_27_FORMAT_REGEX.search(func.value.value) is not None) \
or \
(sys.version_info < (3, 8) and STR_27_FORMAT_REGEX.search(func.value.s) is not None):
self.__vvprint("`\"..{}..\".format(..)`", versions=[(2, 7), (3, 0)])
self.__s.format27 = True
elif attr in ("strftime", "strptime") and hasattr(node, "args"):
for arg in node.args:
look_for = None
if sys.version_info >= (3, 8) and isinstance(arg, getattr(ast, "Constant")):
look_for = arg.value
elif hasattr(arg, "s"):
look_for = arg.s
if look_for is not None:
for directive in STRFTIME_DIRECTIVE_REGEX.findall(look_for):
self.__add_strftime_directive(directive, node.lineno)
if isinstance(func, ast.Attribute):
self.__push_function_name(dotted_name(self.__get_attribute_name(func)))
self.__check_codecs_function(self.__s.function_name, node)
if self.__s.function_name == "array.array":
for arg in node.args:
if sys.version_info >= (3, 8):
if isinstance(arg, getattr(ast, "Constant")) and isinstance(arg.value, str):
# "array.array" = 5 + 1 + 5 + 1 = 12
self.__add_array_typecode(arg.value, node.lineno, node.col_offset + 12)
else:
if isinstance(arg, ast.Str) and hasattr(arg, "s"):
# "array.array" = 5 + 1 + 5 + 1 = 12
self.__add_array_typecode(arg.s, node.lineno, node.col_offset + 12)
self.__check_generalized_unpacking(node)
self.generic_visit(node)
self.__pop_function_name()
def visit_Attribute(self, node):
full_name = self.__get_attribute_name(node)
line = node.lineno
if len(full_name) > 0:
dotted = dotted_name(full_name)
for mod in self.__s.modules:
if full_name[0] == mod:
self.__add_module(dotted, line)
elif full_name[0] in self.__s.import_mem_mod:
self.__add_member(dotted_name([self.__s.import_mem_mod[full_name[0]], full_name]),
line)
self.__add_member(dotted, line)
if full_name[0] in self.__s.name_res:
res = self.__s.name_res[full_name[0]]
if res in self.__s.import_mem_mod:
mod = self.__s.import_mem_mod[res]
self.__add_member(dotted_name([mod, res, full_name[1:]]), line)
# Try as a fully-qualified name.
else:
self.__add_member(dotted_name([res, full_name[1:]]), line)
# Check for two-tier names, like
# d = {} <- "dict"
# i = d.items() <- "dict.items"
# i.mapping <- "dict.items.mapping"
parts = res.split(".")
if len(parts) > 0 and parts[0] in self.__s.name_res:
res2 = self.__s.name_res[parts[0]]
self.__add_member(dotted_name([res2, parts[1:], full_name[1:]]), line)
self.generic_visit(node)
def visit_keyword(self, node):
excluded = False
for func_name in self.__s.function_name_stack:
# kwarg related.
exp_name = func_name.split(".")
# Check if function is imported from module.
if func_name in self.__s.import_mem_mod:
mod = self.__s.import_mem_mod[func_name]
excluded |= \
self.__add_kwargs(dotted_name([mod, func_name]), node.arg, self.__s.line) is None
# When having "ElementTree.tostringlist", for instance, and include mapping "{'ElementTree':
# 'xml.etree'}" then try piecing them together to form a match.
elif exp_name[0] in self.__s.import_mem_mod:
mod = self.__s.import_mem_mod[exp_name[0]]
excluded |= \
self.__add_kwargs(dotted_name([mod, func_name]), node.arg, self.__s.line) is None
# Lookup indirect names via variables.
elif exp_name[0] in self.__s.name_res:
res = self.__s.name_res[exp_name[0]]
if res in self.__s.import_mem_mod:
mod = self.__s.import_mem_mod[res]
excluded |= \
self.__add_kwargs(dotted_name([mod, res, exp_name[1:]]), node.arg,
self.__s.line) is None
# Try as FQN.
else:
excluded |= \
self.__add_kwargs(dotted_name([res, exp_name[1:]]), node.arg, self.__s.line) is None
# Only add direct function if not found via module/class/member.
else:
excluded |= self.__add_kwargs(func_name, node.arg, self.__s.line) is None
# A chained receiver, like `Path.cwd().exists(follow_symlinks=True)`, yields intermediate
# call(s) in the name (`Path.cwd.exists`) that hide the real method being called. When the
# full name didn't match a known kwarg rule, retry with the intermediate call(s) collapsed
# away, keeping the receiver plus the final method (`Path.exists`). The receiver root may
# already be resolved and span several segments (e.g. `pathlib.Path.cwd.exists`), so try
# every receiver-length prefix joined with the final method. Only accept a collapsed form
# that corresponds to an actual kwarg rule, to avoid false matches.
if len(exp_name) > 2:
method = exp_name[-1]
for end in range(len(exp_name) - 1, 0, -1):
collapsed = exp_name[:end] + [method]
# Resolve the receiver root the same way as the primary lookups above.
if collapsed[0] in self.__s.import_mem_mod:
collapsed = [self.__s.import_mem_mod[collapsed[0]]] + collapsed
elif collapsed[0] in self.__s.name_res:
res = self.__s.name_res[collapsed[0]]
if res in self.__s.import_mem_mod:
collapsed = [self.__s.import_mem_mod[res], res] + collapsed[1:]
else:
collapsed = [res] + collapsed[1:]
collapsed_name = dotted_name(collapsed)
if (collapsed_name, node.arg) in self.__s.kwargs_reqs_rules:
excluded |= self.__add_kwargs(collapsed_name, node.arg, self.__s.line) is None
break
# Visit keyword values unless the keyword rule was explicitly excluded.
if not excluded:
self.generic_visit(node)
def visit_Bytes(self, node):
self.__s.bytesv3 = True
self.__vvprint("byte string (b'..') or `str` synonym", versions=[(2, 6), (3, 0)])
if sys.version_info >= (3, 12):
for directive in BYTES_DIRECTIVE_REGEX.findall(str(node.value)):
self.__add_bytes_directive(directive, node.lineno)
else:
if hasattr(node, "s"):
for directive in BYTES_DIRECTIVE_REGEX.findall(str(node.s)):
self.__add_bytes_directive(directive, node.lineno)
def __is_dict(self, node):
"""Checks if node is a dict either by direct instance, name, constructor, function/lambda body,
or subscript index value."""
if isinstance(node, ast.Dict):
return True
if isinstance(node, ast.Name) and\
node.id in self.__s.name_res and self.__s.name_res[node.id] == "dict":
return True
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id == "dict":
return True
if isinstance(node.func, ast.Lambda) and self.__is_dict(node.func.body):
return True
elif isinstance(node, ast.Subscript):
n = None
if sys.version_info >= (3, 9):
if isinstance(node.slice, getattr(ast, "Constant")) and isinstance(node.slice.value, int):
n = node.slice.value
elif sys.version_info >= (3, 8):
if isinstance(node.slice, ast.Index) and \
isinstance(node.slice.value, getattr(ast, "Constant")) and \
isinstance(node.slice.value.value, int):
n = node.slice.value.value
else:
if isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.Num):
n = node.slice.value.n
if isinstance(n, int):
for tup in ast.iter_fields(node.value):
if (tup[0] == "elts" or tup[0] == "values") and n < len(tup[1]) and\
self.__is_dict(tup[1][n]):
return True
return False
def __resolve_full_name(self, name):
"""Tries to resolve name into a fully dotted name. Takes name as a string, ast.Name or
ast.Call(func=ast.Name)."""
if isinstance(name, ast.Name):
name = name.id
elif isinstance(name, ast.Call) and isinstance(name.func, ast.Name):
name = name.func.id
elif isinstance(name, ast.Attribute):
name = dotted_name(self.__get_attribute_name(name))
name = self.__s.name_res[name] if name in self.__s.name_res else name
if name in self.__s.module_as_name:
return self.__s.module_as_name[name]
if name in self.__s.import_mem_mod:
return dotted_name([self.__s.import_mem_mod[name], name])
return name
def visit_BinOp(self, node):
# Examples:
# BinOp(left=Bytes(s=b'%4x'), op=Mod(), right=Num(n=10))
# BinOp(left=Call(func=Name(id='bytearray', ctx=Load()), args=[Bytes(s=b'%x')], keywords=[]),
# op=Mod(), right=Num(n=10))
if (sys.version_info >= (3, 8) and isinstance(node.left, getattr(ast, "Constant")) and
isinstance(node.left.value, bytes) and
isinstance(node.op, ast.Mod)) or \
(sys.version_info < (3, 8) and
hasattr(ast, "Bytes") and isinstance(node.left, ast.Bytes) and
isinstance(node.op, ast.Mod)):
self.__s.bytes_format = True
self.__vvprint("bytes `%` formatting or `str` synonym", versions=[(2, 6), (3, 5)])
if (isinstance(node.left, ast.Call) and isinstance(node.left.func, ast.Name) and
node.left.func.id == "bytearray") and isinstance(node.op, ast.Mod):
self.__s.bytearray_format = True
self.__vvprint("bytearray `%` formatting", versions=[None, (3, 5)])
# Example:
# BinOp(left=Dict(keys=[Constant(value='a')], values=[Constant(value=1)]),
# op=BitOr(),
# right=Dict(keys=[Constant(value='b')], values=[Constant(value=2)]))
if isinstance(node.op, ast.BitOr):
def has_du():
self.__s.dict_union = True
self.__vvprint("dict union (dict | dict)", line=node.lineno, versions=[None, (3, 9)])
left_dict = self.__is_dict(node.left)
right_dict = self.__is_dict(node.right)
left_special = self.__resolve_full_name(node.left) in DICT_UNION_SUPPORTED_TYPES
right_special = self.__resolve_full_name(node.right) in DICT_UNION_SUPPORTED_TYPES
if (left_dict or left_special) and (right_dict or right_special):
has_du()
def is_none_or_name(node):
if is_none_node(node):
return True
name = None
if isinstance(node, ast.Name):
name = node.id
elif isinstance(node, ast.Attribute):
name = dotted_name(self.__get_attribute_name(node))
return name is not None and \
((name not in self.__s.name_res and name not in self.__s.user_defs) or
(name in self.__s.name_res_type))
if self.__s.union_types_enabled and is_none_or_name(node.left) and \
is_none_or_name(node.right):
self.__s.union_types = True
self.__vvprint("union types as `X | Y`", line=node.lineno, versions=[None, (3, 10)],
plural=True)
self.generic_visit(node)
def visit_Constant(self, node):
if hasattr(node, "value"):
# From 3.8, Bytes(s=b'%x') is represented as Constant(value=b'%x', kind=None) instead.
if isinstance(node.value, bytes):
self.__s.bytesv3 = True
self.__vvprint("byte string (b'..') or `str` synonym", versions=[(2, 6), (3, 0)])
for directive in BYTES_DIRECTIVE_REGEX.findall(str(node.value)):
self.__add_bytes_directive(directive, node.lineno)
if node.value is True or node.value is False:
self.__s.bool_const = True
self.__vvvprint("True/False constant", versions=[(2, 3), (3, 0)])
# From 3.8, Ellipsis() is represented as Constant(value=Ellipsis)
if is_ellipsis_node(node):
self.visit_Ellipsis(node)
def visit_JoinedStr(self, node):
self.__s.fstrings = True
self.__vvprint("f-strings", versions=[None, (3, 6)])
if self.__s.fstring_self_doc_enabled and hasattr(node, "values") and \
hasattr(node, "end_lineno"):
if self.__fstr.is_self_doc(node):
self.__s.fstrings_self_doc = True
self.__vvprint("self-documenting f-strings", versions=[None, (3, 8)])
# PEP 701 fstrings detection requires Python 3.12+ to parse the syntax in the first place, and
# avoids both false positives and false negatives.
if self.__s.fstrings_pep701_enabled and sys.version_info >= (3, 12) and \
hasattr(node, "values") and hasattr(node, "end_lineno"):
if self.__fstr.pep701_violation(node) is not None:
self.__s.fstrings_pep701 = True
self.__vvprint("f-strings (PEP 701)", versions=[None, (3, 12)])
# `await` was only allowed within f-string expressions from 3.7.
if hasattr(node, "values") and self.__fstring_has_await(node):
self.__s.fstrings_await = True
self.__vvprint("`await` in f-string", versions=[None, (3, 7)])
self.generic_visit(node)
def __fstring_has_await(self, node):
for value in node.values:
if isinstance(value, ast.FormattedValue) and self.__contains_await(value):
return True
return False
def __contains_await(self, node):
if isinstance(node, ast.Await):
return True
for child in ast.iter_child_nodes(node):
if self.__contains_await(child):
return True
return False
# Mark variable names as aliases.
def visit_Assign(self, node):
if self.__is_no_line(node.lineno):
return
for target in node.targets:
for n in assign_target_walk(target):
self.__add_user_def_node(n)
self.__add_name_res_assign_node(node)
self.generic_visit(node)
def visit_AugAssign(self, node):
if self.__is_no_line(node.lineno):
return
self.__add_user_def_node(node.target)
self.__add_name_res_assign_node(node)
# |=
if isinstance(node.op, ast.BitOr):
def is_union_type(node):
name = None
if isinstance(node, ast.Name):
name = node.id
elif isinstance(node, ast.Attribute):
name = dotted_name(self.__get_attribute_name(node))
return name is not None and \
((name not in self.__s.name_res and name not in self.__s.user_defs) or
# AugAssign: both variable names are the same so require two types.
(name in self.__s.name_res_type and len(self.__s.name_res_type[name]) > 1) or
# Unless it's the target value, then require not name res, is user def and res type.
(name not in self.__s.name_res and name in self.__s.user_defs and
name in self.__s.name_res_type))
# Example:
# AugAssign(target=Name(id='d', ctx=Store()),
# op=BitOr(),
# value=Dict(keys=[Constant(value='b')], values=[Constant(value=2)]))
if self.__is_dict(node.value):
full_name = self.__resolve_full_name(node.target)
if full_name in DICT_UNION_MERGE_SUPPORTED_TYPES or self.__is_dict(node.target):
self.__s.dict_union_merge = True
self.__vvprint("dict union merge (dict var |= dict)", line=node.lineno,
versions=[None, (3, 9)])
# Example:
# Assign(targets=[Name(id='a', ctx=Store())],
# value=Name(id='str', ctx=Load()))
# AugAssign(target=Name(id='a', ctx=Store()),
# op=BitOr(),
# value=Name(id='int', ctx=Load()))
elif self.__s.union_types_enabled and is_union_type(node.target) and \
is_union_type(node.value):
self.__s.union_types = True
self.__vvprint("union types as `a = X; a |= Y`", line=node.lineno, versions=[None, (3, 10)],
plural=True)
self.generic_visit(node)
def visit_AnnAssign(self, node):
if self.__is_no_line(node.lineno):
return
self.__add_user_def_node(node.target)
self.__add_name_res_assign_node(node)
if self.__s.config.eval_annotations():
self.generic_visit(node)
else:
self.__s.maybe_annotations = True
self.__s.annotations = True
self.__s.var_annotations = True
self.__vvprint("variable annotations", line=node.lineno, versions=[None, (3, 6)])
if hasattr(node, "annotation"):
ann = node.annotation
if (isinstance(ann, ast.Name) and ann.id == "Final") or \
(isinstance(ann, ast.Subscript) and hasattr(ann.value, "id") and
ann.value.id == "Final"):
self.__s.final_annotations = True
self.__vvprint("final variable annotations", line=node.lineno, versions=[None, (3, 8)])
elif (isinstance(ann, ast.Name) and ann.id == "Literal") or \
(isinstance(ann, ast.Subscript) and hasattr(ann.value, "id") and
ann.value.id == "Literal"):
self.__s.literal_annotations = True
self.__vvprint("literal variable annotations", line=node.lineno, versions=[None, (3, 8)])
def __check_relaxed_decorators(self, node):
# Checking for relaxed decorators, i.e. decorators that aren't a dotted name (name or attribute)
# or a function call. `Load()` is also ignored since they occur all over the place for
# non-relaxed decorators, too.
for decorator in node.decorator_list:
if self.__is_no_line(decorator.lineno):
continue
# If decorator is a function call, then only look in the body branch, not arguments and
# such.
for n in ast.walk(decorator if not isinstance(decorator, ast.Call) else decorator.func):
if not isinstance(n, (ast.Name, ast.Attribute, ast.Load)):
self.__s.relaxed_decorators = True
self.__vvprint("relaxed decorators", line=decorator.lineno, versions=[None, (3, 9)])
break
def __check_user_func_decorators(self, node):
# Checking for user function decorators, i.e. decorators that aren't used as function calls but
# names, and they take the docorated function as argument in the decorator.
for decorator in node.decorator_list:
if self.__is_no_line(decorator.lineno):
continue
# Not ast.Call.
if isinstance(decorator, (ast.Name, ast.Attribute)):
if isinstance(decorator, ast.Name):
name = decorator.id
elif isinstance(decorator, ast.Attribute):
name = dotted_name(self.__get_attribute_name(decorator))
if name in self.__s.import_mem_mod:
name = dotted_name([self.__s.import_mem_mod[name], name])
elif name in self.__s.module_as_name:
name = self.__s.module_as_name[name]
self.__add_user_func_deco(name, line=decorator.lineno)
def __handle_FunctionDef(self, node):
if self.__is_no_line(node.lineno):
return False
# Add function name and argument names as user-defs.
self.__add_user_def(node.name)
# Module-level `__dir__()` is supported by `dir()` and `__getattr__(name)` through lookup since
# 3.7 but it isn't a version requirement because it has always been possible to define such
# functions.
args = node.args
if self.__s.depth == 1 and self.__s.is_init_file and\
(not hasattr(args, "posonlyargs") or len(args.posonlyargs) == 0) and\
(not hasattr(args, "kwonlyargs") or len(args.kwonlyargs) == 0) and\
(not hasattr(args, "kwarg") or args.kwarg is None):
if node.name == "__dir__" and len(args.args) == 0:
self.__s.module_dir_func = True
self.__vvprint("module `__dir__()` supported by `dir()` since 3.7", line=node.lineno)
elif node.name == "__getattr__" and len(args.args) == 1:
self.__s.module_getattr_func = True
self.__vvprint("module `__getattr__(name)` supported through lookup since 3.7",
line=node.lineno)
if getattr(node, "decorator_list", None):
decos = node.decorator_list
# Exclude only if all decorators are excluded, otherwise the function decorator version
# requirement should still be in effect.
if not all(self.__is_no_line(deco.lineno) for deco in decos):
deco_line = [deco.lineno for deco in decos if not self.__is_no_line(deco.lineno)][0]
self.__s.function_decorators = True
self.__vvprint("function decorators", line=deco_line, versions=[(2, 4), (3, 0)])
self.__check_relaxed_decorators(node)
self.__check_user_func_decorators(node)
user_defs_copy = self.__s.user_defs.copy()
# Don't visit returns annotations if not evaluating annotations. It is only possible by setting
# it as None since it always will be visited via the AST functions.
returns_copy = None
if not self.__s.config.eval_annotations() and hasattr(node, "returns") and node.returns:
returns_copy, node.returns = node.returns, None
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
if returns_copy:
node.returns = returns_copy
def has_ann():
self.__s.annotations = True
self.__vvprint("annotations", line=node.lineno, versions=[None, (3, 0)])
# Check if the return annotation is set
if hasattr(node, "returns") and node.returns:
has_ann()
return True
def has_lit_ann():
if self.__s.config.eval_annotations():
self.__s.literal_annotations = True
self.__vvprint("literal variable annotations", line=node.lineno, versions=[None, (3, 8)])
else:
self.__s.maybe_annotations = True
for arg in node.args.args:
if not hasattr(arg, "annotation") or not arg.annotation:
continue
has_ann()
ann = arg.annotation
if (isinstance(ann, ast.Name) and ann.id == "Literal") or \
(isinstance(ann, ast.Subscript) and
hasattr(ann.value, "id") and ann.value.id == "Literal"):
has_lit_ann()
break
attr_name = dotted_name(self.__get_attribute_name(ann))
if attr_name in ("Literal", "typing.Literal"):
has_lit_ann()
break
return True
def visit_FunctionDef(self, node):
seen_yield = self.__s.seen_yield
if self.__handle_FunctionDef(node):
# Reset to seen yields before function.
self.__s.seen_yield = seen_yield
def visit_AsyncFunctionDef(self, node):
seen_await = self.__s.seen_await
seen_yield = self.__s.seen_yield
if self.__handle_FunctionDef(node):
self.__s.coroutines = True
self.__vvprint("coroutines (async)", line=node.lineno, versions=[None, (3, 5)], plural=True)
if self.__s.seen_yield > seen_yield and self.__s.seen_await > seen_await:
self.__s.async_generator = True
self.__vvprint("async generators (await and yield in same func)",
line=node.lineno, versions=[None, (3, 6)], plural=True)
# Reset to seen awaits/yields before async function.
self.__s.seen_await = seen_await
self.__s.seen_yield = seen_yield
def visit_Lambda(self, node):
user_defs_copy = self.__s.user_defs.copy()
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
def visit_Await(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.coroutines = True
self.__vvprint("coroutines (await)", versions=[None, (3, 5)], plural=True)
self.__s.seen_await += 1
self.generic_visit(node)
def visit_ClassDef(self, node):
if self.__is_no_line(node.lineno):
return
self.__add_user_def(node.name)
self.__add_name_res_type(node.name, node.name)
if getattr(node, "decorator_list", None):
decos = node.decorator_list
# Exclude only if all decorators are excluded, otherwise the class decorator version
# requirement should still be in effect.
if not all(self.__is_no_line(deco.lineno) for deco in decos):
deco_line = [deco.lineno for deco in decos if not self.__is_no_line(deco.lineno)][0]
self.__s.class_decorators = True
self.__vvprint("class decorators", line=deco_line, versions=[(2, 6), (3, 0)])
self.__check_relaxed_decorators(node)
if getattr(node, "keywords", None):
for keyword in node.keywords:
if keyword.arg == "metaclass":
self.__s.metaclass_class_keyword = True
self.__vvprint("'metaclass' class keyword", versions=[None, (3, 0)])
if sys.version_info >= (3, 12) and len(node.type_params) > 0:
self.__s.generic_class = True
self.__vvprint("generic class `class C[T]: ...`", versions=[None, (3, 12)])
self.__s.seen_class += 1
self.generic_visit(node)
# Some nodes aren't visited via `self.generic_visit(node)` so it is done explicitly.
for n in node.body:
self.generic_visit(n)
self.__s.seen_class -= 1
def visit_NameConstant(self, node):
if node.value is True or node.value is False: # pragma: no cover
self.__s.bool_const = True
self.__vvvprint("True/False constant", versions=[(2, 3), (3, 0)])
def visit_NamedExpr(self, node):
if self.__is_no_line(node.lineno):
return
self.__add_user_def_node(node.target)
self.__s.named_exprs = True
self.__vvprint("named expressions", versions=[None, (3, 8)])
self.generic_visit(node)
def visit_arguments(self, node):
all_args = []
if hasattr(node, "args"):
all_args += node.args
if hasattr(node, "posonlyargs") and len(node.posonlyargs) > 0:
self.__s.pos_only_args = True
self.__vvprint("positional-only parameters", versions=[None, (3, 8)])
all_args += node.posonlyargs
if hasattr(node, "kwonlyargs") and len(node.kwonlyargs) > 0:
self.__s.kw_only_args = True
self.__vvprint("keyword-only parameters", versions=[None, (3, 0)])
all_args += node.kwonlyargs
if hasattr(node, "vararg"):
all_args.append(node.vararg)
if hasattr(node, "kwarg"):
all_args.append(node.kwarg)
for arg in all_args:
if arg:
self.__add_user_def_node(arg)
if hasattr(arg, "arg"):
self.__add_user_def_node(arg.arg)
self.generic_visit(node)
def visit_Nonlocal(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.nonlocal_stmt = True
self.__vvprint("`nonlocal`", versions=[None, (3, 0)])
self.generic_visit(node)
def visit_YieldFrom(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.yield_from = True
self.__vvprint("`yield from`", versions=[None, (3, 3)])
self.generic_visit(node)
def visit_Yield(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.seen_yield += 1
self.generic_visit(node)
def visit_Raise(self, node):
if self.__is_no_line(node.lineno):
return
if hasattr(node, "cause") and node.cause is not None:
self.__s.raise_cause = True
self.__vvprint("exception cause", line=node.lineno, versions=[None, (3, 0)])
if is_none_node(node.cause):
self.__s.raise_from_none = True
self.__vvprint("raise ... from None", line=node.lineno, versions=[None, (3, 3)])
# Names used within `raise ..` should be detected as members being used.
branches = []
if hasattr(node, "exc"):
branches.append(node.exc)
if hasattr(node, "cause"):
branches.append(node.cause)
if hasattr(node, "type"): # pragma: no cover
branches.append(node.type)
for branch in branches:
if branch is not None:
for n in ast.walk(branch):
if isinstance(n, ast.Name):
self.__add_member(n.id, n.lineno, n.col_offset)
self.generic_visit(node)
def visit_ExceptHandler(self, node):
if self.__is_no_line(node.lineno):
return
line = self.__get_source_line(node.lineno, node.col_offset)
if line is not None and line.startswith("except") and line[6:].lstrip().startswith("*"):
self.__s.except_star = True
self.__vvprint("`except*`", line=node.lineno, versions=[None, (3, 11)])
# Copy current user-defs and add scoped ones. Note that except handler name is an `ast.Name` in
# py2 and `str` in py3.
user_defs_copy = self.__s.user_defs.copy()
if hasattr(node, "name"):
self.__add_user_def_node(node.name)
# Names used within `except ..:` should be detected as members being used.
if node.type is not None:
for n in ast.walk(node.type):
if isinstance(n, ast.Name):
self.__add_member(n.id, n.lineno, n.col_offset)
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
# Comprehensions:
#
# Target assignments must be handled first because elements of comprehensions will be visited
# first! But they aren't handled in `visit_comprehension()` because they'd be evaluated twice
# then.
def __handle_comprehensions(self, comps):
"""Expects a list of `ast.comprehension` nodes. Returns previous user-defs."""
user_defs_copy = self.__s.user_defs.copy()
for comp in comps:
for target in assign_target_walk(comp.target):
self.__add_user_def_node(target)
return user_defs_copy
def visit_ListComp(self, node):
self.__check_unpacking_in_comprehension(node.elt)
user_defs_copy = self.__handle_comprehensions(node.generators)
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
def visit_SetComp(self, node):
self.__check_unpacking_in_comprehension(node.elt)
self.__s.set_comp = True
self.__vvprint("set comprehensions", versions=[(2, 7), (3, 0)])
user_defs_copy = self.__handle_comprehensions(node.generators)
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
def visit_GeneratorExp(self, node):
self.__check_unpacking_in_comprehension(node.elt)
user_defs_copy = self.__handle_comprehensions(node.generators)
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
def visit_DictComp(self, node):
self.__check_unpacking_in_comprehension(node.value)
self.__s.dict_comp = True
self.__vvprint("dict comprehensions", versions=[(2, 7), (3, 0)])
user_defs_copy = self.__handle_comprehensions(node.generators)
self.generic_visit(node)
self.__s.user_defs = user_defs_copy
def visit_comprehension(self, node):
if hasattr(node, "is_async") and node.is_async == 1:
self.__s.async_comprehension = True
self.__vvprint("async comprehensions", versions=[None, (3, 7)])
seen_await = self.__s.seen_await
self.generic_visit(node)
if self.__s.seen_await > seen_await:
self.__s.await_in_comprehension = True
self.__vvprint("await in comprehensions", versions=[None, (3, 7)])
# Reset to seen awaits before comprehension.
self.__s.seen_await = seen_await
# 0:
(seen_for, seen_while) = self.__s.try_finally[-1]
if seen_for == self.__s.seen_for and seen_while == self.__s.seen_while:
self.__s.continue_in_finally = True
self.__vvprint("continue in finally block", line=node.lineno, versions=[None, (3, 8)])
def __handle_with(self, node):
if self.__is_no_line(node.lineno): # pragma: no cover
return
# Copy current user-defs and add scoped ones.
user_defs_copy = self.__s.user_defs.copy()
if hasattr(node, "items"):
for withitem in node.items:
if hasattr(withitem, "optional_vars") and withitem.optional_vars is not None:
for n in assign_target_walk(withitem.optional_vars):
self.__add_user_def_node(n)
if len(node.items) > 1:
# This feature can only be reliably detected when vermin is running on Python 3.3+.
# On older versions of Python, multiple context expressions in a `with` statement are
# automatically unrolled by the built-in `ast` module into
# With(
# context_expr=,
# optional_vars=,
# body=[
# With(
# context_expr=,
# optional_vars=,
# body=...)
# ]
# )
# and cannot be differentiated from manually writing multiple layers of `with` statements.
self.__s.multi_withitem = True
self.__vvprint("multiple context expressions in a `with` statement",
line=node.lineno, versions=[(2, 7), (3, 1)], plural=True)
# Check for "with (" with "with" part on the first line such that it doesn't match with
# "with (" further down. Note that we don't check for the ending parenthesis because that
# would yield a syntax error if missing anyway. This feature is supposed to work from 3.10+
# but it works from 3.9+.
lines = self.__get_source_lines(node.lineno, node.lineno + 10)
match = WITH_PAREN_REGEX.search(lines)
if match is not None and match.start() < len(lines.splitlines()[0]):
self.__s.with_parentheses = True
self.__vvprint("multiple context expressions in a `with` statement with parentheses",
line=node.lineno, versions=[None, (3, 9)])
elif hasattr(node, "optional_vars") and node.optional_vars is not None: # pragma: no cover
for n in assign_target_walk(node.optional_vars):
self.__add_user_def_node(n)
self.generic_visit(node)
# This is to minimize false positives, though the vars lives after the scope.
self.__s.user_defs = user_defs_copy
def visit_With(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.with_statement = True
self.__vvprint("`with`", line=node.lineno, versions=[(2, 5), (3, 0)])
self.__handle_with(node)
def visit_AsyncWith(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.async_with_statement = True
self.__vvprint("`async with`", line=node.lineno, versions=[None, (3, 5)])
self.__handle_with(node)
def visit_Dict(self, node):
self.__check_generalized_unpacking(node)
self.generic_visit(node)
def visit_Tuple(self, node):
self.__check_generalized_unpacking(node)
self.generic_visit(node)
def visit_List(self, node):
self.__check_generalized_unpacking(node)
self.generic_visit(node)
def visit_Set(self, node):
self.__s.set_literals = True
self.__vvprint("set literals", line=node.lineno, versions=[(2, 7), (3, 0)])
self.__check_generalized_unpacking(node)
self.generic_visit(node)
def visit_Subscript(self, node):
if self.__is_no_line(node.lineno):
return
if isinstance(node.value, (ast.Name, ast.Attribute)):
def match(name):
if self.__s.config.eval_annotations():
if name in self.__s.user_defs:
self.__vvvvprint("Ignoring type '{}' because it's user-defined!".format(name))
else:
self.__s.builtin_generic_type_annotations = True
self.__vvprint("builtin generic type annotation ({}[..])".format(name),
versions=[None, (3, 9)])
else:
self.__s.maybe_annotations = True
if isinstance(node.value, ast.Name):
coll_name = node.value.id
else:
coll_name = dotted_name(self.__get_attribute_name(node.value))
if coll_name in BUILTIN_GENERIC_ANNOTATION_TYPES:
match(coll_name)
elif coll_name in self.__s.import_mem_mod:
full_coll_name = dotted_name([self.__s.import_mem_mod[coll_name], coll_name])
if full_coll_name in BUILTIN_GENERIC_ANNOTATION_TYPES:
match(full_coll_name)
elif coll_name in self.__s.name_res_type:
for t in self.__s.name_res_type[coll_name]:
if t in BUILTIN_GENERIC_ANNOTATION_TYPES:
match(t)
slices_node = node.slice
if hasattr(ast, 'ExtSlice') and isinstance(slices_node, ast.ExtSlice): # pragma: no cover
for n in slices_node.dims:
if is_ellipsis_node(n):
self.__s.ellipsis_nodes_in_slices.add(n)
else:
if sys.version_info < (3, 9) and hasattr(ast, 'Index') and isinstance(slices_node, ast.Index):
slices_node = slices_node.value
if is_ellipsis_node(slices_node):
self.__s.ellipsis_nodes_in_slices.add(slices_node)
if isinstance(slices_node, ast.Tuple):
for n in slices_node.elts:
if is_ellipsis_node(n):
self.__s.ellipsis_nodes_in_slices.add(n)
# `slice[...]` subscript support (3.15+).
if isinstance(node.value, ast.Name) and node.value.id == "slice" \
and "slice" not in self.__s.user_defs:
self.__s.slice_subscription = True
self.__vvprint("slice subscription", line=node.lineno,
versions=[None, (3, 15)])
self.generic_visit(node)
def visit_Match(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.pattern_matching = True
self.__vvprint("pattern matching", line=node.lineno, versions=[None, (3, 10)])
self.generic_visit(node)
def visit_MatchValue(self, node):
has_unary_plus = any(isinstance(n, ast.UnaryOp) and isinstance(n.op, ast.UAdd)
for n in ast.walk(node))
# In early 3.15 builds, the folded `+` survives only in the source at the pattern's start.
if not has_unary_plus:
line = self.__get_source_line(node.lineno, node.col_offset)
has_unary_plus = line is not None and line.startswith("+")
if has_unary_plus:
self.__s.unary_plus_match_pattern = True
self.__vvprint("unary `+` in match literal pattern", line=node.lineno,
versions=[None, (3, 15)])
self.generic_visit(node)
# Comment-excluded lines skip conditional blocks if enabled.
def visit_If(self, node):
if not self.__is_no_line(node.lineno):
self.generic_visit(node)
def visit_IfExp(self, node):
if not self.__is_no_line(node.lineno):
self.generic_visit(node)
def __handle_for(self, node):
if not self.__is_no_line(node.lineno):
self.__s.seen_for += 1
# Copy current user-defs and add scoped ones.
user_defs_copy = self.__s.user_defs.copy()
for n in assign_target_walk(node.target):
self.__add_user_def_node(n)
# Check if any value of the for-iterable is a dictionary, then associate for-target variable
# with a ditionary type such that sub-levels of the for-loop can use it for dict union merge
# detection.
old_name_res = self.__s.name_res
if hasattr(node.target, "id"):
for tup in ast.iter_fields(node.iter):
if tup[0] == "elts" or tup[0] == "values":
if any(self.__is_dict(elm) for elm in tup[1]):
self.__s.name_res[node.target.id] = "dict"
break
self.generic_visit(node)
self.__s.seen_for -= 1
self.__s.name_res = old_name_res
# This is to minimize false positives, though the vars lives after the scope.
self.__s.user_defs = user_defs_copy
def visit_For(self, node):
self.__handle_for(node)
def visit_AsyncFor(self, node):
if self.__is_no_line(node.lineno):
return
self.__s.async_for = True
self.__vvprint("async for-loops", line=node.lineno, versions=[None, (3, 5)])
self.__handle_for(node)
def visit_While(self, node):
if not self.__is_no_line(node.lineno):
self.__s.seen_while += 1
self.generic_visit(node)
self.__s.seen_while -= 1
def __handle_Try(self, node):
if not self.__is_no_line(node.lineno):
if hasattr(node, "finalbody"):
self.__s.try_finally.append((self.__s.seen_for, self.__s.seen_while))
for stm in node.finalbody:
self.visit(stm)
if len(self.__s.try_finally) > 0:
self.__s.try_finally.pop()
self.generic_visit(node)
def visit_Try(self, node):
self.__handle_Try(node)
def visit_TryExcept(self, node):
self.__handle_Try(node) # pragma: no cover
def visit_TryFinally(self, node):
self.__handle_Try(node) # pragma: no cover
def visit_BoolOp(self, node):
if not self.__is_no_line(node.lineno):
self.generic_visit(node)
def visit_Ellipsis(self, node):
# Force identity testing instead of equality testing.
if not any(n is node for n in self.__s.ellipsis_nodes_in_slices):
self.__s.ellipsis_out_of_slices = True
self.__vvprint("ellipsis literal (`...`) out of slices", versions=[None, (3, 0)],
plural=False)
def visit_TypeAlias(self, node):
if not self.__is_no_line(node.lineno):
self.__s.type_alias_statement = True
self.__vvprint("type alias statement (`type X = SomeType`)", versions=[None, (3, 12)],
plural=False)
if self.__s.seen_class > 0:
for n in ast.walk(node.value):
if isinstance(n, ast.Lambda) or \
(hasattr(ast, "comprehension") and isinstance(n, ast.comprehension)):
self.__s.type_alias_statement_class_scope_lambda = True
self.__vvprint("type alias statement using lambda/comp in class scope",
versions=[None, (3, 13)], plural=False)
break
self.generic_visit(node)
def visit_TemplateStr(self, node):
if not self.__is_no_line(node.lineno):
self.__s.template_string_literal = True
self.__vvprint("template string literal (`t'text {var}'`)", versions=[None, (3, 14)],
plural=False)
# Ignore unused nodes as a speed optimization.
def visit_alias(self, node):
pass # pragma: no cover
def visit_Load(self, node):
pass # pragma: no cover
def visit_Store(self, node):
pass # pragma: no cover
def visit_Pass(self, node):
pass # pragma: no cover
def visit_Num(self, node):
pass # pragma: no cover
def visit_Not(self, node):
pass # pragma: no cover
def visit_Add(self, node):
pass # pragma: no cover
def visit_Sub(self, node):
pass # pragma: no cover
def visit_Mult(self, node):
pass # pragma: no cover
def visit_Div(self, node):
pass # pragma: no cover
def visit_BitAnd(self, node):
pass # pragma: no cover
def visit_Or(self, node):
pass # pragma: no cover
def visit_BitOr(self, node):
pass # pragma: no cover
def visit_Eq(self, node):
pass # pragma: no cover
def visit_NotEq(self, node):
pass # pragma: no cover
def visit_Lt(self, node):
pass # pragma: no cover
def visit_Gt(self, node):
pass # pragma: no cover
def visit_In(self, node):
pass # pragma: no cover
def visit_Is(self, node):
pass # pragma: no cover
def visit_Break(self, node):
pass # pragma: no cover
def visit_Mod(self, node):
pass # pragma: no cover
netromdk-vermin-d650a48/vermin/utility.py 0000664 0000000 0000000 00000017501 15265463462 0020566 0 ustar 00root root 0000000 0000000 import re
from math import floor
from functools import reduce
def reverse_range(values):
"""Yields reverse range of values: list(reverse_range([1, 2, 3])) -> [2, 1, 0]."""
return range(len(values) - 1, -1, -1)
def dotted_name(names):
"""Returns a dotted name of a list of strings, integers, lists, and tuples."""
# It will just return the value instead of "b.a.d" if input was "bad"!
if isinstance(names, str):
return names
if isinstance(names, (int, float)):
return str(names)
resolved = []
for name in names:
if isinstance(name, str):
resolved.append(name)
elif isinstance(name, int):
resolved.append(str(name))
elif isinstance(name, (list, tuple)):
resolved += filter(lambda x: x is not None, name)
elif name is None:
continue
else:
assert False
return ".".join(resolved)
def float_version(f):
"""Converts a float X.Y into (X, Y)."""
assert not f < 0
major = floor(f)
minor = int((f - major) * 10)
return (major, minor)
class InvalidVersionException(BaseException):
pass
def __handle_incomp_versions(list1, list2, version_refs=None):
v1, v2 = version_strings(list1), version_strings(list2)
t1, t2 = tuple(list1), tuple(list2)
if version_refs is None or t1 not in version_refs or t2 not in version_refs:
raise InvalidVersionException("Versions could not be combined: {} and {}".format(v1, v2))
def get_ref(key):
ref = version_refs[key]
if len(ref) == 1:
ref = ref[0]
return ref
ref1, ref2 = get_ref(t1), get_ref(t2)
raise InvalidVersionException("{} (requires {}) vs. {} (requires {})".format(ref1, v1, ref2, v2))
def combine_versions(list1, list2, config, version_refs=None):
assert len(list1) == len(list2)
assert len(list1) == 2
if not config.ignore_incomp() and\
((list1[0] is None and list1[1] is not None and list2[0] is not None and list2[1] is None) or
(list1[0] is not None and list1[1] is None and list2[0] is None and list2[1] is not None)):
__handle_incomp_versions(list1, list2, version_refs)
res = []
# Convert integers and floats into version tuples.
def fixup(v):
if isinstance(v, int):
return (v, 0)
if isinstance(v, float):
return float_version(v)
return v
for i in range(len(list1)): # pylint: disable=consider-using-enumerate
v1 = fixup(list1[i])
v2 = fixup(list2[i])
if v1 is None or v2 is None:
res.append(None)
else:
res.append(max(v1, v2))
return res
def version_strings(versions, separator=None):
"""Yields version strings of versions. If one value is 0, 0.0, or (0, 0) then either one or two
values can be specified, otherwise any number is allowed. A None separator means ', '."""
separator = separator or ", "
amount = len(versions)
assert amount > 0
if any(v in (0, (0, 0)) for v in versions):
assert amount < 3
res = []
for i in range(amount):
version = versions[i]
# When versions aren't known, show something instead of nothing. It might run with any
# version.
if version in (0, (0, 0)):
res.append("~{}".format(i + 2))
elif version is None:
res.append("!{}".format(i + 2))
else:
res.append(dotted_name(version))
return separator.join(res)
def remove_whitespace(string, extras=None):
extras = extras or []
return re.sub("[ \t\n\r\f\v{}]".format("".join(extras)), "", string)
def bounded_str_hash(value):
"""Computes bounded hash value of string input that isn't randomly seeded, like `hash()` does
because we need the same hash value for every program execution.
"""
h = reduce(lambda acc, ch: acc + 29 * ord(ch), value, 13)
return float(h % 1000000) / 1000000
LINE_COL_REGEX = re.compile(r"L(\d+)(?:\s*C(\d+))?:(.*)")
def sort_line_column(key):
"""Sorts line and column numbers of input texts with format "LX[ CY]: ..". In order to
consistently sort texts of same line/column but with different subtext, the subtext is hashed and
included in the value. Text without line/column numbers is still hashed and thought of as having
line number 0. This function can be used with `list.sort(key=sort_line_column)`.
"""
m = LINE_COL_REGEX.match(key)
if not m:
return bounded_str_hash(key)
line = int(m.group(1))
col = m.group(2)
h = bounded_str_hash(m.group(3)) / 1000
if col is None:
return line + h
return line + float(col) / 1000 + h
LINE_COL_PARSABLE_REGEX = re.compile(r"(?:.*?):(\d+):(\d*):(.*)")
def sort_line_column_parsable(key):
m = LINE_COL_PARSABLE_REGEX.match(key)
if not m:
return bounded_str_hash(key)
line = int(m.group(1))
col = m.group(2)
if len(col) == 0:
col = 0
h = bounded_str_hash(m.group(3)) / 1000
if col == 0:
return line + h
return line + float(col) / 1000 + h
def format_title_descs(pairs, titles, indent=0):
res = []
longest = len(max(titles, key=len))
for (name, desc) in pairs:
title = "{}{:{fill}} - ".format(" " * indent, name, fill=longest)
first_line = desc[0]
res.append("{}{}".format(title, first_line))
if len(desc) > 1:
for line in desc[1:]:
res.append("{}{}".format(" " * len(title), line))
return "\n".join(res)
TARGETS_SPLIT = re.compile("[\\.,]")
def parse_target(target):
exact = True
if target.endswith("-"):
exact = False
target = target[:-1]
# Parse target as a tuple separated by either commas or dots, which preserves support for old
# float-number inputs.
elms = TARGETS_SPLIT.split(target)
if len(elms) != 1 and len(elms) != 2:
return None
for h in range(len(elms)): # pylint: disable=consider-using-enumerate
try:
n = int(elms[h])
if n < 0:
return None
elms[h] = n
except ValueError:
return None
# When only specifying major version, use zero as minor.
if len(elms) == 1:
elms.append(0)
elms = tuple(elms)
if not (2, 0) <= elms < (4, 0):
return None
return (exact, elms)
def compare_requirements(reqs, targets, ignore_exact=False):
"""Check if requirements satisfy targets: A matching major version must be found for each target
If the target is exact, the requirement must match exactly. Otherwise the requirement must not be
greater. If there are no targets, False is returned.
:param reqs: iterable[tuple[major, minor] | None] | None
:param targets: list[list[exact, (major, minor)]], sorted by version
:param ignore_exact: if True, ignore exactness of targets, just checking if not greater
:returns: True if requirements satisfy targets, False otherwise
"""
if not targets:
return False
for exact, (tmaj, tmin) in targets:
exact &= not ignore_exact
# reqs is 1 or 2 elements when provided, so linear search is fastest
for req in reqs or ():
if req is not None:
rmaj, rmin = req
if rmaj == tmaj:
# target unsatisfied
if (rmin != tmin) if exact else (rmin > tmin):
return False
# target satisfied
break
# matching version not found
else:
return False
# all targets satisfied
return True
def split_lines(source):
"""Splits source into lines on `\\n`, `\\r`, and `\\r\\n` (not vertical tabs or form feeds), and
returns the code-point start offset of each line: `(lines, offsets)` where `lines[i]` is the text
of line `i + 1` with its line terminator stripped and `offsets[i]` is its start offset in source.
"""
lines = []
offsets = [0]
n = len(source)
prev = 0
i = 0
while i < n:
ch = source[i]
if ch == "\n":
i += 1
elif ch == "\r":
i += 1
if i < n and source[i] == "\n":
i += 1
else:
i += 1
continue
offsets.append(i)
seg = source[prev:i]
if seg.endswith("\r\n"):
seg = seg[:-2]
elif seg.endswith("\n") or seg.endswith("\r"):
seg = seg[:-1]
lines.append(seg)
prev = i
if prev < n:
lines.append(source[prev:])
if len(offsets) == len(lines):
offsets.append(n)
return lines, offsets