├── .gitattributes ├── .github └── workflows │ ├── docs-ci.yml │ └── pypi-release.yml ├── .gitignore ├── .readthedocs.yml ├── AUTHORS.rst ├── CHANGELOG.rst ├── CODE_OF_CONDUCT.rst ├── MANIFEST.in ├── Makefile ├── NOTICE ├── README.rst ├── apache-2.0.LICENSE ├── azure-pipelines.yml ├── configure ├── configure.bat ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ └── theme_overrides.css │ ├── conf.py │ ├── contribute │ └── contrib_doc.rst │ ├── dependencies-design.rst │ ├── index.rst │ └── test-protocol.rst ├── etc ├── ci │ ├── azure-container-deb.yml │ ├── azure-container-rpm.yml │ ├── azure-posix.yml │ ├── azure-win.yml │ ├── install_sudo.sh │ ├── macports-ci │ ├── macports-ci.ABOUT │ └── mit.LICENSE └── scripts │ ├── README.rst │ ├── check_thirdparty.py │ ├── fetch_thirdparty.py │ ├── gen_pypi_simple.py │ ├── gen_pypi_simple.py.ABOUT │ ├── gen_pypi_simple.py.NOTICE │ ├── gen_requirements.py │ ├── gen_requirements_dev.py │ ├── requirements.txt │ ├── test_utils_pip_compatibility_tags.py │ ├── test_utils_pip_compatibility_tags.py.ABOUT │ ├── test_utils_pypi_supported_tags.py │ ├── test_utils_pypi_supported_tags.py.ABOUT │ ├── update_skeleton.py │ ├── utils_dejacode.py │ ├── utils_pip_compatibility_tags.py │ ├── utils_pip_compatibility_tags.py.ABOUT │ ├── utils_pypi_supported_tags.py │ ├── utils_pypi_supported_tags.py.ABOUT │ ├── utils_requirements.py │ ├── utils_thirdparty.py │ └── utils_thirdparty.py.ABOUT ├── pyproject.toml ├── requirements-dev.txt ├── requirements.txt ├── requirements_builder.ABOUT ├── resolve_cli.python ├── setup.cfg ├── setup.py ├── src ├── _packagedcode │ ├── __init__.py │ ├── models.py │ ├── pypi.py │ ├── pypi.py.ABOUT │ ├── pypi.py.NOTICE │ ├── pypi_setup_py.py │ ├── pypi_setup_py.py.ABOUT │ ├── pypi_setup_py.py.LICENSE │ └── utils.py └── python_inspector │ ├── __init__.py │ ├── api.py │ ├── cli_utils.py │ ├── dependencies.py │ ├── error.py │ ├── lockfile.py │ ├── package_data.py │ ├── resolution.py │ ├── resolution.py.ABOUT │ ├── resolution.py.LICENSE │ ├── resolve_cli.py │ ├── settings.py │ ├── setup_py_live_eval.py │ ├── setup_py_live_eval.py.ABOUT │ ├── setup_py_live_eval.py.LICENSE │ ├── utils.py │ ├── utils_pip_compatibility_tags.py │ ├── utils_pip_compatibility_tags.py.ABOUT │ ├── utils_pypi.py │ ├── utils_pypi.py.ABOUT │ ├── utils_pypi_supported_tags.py │ └── utils_pypi_supported_tags.py.ABOUT ├── test_resolution2.py.foo └── tests ├── conftest.py ├── data ├── azure-devops.req-310-expected.json ├── azure-devops.req-312-expected.json ├── azure-devops.req-313-expected.json ├── azure-devops.req-38-expected.json ├── azure-devops.req.txt ├── default-url-expected.json ├── environment-marker-test-requirements.txt ├── environment-marker-test-requirements.txt-expected.json ├── error-requirements.txt ├── example-requirements-ignore-errors-expected.json ├── fetch_links_test.html ├── frozen-requirements.txt ├── frozen-requirements.txt-expected.json ├── insecure-setup-2 │ ├── setup.py │ ├── setup.py-expected.json │ └── testpkh │ │ └── __init__.py ├── insecure-setup │ ├── rdflib │ │ └── __init__.py │ ├── setup.py │ └── setup.py-expected.json ├── no-install-requires-expected.json ├── other_req.txt ├── parse-reqs-with-setup_requires-and-python-requires.json ├── parse-reqs.json ├── partial-setup.py ├── pdt-requirements.txt ├── pdt-requirements.txt-expected.json ├── pinned-pdt-requirements.txt ├── pinned-pdt-requirements.txt-expected.json ├── pinned-requirements.txt ├── pinned-requirements.txt-expected.json ├── prefer-source-expected.json ├── psycopg2-links-expected.json ├── psycopg2.html ├── recursive_requirements │ ├── com.txt │ └── r.txt ├── relative-links-expected.json ├── req.txt ├── requirements-test.txt ├── requirements.devel.txt ├── resolved_deps │ ├── autobahn-310-expected.json │ ├── flask-310-expected.json │ ├── flask-310-win-expected.json │ ├── flask-36-expected.json │ ├── flask-39-expected.json │ └── torch-312-expected.json ├── secure-setup │ ├── setup-emptyrequires.py │ ├── setup-norequires.py │ └── setup-requires.py ├── setup-distutils-asnames.txt ├── setup-distutils-qualifiedfct.txt ├── setup-distutils.txt ├── setup-qualifiedfct.txt ├── setup.cfg ├── setup.txt ├── setup │ ├── no-direct-dependencies-setup.py │ ├── no-direct-dependencies-setup.py-expected.json │ ├── simple-setup.py │ ├── simple-setup.py-expected.json │ ├── spdx-setup.py │ └── spdx-setup.py-expected.json ├── setup_if_main.py ├── setup_with_setup_requires_and_python_requires.cfg ├── single-url-env-var-except-simple-expected.json ├── single-url-env-var-expected.json ├── single-url-except-simple-expected.json ├── single-url-expected.json ├── test-api-expected.json ├── test-api-pdt-expected.json ├── test-api-with-lief-python-312.json ├── test-api-with-partial-setup-py.json ├── test-api-with-prefer-source.json ├── test-api-with-python-311.json ├── test-api-with-recursive-requirement-file.json ├── test-api-with-requirement-file.json ├── test-commented.netrc ├── test-default.netrc ├── test.netrc ├── tilde_req-expected-env.json ├── tilde_req-expected-max-rounds.json ├── tilde_req-expected-netrc.json └── tilde_req-expected.json ├── test_api.py ├── test_cli.py ├── test_packagecode_pypi.py ├── test_pypi.py ├── test_requirement_parsing.py ├── test_resolution.py ├── test_setup_py_live_eval.py ├── test_setup_py_live_eval.py.ABOUT ├── test_setup_py_live_eval.py.LICENSE ├── test_setup_py_live_eval_cli.py.ABOUT ├── test_setup_py_live_eval_cli.py.LICENSE ├── test_setup_py_parsing.py ├── test_utils.py ├── test_utils_pip_compatibility_tags.py ├── test_utils_pip_compatibility_tags.py.ABOUT ├── test_utils_pypi.py ├── test_utils_pypi_supported_tags.py └── test_utils_pypi_supported_tags.py.ABOUT /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ignore all Git auto CR/LF line endings conversions 2 | * -text 3 | pyproject.toml export-subst 4 | -------------------------------------------------------------------------------- /.github/workflows/docs-ci.yml: -------------------------------------------------------------------------------- 1 | name: CI Documentation 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-24.04 8 | 9 | strategy: 10 | max-parallel: 4 11 | matrix: 12 | python-version: [3.12] 13 | 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Python ${{ matrix.python-version }} 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: ${{ matrix.python-version }} 22 | 23 | - name: Install Dependencies 24 | run: ./configure --dev 25 | 26 | - name: Check documentation and HTML for errors and dead links 27 | run: make docs-check 28 | 29 | - name: Check documentation for style errors 30 | run: make doc8 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/workflows/pypi-release.yml: -------------------------------------------------------------------------------- 1 | name: Create library release archives, create a GH release and publish PyPI wheel and sdist on tag in main branch 2 | 3 | 4 | # This is executed automatically on a tag in the main branch 5 | 6 | # Summary of the steps: 7 | # - build wheels and sdist 8 | # - upload wheels and sdist to PyPI 9 | # - create gh-release and upload wheels and dists there 10 | # TODO: smoke test wheels and sdist 11 | # TODO: add changelog to release text body 12 | 13 | # WARNING: this is designed only for packages building as pure Python wheels 14 | 15 | on: 16 | workflow_dispatch: 17 | push: 18 | tags: 19 | - "v*.*.*" 20 | 21 | jobs: 22 | build-pypi-distribs: 23 | name: Build and publish library to PyPI 24 | runs-on: ubuntu-24.04 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: Set up Python 29 | uses: actions/setup-python@v5 30 | with: 31 | python-version: 3.12 32 | 33 | - name: Install pypa/build and twine 34 | run: python -m pip install --user build twine 35 | 36 | - name: Build a binary wheel and a source tarball 37 | run: python -m build --sdist --wheel --outdir dist/ 38 | 39 | - name: Validate wheel and sdis for Pypi 40 | run: python -m twine check dist/* 41 | 42 | - name: Upload built archives 43 | uses: actions/upload-artifact@v4 44 | with: 45 | name: pypi_archives 46 | path: dist/* 47 | 48 | 49 | create-gh-release: 50 | name: Create GH release 51 | needs: 52 | - build-pypi-distribs 53 | runs-on: ubuntu-24.04 54 | 55 | steps: 56 | - name: Download built archives 57 | uses: actions/download-artifact@v4 58 | with: 59 | name: pypi_archives 60 | path: dist 61 | 62 | - name: Create GH release 63 | uses: softprops/action-gh-release@v2 64 | with: 65 | draft: true 66 | files: dist/* 67 | 68 | 69 | create-pypi-release: 70 | name: Create PyPI release 71 | needs: 72 | - create-gh-release 73 | runs-on: ubuntu-24.04 74 | 75 | steps: 76 | - name: Download built archives 77 | uses: actions/download-artifact@v4 78 | with: 79 | name: pypi_archives 80 | path: dist 81 | 82 | - name: Publish to PyPI 83 | if: startsWith(github.ref, 'refs/tags') 84 | uses: pypa/gh-action-pypi-publish@release/v1 85 | with: 86 | password: ${{ secrets.PYPI_API_TOKEN }} 87 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | pip3 # Python compiled files 2 | *.py[cod] 3 | 4 | # virtualenv and other misc bits 5 | /src/*.egg-info 6 | *.egg-info 7 | /dist 8 | /build 9 | /bin 10 | /lib 11 | /scripts 12 | /Scripts 13 | /Lib 14 | /pip-selfcheck.json 15 | /tmp 16 | /venv 17 | .Python 18 | /include 19 | /Include 20 | /local 21 | */local/* 22 | /local/ 23 | /share/ 24 | /tcl/ 25 | /.eggs/ 26 | 27 | # Installer logs 28 | pip-log.txt 29 | 30 | # Unit test / coverage reports 31 | .cache 32 | .coverage 33 | .coverage.* 34 | nosetests.xml 35 | htmlcov 36 | 37 | # Translations 38 | *.mo 39 | 40 | # IDEs 41 | .project 42 | .pydevproject 43 | .idea 44 | org.eclipse.core.resources.prefs 45 | .vscode 46 | .vs 47 | 48 | # Sphinx 49 | docs/_build 50 | docs/bin 51 | docs/build 52 | docs/include 53 | docs/Lib 54 | doc/pyvenv.cfg 55 | pyvenv.cfg 56 | 57 | # Various junk and temp files 58 | .DS_Store 59 | *~ 60 | .*.sw[po] 61 | .build 62 | .ve 63 | *.bak 64 | /.cache/ 65 | 66 | # pyenv 67 | /.python-version 68 | /man/ 69 | /.pytest_cache/ 70 | lib64 71 | tcl 72 | 73 | # Ignore Jupyter Notebook related temp files 74 | .ipynb_checkpoints/ 75 | /.ruff_cache/ 76 | .env -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Build in latest ubuntu/python 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.11" 13 | 14 | # Build PDF & ePub 15 | formats: 16 | - epub 17 | - pdf 18 | 19 | # Where the Sphinx conf.py file is located 20 | sphinx: 21 | configuration: docs/source/conf.py 22 | 23 | # Setting the python version and doc build requirements 24 | python: 25 | install: 26 | - method: pip 27 | path: . 28 | extra_requirements: 29 | - dev 30 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | The following organizations or individuals have contributed to this repo: 2 | 3 | - nexB Inc. 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.rst: -------------------------------------------------------------------------------- 1 | Contributor Covenant Code of Conduct 2 | ==================================== 3 | 4 | Our Pledge 5 | ---------- 6 | 7 | In the interest of fostering an open and welcoming environment, we as 8 | contributors and maintainers pledge to making participation in our 9 | project and our community a harassment-free experience for everyone, 10 | regardless of age, body size, disability, ethnicity, gender identity and 11 | expression, level of experience, education, socio-economic status, 12 | nationality, personal appearance, race, religion, or sexual identity and 13 | orientation. 14 | 15 | Our Standards 16 | ------------- 17 | 18 | Examples of behavior that contributes to creating a positive environment 19 | include: 20 | 21 | - Using welcoming and inclusive language 22 | - Being respectful of differing viewpoints and experiences 23 | - Gracefully accepting constructive criticism 24 | - Focusing on what is best for the community 25 | - Showing empathy towards other community members 26 | 27 | Examples of unacceptable behavior by participants include: 28 | 29 | - The use of sexualized language or imagery and unwelcome sexual 30 | attention or advances 31 | - Trolling, insulting/derogatory comments, and personal or political 32 | attacks 33 | - Public or private harassment 34 | - Publishing others’ private information, such as a physical or 35 | electronic address, without explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | Our Responsibilities 40 | -------------------- 41 | 42 | Project maintainers are responsible for clarifying the standards of 43 | acceptable behavior and are expected to take appropriate and fair 44 | corrective action in response to any instances of unacceptable behavior. 45 | 46 | Project maintainers have the right and responsibility to remove, edit, 47 | or reject comments, commits, code, wiki edits, issues, and other 48 | contributions that are not aligned to this Code of Conduct, or to ban 49 | temporarily or permanently any contributor for other behaviors that they 50 | deem inappropriate, threatening, offensive, or harmful. 51 | 52 | Scope 53 | ----- 54 | 55 | This Code of Conduct applies both within project spaces and in public 56 | spaces when an individual is representing the project or its community. 57 | Examples of representing a project or community include using an 58 | official project e-mail address, posting via an official social media 59 | account, or acting as an appointed representative at an online or 60 | offline event. Representation of a project may be further defined and 61 | clarified by project maintainers. 62 | 63 | Enforcement 64 | ----------- 65 | 66 | Instances of abusive, harassing, or otherwise unacceptable behavior may 67 | be reported by contacting the project team at pombredanne@gmail.com 68 | or on the Gitter chat channel at https://gitter.im/aboutcode-org/discuss . 69 | All complaints will be reviewed and investigated and will result in a 70 | response that is deemed necessary and appropriate to the circumstances. 71 | The project team is obligated to maintain confidentiality with regard to 72 | the reporter of an incident. Further details of specific enforcement 73 | policies may be posted separately. 74 | 75 | Project maintainers who do not follow or enforce the Code of Conduct in 76 | good faith may face temporary or permanent repercussions as determined 77 | by other members of the project’s leadership. 78 | 79 | Attribution 80 | ----------- 81 | 82 | This Code of Conduct is adapted from the `Contributor Covenant`_ , 83 | version 1.4, available at 84 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 85 | 86 | .. _Contributor Covenant: https://www.contributor-covenant.org 87 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft src 2 | graft docs 3 | graft etc 4 | 5 | include *.LICENSE 6 | include NOTICE 7 | include *.ABOUT 8 | include *.toml 9 | include *.yml 10 | include *.rst 11 | include *.png 12 | include setup.* 13 | include configure* 14 | include requirements* 15 | include .dockerignore 16 | include .gitignore 17 | include .readthedocs.yml 18 | include manage.py 19 | include Dockerfile* 20 | include Makefile 21 | include MANIFEST.in 22 | 23 | include .VERSION 24 | 25 | global-exclude *.py[co] __pycache__ *.*~ 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # 3 | # Copyright (c) nexB Inc. and others. All rights reserved. 4 | # ScanCode is a trademark of nexB Inc. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 7 | # See https://github.com/aboutcode-org/python-inspector for support or download. 8 | # See https://aboutcode.org for more information about nexB OSS projects. 9 | # 10 | 11 | # Python version can be specified with `$ PYTHON_EXE=python3.x make conf` 12 | PYTHON_EXE?=python3 13 | VENV=venv 14 | ACTIVATE?=. ${VENV}/bin/activate; 15 | 16 | 17 | conf: 18 | @echo "-> Install dependencies" 19 | ./configure 20 | 21 | dev: 22 | @echo "-> Configure and install development dependencies" 23 | ./configure --dev 24 | 25 | doc8: 26 | @echo "-> Run doc8 validation" 27 | @${ACTIVATE} doc8 --config pyproject.toml --ignore-path docs/_build --max-line-length 100 docs/ *.rst 28 | 29 | valid: 30 | @echo "-> Run Ruff format" 31 | @${ACTIVATE} ruff format 32 | @echo "-> Run Ruff linter" 33 | @${ACTIVATE} ruff check --fix 34 | 35 | check: 36 | @echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)" 37 | @${ACTIVATE} ruff check 38 | @echo "-> Run Ruff format validation" 39 | @${ACTIVATE} ruff format --check 40 | @$(MAKE) doc8 41 | @echo "-> Run ABOUT files validation" 42 | @${ACTIVATE} about check etc/ 43 | 44 | clean: 45 | @echo "-> Clean the Python env" 46 | ./configure --clean 47 | 48 | test: 49 | @echo "-> Run the test suite" 50 | ${VENV}/bin/pytest -vvs 51 | 52 | docs: 53 | rm -rf docs/_build/ 54 | @${ACTIVATE} sphinx-build docs/source docs/_build/ 55 | 56 | docs-check: 57 | @${ACTIVATE} sphinx-build -E -W -b html docs/source docs/_build/ 58 | @${ACTIVATE} sphinx-build -E -W -b linkcheck docs/source docs/_build/ 59 | 60 | .PHONY: conf dev check valid clean test docs docs-check 61 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/ for support and download. 6 | # ScanCode is a trademark of nexB Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | 2 | ################################################################################ 3 | # We use Azure to run the full tests suites on multiple Python 3.x 4 | # on multiple Windows, macOS and Linux versions all on 64 bits 5 | # These jobs are using VMs with Azure-provided Python builds 6 | ################################################################################ 7 | 8 | jobs: 9 | 10 | - template: etc/ci/azure-posix.yml 11 | parameters: 12 | job_name: run_code_checks 13 | image_name: ubuntu-24.04 14 | python_versions: ['3.12'] 15 | test_suites: 16 | all: make check 17 | 18 | - template: etc/ci/azure-posix.yml 19 | parameters: 20 | job_name: online_ubuntu24_cpython 21 | image_name: ubuntu-24.04 22 | python_versions: ['3.10'] 23 | test_suites: 24 | all: venv/bin/pytest -n 2 -vvs -m "online" 25 | 26 | - template: etc/ci/azure-win.yml 27 | parameters: 28 | job_name: online_win2022_cpython 29 | image_name: windows-2022 30 | python_versions: ['3.10'] 31 | test_suites: 32 | all: venv\Scripts\pytest -n 2 -vvs -m "online" 33 | 34 | - template: etc/ci/azure-posix.yml 35 | parameters: 36 | job_name: online_macos14_cpython 37 | image_name: macOS-14 38 | python_versions: ['3.10'] 39 | test_suites: 40 | all: venv/bin/pytest -n 2 -vvs -m "online" 41 | 42 | - template: etc/ci/azure-posix.yml 43 | parameters: 44 | job_name: ubuntu22_cpython 45 | image_name: ubuntu-22.04 46 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 47 | test_suites: 48 | all: venv/bin/pytest -n 2 -vvs -m "not online" 49 | 50 | - template: etc/ci/azure-posix.yml 51 | parameters: 52 | job_name: ubuntu24_cpython 53 | image_name: ubuntu-24.04 54 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 55 | test_suites: 56 | all: venv/bin/pytest -n 2 -vvs -m "not online" 57 | 58 | - template: etc/ci/azure-posix.yml 59 | parameters: 60 | job_name: macos13_cpython 61 | image_name: macOS-13 62 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 63 | test_suites: 64 | all: venv/bin/pytest -n 2 -vvs -m "not online" 65 | 66 | - template: etc/ci/azure-posix.yml 67 | parameters: 68 | job_name: macos14_cpython 69 | image_name: macOS-14 70 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 71 | test_suites: 72 | all: venv/bin/pytest -n 2 -vvs -m "not online" 73 | 74 | - template: etc/ci/azure-posix.yml 75 | parameters: 76 | job_name: macos15_cpython 77 | image_name: macOS-15 78 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 79 | test_suites: 80 | all: venv/bin/pytest -n 2 -vvs -m "not online" 81 | 82 | - template: etc/ci/azure-win.yml 83 | parameters: 84 | job_name: win2019_cpython 85 | image_name: windows-2019 86 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 87 | test_suites: 88 | all: venv\Scripts\pytest -n 2 -vvs -m "not online" 89 | 90 | - template: etc/ci/azure-win.yml 91 | parameters: 92 | job_name: win2022_cpython 93 | image_name: windows-2022 94 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 95 | test_suites: 96 | all: venv\Scripts\pytest -n 2 -vvs -m "not online" 97 | 98 | - template: etc/ci/azure-win.yml 99 | parameters: 100 | job_name: win2025_cpython 101 | image_name: windows-2025 102 | python_versions: ['3.9', '3.10', '3.11', '3.12'] 103 | test_suites: 104 | all: venv\Scripts\pytest -n 2 -vvs -m "not online" 105 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SPHINXAUTOBUILD = sphinx-autobuild 9 | SOURCEDIR = source 10 | BUILDDIR = _build 11 | 12 | # Put it first so that "make" without argument is like "make help". 13 | help: 14 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 15 | 16 | .PHONY: help Makefile 17 | 18 | # Run the development server using sphinx-autobuild 19 | docs: 20 | @echo 21 | @echo "Starting up the docs server..." 22 | @echo 23 | $(SPHINXAUTOBUILD) --port 8000 --watch ${SOURCEDIR} $(SOURCEDIR) "$(BUILDDIR)/html" $(SPHINXOPTS) $(O) 24 | 25 | # Catch-all target: route all unknown targets to Sphinx using the new 26 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 27 | %: Makefile 28 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 29 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | if "%SPHINXAUTOBUILD%" == "" ( 11 | set SPHINXAUTOBUILD=sphinx-autobuild 12 | ) 13 | set SOURCEDIR=source 14 | set BUILDDIR=build 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "docs" goto docs 19 | 20 | %SPHINXBUILD% >NUL 2>NUL 21 | if errorlevel 9009 ( 22 | echo. 23 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 24 | echo.installed, then set the SPHINXBUILD environment variable to point 25 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 26 | echo.may add the Sphinx directory to PATH. 27 | echo. 28 | echo.If you don't have Sphinx installed, grab it from 29 | echo.http://sphinx-doc.org/ 30 | exit /b 1 31 | ) 32 | 33 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 34 | goto end 35 | 36 | :docs 37 | @echo 38 | @echo Starting up the docs server... 39 | @echo 40 | %SPHINXAUTOBUILD% --port 8000 --watch %SOURCEDIR% %SOURCEDIR% %BUILDDIR%\html %SPHINXOPTS% %O% 41 | goto end 42 | 43 | :help 44 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 45 | 46 | :end 47 | popd 48 | -------------------------------------------------------------------------------- /docs/source/_static/theme_overrides.css: -------------------------------------------------------------------------------- 1 | /* this is the container for the pages */ 2 | .wy-nav-content { 3 | max-width: 100%; 4 | padding: 0px 40px 0px 0px; 5 | margin-top: 0px; 6 | } 7 | 8 | .wy-nav-content-wrap { 9 | border-right: solid 1px; 10 | } 11 | 12 | div.rst-content { 13 | max-width: 1300px; 14 | border: 0; 15 | padding: 10px 80px 10px 80px; 16 | margin-left: 50px; 17 | } 18 | 19 | @media (max-width: 768px) { 20 | div.rst-content { 21 | max-width: 1300px; 22 | border: 0; 23 | padding: 0px 10px 10px 10px; 24 | margin-left: 0px; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = "python-inspector" 21 | copyright = "nexB Inc., AboutCode and others." 22 | author = "AboutCode.org authors and contributors" 23 | 24 | 25 | # -- General configuration --------------------------------------------------- 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be 28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 29 | # ones. 30 | extensions = [ 31 | "sphinx.ext.intersphinx", 32 | "sphinx_reredirects", 33 | "sphinx_rtd_theme", 34 | "sphinx_rtd_dark_mode", 35 | "sphinx.ext.extlinks", 36 | "sphinx_copybutton", 37 | ] 38 | 39 | 40 | # Redirects for olds pages 41 | # See https://documatt.gitlab.io/sphinx-reredirects/usage.html 42 | redirects = {} 43 | 44 | # This points to aboutcode.readthedocs.io 45 | # In case of "undefined label" ERRORS check docs on intersphinx to troubleshoot 46 | # Link was created at commit - https://github.com/aboutcode-org/aboutcode/commit/faea9fcf3248f8f198844fe34d43833224ac4a83 47 | 48 | intersphinx_mapping = { 49 | "aboutcode": ("https://aboutcode.readthedocs.io/en/latest/", None), 50 | "scancode-workbench": ( 51 | "https://scancode-workbench.readthedocs.io/en/develop/", 52 | None, 53 | ), 54 | } 55 | 56 | 57 | # Add any paths that contain templates here, relative to this directory. 58 | templates_path = ["_templates"] 59 | 60 | # List of patterns, relative to source directory, that match files and 61 | # directories to ignore when looking for source files. 62 | # This pattern also affects html_static_path and html_extra_path. 63 | exclude_patterns = [] 64 | 65 | 66 | # -- Options for HTML output ------------------------------------------------- 67 | 68 | # The theme to use for HTML and HTML Help pages. See the documentation for 69 | # a list of builtin themes. 70 | # 71 | html_theme = "sphinx_rtd_theme" 72 | 73 | # Add any paths that contain custom static files (such as style sheets) here, 74 | # relative to this directory. They are copied after the builtin static files, 75 | # so a file named "default.css" will overwrite the builtin "default.css". 76 | html_static_path = ["_static"] 77 | 78 | master_doc = "index" 79 | 80 | html_context = { 81 | "display_github": True, 82 | "github_user": "nexB", 83 | "github_repo": "python-inspector", 84 | "github_version": "develop", # branch 85 | "conf_py_path": "/docs/source/", # path in the checkout to the docs root 86 | } 87 | 88 | html_css_files = [ 89 | "theme_overrides.css", 90 | ] 91 | 92 | 93 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 94 | html_show_sphinx = True 95 | 96 | # Define CSS and HTML abbreviations used in .rst files. These are examples. 97 | # .. role:: is used to refer to styles defined in _static/theme_overrides.css 98 | # and is used like this: :red:`text` 99 | rst_prolog = """ 100 | .. |psf| replace:: Python Software Foundation 101 | 102 | .. # define a hard line break for HTML 103 | .. |br| raw:: html 104 | 105 |
106 | 107 | .. role:: red 108 | 109 | .. role:: img-title 110 | 111 | .. role:: img-title-para 112 | 113 | """ 114 | 115 | # -- Options for LaTeX output ------------------------------------------------- 116 | 117 | latex_elements = {"classoptions": ",openany,oneside"} 118 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to python-inspector's documentation! 2 | ================================================ 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Contents: 7 | 8 | dependencies-design 9 | test-protocol 10 | contribute/contrib_doc 11 | 12 | Indices and tables 13 | ================== 14 | 15 | * :ref:`genindex` 16 | * :ref:`modindex` 17 | * :ref:`search` 18 | -------------------------------------------------------------------------------- /etc/ci/azure-container-deb.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | job_name: '' 3 | container: '' 4 | python_path: '' 5 | python_version: '' 6 | package_manager: apt-get 7 | install_python: '' 8 | install_packages: | 9 | set -e -x 10 | sudo apt-get -y update 11 | sudo apt-get -y install \ 12 | build-essential \ 13 | xz-utils zlib1g bzip2 libbz2-1.0 tar \ 14 | sqlite3 libxml2-dev libxslt1-dev \ 15 | software-properties-common openssl 16 | test_suite: '' 17 | test_suite_label: '' 18 | 19 | 20 | jobs: 21 | - job: ${{ parameters.job_name }} 22 | 23 | pool: 24 | vmImage: 'ubuntu-16.04' 25 | 26 | container: 27 | image: ${{ parameters.container }} 28 | options: '--name ${{ parameters.job_name }} -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v /usr/bin/docker:/tmp/docker:ro' 29 | 30 | steps: 31 | - checkout: self 32 | fetchDepth: 10 33 | 34 | - script: /tmp/docker exec -t -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -u 0 ${{ parameters.job_name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }} 35 | displayName: Install sudo 36 | 37 | - script: ${{ parameters.install_packages }} 38 | displayName: Install required packages 39 | 40 | - script: ${{ parameters.install_python }} 41 | displayName: 'Install Python ${{ parameters.python_version }}' 42 | 43 | - script: ${{ parameters.python_path }} --version 44 | displayName: 'Show Python version' 45 | 46 | - script: PYTHON_EXE=${{ parameters.python_path }} ./configure --dev 47 | displayName: 'Run Configure' 48 | 49 | - script: ${{ parameters.test_suite }} 50 | displayName: 'Run ${{ parameters.test_suite_label }} tests with py${{ parameters.python_version }} on ${{ parameters.job_name }}' 51 | -------------------------------------------------------------------------------- /etc/ci/azure-container-rpm.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | job_name: '' 3 | image_name: 'ubuntu-16.04' 4 | container: '' 5 | python_path: '' 6 | python_version: '' 7 | package_manager: yum 8 | install_python: '' 9 | install_packages: | 10 | set -e -x 11 | sudo yum groupinstall -y "Development Tools" 12 | sudo yum install -y \ 13 | openssl openssl-devel \ 14 | sqlite-devel zlib-devel xz-devel bzip2-devel \ 15 | bzip2 tar unzip zip \ 16 | libxml2-devel libxslt-devel 17 | test_suite: '' 18 | test_suite_label: '' 19 | 20 | 21 | jobs: 22 | - job: ${{ parameters.job_name }} 23 | 24 | pool: 25 | vmImage: ${{ parameters.image_name }} 26 | 27 | container: 28 | image: ${{ parameters.container }} 29 | options: '--name ${{ parameters.job_name }} -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v /usr/bin/docker:/tmp/docker:ro' 30 | 31 | steps: 32 | - checkout: self 33 | fetchDepth: 10 34 | 35 | - script: /tmp/docker exec -t -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -u 0 ${{ parameters.job_name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }} 36 | displayName: Install sudo 37 | 38 | - script: ${{ parameters.install_packages }} 39 | displayName: Install required packages 40 | 41 | - script: ${{ parameters.install_python }} 42 | displayName: 'Install Python ${{ parameters.python_version }}' 43 | 44 | - script: ${{ parameters.python_path }} --version 45 | displayName: 'Show Python version' 46 | 47 | - script: PYTHON_EXE=${{ parameters.python_path }} ./configure --dev 48 | displayName: 'Run Configure' 49 | 50 | - script: ${{ parameters.test_suite }} 51 | displayName: 'Run ${{ parameters.test_suite_label }} tests with py${{ parameters.python_version }} on ${{ parameters.job_name }}' 52 | -------------------------------------------------------------------------------- /etc/ci/azure-posix.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | job_name: '' 3 | image_name: '' 4 | python_versions: [] 5 | test_suites: {} 6 | python_architecture: x64 7 | 8 | jobs: 9 | - job: ${{ parameters.job_name }} 10 | 11 | pool: 12 | vmImage: ${{ parameters.image_name }} 13 | 14 | strategy: 15 | matrix: 16 | ${{ each tsuite in parameters.test_suites }}: 17 | ${{ tsuite.key }}: 18 | test_suite_label: ${{ tsuite.key }} 19 | test_suite: ${{ tsuite.value }} 20 | 21 | steps: 22 | - checkout: self 23 | fetchDepth: 10 24 | 25 | - ${{ each pyver in parameters.python_versions }}: 26 | - task: UsePythonVersion@0 27 | inputs: 28 | versionSpec: '${{ pyver }}' 29 | architecture: '${{ parameters.python_architecture }}' 30 | displayName: '${{ pyver }} - Install Python' 31 | 32 | - script: | 33 | python${{ pyver }} --version 34 | echo "python${{ pyver }}" > PYTHON_EXECUTABLE 35 | ./configure --clean && ./configure --dev 36 | displayName: '${{ pyver }} - Configure' 37 | 38 | - script: $(test_suite) 39 | displayName: '${{ pyver }} - $(test_suite_label) on ${{ parameters.job_name }}' 40 | -------------------------------------------------------------------------------- /etc/ci/azure-win.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | job_name: '' 3 | image_name: '' 4 | python_versions: [] 5 | test_suites: {} 6 | python_architecture: x64 7 | 8 | jobs: 9 | - job: ${{ parameters.job_name }} 10 | 11 | pool: 12 | vmImage: ${{ parameters.image_name }} 13 | 14 | strategy: 15 | matrix: 16 | ${{ each tsuite in parameters.test_suites }}: 17 | ${{ tsuite.key }}: 18 | test_suite_label: ${{ tsuite.key }} 19 | test_suite: ${{ tsuite.value }} 20 | 21 | steps: 22 | - checkout: self 23 | fetchDepth: 10 24 | 25 | - ${{ each pyver in parameters.python_versions }}: 26 | - task: UsePythonVersion@0 27 | inputs: 28 | versionSpec: '${{ pyver }}' 29 | architecture: '${{ parameters.python_architecture }}' 30 | displayName: '${{ pyver }} - Install Python' 31 | 32 | - script: | 33 | python --version 34 | echo | set /p=python> PYTHON_EXECUTABLE 35 | configure --clean && configure --dev 36 | displayName: '${{ pyver }} - Configure' 37 | 38 | - script: $(test_suite) 39 | displayName: '${{ pyver }} - $(test_suite_label) on ${{ parameters.job_name }}' 40 | -------------------------------------------------------------------------------- /etc/ci/install_sudo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | if [[ "$1" == "apt-get" ]]; then 6 | apt-get update -y 7 | apt-get -o DPkg::Options::="--force-confold" install -y sudo 8 | 9 | elif [[ "$1" == "yum" ]]; then 10 | yum install -y sudo 11 | 12 | elif [[ "$1" == "dnf" ]]; then 13 | dnf install -y sudo 14 | 15 | fi 16 | -------------------------------------------------------------------------------- /etc/ci/macports-ci.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: macports-ci 2 | name: macports-ci 3 | version: c9676e67351a3a519e37437e196cd0ee9c2180b8 4 | download_url: https://raw.githubusercontent.com/GiovanniBussi/macports-ci/c9676e67351a3a519e37437e196cd0ee9c2180b8/macports-ci 5 | description: Simplify MacPorts setup on Travis-CI 6 | homepage_url: https://github.com/GiovanniBussi/macports-ci 7 | license_expression: mit 8 | copyright: Copyright (c) Giovanni Bussi 9 | attribute: yes 10 | checksum_md5: 5d31d479132502f80acdaed78bed9e23 11 | checksum_sha1: 74b15643bd1a528d91b4a7c2169c6fc656f549c2 12 | package_url: pkg:github/giovannibussi/macports-ci@c9676e67351a3a519e37437e196cd0ee9c2180b8#macports-ci 13 | licenses: 14 | - key: mit 15 | name: MIT License 16 | file: mit.LICENSE 17 | -------------------------------------------------------------------------------- /etc/ci/mit.LICENSE: -------------------------------------------------------------------------------- 1 | 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: 2 | 3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 4 | 5 | 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. -------------------------------------------------------------------------------- /etc/scripts/README.rst: -------------------------------------------------------------------------------- 1 | This directory contains the tools to manage a directory of thirdparty Python 2 | package source, wheels and metadata pin, build, update, document and publish to 3 | a PyPI-like repo (GitHub release). 4 | 5 | NOTE: These are tested to run ONLY on Linux. 6 | 7 | 8 | Thirdparty packages management scripts 9 | ====================================== 10 | 11 | Pre-requisites 12 | -------------- 13 | 14 | * There are two run "modes": 15 | 16 | * To generate or update pip requirement files, you need to start with a clean 17 | virtualenv as instructed below (This is to avoid injecting requirements 18 | specific to the tools used here in the main requirements). 19 | 20 | * For other usages, the tools here can run either in their own isolated 21 | virtualenv or in the the main configured development virtualenv. 22 | These requireements need to be installed:: 23 | 24 | pip install --requirement etc/scripts/requirements.txt 25 | 26 | TODO: we need to pin the versions of these tools 27 | 28 | 29 | 30 | Generate or update pip requirement files 31 | ---------------------------------------- 32 | 33 | Scripts 34 | ~~~~~~~ 35 | 36 | **gen_requirements.py**: create/update requirements files from currently 37 | installed requirements. 38 | 39 | **gen_requirements_dev.py** does the same but can subtract the main requirements 40 | to get extra requirements used in only development. 41 | 42 | 43 | Usage 44 | ~~~~~ 45 | 46 | The sequence of commands to run are: 47 | 48 | 49 | * Start with these to generate the main pip requirements file:: 50 | 51 | ./configure --clean 52 | ./configure 53 | python etc/scripts/gen_requirements.py --site-packages-dir 54 | 55 | * You can optionally install or update extra main requirements after the 56 | ./configure step such that these are included in the generated main requirements. 57 | 58 | * Optionally, generate a development pip requirements file by running these:: 59 | 60 | ./configure --clean 61 | ./configure --dev 62 | python etc/scripts/gen_requirements_dev.py --site-packages-dir 63 | 64 | * You can optionally install or update extra dev requirements after the 65 | ./configure step such that these are included in the generated dev 66 | requirements. 67 | 68 | Notes: we generate development requirements after the main as this step requires 69 | the main requirements.txt to be up-to-date first. See **gen_requirements.py and 70 | gen_requirements_dev.py** --help for details. 71 | 72 | Note: this does NOT hash requirements for now. 73 | 74 | Note: Be aware that if you are using "conditional" requirements (e.g. only for 75 | OS or Python versions) in setup.py/setp.cfg/requirements.txt as these are NOT 76 | yet supported. 77 | 78 | 79 | Populate a thirdparty directory with wheels, sources, .ABOUT and license files 80 | ------------------------------------------------------------------------------ 81 | 82 | Scripts 83 | ~~~~~~~ 84 | 85 | * **fetch_thirdparty.py** will fetch package wheels, source sdist tarballs 86 | and their ABOUT, LICENSE and NOTICE files to populate a local directory from 87 | a list of PyPI simple URLs (typically PyPI.org proper and our self-hosted PyPI) 88 | using pip requirements file(s), specifiers or pre-existing packages files. 89 | Fetch wheels for specific python version and operating system combinations. 90 | 91 | * **check_thirdparty.py** will check a thirdparty directory for errors. 92 | 93 | 94 | Upgrade virtualenv app 95 | ---------------------- 96 | 97 | The bundled virtualenv.pyz has to be upgraded by hand and is stored under 98 | etc/thirdparty 99 | 100 | * Fetch https://github.com/pypa/get-virtualenv/raw//public/virtualenv.pyz 101 | for instance https://github.com/pypa/get-virtualenv/raw/20.2.2/public/virtualenv.pyz 102 | and save to thirdparty and update the ABOUT and LICENSE files as needed. 103 | 104 | * This virtualenv app contains also bundled pip, wheel and setuptools that are 105 | essential for the installation to work. 106 | 107 | 108 | Other files 109 | =========== 110 | 111 | The other files and scripts are test, support and utility modules used by the 112 | main scripts documented here. 113 | -------------------------------------------------------------------------------- /etc/scripts/check_thirdparty.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) nexB Inc. and others. All rights reserved. 4 | # ScanCode is a trademark of nexB Inc. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 7 | # See https://github.com/aboutcode-org/skeleton for support or download. 8 | # See https://aboutcode.org for more information about nexB OSS projects. 9 | # 10 | import click 11 | 12 | import utils_thirdparty 13 | 14 | 15 | @click.command() 16 | @click.option( 17 | "-d", 18 | "--dest", 19 | type=click.Path(exists=True, readable=True, path_type=str, file_okay=False), 20 | required=True, 21 | help="Path to the thirdparty directory to check.", 22 | ) 23 | @click.option( 24 | "-w", 25 | "--wheels", 26 | is_flag=True, 27 | help="Check missing wheels.", 28 | ) 29 | @click.option( 30 | "-s", 31 | "--sdists", 32 | is_flag=True, 33 | help="Check missing source sdists tarballs.", 34 | ) 35 | @click.help_option("-h", "--help") 36 | def check_thirdparty_dir( 37 | dest, 38 | wheels, 39 | sdists, 40 | ): 41 | """ 42 | Check a thirdparty directory for problems and print these on screen. 43 | """ 44 | print("==> CHECK FOR PROBLEMS") 45 | utils_thirdparty.find_problems( 46 | dest_dir=dest, 47 | report_missing_sources=sdists, 48 | report_missing_wheels=wheels, 49 | ) 50 | 51 | 52 | if __name__ == "__main__": 53 | check_thirdparty_dir() 54 | -------------------------------------------------------------------------------- /etc/scripts/gen_pypi_simple.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: gen_pypi_simple.py 2 | name: gen_pypi_simple.py 3 | license_expression: bsd-2-clause-views and mit 4 | copyright: Copyright (c) nexB Inc. 5 | Copyright (c) 2010 David Wolever 6 | Copyright (c) The pip developers 7 | notes: Originally from https://github.com/wolever/pip2pi and modified extensivley 8 | Also partially derived from pip code 9 | -------------------------------------------------------------------------------- /etc/scripts/gen_pypi_simple.py.NOTICE: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: BSD-2-Clause-Views AND mit 2 | 3 | Copyright (c) nexB Inc. 4 | Copyright (c) 2010 David Wolever 5 | Copyright (c) The pip developers 6 | 7 | 8 | Original code: copyright 2010 David Wolever . All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | 2. Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR 21 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 23 | EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 28 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | The views and conclusions contained in the software and documentation are those 32 | of the authors and should not be interpreted as representing official policies, 33 | either expressed or implied, of David Wolever. 34 | 35 | 36 | Original code: Copyright (c) 2008-2020 The pip developers 37 | 38 | Permission is hereby granted, free of charge, to any person obtaining 39 | a copy of this software and associated documentation files (the 40 | "Software"), to deal in the Software without restriction, including 41 | without limitation the rights to use, copy, modify, merge, publish, 42 | distribute, sublicense, and/or sell copies of the Software, and to 43 | permit persons to whom the Software is furnished to do so, subject to 44 | the following conditions: 45 | 46 | The above copyright notice and this permission notice shall be 47 | included in all copies or substantial portions of the Software. 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 50 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 51 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 52 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 53 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 54 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 55 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 56 | 57 | -------------------------------------------------------------------------------- /etc/scripts/gen_requirements.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) nexB Inc. and others. All rights reserved. 4 | # ScanCode is a trademark of nexB Inc. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 7 | # See https://github.com/aboutcode-org/skeleton for support or download. 8 | # See https://aboutcode.org for more information about nexB OSS projects. 9 | # 10 | import argparse 11 | import pathlib 12 | 13 | import utils_requirements 14 | 15 | """ 16 | Utilities to manage requirements files. 17 | NOTE: this should use ONLY the standard library and not import anything else 18 | because this is used for boostrapping with no requirements installed. 19 | """ 20 | 21 | 22 | def gen_requirements(): 23 | description = """ 24 | Create or replace the `--requirements-file` file FILE requirements file with all 25 | locally installed Python packages.all Python packages found installed in `--site-packages-dir` 26 | """ 27 | parser = argparse.ArgumentParser(description=description) 28 | 29 | parser.add_argument( 30 | "-s", 31 | "--site-packages-dir", 32 | dest="site_packages_dir", 33 | type=pathlib.Path, 34 | required=True, 35 | metavar="DIR", 36 | help="Path to the 'site-packages' directory where wheels are installed " 37 | "such as lib/python3.12/site-packages", 38 | ) 39 | parser.add_argument( 40 | "-r", 41 | "--requirements-file", 42 | type=pathlib.Path, 43 | metavar="FILE", 44 | default="requirements.txt", 45 | help="Path to the requirements file to update or create.", 46 | ) 47 | 48 | args = parser.parse_args() 49 | 50 | utils_requirements.lock_requirements( 51 | site_packages_dir=args.site_packages_dir, 52 | requirements_file=args.requirements_file, 53 | ) 54 | 55 | 56 | if __name__ == "__main__": 57 | gen_requirements() 58 | -------------------------------------------------------------------------------- /etc/scripts/gen_requirements_dev.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) nexB Inc. and others. All rights reserved. 4 | # ScanCode is a trademark of nexB Inc. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 7 | # See https://github.com/aboutcode-org/skeleton for support or download. 8 | # See https://aboutcode.org for more information about nexB OSS projects. 9 | # 10 | import argparse 11 | import pathlib 12 | 13 | import utils_requirements 14 | 15 | """ 16 | Utilities to manage requirements files. 17 | NOTE: this should use ONLY the standard library and not import anything else 18 | because this is used for boostrapping with no requirements installed. 19 | """ 20 | 21 | 22 | def gen_dev_requirements(): 23 | description = """ 24 | Create or overwrite the `--dev-requirements-file` pip requirements FILE with 25 | all Python packages found installed in `--site-packages-dir`. Exclude 26 | package names also listed in the --main-requirements-file pip requirements 27 | FILE (that are assume to the production requirements and therefore to always 28 | be present in addition to the development requirements). 29 | """ 30 | parser = argparse.ArgumentParser(description=description) 31 | 32 | parser.add_argument( 33 | "-s", 34 | "--site-packages-dir", 35 | type=pathlib.Path, 36 | required=True, 37 | metavar="DIR", 38 | help="Path to the 'site-packages' directory where wheels are installed " 39 | "such as lib/python3.12/site-packages", 40 | ) 41 | parser.add_argument( 42 | "-d", 43 | "--dev-requirements-file", 44 | type=pathlib.Path, 45 | metavar="FILE", 46 | default="requirements-dev.txt", 47 | help="Path to the dev requirements file to update or create.", 48 | ) 49 | parser.add_argument( 50 | "-r", 51 | "--main-requirements-file", 52 | type=pathlib.Path, 53 | default="requirements.txt", 54 | metavar="FILE", 55 | help="Path to the main requirements file. Its requirements will be excluded " 56 | "from the generated dev requirements.", 57 | ) 58 | args = parser.parse_args() 59 | 60 | utils_requirements.lock_dev_requirements( 61 | dev_requirements_file=args.dev_requirements_file, 62 | main_requirements_file=args.main_requirements_file, 63 | site_packages_dir=args.site_packages_dir, 64 | ) 65 | 66 | 67 | if __name__ == "__main__": 68 | gen_dev_requirements() 69 | -------------------------------------------------------------------------------- /etc/scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | aboutcode_toolkit 2 | attrs 3 | commoncode 4 | click 5 | requests 6 | saneyaml 7 | pip 8 | setuptools 9 | twine 10 | wheel 11 | build 12 | packvers 13 | -------------------------------------------------------------------------------- /etc/scripts/test_utils_pip_compatibility_tags.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generate and work with PEP 425 Compatibility Tags. 3 | 4 | copied from pip-20.3.1 pip/tests/unit/test_utils_compatibility_tags.py 5 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py 6 | 7 | Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining 10 | a copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | """ 28 | 29 | import sysconfig 30 | from unittest.mock import patch 31 | 32 | import pytest 33 | 34 | import utils_pip_compatibility_tags 35 | 36 | 37 | @pytest.mark.parametrize( 38 | "version_info, expected", 39 | [ 40 | ((2,), "2"), 41 | ((2, 8), "28"), 42 | ((3,), "3"), 43 | ((3, 6), "36"), 44 | # Test a tuple of length 3. 45 | ((3, 6, 5), "36"), 46 | # Test a 2-digit minor version. 47 | ((3, 10), "310"), 48 | ], 49 | ) 50 | def test_version_info_to_nodot(version_info, expected): 51 | actual = utils_pip_compatibility_tags.version_info_to_nodot(version_info) 52 | assert actual == expected 53 | 54 | 55 | class Testcompatibility_tags: 56 | def mock_get_config_var(self, **kwd): 57 | """ 58 | Patch sysconfig.get_config_var for arbitrary keys. 59 | """ 60 | get_config_var = sysconfig.get_config_var 61 | 62 | def _mock_get_config_var(var): 63 | if var in kwd: 64 | return kwd[var] 65 | return get_config_var(var) 66 | 67 | return _mock_get_config_var 68 | 69 | def test_no_hyphen_tag(self): 70 | """ 71 | Test that no tag contains a hyphen. 72 | """ 73 | import pip._internal.utils.compatibility_tags 74 | 75 | mock_gcf = self.mock_get_config_var(SOABI="cpython-35m-darwin") 76 | 77 | with patch("sysconfig.get_config_var", mock_gcf): 78 | supported = pip._internal.utils.compatibility_tags.get_supported() 79 | 80 | for tag in supported: 81 | assert "-" not in tag.interpreter 82 | assert "-" not in tag.abi 83 | assert "-" not in tag.platform 84 | 85 | 86 | class TestManylinux2010Tags: 87 | @pytest.mark.parametrize( 88 | "manylinux2010,manylinux1", 89 | [ 90 | ("manylinux2010_x86_64", "manylinux1_x86_64"), 91 | ("manylinux2010_i686", "manylinux1_i686"), 92 | ], 93 | ) 94 | def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1): 95 | """ 96 | Specifying manylinux2010 implies manylinux1. 97 | """ 98 | groups = {} 99 | supported = utils_pip_compatibility_tags.get_supported(platforms=[manylinux2010]) 100 | for tag in supported: 101 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform) 102 | 103 | for arches in groups.values(): 104 | if arches == ["any"]: 105 | continue 106 | assert arches[:2] == [manylinux2010, manylinux1] 107 | 108 | 109 | class TestManylinux2014Tags: 110 | @pytest.mark.parametrize( 111 | "manylinuxA,manylinuxB", 112 | [ 113 | ("manylinux2014_x86_64", ["manylinux2010_x86_64", "manylinux1_x86_64"]), 114 | ("manylinux2014_i686", ["manylinux2010_i686", "manylinux1_i686"]), 115 | ], 116 | ) 117 | def test_manylinuxA_implies_manylinuxB(self, manylinuxA, manylinuxB): 118 | """ 119 | Specifying manylinux2014 implies manylinux2010/manylinux1. 120 | """ 121 | groups = {} 122 | supported = utils_pip_compatibility_tags.get_supported(platforms=[manylinuxA]) 123 | for tag in supported: 124 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform) 125 | 126 | expected_arches = [manylinuxA] 127 | expected_arches.extend(manylinuxB) 128 | for arches in groups.values(): 129 | if arches == ["any"]: 130 | continue 131 | assert arches[:3] == expected_arches 132 | -------------------------------------------------------------------------------- /etc/scripts/test_utils_pip_compatibility_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: test_utils_pip_compatibility_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: tests/unit/test_utils_compatibility_tags.py 8 | 9 | package_url: pkg:github/pypa/pip@20.3.1#tests/unit/test_utils_compatibility_tags.py 10 | 11 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py 12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 13 | license_expression: mit 14 | notes: subset copied from pip for tag handling 15 | -------------------------------------------------------------------------------- /etc/scripts/test_utils_pypi_supported_tags.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import pytest 14 | 15 | from utils_pypi_supported_tags import validate_platforms_for_pypi 16 | 17 | """ 18 | Wheel platform checking tests 19 | 20 | Copied and modified on 2020-12-24 from 21 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py 22 | """ 23 | 24 | 25 | def validate_wheel_filename_for_pypi(filename): 26 | """ 27 | Validate if the filename is a PyPI/warehouse-uploadable wheel file name 28 | with supported platform tags. Return a list of unsupported platform tags or 29 | an empty list if all tags are supported. 30 | """ 31 | from utils_thirdparty import Wheel 32 | 33 | wheel = Wheel.from_filename(filename) 34 | return validate_platforms_for_pypi(wheel.platforms) 35 | 36 | 37 | @pytest.mark.parametrize( 38 | "plat", 39 | [ 40 | "any", 41 | "win32", 42 | "win_amd64", 43 | "win_ia64", 44 | "manylinux1_i686", 45 | "manylinux1_x86_64", 46 | "manylinux2010_i686", 47 | "manylinux2010_x86_64", 48 | "manylinux2014_i686", 49 | "manylinux2014_x86_64", 50 | "manylinux2014_aarch64", 51 | "manylinux2014_armv7l", 52 | "manylinux2014_ppc64", 53 | "manylinux2014_ppc64le", 54 | "manylinux2014_s390x", 55 | "manylinux_2_5_i686", 56 | "manylinux_2_12_x86_64", 57 | "manylinux_2_17_aarch64", 58 | "manylinux_2_17_armv7l", 59 | "manylinux_2_17_ppc64", 60 | "manylinux_2_17_ppc64le", 61 | "manylinux_3_0_s390x", 62 | "macosx_10_6_intel", 63 | "macosx_10_13_x86_64", 64 | "macosx_11_0_x86_64", 65 | "macosx_10_15_arm64", 66 | "macosx_11_10_universal2", 67 | # A real tag used by e.g. some numpy wheels 68 | ( 69 | "macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64." 70 | "macosx_10_10_intel.macosx_10_10_x86_64" 71 | ), 72 | ], 73 | ) 74 | def test_is_valid_pypi_wheel_return_true_for_supported_wheel(plat): 75 | filename = f"foo-1.2.3-cp34-none-{plat}.whl" 76 | assert not validate_wheel_filename_for_pypi(filename) 77 | 78 | 79 | @pytest.mark.parametrize( 80 | "plat", 81 | [ 82 | "linux_x86_64", 83 | "linux_x86_64.win32", 84 | "macosx_9_2_x86_64", 85 | "macosx_12_2_arm64", 86 | "macosx_10_15_amd64", 87 | ], 88 | ) 89 | def test_is_valid_pypi_wheel_raise_exception_for_aunsupported_wheel(plat): 90 | filename = f"foo-1.2.3-cp34-none-{plat}.whl" 91 | invalid = validate_wheel_filename_for_pypi(filename) 92 | assert invalid 93 | -------------------------------------------------------------------------------- /etc/scripts/test_utils_pypi_supported_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: test_utils_pypi_supported_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: warehouse 6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d 7 | subpath: tests/unit/forklift/test_legacy.py 8 | 9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#tests/unit/forklift/test_legacy.py 10 | 11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py 12 | copyright: Copyright (c) The warehouse developers 13 | homepage_url: https://warehouse.readthedocs.io 14 | license_expression: apache-2.0 15 | notes: Test for wheel platform checking copied and heavily modified on 16 | 2020-12-24 from warehouse. This contains the basic functions to check if a 17 | wheel file name is would be supported for uploading to PyPI. 18 | -------------------------------------------------------------------------------- /etc/scripts/update_skeleton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) nexB Inc. AboutCode, and others. All rights reserved. 4 | # ScanCode is a trademark of nexB Inc. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 7 | # See https://github.com/aboutcode-org/skeleton for support or download. 8 | # See https://aboutcode.org for more information about nexB OSS projects. 9 | # 10 | 11 | from pathlib import Path 12 | import os 13 | import subprocess 14 | 15 | import click 16 | 17 | 18 | ABOUTCODE_PUBLIC_REPO_NAMES = [ 19 | "aboutcode-toolkit", 20 | "ahocode", 21 | "bitcode", 22 | "clearcode-toolkit", 23 | "commoncode", 24 | "container-inspector", 25 | "debian-inspector", 26 | "deltacode", 27 | "elf-inspector", 28 | "extractcode", 29 | "fetchcode", 30 | "gemfileparser2", 31 | "gh-issue-sandbox", 32 | "go-inspector", 33 | "heritedcode", 34 | "license-expression", 35 | "license_copyright_pipeline", 36 | "nuget-inspector", 37 | "pip-requirements-parser", 38 | "plugincode", 39 | "purldb", 40 | "pygmars", 41 | "python-inspector", 42 | "sanexml", 43 | "saneyaml", 44 | "scancode-analyzer", 45 | "scancode-toolkit-contrib", 46 | "scancode-toolkit-reference-scans", 47 | "thirdparty-toolkit", 48 | "tracecode-toolkit", 49 | "tracecode-toolkit-strace", 50 | "turbo-spdx", 51 | "typecode", 52 | "univers", 53 | ] 54 | 55 | 56 | @click.command() 57 | @click.help_option("-h", "--help") 58 | def update_skeleton_files(repo_names=ABOUTCODE_PUBLIC_REPO_NAMES): 59 | """ 60 | Update project files of AboutCode projects that use the skeleton 61 | 62 | This script will: 63 | - Clone the repo 64 | - Add the skeleton repo as a new origin 65 | - Create a new branch named "update-skeleton-files" 66 | - Merge in the new skeleton files into the "update-skeleton-files" branch 67 | 68 | The user will need to save merge commit messages that pop up when running 69 | this script in addition to resolving the merge conflicts on repos that have 70 | them. 71 | """ 72 | 73 | # Create working directory 74 | work_dir_path = Path("/tmp/update_skeleton/") 75 | if not os.path.exists(work_dir_path): 76 | os.makedirs(work_dir_path, exist_ok=True) 77 | 78 | for repo_name in repo_names: 79 | # Move to work directory 80 | os.chdir(work_dir_path) 81 | 82 | # Clone repo 83 | repo_git = f"git@github.com:aboutcode-org/{repo_name}.git" 84 | subprocess.run(["git", "clone", repo_git]) 85 | 86 | # Go into cloned repo 87 | os.chdir(work_dir_path / repo_name) 88 | 89 | # Add skeleton as an origin 90 | subprocess.run( 91 | ["git", "remote", "add", "skeleton", "git@github.com:aboutcode-org/skeleton.git"] 92 | ) 93 | 94 | # Fetch skeleton files 95 | subprocess.run(["git", "fetch", "skeleton"]) 96 | 97 | # Create and checkout new branch 98 | subprocess.run(["git", "checkout", "-b", "update-skeleton-files"]) 99 | 100 | # Merge skeleton files into the repo 101 | subprocess.run(["git", "merge", "skeleton/main", "--allow-unrelated-histories"]) 102 | 103 | 104 | if __name__ == "__main__": 105 | update_skeleton_files() 106 | -------------------------------------------------------------------------------- /etc/scripts/utils_pip_compatibility_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_pip_compatibility_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: src/pip/_internal/utils/compatibility_tags.py 8 | 9 | package_url: pkg:github/pypa/pip@20.3.1#src/pip/_internal/utils/compatibility_tags.py 10 | 11 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/utils/compatibility_tags.py 12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 13 | license_expression: mit 14 | notes: subset copied from pip for tag handling -------------------------------------------------------------------------------- /etc/scripts/utils_pypi_supported_tags.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import re 14 | 15 | """ 16 | Wheel platform checking 17 | 18 | Copied and modified on 2020-12-24 from 19 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py 20 | 21 | This contains the basic functions to check if a wheel file name is would be 22 | supported for uploading to PyPI. 23 | """ 24 | 25 | # These platforms can be handled by a simple static list: 26 | _allowed_platforms = { 27 | "any", 28 | "win32", 29 | "win_amd64", 30 | "win_ia64", 31 | "manylinux1_x86_64", 32 | "manylinux1_i686", 33 | "manylinux2010_x86_64", 34 | "manylinux2010_i686", 35 | "manylinux2014_x86_64", 36 | "manylinux2014_i686", 37 | "manylinux2014_aarch64", 38 | "manylinux2014_armv7l", 39 | "manylinux2014_ppc64", 40 | "manylinux2014_ppc64le", 41 | "manylinux2014_s390x", 42 | "linux_armv6l", 43 | "linux_armv7l", 44 | } 45 | # macosx is a little more complicated: 46 | _macosx_platform_re = re.compile(r"macosx_(?P\d+)_(\d+)_(?P.*)") 47 | _macosx_arches = { 48 | "ppc", 49 | "ppc64", 50 | "i386", 51 | "x86_64", 52 | "arm64", 53 | "intel", 54 | "fat", 55 | "fat32", 56 | "fat64", 57 | "universal", 58 | "universal2", 59 | } 60 | _macosx_major_versions = { 61 | "10", 62 | "11", 63 | } 64 | 65 | # manylinux pep600 is a little more complicated: 66 | _manylinux_platform_re = re.compile(r"manylinux_(\d+)_(\d+)_(?P.*)") 67 | _manylinux_arches = { 68 | "x86_64", 69 | "i686", 70 | "aarch64", 71 | "armv7l", 72 | "ppc64", 73 | "ppc64le", 74 | "s390x", 75 | } 76 | 77 | 78 | def is_supported_platform_tag(platform_tag): 79 | """ 80 | Return True if the ``platform_tag`` is supported on PyPI. 81 | """ 82 | if platform_tag in _allowed_platforms: 83 | return True 84 | m = _macosx_platform_re.match(platform_tag) 85 | if m and m.group("major") in _macosx_major_versions and m.group("arch") in _macosx_arches: 86 | return True 87 | m = _manylinux_platform_re.match(platform_tag) 88 | if m and m.group("arch") in _manylinux_arches: 89 | return True 90 | return False 91 | 92 | 93 | def validate_platforms_for_pypi(platforms): 94 | """ 95 | Validate if the wheel platforms are supported platform tags on Pypi. Return 96 | a list of unsupported platform tags or an empty list if all tags are 97 | supported. 98 | """ 99 | 100 | # Check that if it's a binary wheel, it's on a supported platform 101 | invalid_tags = [] 102 | for plat in platforms: 103 | if not is_supported_platform_tag(plat): 104 | invalid_tags.append(plat) 105 | return invalid_tags 106 | -------------------------------------------------------------------------------- /etc/scripts/utils_pypi_supported_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_pypi_supported_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: warehouse 6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d 7 | subpath: warehouse/forklift/legacy.py 8 | 9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#warehouse/forklift/legacy.py 10 | 11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py 12 | copyright: Copyright (c) The warehouse developers 13 | homepage_url: https://warehouse.readthedocs.io 14 | license_expression: apache-2.0 15 | notes: Wheel platform checking copied and heavily modified on 2020-12-24 from 16 | warehouse. This contains the basic functions to check if a wheel file name is 17 | would be supported for uploading to PyPI. 18 | -------------------------------------------------------------------------------- /etc/scripts/utils_thirdparty.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_thirdparty.py 2 | package_url: pkg:github.com/pypa/pip/@20.3.1#src/pip/_internal/models/wheel.py 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: src/pip/_internal/models/wheel.py 8 | 9 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/models/wheel.py 10 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 11 | license_expression: mit 12 | notes: copied from pip-20.3.1 pip/_internal/models/wheel.py 13 | The models code has been heavily inspired from the ISC-licensed packaging-dists 14 | https://github.com/uranusjr/packaging-dists by Tzu-ping Chung 15 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools >= 50", "wheel", "setuptools_scm[toml] >= 6"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [tool.setuptools_scm] 6 | # this is used populated when creating a git archive 7 | # and when there is .git dir and/or there is no git installed 8 | fallback_version = "9999.3ff5dd5a-2025-06-27" 9 | 10 | [tool.pytest.ini_options] 11 | norecursedirs = [ 12 | ".git", 13 | "bin", 14 | "dist", 15 | "build", 16 | "_build", 17 | "etc", 18 | "local", 19 | "ci", 20 | "docs", 21 | "man", 22 | "share", 23 | "samples", 24 | ".cache", 25 | ".settings", 26 | "Include", 27 | "include", 28 | "Lib", 29 | "lib", 30 | "lib64", 31 | "Lib64", 32 | "Scripts", 33 | "thirdparty", 34 | "tmp", 35 | "venv", 36 | ".venv", 37 | "tests/data", 38 | "*/tests/test_data", 39 | ".eggs", 40 | "src/*/data", 41 | "tests/*/data" 42 | ] 43 | 44 | python_files = "*.py" 45 | 46 | python_classes = "Test" 47 | python_functions = "test" 48 | 49 | addopts = [ 50 | "-rfExXw", 51 | "--strict-markers", 52 | "--doctest-modules" 53 | ] 54 | 55 | [tool.ruff] 56 | line-length = 100 57 | extend-exclude = [] 58 | target-version = "py310" 59 | include = [ 60 | "pyproject.toml", 61 | "src/**/*.py", 62 | "etc/**/*.py", 63 | "test/**/*.py", 64 | "tests/**/*.py", 65 | "doc/**/*.py", 66 | "docs/**/*.py", 67 | "*.py", 68 | "." 69 | 70 | ] 71 | # ignore test data and testfiles: they should never be linted nor formatted 72 | exclude = [ 73 | # main style 74 | "**/tests/data/**/*", 75 | # scancode-toolkit 76 | "**/tests/*/data/**/*", 77 | # dejacode, purldb 78 | "**/tests/testfiles/**/*", 79 | # vulnerablecode, fetchcode 80 | "**/tests/*/test_data/**/*", 81 | "**/tests/test_data/**/*", 82 | # django migrations 83 | "**/migrations/**/*", 84 | # exclude vendored code from ScanCode 85 | "src/_packagedcode", 86 | ] 87 | 88 | [tool.ruff.lint] 89 | # Rules: https://docs.astral.sh/ruff/rules/ 90 | select = [ 91 | # "E", # pycodestyle 92 | # "W", # pycodestyle warnings 93 | "D", # pydocstyle 94 | # "F", # Pyflakes 95 | # "UP", # pyupgrade 96 | # "S", # flake8-bandit 97 | "I", # isort 98 | # "C9", # McCabe complexity 99 | ] 100 | ignore = ["D1", "D200", "D202", "D203", "D205", "D212", "D400", "D415", "I001"] 101 | 102 | 103 | [tool.ruff.lint.isort] 104 | force-single-line = true 105 | lines-after-imports = 1 106 | default-section = "first-party" 107 | known-first-party = ["src", "tests", "etc/scripts/**/*.py"] 108 | known-third-party = ["click", "pytest"] 109 | 110 | sections = { django = ["django"] } 111 | section-order = [ 112 | "future", 113 | "standard-library", 114 | "django", 115 | "third-party", 116 | "first-party", 117 | "local-folder", 118 | ] 119 | 120 | [tool.ruff.lint.mccabe] 121 | max-complexity = 10 122 | 123 | [tool.ruff.lint.per-file-ignores] 124 | # Place paths of files to be ignored by ruff here 125 | "tests/*" = ["S101"] 126 | "test_*.py" = ["S101"] 127 | 128 | 129 | [tool.doc8] 130 | ignore-path = ["docs/build", "doc/build", "docs/_build", "doc/_build"] 131 | max-line-length=100 132 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | aboutcode-toolkit==7.0.2 2 | black==22.3.0 3 | bleach==4.1.0 4 | boolean.py==4.0 5 | cffi==1.15.0 6 | cryptography==37.0.2 7 | dataclasses==0.8 8 | docutils==0.18.1 9 | et-xmlfile==1.1.0 10 | execnet==2.1.1 11 | importlib-resources==5.4.0 12 | iniconfig==1.1.1 13 | isort==5.10.1 14 | jeepney==0.7.1 15 | jinja2==3.0.3 16 | keyring==23.4.1 17 | license-expression==30.0.0 18 | markupsafe==2.0.1 19 | mypy-extensions==0.4.3 20 | openpyxl==3.0.10 21 | pathspec==0.9.0 22 | pkginfo==1.8.3 23 | platformdirs==2.4.0 24 | pluggy==1.6.0 25 | py==1.11.0 26 | pycodestyle==2.8.0 27 | pycparser==2.21 28 | pygments==2.12.0 29 | pytest==8.4.0 30 | pytest-xdist==3.7.0 31 | pytest-forked==1.6.0 32 | pytest-rerunfailures==15.1 33 | readme-renderer==34.0 34 | requests-toolbelt==0.9.1 35 | rfc3986==1.5.0 36 | secretstorage==3.3.2 37 | six==1.16.0 38 | tomli==1.2.3 39 | tqdm==4.64.0 40 | twine==3.8.0 41 | typed-ast==1.5.4 42 | webencodings==0.5.1 43 | pytest-asyncio==1.0.0 44 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | attrs==22.1.0 2 | beautifulsoup4==4.11.1 3 | certifi==2022.6.15 4 | charset-normalizer==2.1.0 5 | click==8.1.3 6 | colorama==0.4.5 7 | commoncode==30.2.0 8 | dparse2==0.7.0 9 | fasteners==0.17.3 10 | idna==3.3 11 | importlib-metadata==4.12.0 12 | intbitset==3.1.0 13 | packageurl-python==0.10.0 14 | packaging==24.2 15 | packvers==21.5 16 | pip-requirements-parser==32.0.1 17 | pkginfo2==30.0.0 18 | pydantic_settings == 2.8.1 19 | pydantic == 2.11.2 20 | pyparsing==3.0.9 21 | PyYAML==6.0 22 | requests==2.28.1 23 | resolvelib >= 1.0.0 24 | saneyaml==0.5.2 25 | soupsieve==2.3.2.post1 26 | text-unidecode==1.3 27 | toml==0.10.2 28 | urllib3==1.26.11 29 | zipp==3.8.1 30 | aiohttp==3.12.7 31 | aiofiles==24.1.0 32 | -------------------------------------------------------------------------------- /requirements_builder.ABOUT: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = python-inspector 3 | license = Apache-2.0 4 | 5 | # description must be on ONE line https://github.com/pypa/setuptools/issues/1390 6 | description = python-inspector is is a collection of utilities to collect PyPI package metadata and resolve packages dependencies. 7 | long_description = file:README.rst 8 | long_description_content_type = text/x-rst 9 | url = https://github.com/aboutcode-org/python-inspector 10 | 11 | author = nexB. Inc. and others 12 | author_email = info@aboutcode.org 13 | 14 | classifiers = 15 | Development Status :: 4 - Beta 16 | Intended Audience :: Developers 17 | Programming Language :: Python :: 3 18 | Programming Language :: Python :: 3 :: Only 19 | Topic :: Software Development 20 | Topic :: Utilities 21 | 22 | keywords = 23 | open source 24 | scan 25 | package 26 | dependency 27 | pypi 28 | python 29 | SBOM 30 | sca 31 | dependencies 32 | dependency resolution 33 | resolver 34 | resolvelib 35 | pip 36 | requirements 37 | 38 | license_files = 39 | apache-2.0.LICENSE 40 | NOTICE 41 | AUTHORS.rst 42 | CHANGELOG.rst 43 | CODE_OF_CONDUCT.rst 44 | 45 | [options] 46 | package_dir = 47 | =src 48 | packages = find: 49 | include_package_data = true 50 | zip_safe = false 51 | 52 | setup_requires = setuptools_scm[toml] >= 4 53 | 54 | python_requires = >=3.6.* 55 | 56 | install_requires = 57 | attrs >= 18.1, !=20.1.0 58 | click > 7.0 59 | colorama >= 0.3.9 60 | commoncode >= 30.0.0 61 | dparse2 >= 0.6.1 62 | importlib_metadata >= 4.12.0 63 | packageurl_python >= 0.9.0 64 | pkginfo2 >= 30.0.0 65 | pip-requirements-parser >= 31.2.0 66 | requests >= 2.18.0 67 | resolvelib >= 0.8.1 68 | saneyaml >= 0.5.2 69 | toml >= 0.10.0 70 | mock >= 3.0.5 71 | 72 | [options.packages.find] 73 | where = src 74 | 75 | [options.entry_points] 76 | console_scripts = 77 | python-inspector = python_inspector.resolve_cli:resolve_dependencies 78 | 79 | [options.extras_require] 80 | testing = 81 | pytest >= 6, != 7.0.0 82 | pytest-xdist >= 2 83 | aboutcode-toolkit >= 7.0.2 84 | twine 85 | black 86 | isort 87 | pycodestyle 88 | 89 | docs = 90 | Sphinx >= 3.3.1,<7.0.0 91 | sphinx-rtd-theme >= 0.5.0 92 | doc8 >= 0.8.1 93 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = python-inspector 3 | license = Apache-2.0 4 | 5 | # description must be on ONE line https://github.com/pypa/setuptools/issues/1390 6 | description = python-inspector is is a collection of utilities to collect PyPI package metadata and resolve packages dependencies. 7 | long_description = file:README.rst 8 | long_description_content_type = text/x-rst 9 | url = https://github.com/aboutcode-org/python-inspector 10 | 11 | author = nexB. Inc. and others 12 | author_email = info@aboutcode.org 13 | 14 | classifiers = 15 | Development Status :: 4 - Beta 16 | Intended Audience :: Developers 17 | Programming Language :: Python :: 3 18 | Programming Language :: Python :: 3 :: Only 19 | Topic :: Software Development 20 | Topic :: Utilities 21 | 22 | keywords = 23 | open source 24 | scan 25 | package 26 | dependency 27 | pypi 28 | python 29 | SBOM 30 | sca 31 | dependencies 32 | dependency resolution 33 | resolver 34 | resolvelib 35 | pip 36 | requirements 37 | 38 | license_files = 39 | apache-2.0.LICENSE 40 | NOTICE 41 | AUTHORS.rst 42 | CHANGELOG.rst 43 | CODE_OF_CONDUCT.rst 44 | README.rst 45 | 46 | [options] 47 | python_requires = >=3.9 48 | 49 | package_dir = 50 | =src 51 | packages = find: 52 | include_package_data = true 53 | zip_safe = false 54 | 55 | setup_requires = setuptools_scm[toml] >= 4 56 | 57 | 58 | install_requires = 59 | attrs >= 18.1, !=20.1.0 60 | click > 7.0 61 | colorama >= 0.3.9 62 | commoncode >= 30.0.0 63 | dparse2 >= 0.7.0 64 | fasteners >= 0.17.3 65 | importlib_metadata >= 4.12.0 66 | packageurl_python >= 0.9.0 67 | pkginfo2 >= 30.0.0 68 | pip-requirements-parser >= 32.0.1 69 | requests >= 2.18.0 70 | resolvelib >= 1.0.0 71 | saneyaml >= 0.5.2 72 | toml >= 0.10.0 73 | mock >= 3.0.5 74 | packvers >= 21.5 75 | aiohttp >= 3.8 76 | aiofiles >= 23.1 77 | pydantic >= 2.10.0 78 | pydantic_settings >= 2.8.0 79 | 80 | [options.packages.find] 81 | where = src 82 | 83 | [options.entry_points] 84 | console_scripts = 85 | python-inspector = python_inspector.resolve_cli:resolve_dependencies 86 | 87 | [options.extras_require] 88 | dev = 89 | pytest >= 7.0.1 90 | pytest-xdist >= 2 91 | aboutcode-toolkit >= 7.0.2 92 | twine 93 | ruff 94 | pytest-rerunfailures 95 | pytest-asyncio >= 0.21 96 | Sphinx>=5.0.2 97 | sphinx-rtd-theme>=1.0.0 98 | sphinx-reredirects >= 0.1.2 99 | doc8>=0.11.2 100 | sphinx-autobuild 101 | sphinx-rtd-dark-mode>=1.3.0 102 | sphinx-copybutton 103 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import setuptools 4 | 5 | if __name__ == "__main__": 6 | setuptools.setup() 7 | -------------------------------------------------------------------------------- /src/_packagedcode/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/aboutcode-org/scancode-toolkit for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | -------------------------------------------------------------------------------- /src/_packagedcode/pypi.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: pypi.py 2 | name: pyserial 3 | namespace: pyserial 4 | package_url: pkg:github/pyserial/pyserial@d867871e6aa33301#setup.py 5 | attribute: yes 6 | copyright: Copyright (c) 2001-2020 Chris Liechti 7 | download_url: https://github.com/pyserial/pyserial/blob/d867871e6aa333014a77498b4ac96fdd1d3bf1d8/setup.py#L34 8 | license_expression: bsd-new 9 | notice_file: pypi.py.NOTICE 10 | primary_language: Python 11 | notes: The functions find_pattern(), find_dunder_version(), 12 | find_setup_py_dunder_version() are inspired and heavily modified from Pyserial 13 | setup.py 14 | -------------------------------------------------------------------------------- /src/_packagedcode/pypi.py.NOTICE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2001-2020 Chris Liechti 2 | All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | --------------------------------------------------------------------------- 33 | Note: 34 | Individual files contain the following tag instead of the full license text. 35 | 36 | SPDX-License-Identifier: BSD-3-Clause 37 | 38 | This enables machine processing of license information based on the SPDX 39 | License Identifiers that are here available: http://spdx.org/licenses/ -------------------------------------------------------------------------------- /src/_packagedcode/pypi_setup_py.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: pypi_setup_py.py 2 | name: dephell_setuptools 3 | author: Gram (@orsinium) 4 | author_email: gram@orsinium.dev 5 | homepage_url: https://github.com/dephell/dephell_setuptools 6 | license_expression: mit 7 | package_url: pkg:github/dephell/dephell_setuptools@v.0.2.4 8 | notes: code heavily modified from original -------------------------------------------------------------------------------- /src/_packagedcode/pypi_setup_py.py.LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2019 Gram 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice (including the next 11 | paragraph) shall be included in all copies or substantial portions of the 12 | Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/python_inspector/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/aboutcode-org/scancode-toolkit for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | from python_inspector import settings 11 | 12 | # Initialize global settings 13 | pyinspector_settings = settings.Settings() 14 | 15 | settings.create_cache_directory(pyinspector_settings.CACHE_THIRDPARTY_DIR) 16 | -------------------------------------------------------------------------------- /src/python_inspector/cli_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/aboutcode-org/scancode-toolkit for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | import os 11 | from itertools import chain 12 | 13 | import click 14 | 15 | 16 | class FileOptionType(click.File): 17 | """ 18 | A click.File subclass that ensures that a file name is not set to an 19 | existing option parameter to avoid mistakes. 20 | """ 21 | 22 | def convert(self, value, param, ctx): 23 | known_opts = set( 24 | chain.from_iterable(p.opts for p in ctx.command.params if isinstance(p, click.Option)) 25 | ) 26 | if value in known_opts: 27 | self.fail( 28 | "Illegal file name conflicting with an option name: " 29 | f"{os.fsdecode(value)}. " 30 | 'Use the special "-" file name to print results on screen/stdout.', 31 | param, 32 | ctx, 33 | ) 34 | return click.File.convert(self, value, param, ctx) 35 | -------------------------------------------------------------------------------- /src/python_inspector/dependencies.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/nexB/skeleton for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | from typing import Iterable 12 | from typing import Mapping 13 | 14 | from packageurl import PackageURL 15 | from packvers.requirements import Requirement 16 | 17 | from _packagedcode import models 18 | from _packagedcode.models import DependentPackage 19 | from _packagedcode.pypi import PipRequirementsFileHandler 20 | from _packagedcode.pypi import get_requirements_txt_dependencies 21 | 22 | """ 23 | Utilities to resolve dependencies. 24 | """ 25 | 26 | TRACE = False 27 | 28 | 29 | def get_dependencies_from_requirements( 30 | requirements_file="requirements.txt", 31 | ) -> Iterable[DependentPackage]: 32 | """ 33 | Yield DependentPackage for each requirement in a `requirement` file. 34 | """ 35 | dependent_packages, _ = get_requirements_txt_dependencies( 36 | location=requirements_file, include_nested=True 37 | ) 38 | for dependent_package in dependent_packages: 39 | if TRACE: 40 | print( 41 | "dependent_package.extracted_requirement:", 42 | dependent_package.extracted_requirement, 43 | ) 44 | yield dependent_package 45 | 46 | 47 | def get_extra_data_from_requirements(requirements_file="requirements.txt") -> Iterable[Mapping]: 48 | """ 49 | Yield extra_data for each requirement in a `requirement` file. 50 | """ 51 | for package_data in PipRequirementsFileHandler.parse(location=requirements_file): 52 | yield package_data.extra_data 53 | 54 | 55 | def is_requirement_pinned(requirement: Requirement) -> bool: 56 | specifiers = requirement.specifier 57 | return specifiers and len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="} 58 | 59 | 60 | def get_dependency(specifier) -> DependentPackage: 61 | """ 62 | Return a DependentPackage given a requirement ``specifier`` string. 63 | 64 | For example: 65 | >>> dep = get_dependency("foo==1.2.3") 66 | >>> assert dep.purl == "pkg:pypi/foo@1.2.3" 67 | """ 68 | specifier = specifier and "".join(specifier.lower().split()) 69 | assert specifier, f"specifier is required but empty:{specifier!r}" 70 | 71 | requirement = Requirement(requirement_string=specifier) 72 | 73 | scope = "install" 74 | is_runtime = True 75 | is_optional = False 76 | 77 | if requirement.name: 78 | # will be None if not pinned 79 | version = None 80 | if is_requirement_pinned(requirement): 81 | version = str(list(requirement.specifier)[0].version) 82 | purl = PackageURL(type="pypi", name=requirement.name, version=version).to_string() 83 | 84 | return models.DependentPackage( 85 | purl=purl, 86 | scope=scope, 87 | is_runtime=is_runtime, 88 | is_optional=is_optional, 89 | is_resolved=False or is_requirement_pinned(requirement), 90 | extracted_requirement=specifier, 91 | ) 92 | -------------------------------------------------------------------------------- /src/python_inspector/error.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/aboutcode-org/python-inspector for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | 12 | 13 | class NoVersionsFound(Exception): 14 | pass 15 | -------------------------------------------------------------------------------- /src/python_inspector/lockfile.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/nexB/scancode-toolkit for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | from contextlib import contextmanager 11 | 12 | import fasteners 13 | 14 | """ 15 | An interprocess lockfile with a timeout. 16 | """ 17 | 18 | 19 | class LockTimeout(Exception): 20 | pass 21 | 22 | 23 | class FileLock(fasteners.InterProcessLock): 24 | @contextmanager 25 | def locked(self, timeout): 26 | acquired = self.acquire(timeout=timeout) 27 | if not acquired: 28 | raise LockTimeout(timeout) 29 | try: 30 | yield 31 | finally: 32 | self.release() 33 | -------------------------------------------------------------------------------- /src/python_inspector/resolution.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: resolution.py 2 | package_url: pkg:github.com/sarugaku/resolvelib/@a5ae68140afac49dd1a1a8e87eff9550db4a586b#tests/functional/python/test_resolvers_python.py 3 | type: github 4 | namespace: sarugaku 5 | name: resolvelib 6 | version: a5ae68140afac49dd1a1a8e87eff9550db4a586b 7 | subpath: tests/functional/python/test_resolvers_python.py 8 | 9 | download_url: https://github.com/sarugaku/resolvelib/blob/a5ae68140afac49dd1a1a8e87eff9550db4a586b/tests/functional/python/test_resolvers_python.py 10 | copyright: Copyright (c) 2018, Tzu-ping Chung 11 | license_expression: isc 12 | notes: The PythonInputProvider is copied in part and heavily modified from 13 | resolvelib tests/functional/python/test_resolvers_python.py 14 | -------------------------------------------------------------------------------- /src/python_inspector/resolution.py.LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Tzu-ping Chung 2 | 3 | Permission to use, copy, modify, and distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /src/python_inspector/settings.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/aboutcode-org/python-inspector for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | from pathlib import Path 11 | 12 | from pydantic import field_validator 13 | from pydantic_settings import BaseSettings 14 | from pydantic_settings import SettingsConfigDict 15 | 16 | DEFAULT_PYTHON_VERSION = "39" 17 | PYPI_SIMPLE_URL = "https://pypi.org/simple" 18 | 19 | 20 | class Settings(BaseSettings): 21 | """ 22 | Reference: https://docs.pydantic.dev/latest/concepts/pydantic_settings/ 23 | A settings object: use it with an .env file and/or environment variables all prefixed with 24 | PYINSP_ 25 | """ 26 | 27 | model_config = SettingsConfigDict( 28 | env_file=".env", 29 | env_file_encoding="utf-8", 30 | env_prefix="PYINSP_", 31 | case_sensitive=True, 32 | extra="allow", 33 | # never treat data as JSON 34 | enable_decoding=False, 35 | ) 36 | 37 | # the default Python version to use if none is provided 38 | DEFAULT_PYTHON_VERSION: str = DEFAULT_PYTHON_VERSION 39 | 40 | # the default OS to use if none is provided 41 | DEFAULT_OS: str = "linux" 42 | 43 | # a string with a tuple of PyPI simple index URLs, each separated by a space 44 | INDEX_URL: tuple[str, ...] = (PYPI_SIMPLE_URL,) 45 | 46 | # If True, only uses configured INDEX_URLs listed above and ignore other URLs found in requirements 47 | USE_ONLY_CONFIGURED_INDEX_URLS: bool = False 48 | 49 | # a path string where to store the cached downloads. Will be created if it does not exists. 50 | CACHE_THIRDPARTY_DIR: str = str(Path(Path.home() / ".cache/python_inspector")) 51 | 52 | @field_validator("INDEX_URL", mode="before") 53 | @classmethod 54 | def validate_index_url(cls, value): 55 | if isinstance(value, str): 56 | return tuple(value.split()) 57 | elif isinstance(value, (tuple, list)): 58 | return tuple(value) 59 | else: 60 | raise ValueError(f"INDEX_URL must be either a URL or list of URLs: {value!r}") 61 | 62 | 63 | def create_cache_directory(cache_dir): 64 | cache_dir = Path(cache_dir).expanduser().resolve().absolute() 65 | if not cache_dir.exists(): 66 | cache_dir.mkdir(parents=True, exist_ok=True) 67 | -------------------------------------------------------------------------------- /src/python_inspector/setup_py_live_eval.py.ABOUT: -------------------------------------------------------------------------------- 1 | name: requirements-builder 2 | version: 597340d1e84138af64786d45e74fc9f03315bf2d 3 | copyright: Copyright (C) CERN. 4 | homepage_url: https://github.com/inveniosoftware/requirements-builder/ 5 | description: Build requirements files from setup.py requirements. 6 | license_expression: bsd-new 7 | license_file: requirements_builder.LICENSE 8 | notes: this is a subset of requirements-builder that has been heavily modified. 9 | -------------------------------------------------------------------------------- /src/python_inspector/setup_py_live_eval.py.LICENSE: -------------------------------------------------------------------------------- 1 | Requirements-Builder is free software; you can redistribute it and/or 2 | modify it under the terms of the Revised BSD License; see LICENSE 3 | file for more details. 4 | 5 | Copyright (C) 2015, CERN 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from 21 | this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 32 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 33 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 34 | DAMAGE. 35 | -------------------------------------------------------------------------------- /src/python_inspector/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/aboutcode-org/python-inspector for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | 12 | import json 13 | import os 14 | from typing import Dict 15 | from typing import List 16 | from typing import NamedTuple 17 | from typing import Optional 18 | 19 | from urllib.parse import urlparse 20 | 21 | import aiohttp 22 | import requests 23 | 24 | 25 | def get_netrc_auth(url, netrc): 26 | """ 27 | Return login and password if either the hostname is in netrc or a default is set in netrc 28 | else return login and password as None 29 | """ 30 | hostname = urlparse(url).hostname 31 | hosts = netrc.hosts 32 | if hostname in hosts: 33 | url_auth = hosts.get(hostname) 34 | # netrc returns a tuple of (login, account, password) 35 | return (url_auth[0], url_auth[2]) 36 | 37 | if "default" in hosts: 38 | default_auth = hosts.get("default") 39 | return (default_auth[0], default_auth[2]) 40 | 41 | return (None, None) 42 | 43 | 44 | def contain_string(string: str, files: List) -> bool: 45 | """ 46 | Return True if the ``string`` is contained in any of the ``files`` list of file paths. 47 | """ 48 | for file in files: 49 | if not os.path.exists(file): 50 | continue 51 | with open(file, encoding="utf-8") as f: 52 | # TODO also consider other file names 53 | if string in f.read(): 54 | return True 55 | return False 56 | 57 | 58 | def write_output_in_file(output, location): 59 | """ 60 | Write headers, requirements and resolved_dependencies as JSON to ``json_output``. 61 | Return the output data. 62 | """ 63 | json.dump(output, location, indent=2) 64 | return output 65 | 66 | 67 | class Candidate(NamedTuple): 68 | """ 69 | A candidate is a package that can be installed. 70 | """ 71 | 72 | name: str 73 | version: str 74 | extras: str 75 | 76 | 77 | def get_response(url: str) -> Dict: 78 | """ 79 | Return a mapping of the JSON response from fetching ``url`` 80 | or None if the ``url`` cannot be fetched. 81 | """ 82 | resp = requests.get(url) 83 | if resp.status_code == 200: 84 | return resp.json() 85 | 86 | 87 | async def get_response_async(url: str) -> Optional[Dict]: 88 | """ 89 | Return a mapping of the JSON response from fetching ``url`` 90 | or None if the ``url`` cannot be fetched. 91 | """ 92 | async with aiohttp.ClientSession() as session: 93 | async with session.get(url) as response: 94 | if response.status == 200: 95 | return await response.json() 96 | else: 97 | return None 98 | 99 | 100 | def remove_test_data_dir_variable_prefix(path, placeholder=""): 101 | """ 102 | Return a clean path, removing variable test path prefix or using a ``placeholder``. 103 | Used for testing to ensure that results are stable across runs. 104 | """ 105 | path = path.replace("\\", "/") 106 | if "tests/data/" in path: 107 | _junk, test_dir, cleaned = path.partition("tests/data/") 108 | cleaned = f"{test_dir}{cleaned}" 109 | return cleaned.replace("\\", "/") 110 | else: 111 | return placeholder 112 | 113 | 114 | def unique(sequence): 115 | """ 116 | Return a list of unique items found in sequence. Preserve the original sequence order. 117 | Items must be hashable. 118 | For example: 119 | >>> unique([1, 5, 3, 5]) 120 | [1, 5, 3] 121 | """ 122 | seen = set() 123 | deduped = [] 124 | for item in sequence: 125 | if item not in seen: 126 | deduped.append(item) 127 | seen.add(item) 128 | return deduped 129 | -------------------------------------------------------------------------------- /src/python_inspector/utils_pip_compatibility_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_pip_compatibility_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: src/pip/_internal/utils/compatibility_tags.py 8 | 9 | package_url: pkg:github/pypa/pip@20.3.1#src/pip/_internal/utils/compatibility_tags.py 10 | 11 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/utils/compatibility_tags.py 12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 13 | license_expression: mit 14 | notes: subset copied from pip for tag handling. Modified copy of pip compatibility_tags.py. 15 | -------------------------------------------------------------------------------- /src/python_inspector/utils_pypi.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_pypi.py 2 | package_url: pkg:github.com/pypa/pip/@20.3.1#src/pip/_internal/models/wheel.py 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: src/pip/_internal/models/wheel.py 8 | 9 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/models/wheel.py 10 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 11 | license_expression: mit 12 | notes: The Wheel class is copied and heavily modified from 13 | pip-20.3.1 pip/_internal/models/wheel.py 14 | The models code is alos inspired from the ISC-licensed packaging-dists 15 | https://github.com/uranusjr/packaging-dists by Tzu-ping Chung 16 | -------------------------------------------------------------------------------- /src/python_inspector/utils_pypi_supported_tags.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import re 14 | 15 | """ 16 | Wheel platform checking 17 | 18 | Copied and modified on 2020-12-24 from 19 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py 20 | 21 | This contains the basic functions to check if a wheel file name is would be 22 | supported for uploading to PyPI. 23 | """ 24 | 25 | # These platforms can be handled by a simple static list: 26 | _allowed_platforms = { 27 | "any", 28 | "win32", 29 | "win_amd64", 30 | "win_ia64", 31 | "manylinux1_x86_64", 32 | "manylinux1_i686", 33 | "manylinux2010_x86_64", 34 | "manylinux2010_i686", 35 | "manylinux2014_x86_64", 36 | "manylinux2014_i686", 37 | "manylinux2014_aarch64", 38 | "manylinux2014_armv7l", 39 | "manylinux2014_ppc64", 40 | "manylinux2014_ppc64le", 41 | "manylinux2014_s390x", 42 | "linux_armv6l", 43 | "linux_armv7l", 44 | } 45 | # macosx is a little more complicated: 46 | _macosx_platform_re = re.compile(r"macosx_(?P\d+)_(\d+)_(?P.*)") 47 | _macosx_arches = { 48 | "ppc", 49 | "ppc64", 50 | "i386", 51 | "x86_64", 52 | "arm64", 53 | "intel", 54 | "fat", 55 | "fat32", 56 | "fat64", 57 | "universal", 58 | "universal2", 59 | } 60 | _macosx_major_versions = { 61 | "10", 62 | "11", 63 | } 64 | 65 | # manylinux pep600 is a little more complicated: 66 | _manylinux_platform_re = re.compile(r"manylinux_(\d+)_(\d+)_(?P.*)") 67 | _manylinux_arches = { 68 | "x86_64", 69 | "i686", 70 | "aarch64", 71 | "armv7l", 72 | "ppc64", 73 | "ppc64le", 74 | "s390x", 75 | } 76 | 77 | 78 | def is_supported_platform_tag(platform_tag): 79 | """ 80 | Return True if the ``platform_tag`` is supported on PyPI. 81 | """ 82 | if platform_tag in _allowed_platforms: 83 | return True 84 | m = _macosx_platform_re.match(platform_tag) 85 | if m and m.group("major") in _macosx_major_versions and m.group("arch") in _macosx_arches: 86 | return True 87 | m = _manylinux_platform_re.match(platform_tag) 88 | if m and m.group("arch") in _manylinux_arches: 89 | return True 90 | return False 91 | 92 | 93 | def validate_platforms_for_pypi(platforms): 94 | """ 95 | Validate if the wheel platforms are supported platform tags on Pypi. Return 96 | a list of unsupported platform tags or an empty list if all tags are 97 | supported. 98 | """ 99 | 100 | # Check that if it's a binary wheel, it's on a supported platform 101 | invalid_tags = [] 102 | for plat in platforms: 103 | if not is_supported_platform_tag(plat): 104 | invalid_tags.append(plat) 105 | return invalid_tags 106 | -------------------------------------------------------------------------------- /src/python_inspector/utils_pypi_supported_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: utils_pypi_supported_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: warehouse 6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d 7 | subpath: warehouse/forklift/legacy.py 8 | 9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#warehouse/forklift/legacy.py 10 | 11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py 12 | copyright: Copyright (c) The warehouse developers 13 | homepage_url: https://warehouse.readthedocs.io 14 | license_expression: apache-2.0 15 | notes: Wheel platform checking copied and heavily modified on 2020-12-24 from 16 | warehouse. This contains the basic functions to check if a wheel file name is 17 | would be supported for uploading to PyPI. 18 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/nexB/python-inspector for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | 12 | 13 | def pytest_configure(config): 14 | config.addinivalue_line("markers", "online: mark test as requiring network connectivity") 15 | -------------------------------------------------------------------------------- /tests/data/azure-devops.req.txt: -------------------------------------------------------------------------------- 1 | azure-devops 2 | azure-storage-blob 3 | click -------------------------------------------------------------------------------- /tests/data/default-url-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "tool_version": "0.13.0", 6 | "options": [ 7 | "--index-url https://pypi.org/simple", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp==3.8.0", 12 | "--use-pypi-json-api" 13 | ], 14 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 15 | "warnings": [], 16 | "errors": [] 17 | }, 18 | "files": [], 19 | "packages": [], 20 | "resolved_dependencies_graph": [ 21 | { 22 | "package": "pkg:pypi/zipp@3.8.0", 23 | "dependencies": [] 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /tests/data/environment-marker-test-requirements.txt: -------------------------------------------------------------------------------- 1 | click>6,<6.8 2 | Flask==1.0 3 | itsdangerous<0.25 4 | license-expression ; platform_system == "Windows" 5 | Jinja2==2.11.3 6 | MarkupSafe==1.0 7 | Werkzeug==0.15.3 -------------------------------------------------------------------------------- /tests/data/error-requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | noexistingpacjagee -------------------------------------------------------------------------------- /tests/data/fetch_links_test.html: -------------------------------------------------------------------------------- 1 | 2 | Simple Index 3 | sources.whl
4 | -------------------------------------------------------------------------------- /tests/data/frozen-requirements.txt: -------------------------------------------------------------------------------- 1 | aboutcode-toolkit==7.0.2 2 | attrs==21.4.0 3 | beautifulsoup4==4.11.1 4 | black==22.3.0 5 | bleach==4.1.0 6 | boolean.py==4.0 7 | certifi==2022.5.18.1 8 | cffi==1.15.0 9 | charset-normalizer==2.0.12 10 | click==8.0.4 11 | colorama==0.4.4 12 | commoncode==30.2.0 13 | cryptography==37.0.2 14 | docutils==0.18.1 15 | dparse2==0.6.1 16 | et-xmlfile==1.1.0 17 | execnet==1.9.0 18 | Flask==2.1.2 19 | idna==3.3 20 | importlib-metadata==4.8.3 21 | iniconfig==1.1.1 22 | intbitset==3.0.1 23 | isort==5.10.1 24 | itsdangerous==2.1.2 25 | jeepney==0.7.1 26 | Jinja2==3.0.3 27 | keyring==23.4.1 28 | license-expression==30.0.0 29 | MarkupSafe==2.0.1 30 | mypy-extensions==0.4.3 31 | openpyxl==3.0.10 32 | packageurl-python==0.9.9 33 | packaging==21.3 34 | pathspec==0.9.0 35 | pip-requirements-parser==31.2.0 36 | pipdeptree==2.2.1 37 | pkginfo==1.8.3 38 | pkginfo2==30.0.0 39 | platformdirs==2.4.0 40 | pluggy==1.0.0 41 | py==1.11.0 42 | pycodestyle==2.8.0 43 | pycparser==2.21 44 | Pygments==2.12.0 45 | pyparsing==3.0.9 46 | pytest==7.0.1 47 | pytest-forked==1.4.0 48 | pytest-xdist==2.5.0 49 | PyYAML==6.0 50 | readme-renderer==34.0 51 | requests==2.27.1 52 | requests-toolbelt==0.9.1 53 | resolvelib==0.8.1 54 | rfc3986==1.5.0 55 | saneyaml==0.5.2 56 | SecretStorage==3.3.2 57 | six==1.16.0 58 | soupsieve==2.3.2.post1 59 | text-unidecode==1.3 60 | toml==0.10.2 61 | tomli==1.2.3 62 | tqdm==4.64.0 63 | twine==3.8.0 64 | typing_extensions==4.1.1 65 | urllib3==1.26.9 66 | webencodings==0.5.1 67 | Werkzeug==2.1.2 68 | zipp==3.6.0 69 | -------------------------------------------------------------------------------- /tests/data/insecure-setup-2/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is part of Requirements-Builder 4 | # Copyright (C) 2015, 2016, 2017, 2018 CERN. 5 | # 6 | # Requirements-Builder is free software; you can redistribute it and/or 7 | # modify it under the terms of the Revised BSD License; see LICENSE 8 | # file for more details. 9 | # 10 | """Build requirements files from setup.py requirements.""" 11 | 12 | import os 13 | 14 | import testpkh 15 | from setuptools import setup 16 | 17 | dirname = os.path.dirname(__file__) 18 | 19 | requirements = [ 20 | "click>=5.0.0", 21 | "mock>=1.3.0", 22 | "CairoSVG<2.0.0,>=1.0.20", 23 | "invenio-records~=1.0.0", 24 | "invenio[base,auth,metadata]>=3.0.0", 25 | ] 26 | 27 | extras_require = { 28 | "docs": ["Sphinx>=1.4.2"], 29 | "tests": ["pytest>=2.7"], 30 | "flask": ["Flask>=0.11"], 31 | ':python_version=="2.7"': ["ipaddr>=2.1.11"], 32 | } 33 | 34 | setup( 35 | name="testpkh", 36 | version=testpkh.__version__, 37 | install_requires=requirements, 38 | extras_require=extras_require, 39 | ) 40 | -------------------------------------------------------------------------------- /tests/data/insecure-setup-2/testpkh/__init__.py: -------------------------------------------------------------------------------- 1 | """Version.""" 2 | __version__ = "0.0.1" 3 | -------------------------------------------------------------------------------- /tests/data/insecure-setup/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import re 5 | 6 | import setuptools 7 | 8 | kwargs = {} 9 | kwargs["install_requires"] = ["six", "isodate", "pyparsing"] 10 | kwargs["tests_require"] = ["html5lib", "networkx", "nose", "doctest-ignore-unicode"] 11 | kwargs["test_suite"] = "nose.collector" 12 | kwargs["extras_require"] = { 13 | "html": ["html5lib"], 14 | "sparql": ["requests"], 15 | "tests": kwargs["tests_require"], 16 | "docs": ["sphinx < 3", "sphinxcontrib-apidoc"], 17 | } 18 | 19 | 20 | def find_version(filename): 21 | _version_re = re.compile(r'__version__ = "(.*)"') 22 | for line in open(filename): 23 | version_match = _version_re.match(line) 24 | if version_match: 25 | return version_match.group(1) 26 | 27 | 28 | version = find_version("rdflib/__init__.py") 29 | 30 | packages = setuptools.find_packages(exclude=("examples*", "test*")) 31 | 32 | if os.environ.get("READTHEDOCS", None): 33 | # if building docs for RTD 34 | # install examples, to get docstrings 35 | packages.append("examples") 36 | 37 | setuptools.setup( 38 | name="rdflib", 39 | version=version, 40 | description="RDFLib is a Python library for working with RDF, a " 41 | "simple yet powerful language for representing information.", 42 | author="Daniel 'eikeon' Krech", 43 | author_email="eikeon@eikeon.com", 44 | maintainer="RDFLib Team", 45 | maintainer_email="rdflib-dev@google.com", 46 | url="https://github.com/RDFLib/rdflib", 47 | license="BSD-3-Clause", 48 | platforms=["any"], 49 | classifiers=[ 50 | "Programming Language :: Python", 51 | "Programming Language :: Python :: 2", 52 | "Programming Language :: Python :: 3", 53 | "Programming Language :: Python :: 2.7", 54 | "Programming Language :: Python :: 3.4", 55 | "Programming Language :: Python :: 3.5", 56 | "Programming Language :: Python :: 3.6", 57 | "Programming Language :: Python :: 3.7", 58 | "License :: OSI Approved :: BSD License", 59 | "Topic :: Software Development :: Libraries :: Python Modules", 60 | "Operating System :: OS Independent", 61 | "Natural Language :: English", 62 | ], 63 | long_description="""\ 64 | RDFLib is a Python library for working with 65 | RDF, a simple yet powerful language for representing information. 66 | 67 | The library contains parsers and serializers for RDF/XML, N3, 68 | NTriples, Turtle, TriX, RDFa and Microdata . The library presents 69 | a Graph interface which can be backed by any one of a number of 70 | Store implementations. The core rdflib includes store 71 | implementations for in memory storage, persistent storage on top 72 | of the Berkeley DB, and a wrapper for remote SPARQL endpoints. 73 | 74 | A SPARQL 1.1 engine is also included. 75 | 76 | If you have recently reported a bug marked as fixed, or have a craving for 77 | the very latest, you may want the development version instead: 78 | 79 | pip install git+https://github.com/rdflib/rdflib 80 | 81 | 82 | Read the docs at: 83 | 84 | http://rdflib.readthedocs.io 85 | 86 | """, 87 | packages=packages, 88 | entry_points={ 89 | "console_scripts": [ 90 | "rdfpipe = rdflib.tools.rdfpipe:main", 91 | "csv2rdf = rdflib.tools.csv2rdf:main", 92 | "rdf2dot = rdflib.tools.rdf2dot:main", 93 | "rdfs2dot = rdflib.tools.rdfs2dot:main", 94 | "rdfgraphisomorphism = rdflib.tools.graphisomorphism:main", 95 | ], 96 | }, 97 | **kwargs 98 | ) 99 | -------------------------------------------------------------------------------- /tests/data/other_req.txt: -------------------------------------------------------------------------------- 1 | # This file is part of Requirements-Builder 2 | # Copyright (C) 2017 CERN. 3 | # 4 | # Requirements-Builder is free software; you can redistribute it and/or 5 | # modify it under the terms of the Revised BSD License; see LICENSE 6 | # file for more details. 7 | 8 | -e git+https://github.com/mitsuhiko/click.git#egg=click 9 | -------------------------------------------------------------------------------- /tests/data/parse-reqs-with-setup_requires-and-python-requires.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "pypi", 4 | "namespace": null, 5 | "name": null, 6 | "version": null, 7 | "qualifiers": {}, 8 | "subpath": null, 9 | "primary_language": "Python", 10 | "description": null, 11 | "release_date": null, 12 | "parties": [], 13 | "keywords": [], 14 | "homepage_url": null, 15 | "download_url": null, 16 | "size": null, 17 | "sha1": null, 18 | "md5": null, 19 | "sha256": null, 20 | "sha512": null, 21 | "bug_tracking_url": null, 22 | "code_view_url": null, 23 | "vcs_url": null, 24 | "copyright": null, 25 | "license_expression": null, 26 | "declared_license": null, 27 | "notice_text": null, 28 | "source_packages": [], 29 | "file_references": [], 30 | "extra_data": {}, 31 | "dependencies": [ 32 | { 33 | "purl": "pkg:pypi/setuptools", 34 | "extracted_requirement": "setuptools>=42.0.2", 35 | "scope": "install", 36 | "is_runtime": true, 37 | "is_optional": false, 38 | "is_resolved": false, 39 | "resolved_package": {}, 40 | "extra_data": {} 41 | }, 42 | { 43 | "purl": "pkg:pypi/qtpy", 44 | "extracted_requirement": "QtPy~=1.9.0", 45 | "scope": "install", 46 | "is_runtime": true, 47 | "is_optional": false, 48 | "is_resolved": false, 49 | "resolved_package": {}, 50 | "extra_data": {} 51 | }, 52 | { 53 | "purl": "pkg:pypi/setuptools", 54 | "extracted_requirement": "setuptools>=42.0.2", 55 | "scope": "setup", 56 | "is_runtime": true, 57 | "is_optional": false, 58 | "is_resolved": false, 59 | "resolved_package": {}, 60 | "extra_data": {} 61 | }, 62 | { 63 | "purl": "pkg:generic/python", 64 | "extracted_requirement": "python_requires>=3.6.0,<3.8.0", 65 | "scope": "python", 66 | "is_runtime": true, 67 | "is_optional": false, 68 | "is_resolved": false, 69 | "resolved_package": {}, 70 | "extra_data": {} 71 | }, 72 | { 73 | "purl": "pkg:pypi/pyside2", 74 | "extracted_requirement": "PySide2~=5.13.2", 75 | "scope": "pyside", 76 | "is_runtime": true, 77 | "is_optional": false, 78 | "is_resolved": false, 79 | "resolved_package": {}, 80 | "extra_data": {} 81 | }, 82 | { 83 | "purl": "pkg:pypi/pyqt5", 84 | "extracted_requirement": "PyQt5~=5.13.2", 85 | "scope": "pyqt", 86 | "is_runtime": true, 87 | "is_optional": false, 88 | "is_resolved": false, 89 | "resolved_package": {}, 90 | "extra_data": {} 91 | }, 92 | { 93 | "purl": "pkg:pypi/sphinx", 94 | "extracted_requirement": "Sphinx>=3.2.1", 95 | "scope": "doc", 96 | "is_runtime": true, 97 | "is_optional": false, 98 | "is_resolved": false, 99 | "resolved_package": {}, 100 | "extra_data": {} 101 | }, 102 | { 103 | "purl": "pkg:pypi/restructuredtext-lint", 104 | "extracted_requirement": "restructuredtext-lint>=1.3.1", 105 | "scope": "doc", 106 | "is_runtime": true, 107 | "is_optional": false, 108 | "is_resolved": false, 109 | "resolved_package": {}, 110 | "extra_data": {} 111 | }, 112 | { 113 | "purl": "pkg:pypi/pyside2", 114 | "extracted_requirement": "PySide2~=5.13.2", 115 | "scope": "test", 116 | "is_runtime": true, 117 | "is_optional": false, 118 | "is_resolved": false, 119 | "resolved_package": {}, 120 | "extra_data": {} 121 | } 122 | ], 123 | "repository_homepage_url": null, 124 | "repository_download_url": null, 125 | "api_data_url": null, 126 | "datasource_id": "pypi_setup_cfg", 127 | "purl": null 128 | } 129 | ] -------------------------------------------------------------------------------- /tests/data/partial-setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | semver_version = "2.13.0" 4 | 5 | setup( 6 | name="example", 7 | version="0.0.1", 8 | install_requires=[ 9 | f"semver @ git+https://github.com/python-semver/python-semver.git@{semver_version}", 10 | ], 11 | extras_require={"test": ["botocore==1.27.76"]}, 12 | ) 13 | -------------------------------------------------------------------------------- /tests/data/pdt-requirements.txt: -------------------------------------------------------------------------------- 1 | click==6.7 2 | Flask==1.0 3 | itsdangerous==0.24 4 | Jinja2==2.11.3 5 | MarkupSafe==1.0 6 | Werkzeug==0.15.3 -------------------------------------------------------------------------------- /tests/data/pinned-pdt-requirements.txt: -------------------------------------------------------------------------------- 1 | aboutcode-toolkit==7.0.2 2 | attrs==21.4.0 3 | beautifulsoup4==4.11.1 4 | certifi==2022.5.18.1 5 | charset-normalizer==2.0.12 6 | click==8.0.4 7 | colorama==0.4.4 8 | commoncode==30.2.0 9 | dparse2==0.6.1 10 | idna==3.3 11 | importlib-metadata==4.8.3 12 | intbitset==3.0.1 13 | packageurl-python==0.9.9 14 | packaging==21.3 15 | -e git+https://github.com/nexB/python-inspector@18baae17824d6bacb4b1d519b10a0d0e50775884#egg=python_inspector 16 | pip-requirements-parser==31.2.0 17 | pkginfo2==30.0.0 18 | pyparsing==3.0.9 19 | PyYAML==6.0 20 | requests==2.27.1 21 | resolvelib==0.8.1 22 | saneyaml==0.5.2 23 | soupsieve==2.3.2.post1 24 | text-unidecode==1.3 25 | toml==0.10.2 26 | typing==3.6.6 27 | typing_extensions==4.1.1 28 | urllib3==1.26.9 29 | zipp==3.6.0 30 | boolean.py==4.0.0 31 | -------------------------------------------------------------------------------- /tests/data/pinned-requirements.txt: -------------------------------------------------------------------------------- 1 | aboutcode-toolkit==7.0.2 2 | attrs==21.4.0 3 | beautifulsoup4==4.11.1 4 | certifi==2022.5.18.1 5 | charset-normalizer==2.0.12 6 | click==8.0.4 7 | colorama==0.4.4 8 | commoncode==30.2.0 9 | dparse2==0.6.1 10 | idna==3.3 11 | importlib-metadata==4.8.3 12 | intbitset==3.0.1 13 | packageurl-python==0.9.9 14 | packaging==21.3 15 | -e git+https://github.com/nexB/python-inspector@18baae17824d6bacb4b1d519b10a0d0e50775884#egg=python_inspector 16 | pip-requirements-parser==31.2.0 17 | pkginfo2==30.0.0 18 | pyparsing==3.0.9 19 | PyYAML==6.0 20 | requests==2.27.1 21 | resolvelib==0.8.1 22 | saneyaml==0.5.2 23 | soupsieve==2.3.2.post1 24 | text-unidecode==1.3 25 | toml==0.10.2 26 | typing==3.6.6 27 | typing_extensions==4.1.1 28 | urllib3==1.26.9 29 | zipp==3.6.0 30 | boolean.py==4.0.0 31 | -------------------------------------------------------------------------------- /tests/data/prefer-source-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "tool_version": "0.13.0", 6 | "options": [ 7 | "--index-url https://pypi.org/simple", 8 | "--json ", 9 | "--operating-system linux", 10 | "--prefer-source", 11 | "--python-version 38", 12 | "--specifier zipp==3.8.0" 13 | ], 14 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 15 | "warnings": [], 16 | "errors": [] 17 | }, 18 | "files": [], 19 | "packages": [ 20 | { 21 | "type": "pypi", 22 | "namespace": null, 23 | "name": "zipp", 24 | "version": "3.8.0", 25 | "qualifiers": {}, 26 | "subpath": null, 27 | "primary_language": "Python", 28 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.", 29 | "release_date": "2022-04-03T15:07:28", 30 | "parties": [ 31 | { 32 | "type": "person", 33 | "role": "author", 34 | "name": "Jason R. Coombs", 35 | "email": "jaraco@jaraco.com", 36 | "url": null 37 | } 38 | ], 39 | "keywords": [ 40 | "Development Status :: 5 - Production/Stable", 41 | "Intended Audience :: Developers", 42 | "Programming Language :: Python :: 3", 43 | "Programming Language :: Python :: 3 :: Only" 44 | ], 45 | "homepage_url": "https://github.com/jaraco/zipp", 46 | "download_url": "https://files.pythonhosted.org/packages/cc/3c/3e8c69cd493297003da83f26ccf1faea5dd7da7892a0a7c965ac3bcba7bf/zipp-3.8.0.tar.gz", 47 | "size": 13344, 48 | "sha1": null, 49 | "md5": "8864ff5ed01cd28755cc87f1443dbc67", 50 | "sha256": "56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad", 51 | "sha512": null, 52 | "bug_tracking_url": null, 53 | "code_view_url": null, 54 | "vcs_url": null, 55 | "copyright": null, 56 | "license_expression": null, 57 | "declared_license": { 58 | "classifiers": [ 59 | "License :: OSI Approved :: MIT License" 60 | ] 61 | }, 62 | "notice_text": null, 63 | "source_packages": [], 64 | "file_references": [], 65 | "extra_data": {}, 66 | "dependencies": [], 67 | "repository_homepage_url": null, 68 | "repository_download_url": null, 69 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.0/json", 70 | "datasource_id": null, 71 | "purl": "pkg:pypi/zipp@3.8.0" 72 | } 73 | ], 74 | "resolved_dependencies_graph": [ 75 | { 76 | "package": "pkg:pypi/zipp@3.8.0", 77 | "dependencies": [] 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /tests/data/recursive_requirements/com.txt: -------------------------------------------------------------------------------- 1 | simplekml==1.3.5 -------------------------------------------------------------------------------- /tests/data/recursive_requirements/r.txt: -------------------------------------------------------------------------------- 1 | # Only installs requirements for deployments 2 | PyYAML==6.0 3 | retrying==1.3.3 4 | shapely==1.7.1 5 | -r com.txt -------------------------------------------------------------------------------- /tests/data/relative-links-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | "https://pypi.org/simple/sources.whl", 4 | null 5 | ] 6 | ] -------------------------------------------------------------------------------- /tests/data/req.txt: -------------------------------------------------------------------------------- 1 | # This file is part of Requirements-Builder 2 | # Copyright (C) 2015, 2017 CERN. 3 | # 4 | # Requirements-Builder is free software; you can redistribute it and/or 5 | # modify it under the terms of the Revised BSD License; see LICENSE 6 | # file for more details. 7 | 8 | -r other_req.txt 9 | Cython>=0.20 10 | -------------------------------------------------------------------------------- /tests/data/requirements-test.txt: -------------------------------------------------------------------------------- 1 | attrs 2 | --extra-index-url https://pypi.python.org/simple/ 3 | --extra-index-url https://testpypi.python.org/simple/ 4 | --extra-index-url https://pypi1.python.org/simple/ 5 | --index-url https://pypi-index1.python.org/simple/ 6 | -------------------------------------------------------------------------------- /tests/data/requirements.devel.txt: -------------------------------------------------------------------------------- 1 | # This file is part of Requirements-Builder 2 | # Copyright (C) 2015, 2018, 2020 CERN. 3 | # 4 | # Requirements-Builder is free software; you can redistribute it and/or 5 | # modify it under the terms of the Revised BSD License; see LICENSE 6 | # file for more details. 7 | 8 | -e git+https://github.com/pallets/click.git#egg=click 9 | -------------------------------------------------------------------------------- /tests/data/resolved_deps/autobahn-310-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/autobahn@22.3.2", 5 | "dependencies": [ 6 | "pkg:pypi/cryptography@43.0.3", 7 | "pkg:pypi/hyperlink@21.0.0", 8 | "pkg:pypi/setuptools@80.9.0", 9 | "pkg:pypi/txaio@23.6.1" 10 | ] 11 | }, 12 | { 13 | "package": "pkg:pypi/cffi@1.17.1", 14 | "dependencies": [ 15 | "pkg:pypi/pycparser@2.22" 16 | ] 17 | }, 18 | { 19 | "package": "pkg:pypi/cryptography@43.0.3", 20 | "dependencies": [ 21 | "pkg:pypi/cffi@1.17.1" 22 | ] 23 | }, 24 | { 25 | "package": "pkg:pypi/hyperlink@21.0.0", 26 | "dependencies": [ 27 | "pkg:pypi/idna@3.10" 28 | ] 29 | }, 30 | { 31 | "package": "pkg:pypi/idna@3.10", 32 | "dependencies": [] 33 | }, 34 | { 35 | "package": "pkg:pypi/pycparser@2.22", 36 | "dependencies": [] 37 | }, 38 | { 39 | "package": "pkg:pypi/setuptools@80.9.0", 40 | "dependencies": [] 41 | }, 42 | { 43 | "package": "pkg:pypi/txaio@23.6.1", 44 | "dependencies": [] 45 | } 46 | ], 47 | [ 48 | "pkg:pypi/autobahn@22.3.2", 49 | "pkg:pypi/cffi@1.17.1", 50 | "pkg:pypi/cryptography@43.0.3", 51 | "pkg:pypi/hyperlink@21.0.0", 52 | "pkg:pypi/idna@3.10", 53 | "pkg:pypi/pycparser@2.22", 54 | "pkg:pypi/setuptools@80.9.0", 55 | "pkg:pypi/txaio@23.6.1" 56 | ] 57 | ] -------------------------------------------------------------------------------- /tests/data/resolved_deps/flask-310-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/click@8.2.1", 5 | "dependencies": [] 6 | }, 7 | { 8 | "package": "pkg:pypi/flask@2.1.2", 9 | "dependencies": [ 10 | "pkg:pypi/click@8.2.1", 11 | "pkg:pypi/itsdangerous@2.2.0", 12 | "pkg:pypi/jinja2@3.1.6", 13 | "pkg:pypi/werkzeug@3.1.3" 14 | ] 15 | }, 16 | { 17 | "package": "pkg:pypi/itsdangerous@2.2.0", 18 | "dependencies": [] 19 | }, 20 | { 21 | "package": "pkg:pypi/jinja2@3.1.6", 22 | "dependencies": [ 23 | "pkg:pypi/markupsafe@3.0.2" 24 | ] 25 | }, 26 | { 27 | "package": "pkg:pypi/markupsafe@3.0.2", 28 | "dependencies": [] 29 | }, 30 | { 31 | "package": "pkg:pypi/werkzeug@3.1.3", 32 | "dependencies": [ 33 | "pkg:pypi/markupsafe@3.0.2" 34 | ] 35 | } 36 | ], 37 | [ 38 | "pkg:pypi/click@8.2.1", 39 | "pkg:pypi/flask@2.1.2", 40 | "pkg:pypi/itsdangerous@2.2.0", 41 | "pkg:pypi/jinja2@3.1.6", 42 | "pkg:pypi/markupsafe@3.0.2", 43 | "pkg:pypi/werkzeug@3.1.3" 44 | ] 45 | ] -------------------------------------------------------------------------------- /tests/data/resolved_deps/flask-310-win-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/click@8.2.1", 5 | "dependencies": [ 6 | "pkg:pypi/colorama@0.4.6" 7 | ] 8 | }, 9 | { 10 | "package": "pkg:pypi/colorama@0.4.6", 11 | "dependencies": [] 12 | }, 13 | { 14 | "package": "pkg:pypi/flask@2.1.2", 15 | "dependencies": [ 16 | "pkg:pypi/click@8.2.1", 17 | "pkg:pypi/itsdangerous@2.2.0", 18 | "pkg:pypi/jinja2@3.1.6", 19 | "pkg:pypi/werkzeug@3.1.3" 20 | ] 21 | }, 22 | { 23 | "package": "pkg:pypi/itsdangerous@2.2.0", 24 | "dependencies": [] 25 | }, 26 | { 27 | "package": "pkg:pypi/jinja2@3.1.6", 28 | "dependencies": [ 29 | "pkg:pypi/markupsafe@3.0.2" 30 | ] 31 | }, 32 | { 33 | "package": "pkg:pypi/markupsafe@3.0.2", 34 | "dependencies": [] 35 | }, 36 | { 37 | "package": "pkg:pypi/werkzeug@3.1.3", 38 | "dependencies": [ 39 | "pkg:pypi/markupsafe@3.0.2" 40 | ] 41 | } 42 | ], 43 | [ 44 | "pkg:pypi/click@8.2.1", 45 | "pkg:pypi/colorama@0.4.6", 46 | "pkg:pypi/flask@2.1.2", 47 | "pkg:pypi/itsdangerous@2.2.0", 48 | "pkg:pypi/jinja2@3.1.6", 49 | "pkg:pypi/markupsafe@3.0.2", 50 | "pkg:pypi/werkzeug@3.1.3" 51 | ] 52 | ] -------------------------------------------------------------------------------- /tests/data/resolved_deps/flask-36-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/click@8.0.4", 5 | "dependencies": [ 6 | "pkg:pypi/importlib-metadata@4.8.3" 7 | ] 8 | }, 9 | { 10 | "package": "pkg:pypi/dataclasses@0.8", 11 | "dependencies": [] 12 | }, 13 | { 14 | "package": "pkg:pypi/flask@2.0.3", 15 | "dependencies": [ 16 | "pkg:pypi/click@8.0.4", 17 | "pkg:pypi/itsdangerous@2.0.1", 18 | "pkg:pypi/jinja2@3.0.3", 19 | "pkg:pypi/werkzeug@2.0.3" 20 | ] 21 | }, 22 | { 23 | "package": "pkg:pypi/importlib-metadata@4.8.3", 24 | "dependencies": [ 25 | "pkg:pypi/typing-extensions@4.1.1", 26 | "pkg:pypi/zipp@3.6.0" 27 | ] 28 | }, 29 | { 30 | "package": "pkg:pypi/itsdangerous@2.0.1", 31 | "dependencies": [] 32 | }, 33 | { 34 | "package": "pkg:pypi/jinja2@3.0.3", 35 | "dependencies": [ 36 | "pkg:pypi/markupsafe@2.0.1" 37 | ] 38 | }, 39 | { 40 | "package": "pkg:pypi/markupsafe@2.0.1", 41 | "dependencies": [] 42 | }, 43 | { 44 | "package": "pkg:pypi/typing-extensions@4.1.1", 45 | "dependencies": [] 46 | }, 47 | { 48 | "package": "pkg:pypi/werkzeug@2.0.3", 49 | "dependencies": [ 50 | "pkg:pypi/dataclasses@0.8" 51 | ] 52 | }, 53 | { 54 | "package": "pkg:pypi/zipp@3.6.0", 55 | "dependencies": [] 56 | } 57 | ], 58 | [ 59 | "pkg:pypi/click@8.0.4", 60 | "pkg:pypi/dataclasses@0.8", 61 | "pkg:pypi/flask@2.0.3", 62 | "pkg:pypi/importlib-metadata@4.8.3", 63 | "pkg:pypi/itsdangerous@2.0.1", 64 | "pkg:pypi/jinja2@3.0.3", 65 | "pkg:pypi/markupsafe@2.0.1", 66 | "pkg:pypi/typing-extensions@4.1.1", 67 | "pkg:pypi/werkzeug@2.0.3", 68 | "pkg:pypi/zipp@3.6.0" 69 | ] 70 | ] -------------------------------------------------------------------------------- /tests/data/resolved_deps/flask-39-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/click@8.1.8", 5 | "dependencies": [] 6 | }, 7 | { 8 | "package": "pkg:pypi/flask@2.1.3", 9 | "dependencies": [ 10 | "pkg:pypi/click@8.1.8", 11 | "pkg:pypi/importlib-metadata@8.7.0", 12 | "pkg:pypi/itsdangerous@2.2.0", 13 | "pkg:pypi/jinja2@3.1.6", 14 | "pkg:pypi/werkzeug@3.1.3" 15 | ] 16 | }, 17 | { 18 | "package": "pkg:pypi/importlib-metadata@8.7.0", 19 | "dependencies": [ 20 | "pkg:pypi/zipp@3.23.0" 21 | ] 22 | }, 23 | { 24 | "package": "pkg:pypi/itsdangerous@2.2.0", 25 | "dependencies": [] 26 | }, 27 | { 28 | "package": "pkg:pypi/jinja2@3.1.6", 29 | "dependencies": [ 30 | "pkg:pypi/markupsafe@3.0.2" 31 | ] 32 | }, 33 | { 34 | "package": "pkg:pypi/markupsafe@3.0.2", 35 | "dependencies": [] 36 | }, 37 | { 38 | "package": "pkg:pypi/werkzeug@3.1.3", 39 | "dependencies": [ 40 | "pkg:pypi/markupsafe@3.0.2" 41 | ] 42 | }, 43 | { 44 | "package": "pkg:pypi/zipp@3.23.0", 45 | "dependencies": [] 46 | } 47 | ], 48 | [ 49 | "pkg:pypi/click@8.1.8", 50 | "pkg:pypi/flask@2.1.3", 51 | "pkg:pypi/importlib-metadata@8.7.0", 52 | "pkg:pypi/itsdangerous@2.2.0", 53 | "pkg:pypi/jinja2@3.1.6", 54 | "pkg:pypi/markupsafe@3.0.2", 55 | "pkg:pypi/werkzeug@3.1.3", 56 | "pkg:pypi/zipp@3.23.0" 57 | ] 58 | ] -------------------------------------------------------------------------------- /tests/data/resolved_deps/torch-312-expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "package": "pkg:pypi/torchcodec@0.3.0%2Bcu126", 5 | "dependencies": [] 6 | } 7 | ], 8 | [ 9 | "pkg:pypi/torchcodec@0.3.0%2Bcu126" 10 | ] 11 | ] -------------------------------------------------------------------------------- /tests/data/secure-setup/setup-emptyrequires.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | from distutils.core import setup 17 | 18 | from setuptools import find_packages 19 | 20 | setup( 21 | name="packer.py", 22 | version="0.3.0", 23 | author="Matthew Aynalem", 24 | author_email="maynalem@gmail.com", 25 | packages=["packerpy"], 26 | url="https://github.com/mayn/packer.py", 27 | license="Apache License 2.0", 28 | description="packer.py - python library to run hashicorp packer CLI commands", 29 | keywords="hashicorp packer", 30 | long_description=open("README.rst").read(), 31 | install_requires=[], 32 | classifiers=[ 33 | "License :: OSI Approved :: Apache Software License", 34 | "Programming Language :: Python :: 2", 35 | "Programming Language :: Python :: 2.7", 36 | "Programming Language :: Python :: 3", 37 | "Programming Language :: Python :: 3.4", 38 | "Programming Language :: Python :: 3.5", 39 | "Programming Language :: Python :: 3.6", 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /tests/data/secure-setup/setup-norequires.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | from distutils.core import setup 17 | 18 | from setuptools import find_packages 19 | 20 | setup( 21 | name="packer.py", 22 | version="0.3.0", 23 | author="Matthew Aynalem", 24 | author_email="maynalem@gmail.com", 25 | packages=["packerpy"], 26 | url="https://github.com/mayn/packer.py", 27 | license="Apache License 2.0", 28 | description="packer.py - python library to run hashicorp packer CLI commands", 29 | keywords="hashicorp packer", 30 | long_description=open("README.rst").read(), 31 | classifiers=[ 32 | "License :: OSI Approved :: Apache Software License", 33 | "Programming Language :: Python :: 2", 34 | "Programming Language :: Python :: 2.7", 35 | "Programming Language :: Python :: 3", 36 | "Programming Language :: Python :: 3.4", 37 | "Programming Language :: Python :: 3.5", 38 | "Programming Language :: Python :: 3.6", 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /tests/data/secure-setup/setup-requires.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | from distutils.core import setup 17 | 18 | from setuptools import find_packages 19 | 20 | setup( 21 | name="packer.py", 22 | version="0.3.0", 23 | author="Matthew Aynalem", 24 | author_email="maynalem@gmail.com", 25 | packages=["packerpy"], 26 | url="https://github.com/mayn/packer.py", 27 | license="Apache License 2.0", 28 | description="packer.py - python library to run hashicorp packer CLI commands", 29 | keywords="hashicorp packer", 30 | long_description=open("README.rst").read(), 31 | install_requires=["requirement1", "requirement2"], 32 | classifiers=[ 33 | "License :: OSI Approved :: Apache Software License", 34 | "Programming Language :: Python :: 2", 35 | "Programming Language :: Python :: 2.7", 36 | "Programming Language :: Python :: 3", 37 | "Programming Language :: Python :: 3.4", 38 | "Programming Language :: Python :: 3.5", 39 | "Programming Language :: Python :: 3.6", 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /tests/data/setup-distutils-asnames.txt: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | import distutils.core as dts, os 17 | from setuptools import find_packages 18 | 19 | dts.setup( 20 | name='packer.py', 21 | version='0.3.0', 22 | author='Matthew Aynalem', 23 | author_email='maynalem@gmail.com', 24 | packages=['packerpy'], 25 | url='https://github.com/mayn/packer.py', 26 | license='Apache License 2.0', 27 | description='packer.py - python library to run hashicorp packer CLI commands', 28 | keywords="hashicorp packer", 29 | install_requires=[ 30 | ], 31 | classifiers=[ 32 | 'License :: OSI Approved :: Apache Software License', 33 | 'Programming Language :: Python :: 2', 34 | 'Programming Language :: Python :: 2.7', 35 | 'Programming Language :: Python :: 3', 36 | 'Programming Language :: Python :: 3.4', 37 | 'Programming Language :: Python :: 3.5', 38 | 'Programming Language :: Python :: 3.6', 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /tests/data/setup-distutils-qualifiedfct.txt: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | import distutils.core 17 | from setuptools import find_packages 18 | 19 | distutils.core.setup( 20 | name='packer.py', 21 | version='0.3.0', 22 | author='Matthew Aynalem', 23 | author_email='maynalem@gmail.com', 24 | packages=['packerpy'], 25 | url='https://github.com/mayn/packer.py', 26 | license='Apache License 2.0', 27 | description='packer.py - python library to run hashicorp packer CLI commands', 28 | keywords="hashicorp packer", 29 | install_requires=[ 30 | ], 31 | classifiers=[ 32 | 'License :: OSI Approved :: Apache Software License', 33 | 'Programming Language :: Python :: 2', 34 | 'Programming Language :: Python :: 2.7', 35 | 'Programming Language :: Python :: 3', 36 | 'Programming Language :: Python :: 3.4', 37 | 'Programming Language :: Python :: 3.5', 38 | 'Programming Language :: Python :: 3.6', 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /tests/data/setup-distutils.txt: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2018 Matthew Aynalem 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | from distutils.core import setup 17 | from setuptools import find_packages 18 | 19 | setup( 20 | name='packer.py', 21 | version='0.3.0', 22 | author='Matthew Aynalem', 23 | author_email='maynalem@gmail.com', 24 | packages=['packerpy'], 25 | url='https://github.com/mayn/packer.py', 26 | license='Apache License 2.0', 27 | description='packer.py - python library to run hashicorp packer CLI commands', 28 | keywords="hashicorp packer", 29 | install_requires=[ 30 | ], 31 | classifiers=[ 32 | 'License :: OSI Approved :: Apache Software License', 33 | 'Programming Language :: Python :: 2', 34 | 'Programming Language :: Python :: 2.7', 35 | 'Programming Language :: Python :: 3', 36 | 'Programming Language :: Python :: 3.4', 37 | 'Programming Language :: Python :: 3.5', 38 | 'Programming Language :: Python :: 3.6', 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /tests/data/setup-qualifiedfct.txt: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is part of Requirements-Builder 4 | # Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 CERN. 5 | # 6 | # Requirements-Builder is free software; you can redistribute it and/or 7 | # modify it under the terms of the Revised BSD License; see LICENSE 8 | # file for more details. 9 | # 10 | """Build requirements files from setup.py requirements.""" 11 | 12 | import os 13 | 14 | import setuptools 15 | 16 | # Get the version string. Cannot be done with import! 17 | g = {} 18 | 19 | install_requires = [ 20 | 'click>=6.1.0', 21 | 'mock>=1.3.0', 22 | ] 23 | 24 | tests_require = [ 25 | 'check-manifest>=0.25', 26 | 'coverage>=4.0', 27 | 'isort>=4.0.0', 28 | 'pydocstyle>=1.0.0', 29 | 'pytest-cache>=1.0', 30 | 'pytest-cov>=2.0.0', 31 | 'pytest-pep8>=1.0.6', 32 | 'pytest>=2.8.0', 33 | ] 34 | 35 | extras_require = { 36 | 'docs': [ 37 | 'Sphinx>=2.4', 38 | ], 39 | 'tests': tests_require, 40 | } 41 | 42 | extras_require['all'] = extras_require['tests'] + extras_require['docs'] 43 | 44 | setup_requires = ['pytest-runner>=2.6.2', ] 45 | 46 | setuptools.setup( 47 | name='requirements-builder', 48 | version="0.1.0", 49 | description=__doc__, 50 | long_description='\n\n', 51 | author="Invenio Collaboration", 52 | author_email='info@inveniosoftware.org', 53 | url='https://github.com/inveniosoftware/requirements-builder', 54 | entry_points={ 55 | 'console_scripts': 56 | ["requirements-builder = requirements_builder.cli:cli"] 57 | }, 58 | packages=['requirements_builder', ], 59 | include_package_data=True, 60 | extras_require=extras_require, 61 | install_requires=install_requires, 62 | setup_requires=setup_requires, 63 | tests_require=tests_require, 64 | license='BSD', 65 | zip_safe=False, 66 | keywords='requirements-builder', 67 | classifiers=[ 68 | 'Intended Audience :: Developers', 69 | 'License :: OSI Approved :: BSD License', 70 | 'Natural Language :: English', 71 | 'Programming Language :: Python :: 3', 72 | 'Programming Language :: Python :: 3.5', 73 | 'Programming Language :: Python :: 3.6', 74 | 'Programming Language :: Python :: 3.7', 75 | 'Programming Language :: Python :: 3.8', 76 | ], 77 | ) 78 | -------------------------------------------------------------------------------- /tests/data/setup.cfg: -------------------------------------------------------------------------------- 1 | [options] 2 | install_requires = 3 | pytest-black >= 0.3.7; \ 4 | python_implementation != "PyPy" 5 | attrs >= 18.1, !=20.1.0 6 | Beautifulsoup4 >= 4.0.0 7 | pip>=19.1 # For proper file:// URLs support 8 | click >= 6.7, !=7.0 9 | intbitset >= 2.3.0 10 | requests >= 2.7.0 11 | saneyaml >= 0.5.2 12 | text_unidecode >= 1.0 13 | typing >=3.6, < 3.7; python_version < "3.7" 14 | 15 | [options.extras_require] 16 | testing = 17 | pytest >= 6, != 7.0.0 18 | pytest-xdist >= 2 19 | aboutcode-toolkit >= 6.0.0 20 | black 21 | docs = 22 | Sphinx >= 3.3.1 23 | sphinx-rtd-theme >= 0.5.0 24 | doc8 >= 0.8.1 -------------------------------------------------------------------------------- /tests/data/setup.txt: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is part of Requirements-Builder 4 | # Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 CERN. 5 | # 6 | # Requirements-Builder is free software; you can redistribute it and/or 7 | # modify it under the terms of the Revised BSD License; see LICENSE 8 | # file for more details. 9 | # 10 | """Build requirements files from setup.py requirements.""" 11 | 12 | import os 13 | 14 | from setuptools import setup 15 | 16 | # Get the version string. Cannot be done with import! 17 | g = {} 18 | 19 | install_requires = [ 20 | 'click>=6.1.0', 21 | 'mock>=1.3.0', 22 | ] 23 | 24 | tests_require = [ 25 | 'check-manifest>=0.25', 26 | 'coverage>=4.0', 27 | 'isort>=4.0.0', 28 | 'pydocstyle>=1.0.0', 29 | 'pytest-cache>=1.0', 30 | 'pytest-cov>=2.0.0', 31 | 'pytest-pep8>=1.0.6', 32 | 'pytest>=2.8.0', 33 | ] 34 | 35 | extras_require = { 36 | 'docs': [ 37 | 'Sphinx>=2.4', 38 | ], 39 | 'tests': tests_require, 40 | } 41 | 42 | extras_require['all'] = extras_require['tests'] + extras_require['docs'] 43 | 44 | setup_requires = ['pytest-runner>=2.6.2', ] 45 | 46 | setup( 47 | name='requirements-builder', 48 | version="0.1.0", 49 | description=__doc__, 50 | long_description='\n\n', 51 | author="Invenio Collaboration", 52 | author_email='info@inveniosoftware.org', 53 | url='https://github.com/inveniosoftware/requirements-builder', 54 | entry_points={ 55 | 'console_scripts': 56 | ["requirements-builder = requirements_builder.cli:cli"] 57 | }, 58 | packages=['requirements_builder', ], 59 | include_package_data=True, 60 | extras_require=extras_require, 61 | install_requires=install_requires, 62 | setup_requires=setup_requires, 63 | tests_require=tests_require, 64 | license='BSD', 65 | zip_safe=False, 66 | keywords='requirements-builder', 67 | classifiers=[ 68 | 'Intended Audience :: Developers', 69 | 'License :: OSI Approved :: BSD License', 70 | 'Natural Language :: English', 71 | 'Programming Language :: Python :: 3', 72 | 'Programming Language :: Python :: 3.5', 73 | 'Programming Language :: Python :: 3.6', 74 | 'Programming Language :: Python :: 3.7', 75 | 'Programming Language :: Python :: 3.8', 76 | ], 77 | ) 78 | -------------------------------------------------------------------------------- /tests/data/setup/no-direct-dependencies-setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 -*- 3 | from __future__ import absolute_import 4 | from __future__ import print_function 5 | 6 | import unittest 7 | 8 | from setuptools import setup 9 | 10 | 11 | def test_suite(): 12 | return unittest.TestLoader().discover("tests", pattern="test_*.py") 13 | 14 | 15 | setup( 16 | name="spdx-tools", 17 | version="0.5.4", 18 | description="SPDX parser and tools.", 19 | packages=["spdx", "spdx.parsers", "spdx.writers", "spdx.parsers.lexers"], 20 | package_data={"spdx": ["spdx_licenselist.csv"]}, 21 | include_package_data=True, 22 | zip_safe=False, 23 | test_suite="setup.test_suite", 24 | install_requires=[], 25 | entry_points={ 26 | "console_scripts": [ 27 | "spdx-tv2rdf = spdx.tv_to_rdf:main", 28 | ], 29 | }, 30 | tests_require=[ 31 | "xmltodict", 32 | ], 33 | author="Ahmed H. Ismail", 34 | author_email="ahm3d.hisham@gmail.com", 35 | maintainer="Philippe Ombredanne, SPDX group at the Linux Foundation and others", 36 | maintainer_email="pombredanne@gmail.com", 37 | url="https://github.com/spdx/tools-python", 38 | license="Apache-2.0", 39 | classifiers=[ 40 | "Intended Audience :: Developers", 41 | "License :: OSI Approved :: Apache Software License", 42 | "Programming Language :: Python :: 2.7", 43 | ], 44 | ) 45 | -------------------------------------------------------------------------------- /tests/data/setup/no-direct-dependencies-setup.py-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "tool_version": "0.13.0", 6 | "options": [ 7 | "--analyze-setup-py-insecurely", 8 | "--index-url https://pypi.org/simple", 9 | "--json ", 10 | "--operating-system linux", 11 | "--python-version 27", 12 | "--setup-py tests/data/setup/no-direct-dependencies-setup.py" 13 | ], 14 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 15 | "warnings": [], 16 | "errors": [] 17 | }, 18 | "files": [ 19 | { 20 | "type": "file", 21 | "path": "tests/data/setup/no-direct-dependencies-setup.py", 22 | "package_data": [ 23 | { 24 | "type": "pypi", 25 | "namespace": null, 26 | "name": "spdx-tools", 27 | "version": "0.5.4", 28 | "qualifiers": {}, 29 | "subpath": null, 30 | "primary_language": "Python", 31 | "description": "SPDX parser and tools.", 32 | "release_date": null, 33 | "parties": [ 34 | { 35 | "type": "person", 36 | "role": "author", 37 | "name": "Ahmed H. Ismail", 38 | "email": "ahm3d.hisham@gmail.com", 39 | "url": null 40 | }, 41 | { 42 | "type": "person", 43 | "role": "maintainer", 44 | "name": "Philippe Ombredanne, SPDX group at the Linux Foundation and others", 45 | "email": "pombredanne@gmail.com", 46 | "url": null 47 | } 48 | ], 49 | "keywords": [ 50 | "Intended Audience :: Developers", 51 | "Programming Language :: Python :: 2.7" 52 | ], 53 | "homepage_url": "https://github.com/spdx/tools-python", 54 | "download_url": null, 55 | "size": null, 56 | "sha1": null, 57 | "md5": null, 58 | "sha256": null, 59 | "sha512": null, 60 | "bug_tracking_url": null, 61 | "code_view_url": null, 62 | "vcs_url": null, 63 | "copyright": null, 64 | "license_expression": null, 65 | "declared_license": { 66 | "license": "Apache-2.0", 67 | "classifiers": [ 68 | "License :: OSI Approved :: Apache Software License" 69 | ] 70 | }, 71 | "notice_text": null, 72 | "source_packages": [], 73 | "file_references": [], 74 | "extra_data": {}, 75 | "dependencies": [], 76 | "repository_homepage_url": "https://pypi.org/project/spdx-tools", 77 | "repository_download_url": "https://pypi.org/packages/source/s/spdx-tools/spdx-tools-0.5.4.tar.gz", 78 | "api_data_url": "https://pypi.org/pypi/spdx-tools/0.5.4/json", 79 | "datasource_id": "pypi_setup_py", 80 | "purl": "pkg:pypi/spdx-tools@0.5.4" 81 | } 82 | ] 83 | } 84 | ], 85 | "packages": [], 86 | "resolved_dependencies_graph": [] 87 | } -------------------------------------------------------------------------------- /tests/data/setup/simple-setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017-2021 HERE Europe B.V. 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # SPDX-License-Identifier: Apache-2.0 16 | # License-Filename: LICENSE 17 | 18 | from setuptools import find_packages 19 | from setuptools import setup 20 | 21 | setup( 22 | name="Example-App", 23 | description="A synthetic test case for OSS Review Toolkit", 24 | version="2.4.0", 25 | url="https://example.org/app", 26 | license="MIT License", 27 | classifiers=["License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2"], 28 | python_requires=">2, <=3", 29 | install_requires=["license-expression>=0.1, <1.2"], 30 | packages=find_packages(), 31 | ) 32 | -------------------------------------------------------------------------------- /tests/data/setup/spdx-setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 -*- 3 | from __future__ import absolute_import 4 | from __future__ import print_function 5 | 6 | import unittest 7 | 8 | from setuptools import setup 9 | 10 | 11 | def test_suite(): 12 | return unittest.TestLoader().discover("tests", pattern="test_*.py") 13 | 14 | 15 | setup( 16 | name="spdx-tools", 17 | version="0.5.4", 18 | description="SPDX parser and tools.", 19 | packages=["spdx", "spdx.parsers", "spdx.writers", "spdx.parsers.lexers"], 20 | package_data={"spdx": ["spdx_licenselist.csv"]}, 21 | include_package_data=True, 22 | zip_safe=False, 23 | test_suite="setup.test_suite", 24 | install_requires=[ 25 | "ply", 26 | "rdflib", 27 | "six", 28 | ], 29 | entry_points={ 30 | "console_scripts": [ 31 | "spdx-tv2rdf = spdx.tv_to_rdf:main", 32 | ], 33 | }, 34 | tests_require=[ 35 | "xmltodict", 36 | ], 37 | author="Ahmed H. Ismail", 38 | author_email="ahm3d.hisham@gmail.com", 39 | maintainer="Philippe Ombredanne, SPDX group at the Linux Foundation and others", 40 | maintainer_email="pombredanne@gmail.com", 41 | url="https://github.com/spdx/tools-python", 42 | license="Apache-2.0", 43 | classifiers=[ 44 | "Intended Audience :: Developers", 45 | "License :: OSI Approved :: Apache Software License", 46 | "Programming Language :: Python :: 2.7", 47 | ], 48 | ) 49 | -------------------------------------------------------------------------------- /tests/data/setup_if_main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is part of Requirements-Builder 4 | # Copyright (C) 2017 CERN. 5 | # 6 | # Requirements-Builder is free software; you can redistribute it and/or 7 | # modify it under the terms of the Revised BSD License; see LICENSE 8 | # file for more details. 9 | # 10 | """Build requirements files from setup.py requirements.""" 11 | 12 | import testpkh 13 | from setuptools import setup 14 | 15 | requirements = [ 16 | "click>=5.0.0", 17 | ] 18 | 19 | extras_require = { 20 | "docs": ["Sphinx>=1.4.2"], 21 | } 22 | 23 | if __name__ == "__main__": 24 | setup( 25 | name="testpkh", 26 | version=testpkh.__version__, 27 | install_requires=requirements, 28 | extras_require=extras_require, 29 | ) 30 | -------------------------------------------------------------------------------- /tests/data/setup_with_setup_requires_and_python_requires.cfg: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012-2020 Adam Karpierz 2 | # Licensed under the zlib/libpng License 3 | # https://opensource.org/licenses/Zlib 4 | 5 | [metadata] 6 | long_description = file: README.rst, CHANGES.rst 7 | long_description_content_type = text/x-rst; charset=UTF-8 8 | project_urls = 9 | Documentation=https://QQt.readthedocs.io/ 10 | Source=https://github.com/karpierz/QQt 11 | Issues=https://github.com/karpierz/QQt/issues 12 | license_files = LICENSE 13 | keywords = QQt, PySide2, PySide, PyQt5, PyQt4, PyQt, Qt 14 | platforms = any 15 | classifiers = 16 | Development Status :: 5 - Production/Stable 17 | Intended Audience :: Developers 18 | License :: OSI Approved :: zlib/libpng License 19 | Operating System :: OS Independent 20 | Natural Language :: Polish 21 | Programming Language :: Python 22 | Programming Language :: Python :: 3 23 | Programming Language :: Python :: 3.6 24 | Programming Language :: Python :: 3.7 25 | Programming Language :: Python :: 3 :: Only 26 | Programming Language :: Python :: Implementation :: CPython 27 | Programming Language :: Python :: Implementation :: Stackless 28 | Topic :: Software Development :: Libraries :: Python Modules 29 | 30 | [options] 31 | python_requires = >=3.6.0,<3.8.0 32 | setup_requires = 33 | setuptools>=42.0.2 34 | install_requires = 35 | setuptools>=42.0.2 36 | QtPy~=1.9.0 37 | test_requires = 38 | pytest>=42.0.2 39 | packages = find: 40 | package_dir = 41 | = src 42 | # QQt.tests = tests 43 | zip_safe = True 44 | 45 | [options.packages.find] 46 | where = src 47 | 48 | [options.extras_require] 49 | PySide = 50 | PySide2~=5.13.2 51 | PyQt = 52 | PyQt5~=5.13.2 53 | doc = 54 | Sphinx>=3.2.1 55 | restructuredtext-lint>=1.3.1 56 | test = 57 | PySide2~=5.13.2 58 | 59 | [sdist] 60 | formats = zip 61 | 62 | [bdist_wheel] 63 | universal = False 64 | 65 | [build_sphinx] 66 | source-dir = docs 67 | build-dir = build/docs 68 | builder = html 69 | all-files = True 70 | warning-is-error = True 71 | 72 | # 73 | # Configuration(s) for tox 74 | # 75 | 76 | [tox:tox] 77 | envlist = py{36,37}, docs 78 | minversion = 3.13.2 79 | requires = 80 | tox-venv>=0.4.0 81 | {[base]setup_requires} 82 | skip_missing_interpreters = true 83 | 84 | [base] 85 | setup_requires = 86 | pip>=20.2.3 87 | setuptools>=50.3.0 88 | wheel>=0.35.1 89 | packagesubdir = QQt 90 | 91 | [testenv] 92 | passenv = WINDIR 93 | commands = 94 | {envpython} --version 95 | {envpython} -B -m tests {posargs} 96 | extras = test 97 | deps = 98 | {[base]setup_requires} 99 | 100 | [testenv:prepare] 101 | basepython = python3.7 102 | skip_install = true 103 | whitelist_externals = 104 | cmd 105 | .build 106 | commands = 107 | cmd /C if exist .build.cmd .build.cmd 108 | 109 | [testenv:docs] 110 | basepython = python3.7 111 | commands = 112 | #{envpython} -m sphinx.apidoc -f {envsitepackagesdir}/{[base]packagesubdir} 113 | {envpython} setup.py -v build_sphinx -b html -E 114 | {envpython} setup.py -v build_sphinx -b linkcheck 115 | {envpython} setup.py -v build_sphinx -b doctest 116 | extras = doc 117 | 118 | [testenv:lint] 119 | basepython = python3.7 120 | commands = 121 | {envpython} -m flake8 {envsitepackagesdir}/{[base]packagesubdir}/ 122 | extras = 123 | deps = 124 | {[testenv]deps} 125 | flake8>=3.8.3 126 | flake8-docstrings>=1.5.0 127 | pep8-naming>=0.11.1 128 | flake8-builtins>=1.5.3 129 | 130 | [testenv:publish] 131 | basepython = python3.7 132 | commands = 133 | {envpython} setup.py sdist 134 | {envpython} -m twine check dist/* 135 | {envpython} -m twine upload dist/* 136 | extras = 137 | deps = 138 | {[testenv]deps} 139 | twine>=3.2.0 140 | 141 | [flake8] 142 | filename = *.py,*.pyx 143 | #include = tests 144 | #exclude = .tox,*.egg,.git,_build,.hypothesis 145 | max-line-length = 99 146 | ignore = E126,E203,E221,E251,E302,E701,E702,E731, 147 | E122,E127,E128,E222,E272,E241,E266, E226,E704, 148 | D100, D101, D102, D103, D104, D400, D401, D202, 149 | N806, N802, N803, 150 | I100 151 | # (e.g. E4,W) default: E121,E123, 126, 226,E24, 704 152 | #select = 153 | #select = E,W,F,N,I 154 | output-file = .tox/lint/flake8out.txt 155 | count = True 156 | #show-pep8, 157 | #show-source 158 | #verbose 159 | #quiet -------------------------------------------------------------------------------- /tests/data/single-url-env-var-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "tool_version": "0.13.0", 6 | "options": [ 7 | "--index-url https://pypi.org/simple", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp==3.8.0" 12 | ], 13 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 14 | "warnings": [], 15 | "errors": [] 16 | }, 17 | "files": [], 18 | "packages": [ 19 | { 20 | "type": "pypi", 21 | "namespace": null, 22 | "name": "zipp", 23 | "version": "3.8.0", 24 | "qualifiers": {}, 25 | "subpath": null, 26 | "primary_language": "Python", 27 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.", 28 | "release_date": "2022-04-03T15:07:27", 29 | "parties": [ 30 | { 31 | "type": "person", 32 | "role": "author", 33 | "name": "Jason R. Coombs", 34 | "email": "jaraco@jaraco.com", 35 | "url": null 36 | } 37 | ], 38 | "keywords": [ 39 | "Development Status :: 5 - Production/Stable", 40 | "Intended Audience :: Developers", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 3 :: Only" 43 | ], 44 | "homepage_url": "https://github.com/jaraco/zipp", 45 | "download_url": "https://files.pythonhosted.org/packages/80/0e/16a7ee38617aab6a624e95948d314097cc2669edae9b02ded53309941cfc/zipp-3.8.0-py3-none-any.whl", 46 | "size": 5369, 47 | "sha1": null, 48 | "md5": "da531f1b3a5c5e65470cb74729242bfc", 49 | "sha256": "c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099", 50 | "sha512": null, 51 | "bug_tracking_url": null, 52 | "code_view_url": null, 53 | "vcs_url": null, 54 | "copyright": null, 55 | "license_expression": null, 56 | "declared_license": { 57 | "classifiers": [ 58 | "License :: OSI Approved :: MIT License" 59 | ] 60 | }, 61 | "notice_text": null, 62 | "source_packages": [], 63 | "file_references": [], 64 | "extra_data": {}, 65 | "dependencies": [], 66 | "repository_homepage_url": null, 67 | "repository_download_url": null, 68 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.0/json", 69 | "datasource_id": null, 70 | "purl": "pkg:pypi/zipp@3.8.0" 71 | } 72 | ], 73 | "resolved_dependencies_graph": [ 74 | { 75 | "package": "pkg:pypi/zipp@3.8.0", 76 | "dependencies": [] 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /tests/data/single-url-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "tool_version": "0.13.0", 6 | "options": [ 7 | "--index-url https://pypi.org/simple", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp==3.8.0" 12 | ], 13 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 14 | "warnings": [], 15 | "errors": [] 16 | }, 17 | "files": [], 18 | "packages": [ 19 | { 20 | "type": "pypi", 21 | "namespace": null, 22 | "name": "zipp", 23 | "version": "3.8.0", 24 | "qualifiers": {}, 25 | "subpath": null, 26 | "primary_language": "Python", 27 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.", 28 | "release_date": "2022-04-03T15:07:27", 29 | "parties": [ 30 | { 31 | "type": "person", 32 | "role": "author", 33 | "name": "Jason R. Coombs", 34 | "email": "jaraco@jaraco.com", 35 | "url": null 36 | } 37 | ], 38 | "keywords": [ 39 | "Development Status :: 5 - Production/Stable", 40 | "Intended Audience :: Developers", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 3 :: Only" 43 | ], 44 | "homepage_url": "https://github.com/jaraco/zipp", 45 | "download_url": "https://files.pythonhosted.org/packages/80/0e/16a7ee38617aab6a624e95948d314097cc2669edae9b02ded53309941cfc/zipp-3.8.0-py3-none-any.whl", 46 | "size": 5369, 47 | "sha1": null, 48 | "md5": "da531f1b3a5c5e65470cb74729242bfc", 49 | "sha256": "c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099", 50 | "sha512": null, 51 | "bug_tracking_url": null, 52 | "code_view_url": null, 53 | "vcs_url": null, 54 | "copyright": null, 55 | "license_expression": null, 56 | "declared_license": { 57 | "classifiers": [ 58 | "License :: OSI Approved :: MIT License" 59 | ] 60 | }, 61 | "notice_text": null, 62 | "source_packages": [], 63 | "file_references": [], 64 | "extra_data": {}, 65 | "dependencies": [], 66 | "repository_homepage_url": null, 67 | "repository_download_url": null, 68 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.0/json", 69 | "datasource_id": null, 70 | "purl": "pkg:pypi/zipp@3.8.0" 71 | } 72 | ], 73 | "resolved_dependencies_graph": [ 74 | { 75 | "package": "pkg:pypi/zipp@3.8.0", 76 | "dependencies": [] 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /tests/data/test-api-with-lief-python-312.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "packages": [ 4 | { 5 | "type": "pypi", 6 | "namespace": null, 7 | "name": "lief", 8 | "version": "0.15.1", 9 | "qualifiers": {}, 10 | "subpath": null, 11 | "primary_language": "Python", 12 | "description": "Library to instrument executable formats\nAbout\n=====\n\nThe purpose of this project is to provide a cross platform library that can parse, modify and\nabstract ELF, PE and MachO formats.\n\nMain features:\n\n * **Parsing**: LIEF can parse ELF, PE, MachO, OAT, DEX, VDEX, ART and provides an user-friendly API to access to format internals.\n * **Modify**: LIEF enables to modify some parts of these formats\n * **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.\n * **API**: LIEF can be used in C, C++ and Python\n\n\nDownloads / Install\n===================\n\nFirst, make sure to have an updated version of setuptools:\n\n.. code-block:: console\n\n $ pip install setuptools --upgrade\n\nTo install the latest **version** (release):\n\n.. code-block:: console\n\n $ pip install lief\n\nTo install nightly build:\n\n.. code-block:: console\n\n $ pip install [--user] --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief\n\n\nGetting started\n===============\n\nPython\n------\n\n.. code-block:: python\n\n import lief\n\n # ELF\n binary = lief.parse(\"/usr/bin/ls\")\n print(binary)\n\n # PE\n binary = lief.parse(\"C:\\\\Windows\\\\explorer.exe\")\n print(binary)\n\n # Mach-O\n binary = lief.parse(\"/usr/bin/ls\")\n print(binary)\n\nC++\n---\n\n.. code-block:: cpp\n\n #include \n\n int main(int argc, char** argv) {\n // ELF\n try {\n std::unique_ptr elf = LIEF::ELF::Parser::parse(\"/bin/ls\");\n std::cout << *elf << '\\n';\n } catch (const LIEF::exception& err) {\n std::cerr << err.what() << '\\n';\n }\n\n // PE\n try {\n std::unique_ptr pe = LIEF::PE::Parser::parse(\"C:\\\\Windows\\\\explorer.exe\");\n std::cout << *pe << '\\n';\n } catch (const LIEF::exception& err) {\n std::cerr << err.what() << '\\n';\n }\n\n // Mach-O\n try {\n std::unique_ptr macho = LIEF::MachO::Parser::parse(\"/bin/ls\");\n std::cout << *macho << '\\n';\n } catch (const LIEF::exception& err) {\n std::cerr << err.what() << '\\n';\n }\n\n return 0;\n }\n\nC (Limited API)\n----------------\n\n.. code-block:: cpp\n\n #include \n\n int main(int argc, char** argv) {\n Elf_Binary_t* elf = elf_parse(\"/usr/bin/ls\");\n\n Elf_Section_t** sections = elf->sections;\n\n for (size_t i = 0; sections[i] != NULL; ++i) {\n printf(\"%s\\n\", sections[i]->name);\n }\n\n elf_binary_destroy(elf);\n return 0;\n }\n\nDocumentation\n=============\n\n* `Main documentation `_\n* `Tutorial `_\n* `API `_\n* `Doxygen `_\n\nContact\n=======\n\n* **Mail**: contact at lief.re\n* **Gitter**: `lief-project `_\n\n\nAuthors\n=======\n\nRomain Thomas `@rh0main `_ - `Quarkslab `_\n\n----\n\nLIEF is provided under the `Apache 2.0 license `_", 13 | "release_date": "2024-07-23T14:52:11", 14 | "parties": [ 15 | { 16 | "type": "person", 17 | "role": "author", 18 | "name": null, 19 | "email": "Romain Thomas ", 20 | "url": null 21 | } 22 | ], 23 | "keywords": [ 24 | "parser", 25 | "elf", 26 | "pe", 27 | "macho", 28 | "reverse-engineering", 29 | "Development Status :: 4 - Beta", 30 | "Programming Language :: C++", 31 | "Programming Language :: Python :: 3", 32 | "Topic :: Software Development :: Libraries" 33 | ], 34 | "homepage_url": "https://lief-project.github.io/", 35 | "download_url": "https://files.pythonhosted.org/packages/bd/e8/398583add15a3a74207624be6a853a30a986252440f19b4052022cea911a/lief-0.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", 36 | "size": 2476427, 37 | "sha1": null, 38 | "md5": "0a223b5258a2a5a112b92af3f38cf9f2", 39 | "sha256": "c2ec738bcafee8a569741f4a749f0596823b12f10713306c7d0cbbf85759f51c", 40 | "sha512": null, 41 | "bug_tracking_url": "https://github.com/lief-project/LIEF/issues", 42 | "code_view_url": null, 43 | "vcs_url": null, 44 | "copyright": null, 45 | "license_expression": null, 46 | "declared_license": { 47 | "license": "Apache License 2.0" 48 | }, 49 | "notice_text": null, 50 | "source_packages": [], 51 | "file_references": [], 52 | "extra_data": {}, 53 | "dependencies": [], 54 | "repository_homepage_url": null, 55 | "repository_download_url": null, 56 | "api_data_url": "https://pypi.org/pypi/lief/0.15.1/json", 57 | "datasource_id": null, 58 | "purl": "pkg:pypi/lief@0.15.1" 59 | } 60 | ], 61 | "resolution": [ 62 | { 63 | "package": "pkg:pypi/lief@0.15.1", 64 | "dependencies": [] 65 | } 66 | ] 67 | } -------------------------------------------------------------------------------- /tests/data/test-commented.netrc: -------------------------------------------------------------------------------- 1 | machine pyp2.org login test password test123 2 | # machine pyp1.org login test password test123 -------------------------------------------------------------------------------- /tests/data/test-default.netrc: -------------------------------------------------------------------------------- 1 | machine example.com login test password test123 2 | default login defaultuser password defaultpass 3 | -------------------------------------------------------------------------------- /tests/data/test.netrc: -------------------------------------------------------------------------------- 1 | machine pyp1.org login test password test123 2 | machine subdomain.example.com login subdomain-user password subdomain-secret -------------------------------------------------------------------------------- /tests/data/tilde_req-expected-env.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "options": [ 6 | "--index-url https://pypi.org/simple", 7 | "--json ", 8 | "--operating-system linux", 9 | "--python-version 38", 10 | "--specifier zipp~=3.8.0" 11 | ], 12 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 13 | "warnings": [], 14 | "errors": [] 15 | }, 16 | "files": [], 17 | "packages": [ 18 | { 19 | "type": "pypi", 20 | "namespace": null, 21 | "name": "zipp", 22 | "version": "3.8.1", 23 | "qualifiers": {}, 24 | "subpath": null, 25 | "primary_language": "Python", 26 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/zipp\n :target: https://tidelift.com/subscription/pkg/pypi-zipp?utm_source=pypi-zipp&utm_medium=readme\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.", 27 | "release_date": "2022-07-12T14:21:20", 28 | "parties": [ 29 | { 30 | "type": "person", 31 | "role": "author", 32 | "name": "Jason R. Coombs", 33 | "email": "jaraco@jaraco.com", 34 | "url": null 35 | } 36 | ], 37 | "keywords": [ 38 | "Development Status :: 5 - Production/Stable", 39 | "Intended Audience :: Developers", 40 | "Programming Language :: Python :: 3", 41 | "Programming Language :: Python :: 3 :: Only" 42 | ], 43 | "homepage_url": "https://github.com/jaraco/zipp", 44 | "download_url": "https://files.pythonhosted.org/packages/f0/36/639d6742bcc3ffdce8b85c31d79fcfae7bb04b95f0e5c4c6f8b206a038cc/zipp-3.8.1-py3-none-any.whl", 45 | "size": 5645, 46 | "sha1": null, 47 | "md5": "300aa262796e7ebfb57b4d6731821c29", 48 | "sha256": "47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009", 49 | "sha512": null, 50 | "bug_tracking_url": null, 51 | "code_view_url": null, 52 | "vcs_url": null, 53 | "copyright": null, 54 | "license_expression": null, 55 | "declared_license": { 56 | "classifiers": [ 57 | "License :: OSI Approved :: MIT License" 58 | ] 59 | }, 60 | "notice_text": null, 61 | "source_packages": [], 62 | "file_references": [], 63 | "extra_data": {}, 64 | "dependencies": [], 65 | "repository_homepage_url": null, 66 | "repository_download_url": null, 67 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", 68 | "datasource_id": null, 69 | "purl": "pkg:pypi/zipp@3.8.1" 70 | } 71 | ], 72 | "resolved_dependencies_graph": [ 73 | { 74 | "package": "pkg:pypi/zipp@3.8.1", 75 | "dependencies": [] 76 | } 77 | ] 78 | } -------------------------------------------------------------------------------- /tests/data/tilde_req-expected-max-rounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "options": [ 6 | "--index-url https://pypi.org/simple", 7 | "--index-url https://thirdparty.aboutcode.org/pypi/simple/", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp~=3.8.0" 12 | ], 13 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 14 | "warnings": [], 15 | "errors": [] 16 | }, 17 | "files": [], 18 | "packages": [ 19 | { 20 | "type": "pypi", 21 | "namespace": null, 22 | "name": "zipp", 23 | "version": "3.8.1", 24 | "qualifiers": {}, 25 | "subpath": null, 26 | "primary_language": "Python", 27 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/zipp\n :target: https://tidelift.com/subscription/pkg/pypi-zipp?utm_source=pypi-zipp&utm_medium=readme\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.", 28 | "release_date": "2022-07-12T14:21:21", 29 | "parties": [ 30 | { 31 | "type": "person", 32 | "role": "author", 33 | "name": "Jason R. Coombs", 34 | "email": "jaraco@jaraco.com", 35 | "url": null 36 | } 37 | ], 38 | "keywords": [ 39 | "Development Status :: 5 - Production/Stable", 40 | "Intended Audience :: Developers", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 3 :: Only" 43 | ], 44 | "homepage_url": "https://github.com/jaraco/zipp", 45 | "download_url": "https://files.pythonhosted.org/packages/3b/e3/fb79a1ea5f3a7e9745f688855d3c673f2ef7921639a380ec76f7d4d83a85/zipp-3.8.1.tar.gz", 46 | "size": 14189, 47 | "sha1": null, 48 | "md5": "6f15c3e3c78919f8936749b0033e0cea", 49 | "sha256": "05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", 50 | "sha512": null, 51 | "bug_tracking_url": null, 52 | "code_view_url": null, 53 | "vcs_url": null, 54 | "copyright": null, 55 | "license_expression": null, 56 | "declared_license": { 57 | "classifiers": [ 58 | "License :: OSI Approved :: MIT License" 59 | ] 60 | }, 61 | "notice_text": null, 62 | "source_packages": [], 63 | "file_references": [], 64 | "extra_data": {}, 65 | "dependencies": [], 66 | "repository_homepage_url": null, 67 | "repository_download_url": null, 68 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", 69 | "datasource_id": null, 70 | "purl": "pkg:pypi/zipp@3.8.1" 71 | } 72 | ], 73 | "resolved_dependencies_graph": [ 74 | { 75 | "package": "pkg:pypi/zipp@3.8.1", 76 | "dependencies": [] 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /tests/data/tilde_req-expected-netrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "options": [ 6 | "--index-url https://pypi.org/simple", 7 | "--index-url https://thirdparty.aboutcode.org/pypi/simple/", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp~=3.8.0" 12 | ], 13 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 14 | "warnings": [], 15 | "errors": [] 16 | }, 17 | "files": [], 18 | "packages": [ 19 | { 20 | "type": "pypi", 21 | "namespace": null, 22 | "name": "zipp", 23 | "version": "3.8.1", 24 | "qualifiers": {}, 25 | "subpath": null, 26 | "primary_language": "Python", 27 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/zipp\n :target: https://tidelift.com/subscription/pkg/pypi-zipp?utm_source=pypi-zipp&utm_medium=readme\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.", 28 | "release_date": "2022-07-12T14:21:21", 29 | "parties": [ 30 | { 31 | "type": "person", 32 | "role": "author", 33 | "name": "Jason R. Coombs", 34 | "email": "jaraco@jaraco.com", 35 | "url": null 36 | } 37 | ], 38 | "keywords": [ 39 | "Development Status :: 5 - Production/Stable", 40 | "Intended Audience :: Developers", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 3 :: Only" 43 | ], 44 | "homepage_url": "https://github.com/jaraco/zipp", 45 | "download_url": "https://files.pythonhosted.org/packages/3b/e3/fb79a1ea5f3a7e9745f688855d3c673f2ef7921639a380ec76f7d4d83a85/zipp-3.8.1.tar.gz", 46 | "size": 14189, 47 | "sha1": null, 48 | "md5": "6f15c3e3c78919f8936749b0033e0cea", 49 | "sha256": "05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", 50 | "sha512": null, 51 | "bug_tracking_url": null, 52 | "code_view_url": null, 53 | "vcs_url": null, 54 | "copyright": null, 55 | "license_expression": null, 56 | "declared_license": { 57 | "classifiers": [ 58 | "License :: OSI Approved :: MIT License" 59 | ] 60 | }, 61 | "notice_text": null, 62 | "source_packages": [], 63 | "file_references": [], 64 | "extra_data": {}, 65 | "dependencies": [], 66 | "repository_homepage_url": null, 67 | "repository_download_url": null, 68 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", 69 | "datasource_id": null, 70 | "purl": "pkg:pypi/zipp@3.8.1" 71 | } 72 | ], 73 | "resolved_dependencies_graph": [ 74 | { 75 | "package": "pkg:pypi/zipp@3.8.1", 76 | "dependencies": [] 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /tests/data/tilde_req-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "headers": { 3 | "tool_name": "python-inspector", 4 | "tool_homepageurl": "https://github.com/aboutcode-org/python-inspector", 5 | "options": [ 6 | "--index-url https://pypi.org/simple", 7 | "--index-url https://thirdparty.aboutcode.org/pypi/simple/", 8 | "--json ", 9 | "--operating-system linux", 10 | "--python-version 38", 11 | "--specifier zipp~=3.8.0" 12 | ], 13 | "notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.", 14 | "warnings": [], 15 | "errors": [] 16 | }, 17 | "files": [], 18 | "packages": [ 19 | { 20 | "type": "pypi", 21 | "namespace": null, 22 | "name": "zipp", 23 | "version": "3.8.1", 24 | "qualifiers": {}, 25 | "subpath": null, 26 | "primary_language": "Python", 27 | "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/zipp\n :target: https://tidelift.com/subscription/pkg/pypi-zipp?utm_source=pypi-zipp&utm_medium=readme\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.", 28 | "release_date": "2022-07-12T14:21:21", 29 | "parties": [ 30 | { 31 | "type": "person", 32 | "role": "author", 33 | "name": "Jason R. Coombs", 34 | "email": "jaraco@jaraco.com", 35 | "url": null 36 | } 37 | ], 38 | "keywords": [ 39 | "Development Status :: 5 - Production/Stable", 40 | "Intended Audience :: Developers", 41 | "Programming Language :: Python :: 3", 42 | "Programming Language :: Python :: 3 :: Only" 43 | ], 44 | "homepage_url": "https://github.com/jaraco/zipp", 45 | "download_url": "https://files.pythonhosted.org/packages/3b/e3/fb79a1ea5f3a7e9745f688855d3c673f2ef7921639a380ec76f7d4d83a85/zipp-3.8.1.tar.gz", 46 | "size": 14189, 47 | "sha1": null, 48 | "md5": "6f15c3e3c78919f8936749b0033e0cea", 49 | "sha256": "05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", 50 | "sha512": null, 51 | "bug_tracking_url": null, 52 | "code_view_url": null, 53 | "vcs_url": null, 54 | "copyright": null, 55 | "license_expression": null, 56 | "declared_license": { 57 | "classifiers": [ 58 | "License :: OSI Approved :: MIT License" 59 | ] 60 | }, 61 | "notice_text": null, 62 | "source_packages": [], 63 | "file_references": [], 64 | "extra_data": {}, 65 | "dependencies": [], 66 | "repository_homepage_url": null, 67 | "repository_download_url": null, 68 | "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", 69 | "datasource_id": null, 70 | "purl": "pkg:pypi/zipp@3.8.1" 71 | } 72 | ], 73 | "resolved_dependencies_graph": [ 74 | { 75 | "package": "pkg:pypi/zipp@3.8.1", 76 | "dependencies": [] 77 | } 78 | ] 79 | } -------------------------------------------------------------------------------- /tests/test_packagecode_pypi.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/nexB/skeleton for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | from _packagedcode.models import DependentPackage 11 | from _packagedcode.pypi import create_dependency_for_python_requires 12 | 13 | 14 | def test_create_dependency_for_python_requires(): 15 | assert create_dependency_for_python_requires( 16 | python_requires_specifier=">=3.6" 17 | ) == DependentPackage( 18 | purl="pkg:generic/python", extracted_requirement="python_requires>=3.6", scope="python" 19 | ) 20 | -------------------------------------------------------------------------------- /tests/test_pypi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/nexB/python-inspector for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | 12 | from _packagedcode import models 13 | from _packagedcode.pypi import can_process_dependent_package 14 | 15 | 16 | def test_can_process_dependent_package(): 17 | dependency = models.DependentPackage( 18 | purl="pkg:pypi/django", 19 | scope="install", 20 | is_runtime=True, 21 | is_optional=False, 22 | is_resolved=False, 23 | extracted_requirement="django>=1.11.11", 24 | extra_data=dict( 25 | is_editable=False, 26 | link=None, 27 | hash_options=[], 28 | is_constraint=False, 29 | is_archive=False, 30 | is_wheel=False, 31 | is_url=False, 32 | is_vcs_url=False, 33 | is_name_at_url=False, 34 | is_local_path=False, 35 | ), 36 | ) 37 | 38 | assert can_process_dependent_package(dependency) 39 | 40 | 41 | def test_can_not_process_editable_dependent_package(): 42 | dependency = models.DependentPackage( 43 | purl="pkg:pypi/django", 44 | scope="install", 45 | is_runtime=True, 46 | is_optional=False, 47 | is_resolved=False, 48 | extracted_requirement="django>=1.11.11", 49 | extra_data=dict( 50 | is_editable=True, 51 | link=None, 52 | hash_options=[], 53 | is_constraint=False, 54 | is_archive=False, 55 | is_wheel=False, 56 | is_url=False, 57 | is_vcs_url=False, 58 | is_name_at_url=False, 59 | is_local_path=False, 60 | ), 61 | ) 62 | 63 | assert not can_process_dependent_package(dependency) 64 | 65 | 66 | def test_can_process_dependent_package_without_extra_data(): 67 | dependency = models.DependentPackage( 68 | purl="pkg:pypi/django", 69 | scope="install", 70 | is_runtime=True, 71 | is_optional=False, 72 | is_resolved=False, 73 | extracted_requirement="django>=1.11.11", 74 | ) 75 | 76 | assert can_process_dependent_package(dependency) 77 | 78 | 79 | def test_can_not_process_dependent_package_with_any_flags_set(): 80 | dependency = models.DependentPackage( 81 | purl="pkg:pypi/django", 82 | scope="install", 83 | is_runtime=True, 84 | is_optional=False, 85 | is_resolved=False, 86 | extracted_requirement="django>=1.11.11", 87 | extra_data=dict( 88 | is_editable=True, 89 | link="http://example.com/django.tar.gz", 90 | hash_options=["--hash", "sha256:12345"], 91 | is_constraint=True, 92 | is_archive=True, 93 | is_wheel=True, 94 | is_url=True, 95 | is_vcs_url=True, 96 | is_name_at_url=True, 97 | is_local_path=True, 98 | ), 99 | ) 100 | 101 | assert not can_process_dependent_package(dependency) 102 | -------------------------------------------------------------------------------- /tests/test_requirement_parsing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (c) nexB Inc. and others. All rights reserved. 5 | # ScanCode is a trademark of nexB Inc. 6 | # SPDX-License-Identifier: Apache-2.0 7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 8 | # See https://github.com/nexB/python-inspector for support or download. 9 | # See https://aboutcode.org for more information about nexB OSS projects. 10 | # 11 | 12 | import os 13 | 14 | from python_inspector.dependencies import get_extra_data_from_requirements 15 | 16 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 17 | 18 | 19 | def test_get_extra_data_from_requirements(): 20 | req_file = os.path.join(BASE_DIR, "data", "requirements-test.txt") 21 | expected = [ 22 | { 23 | "extra_index_urls": [ 24 | "https://pypi.python.org/simple/", 25 | "https://testpypi.python.org/simple/", 26 | "https://pypi1.python.org/simple/", 27 | ], 28 | "index_url": "https://pypi-index1.python.org/simple/", 29 | } 30 | ] 31 | result = list(get_extra_data_from_requirements(req_file)) 32 | assert expected == result 33 | -------------------------------------------------------------------------------- /tests/test_setup_py_live_eval.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is part of Requirements-Builder 4 | # Copyright (C) 2015 CERN. 5 | # 6 | # Requirements-Builder is free software; you can redistribute it and/or 7 | # modify it under the terms of the Revised BSD License; see LICENSE 8 | # file for more details. 9 | # 10 | """Tests for `requirements-builder` module.""" 11 | 12 | from os.path import abspath 13 | from os.path import dirname 14 | from os.path import join 15 | 16 | import pytest 17 | 18 | from python_inspector.setup_py_live_eval import iter_requirements 19 | 20 | REQ = abspath(join(dirname(__file__), "./data/requirements.devel.txt")) 21 | 22 | 23 | @pytest.mark.parametrize( 24 | "setup_py", 25 | [ 26 | abspath(join(dirname(__file__), "./data/setup.txt")), 27 | abspath(join(dirname(__file__), "./data/setup-qualifiedfct.txt")), 28 | ], 29 | ) 30 | def test_iter_requirements_with_setup_py(setup_py): 31 | """Test requirements-builder.""" 32 | # Min 33 | assert list(iter_requirements("min", [], setup_py)) == ["click==6.1.0", "mock==1.3.0"] 34 | 35 | # PyPI 36 | assert list(iter_requirements("pypi", [], setup_py)) == ["click>=6.1.0", "mock>=1.3.0"] 37 | 38 | # Dev 39 | assert list(iter_requirements("dev", [], setup_py)) == ["click>=6.1.0", "mock>=1.3.0"] 40 | 41 | 42 | @pytest.mark.parametrize( 43 | "setup_py", 44 | [ 45 | abspath(join(dirname(__file__), "./data/setup-distutils.txt")), 46 | abspath(join(dirname(__file__), "./data/setup-distutils-qualifiedfct.txt")), 47 | abspath(join(dirname(__file__), "./data/setup-distutils-asnames.txt")), 48 | ], 49 | ) 50 | def test_iter_requirements_with_setup_py_noreqs(setup_py): 51 | """Test against setup.py files which import setup in different ways""" 52 | # Min 53 | assert list(iter_requirements("min", [], setup_py)) == [] 54 | 55 | # PyPI 56 | assert list(iter_requirements("pypi", [], setup_py)) == [] 57 | 58 | # Dev 59 | assert list(iter_requirements("dev", [], setup_py)) == [] 60 | -------------------------------------------------------------------------------- /tests/test_setup_py_live_eval.py.ABOUT: -------------------------------------------------------------------------------- 1 | name: requirements-builder 2 | version: 597340d1e84138af64786d45e74fc9f03315bf2d 3 | copyright: Copyright (C) CERN. 4 | homepage_url: https://github.com/inveniosoftware/requirements-builder/ 5 | description: Build requirements files from setup.py requirements. 6 | license_expression: bsd-new 7 | license_file: requirements_builder.LICENSE 8 | notes: this is a subset of requirements-builder that has been heavily modified. 9 | -------------------------------------------------------------------------------- /tests/test_setup_py_live_eval.py.LICENSE: -------------------------------------------------------------------------------- 1 | Requirements-Builder is free software; you can redistribute it and/or 2 | modify it under the terms of the Revised BSD License; see LICENSE 3 | file for more details. 4 | 5 | Copyright (C) 2015, CERN 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from 21 | this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 32 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 33 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 34 | DAMAGE. 35 | -------------------------------------------------------------------------------- /tests/test_setup_py_live_eval_cli.py.ABOUT: -------------------------------------------------------------------------------- 1 | name: requirements-builder 2 | version: 597340d1e84138af64786d45e74fc9f03315bf2d 3 | copyright: Copyright (C) CERN. 4 | homepage_url: https://github.com/inveniosoftware/requirements-builder/ 5 | description: Build requirements files from setup.py requirements. 6 | license_expression: bsd-new 7 | license_file: requirements_builder.LICENSE 8 | notes: this is a subset of requirements-builder that has been heavily modified. 9 | -------------------------------------------------------------------------------- /tests/test_setup_py_live_eval_cli.py.LICENSE: -------------------------------------------------------------------------------- 1 | Requirements-Builder is free software; you can redistribute it and/or 2 | modify it under the terms of the Revised BSD License; see LICENSE 3 | file for more details. 4 | 5 | Copyright (C) 2015, CERN 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from 21 | this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30 | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 32 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 33 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 34 | DAMAGE. 35 | -------------------------------------------------------------------------------- /tests/test_setup_py_parsing.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) nexB Inc. and others. All rights reserved. 3 | # ScanCode is a trademark of nexB Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text. 6 | # See https://github.com/nexB/skeleton for support or download. 7 | # See https://aboutcode.org for more information about nexB OSS projects. 8 | # 9 | 10 | import os 11 | 12 | from _packagedcode.models import DependentPackage 13 | from _packagedcode.pypi import PythonSetupPyHandler 14 | 15 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 16 | 17 | 18 | def test_setup_py_parsing(): 19 | setup_py_file = os.path.join(BASE_DIR, "data", "setup", "simple-setup.py") 20 | package_data = list(PythonSetupPyHandler.parse(location=setup_py_file)) 21 | deps = [] 22 | for pkg in package_data: 23 | deps.extend(pkg.dependencies) 24 | assert deps == [ 25 | DependentPackage( 26 | purl="pkg:pypi/license-expression", 27 | extracted_requirement="license-expression<1.2,>=0.1", 28 | scope="install", 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /tests/test_utils_pip_compatibility_tags.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generate and work with PEP 425 Compatibility Tags. 3 | 4 | copied from pip-20.3.1 pip/tests/unit/test_utils_compatibility_tags.py 5 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py 6 | 7 | Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining 10 | a copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | """ 28 | 29 | import sysconfig 30 | from unittest.mock import patch 31 | 32 | import pytest 33 | 34 | from python_inspector import utils_pip_compatibility_tags 35 | 36 | 37 | @pytest.mark.parametrize( 38 | "version_info, expected", 39 | [ 40 | ((2,), "2"), 41 | ((2, 8), "28"), 42 | ((3,), "3"), 43 | ((3, 6), "36"), 44 | # Test a tuple of length 3. 45 | ((3, 6, 5), "36"), 46 | # Test a 2-digit minor version. 47 | ((3, 10), "310"), 48 | ], 49 | ) 50 | def test_version_info_to_nodot(version_info, expected): 51 | actual = utils_pip_compatibility_tags.version_info_to_nodot(version_info) 52 | assert actual == expected 53 | 54 | 55 | class Testcompatibility_tags(object): 56 | def mock_get_config_var(self, **kwd): 57 | """ 58 | Patch sysconfig.get_config_var for arbitrary keys. 59 | """ 60 | get_config_var = sysconfig.get_config_var 61 | 62 | def _mock_get_config_var(var): 63 | if var in kwd: 64 | return kwd[var] 65 | return get_config_var(var) 66 | 67 | return _mock_get_config_var 68 | 69 | def test_no_hyphen_tag(self): 70 | """ 71 | Test that no tag contains a hyphen. 72 | """ 73 | import pip._internal.utils.compatibility_tags 74 | 75 | mock_gcf = self.mock_get_config_var(SOABI="cpython-35m-darwin") 76 | 77 | with patch("sysconfig.get_config_var", mock_gcf): 78 | supported = pip._internal.utils.compatibility_tags.get_supported() 79 | 80 | for tag in supported: 81 | assert "-" not in tag.interpreter 82 | assert "-" not in tag.abi 83 | assert "-" not in tag.platform 84 | 85 | 86 | class TestManylinux2010Tags(object): 87 | @pytest.mark.parametrize( 88 | "manylinux2010,manylinux1", 89 | [ 90 | ("manylinux2010_x86_64", "manylinux1_x86_64"), 91 | ("manylinux2010_i686", "manylinux1_i686"), 92 | ], 93 | ) 94 | def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1): 95 | """ 96 | Specifying manylinux2010 implies manylinux1. 97 | """ 98 | groups = {} 99 | supported = utils_pip_compatibility_tags.get_supported( 100 | platforms=[manylinux2010], 101 | ) 102 | for tag in supported: 103 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform) 104 | 105 | for arches in groups.values(): 106 | if arches == ["any"]: 107 | continue 108 | assert arches[:2] == [manylinux2010, manylinux1] 109 | 110 | 111 | class TestManylinux2014Tags(object): 112 | @pytest.mark.parametrize( 113 | "manylinuxA,manylinuxB", 114 | [ 115 | ("manylinux2014_x86_64", ["manylinux2010_x86_64", "manylinux1_x86_64"]), 116 | ("manylinux2014_i686", ["manylinux2010_i686", "manylinux1_i686"]), 117 | ], 118 | ) 119 | def test_manylinuxA_implies_manylinuxB(self, manylinuxA, manylinuxB): 120 | """ 121 | Specifying manylinux2014 implies manylinux2010/manylinux1. 122 | """ 123 | groups = {} 124 | supported = utils_pip_compatibility_tags.get_supported(platforms=[manylinuxA]) 125 | for tag in supported: 126 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform) 127 | 128 | expected_arches = [manylinuxA] 129 | expected_arches.extend(manylinuxB) 130 | for arches in groups.values(): 131 | if arches == ["any"]: 132 | continue 133 | assert arches[:3] == expected_arches 134 | -------------------------------------------------------------------------------- /tests/test_utils_pip_compatibility_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: test_utils_pip_compatibility_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: pip 6 | version: 20.3.1 7 | subpath: tests/unit/test_utils_compatibility_tags.py 8 | 9 | package_url: pkg:github/pypa/pip@20.3.1#tests/unit/test_utils_compatibility_tags.py 10 | 11 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py 12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) 13 | license_expression: mit 14 | notes: subset copied from pip for tag handling 15 | -------------------------------------------------------------------------------- /tests/test_utils_pypi_supported_tags.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import pytest 14 | 15 | from python_inspector.utils_pypi_supported_tags import validate_platforms_for_pypi 16 | 17 | """ 18 | Wheel platform checking tests 19 | 20 | Copied and modified on 2020-12-24 from 21 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py 22 | """ 23 | 24 | 25 | def validate_wheel_filename_for_pypi(filename): 26 | """ 27 | Validate if the filename is a PyPI/warehouse-uploadable wheel file name 28 | with supported platform tags. Return a list of unsupported platform tags or 29 | an empty list if all tags are supported. 30 | """ 31 | from python_inspector.utils_pypi import Wheel 32 | 33 | wheel = Wheel.from_filename(filename) 34 | return validate_platforms_for_pypi(wheel.platforms) 35 | 36 | 37 | @pytest.mark.parametrize( 38 | "plat", 39 | [ 40 | "any", 41 | "win32", 42 | "win_amd64", 43 | "win_ia64", 44 | "manylinux1_i686", 45 | "manylinux1_x86_64", 46 | "manylinux2010_i686", 47 | "manylinux2010_x86_64", 48 | "manylinux2014_i686", 49 | "manylinux2014_x86_64", 50 | "manylinux2014_aarch64", 51 | "manylinux2014_armv7l", 52 | "manylinux2014_ppc64", 53 | "manylinux2014_ppc64le", 54 | "manylinux2014_s390x", 55 | "manylinux_2_5_i686", 56 | "manylinux_2_12_x86_64", 57 | "manylinux_2_17_aarch64", 58 | "manylinux_2_17_armv7l", 59 | "manylinux_2_17_ppc64", 60 | "manylinux_2_17_ppc64le", 61 | "manylinux_3_0_s390x", 62 | "macosx_10_6_intel", 63 | "macosx_10_13_x86_64", 64 | "macosx_11_0_x86_64", 65 | "macosx_10_15_arm64", 66 | "macosx_11_10_universal2", 67 | # A real tag used by e.g. some numpy wheels 68 | ( 69 | "macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64." 70 | "macosx_10_10_intel.macosx_10_10_x86_64" 71 | ), 72 | ], 73 | ) 74 | def test_is_valid_pypi_wheel_return_true_for_supported_wheel(plat): 75 | filename = f"foo-1.2.3-cp34-none-{plat}.whl" 76 | assert not validate_wheel_filename_for_pypi(filename) 77 | 78 | 79 | @pytest.mark.parametrize( 80 | "plat", 81 | [ 82 | "linux_x86_64", 83 | "linux_x86_64.win32", 84 | "macosx_9_2_x86_64", 85 | "macosx_12_2_arm64", 86 | "macosx_10_15_amd64", 87 | ], 88 | ) 89 | def test_is_valid_pypi_wheel_raise_exception_for_aunsupported_wheel(plat): 90 | filename = f"foo-1.2.3-cp34-none-{plat}.whl" 91 | invalid = validate_wheel_filename_for_pypi(filename) 92 | assert invalid 93 | -------------------------------------------------------------------------------- /tests/test_utils_pypi_supported_tags.py.ABOUT: -------------------------------------------------------------------------------- 1 | about_resource: test_utils_pypi_supported_tags.py 2 | 3 | type: github 4 | namespace: pypa 5 | name: warehouse 6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d 7 | subpath: tests/unit/forklift/test_legacy.py 8 | 9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#tests/unit/forklift/test_legacy.py 10 | 11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py 12 | copyright: Copyright (c) The warehouse developers 13 | homepage_url: https://warehouse.readthedocs.io 14 | license_expression: apache-2.0 15 | notes: Test for wheel platform checking copied and heavily modified on 16 | 2020-12-24 from warehouse. This contains the basic functions to check if a 17 | wheel file name is would be supported for uploading to PyPI. 18 | --------------------------------------------------------------------------------