├── .bumpversion.cfg ├── .codecov.yml ├── .coveragerc ├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ ├── distutils-deprecation.yml │ ├── documentation-report.yml │ └── feature-request.yml ├── pull_request_template.md └── workflows │ ├── ci-sage.yml │ ├── main.yml │ └── pyright.yml ├── .mergify.yml ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── LICENSE ├── MANIFEST.in ├── NEWS.rst ├── README.rst ├── SECURITY.md ├── _distutils_hack ├── __init__.py └── override.py ├── bootstrap.egg-info ├── PKG-INFO └── entry_points.txt ├── conftest.py ├── docs ├── artwork.rst ├── build_meta.rst ├── conf.py ├── deprecated │ ├── changed_keywords.rst │ ├── commands.rst │ ├── dependency_links.rst │ ├── distutils-legacy.rst │ ├── distutils │ │ ├── _setuptools_disclaimer.rst │ │ ├── apiref.rst │ │ ├── builtdist.rst │ │ ├── commandref.rst │ │ ├── configfile.rst │ │ ├── examples.rst │ │ ├── extending.rst │ │ ├── index.rst │ │ ├── introduction.rst │ │ ├── packageindex.rst │ │ ├── setupscript.rst │ │ ├── sourcedist.rst │ │ └── uploading.rst │ ├── easy_install.rst │ ├── functionalities.rst │ ├── index.rst │ ├── python_eggs.rst │ ├── resource_extraction.rst │ └── zip_safe.rst ├── development │ ├── developer-guide.rst │ ├── index.rst │ └── releases.rst ├── history.rst ├── images │ ├── banner-640x320.svg │ ├── banner-negative-640x320.svg │ ├── favicon.svg │ ├── logo-demo-editable-inkscape.svg │ ├── logo-demo.svg │ ├── logo-editable-inkscape.svg │ ├── logo-inline-negative.svg │ ├── logo-inline.svg │ ├── logo-negative.svg │ ├── logo-over-white.svg │ ├── logo-symbol-only.svg │ ├── logo-text-only.svg │ └── logo.svg ├── index.rst ├── pkg_resources.rst ├── python 2 sunset.rst ├── references │ └── keywords.rst ├── roadmap.rst ├── setuptools.rst └── userguide │ ├── datafiles.rst │ ├── declarative_config.rst │ ├── dependency_management.rst │ ├── development_mode.rst │ ├── distribution.rst │ ├── entry_point.rst │ ├── ext_modules.rst │ ├── extension.rst │ ├── index.rst │ ├── interfaces.rst │ ├── miscellaneous.rst │ ├── package_discovery.rst │ ├── pyproject_config.rst │ └── quickstart.rst ├── exercises.py ├── launcher.c ├── launcher └── CMakeLists.txt ├── mypy.ini ├── newsfragments ├── .gitignore ├── 4530.feature.rst └── README.rst ├── pkg_resources ├── __init__.py ├── api_tests.txt ├── py.typed └── tests │ ├── __init__.py │ ├── data │ ├── my-test-package-source │ │ ├── setup.cfg │ │ └── setup.py │ ├── my-test-package-zip │ │ └── my-test-package.zip │ ├── my-test-package_unpacked-egg │ │ └── my_test_package-1.0-py3.7.egg │ │ │ └── EGG-INFO │ │ │ ├── PKG-INFO │ │ │ ├── SOURCES.txt │ │ │ ├── dependency_links.txt │ │ │ ├── top_level.txt │ │ │ └── zip-safe │ └── my-test-package_zipped-egg │ │ └── my_test_package-1.0-py3.7.egg │ ├── test_find_distributions.py │ ├── test_integration_zope_interface.py │ ├── test_markers.py │ ├── test_pkg_resources.py │ ├── test_resources.py │ └── test_working_set.py ├── pyproject.toml ├── pyrightconfig.json ├── pytest.ini ├── ruff.toml ├── setup.py ├── setuptools ├── __init__.py ├── _core_metadata.py ├── _discovery.py ├── _distutils │ ├── __init__.py │ ├── _log.py │ ├── _macos_compat.py │ ├── _modified.py │ ├── _msvccompiler.py │ ├── archive_util.py │ ├── ccompiler.py │ ├── cmd.py │ ├── command │ │ ├── __init__.py │ │ ├── _framework_compat.py │ │ ├── bdist.py │ │ ├── bdist_dumb.py │ │ ├── bdist_rpm.py │ │ ├── build.py │ │ ├── build_clib.py │ │ ├── build_ext.py │ │ ├── build_py.py │ │ ├── build_scripts.py │ │ ├── check.py │ │ ├── clean.py │ │ ├── command_template │ │ ├── config.py │ │ ├── install.py │ │ ├── install_data.py │ │ ├── install_egg_info.py │ │ ├── install_headers.py │ │ ├── install_lib.py │ │ ├── install_scripts.py │ │ └── sdist.py │ ├── compat │ │ ├── __init__.py │ │ ├── numpy.py │ │ └── py39.py │ ├── compilers │ │ └── C │ │ │ ├── base.py │ │ │ ├── cygwin.py │ │ │ ├── errors.py │ │ │ ├── msvc.py │ │ │ ├── tests │ │ │ ├── test_base.py │ │ │ ├── test_cygwin.py │ │ │ ├── test_mingw.py │ │ │ ├── test_msvc.py │ │ │ └── test_unix.py │ │ │ ├── unix.py │ │ │ └── zos.py │ ├── core.py │ ├── cygwinccompiler.py │ ├── debug.py │ ├── dep_util.py │ ├── dir_util.py │ ├── dist.py │ ├── errors.py │ ├── extension.py │ ├── fancy_getopt.py │ ├── file_util.py │ ├── filelist.py │ ├── log.py │ ├── ruff.toml │ ├── spawn.py │ ├── sysconfig.py │ ├── tests │ │ ├── Setup.sample │ │ ├── __init__.py │ │ ├── compat │ │ │ ├── __init__.py │ │ │ └── py39.py │ │ ├── includetest.rst │ │ ├── support.py │ │ ├── test_archive_util.py │ │ ├── test_bdist.py │ │ ├── test_bdist_dumb.py │ │ ├── test_bdist_rpm.py │ │ ├── test_build.py │ │ ├── test_build_clib.py │ │ ├── test_build_ext.py │ │ ├── test_build_py.py │ │ ├── test_build_scripts.py │ │ ├── test_check.py │ │ ├── test_clean.py │ │ ├── test_cmd.py │ │ ├── test_config_cmd.py │ │ ├── test_core.py │ │ ├── test_dir_util.py │ │ ├── test_dist.py │ │ ├── test_extension.py │ │ ├── test_file_util.py │ │ ├── test_filelist.py │ │ ├── test_install.py │ │ ├── test_install_data.py │ │ ├── test_install_headers.py │ │ ├── test_install_lib.py │ │ ├── test_install_scripts.py │ │ ├── test_log.py │ │ ├── test_modified.py │ │ ├── test_sdist.py │ │ ├── test_spawn.py │ │ ├── test_sysconfig.py │ │ ├── test_text_file.py │ │ ├── test_util.py │ │ ├── test_version.py │ │ ├── test_versionpredicate.py │ │ ├── unix_compat.py │ │ ├── xxmodule-3.8.c │ │ └── xxmodule.c │ ├── text_file.py │ ├── unixccompiler.py │ ├── util.py │ ├── version.py │ ├── versionpredicate.py │ └── zosccompiler.py ├── _entry_points.py ├── _imp.py ├── _importlib.py ├── _itertools.py ├── _normalization.py ├── _path.py ├── _reqs.py ├── _scripts.py ├── _shutil.py ├── _static.py ├── _vendor │ ├── autocommand-2.2.2.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── WHEEL │ │ └── top_level.txt │ ├── autocommand │ │ ├── __init__.py │ │ ├── autoasync.py │ │ ├── autocommand.py │ │ ├── automain.py │ │ ├── autoparse.py │ │ └── errors.py │ ├── backports.tarfile-1.2.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── top_level.txt │ ├── backports │ │ ├── __init__.py │ │ └── tarfile │ │ │ ├── __init__.py │ │ │ ├── __main__.py │ │ │ └── compat │ │ │ ├── __init__.py │ │ │ └── py38.py │ ├── importlib_metadata-8.0.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── top_level.txt │ ├── importlib_metadata │ │ ├── __init__.py │ │ ├── _adapters.py │ │ ├── _collections.py │ │ ├── _compat.py │ │ ├── _functools.py │ │ ├── _itertools.py │ │ ├── _meta.py │ │ ├── _text.py │ │ ├── compat │ │ │ ├── __init__.py │ │ │ ├── py311.py │ │ │ └── py39.py │ │ ├── diagnose.py │ │ └── py.typed │ ├── inflect-7.3.1.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── WHEEL │ │ └── top_level.txt │ ├── inflect │ │ ├── __init__.py │ │ ├── compat │ │ │ ├── __init__.py │ │ │ └── py38.py │ │ └── py.typed │ ├── jaraco.collections-5.1.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── top_level.txt │ ├── jaraco.context-5.3.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── WHEEL │ │ └── top_level.txt │ ├── jaraco.functools-4.0.1.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── WHEEL │ │ └── top_level.txt │ ├── jaraco.text-3.12.1.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── top_level.txt │ ├── jaraco │ │ ├── collections │ │ │ ├── __init__.py │ │ │ └── py.typed │ │ ├── context.py │ │ ├── functools │ │ │ ├── __init__.py │ │ │ ├── __init__.pyi │ │ │ └── py.typed │ │ └── text │ │ │ ├── Lorem ipsum.txt │ │ │ ├── __init__.py │ │ │ ├── layouts.py │ │ │ ├── show-newlines.py │ │ │ ├── strip-prefix.py │ │ │ ├── to-dvorak.py │ │ │ └── to-qwerty.py │ ├── more_itertools-10.3.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ └── WHEEL │ ├── more_itertools │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── more.py │ │ ├── more.pyi │ │ ├── py.typed │ │ ├── recipes.py │ │ └── recipes.pyi │ ├── packaging-24.2.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── LICENSE.APACHE │ │ ├── LICENSE.BSD │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ └── WHEEL │ ├── packaging │ │ ├── __init__.py │ │ ├── _elffile.py │ │ ├── _manylinux.py │ │ ├── _musllinux.py │ │ ├── _parser.py │ │ ├── _structures.py │ │ ├── _tokenizer.py │ │ ├── licenses │ │ │ ├── __init__.py │ │ │ └── _spdx.py │ │ ├── markers.py │ │ ├── metadata.py │ │ ├── py.typed │ │ ├── requirements.py │ │ ├── specifiers.py │ │ ├── tags.py │ │ ├── utils.py │ │ └── version.py │ ├── platformdirs-4.2.2.dist-info │ │ ├── INSTALLER │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── licenses │ │ │ └── LICENSE │ ├── platformdirs │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── android.py │ │ ├── api.py │ │ ├── macos.py │ │ ├── py.typed │ │ ├── unix.py │ │ ├── version.py │ │ └── windows.py │ ├── ruff.toml │ ├── tomli-2.0.1.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ └── WHEEL │ ├── tomli │ │ ├── __init__.py │ │ ├── _parser.py │ │ ├── _re.py │ │ ├── _types.py │ │ └── py.typed │ ├── typeguard-4.3.0.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── WHEEL │ │ ├── entry_points.txt │ │ └── top_level.txt │ ├── typeguard │ │ ├── __init__.py │ │ ├── _checkers.py │ │ ├── _config.py │ │ ├── _decorators.py │ │ ├── _exceptions.py │ │ ├── _functions.py │ │ ├── _importhook.py │ │ ├── _memo.py │ │ ├── _pytest_plugin.py │ │ ├── _suppression.py │ │ ├── _transformer.py │ │ ├── _union_transformer.py │ │ ├── _utils.py │ │ └── py.typed │ ├── typing_extensions-4.12.2.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ └── WHEEL │ ├── typing_extensions.py │ ├── wheel-0.45.1.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE.txt │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── entry_points.txt │ ├── wheel │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── _bdist_wheel.py │ │ ├── _setuptools_logging.py │ │ ├── bdist_wheel.py │ │ ├── cli │ │ │ ├── __init__.py │ │ │ ├── convert.py │ │ │ ├── pack.py │ │ │ ├── tags.py │ │ │ └── unpack.py │ │ ├── macosx_libfile.py │ │ ├── metadata.py │ │ ├── util.py │ │ ├── vendored │ │ │ ├── __init__.py │ │ │ ├── packaging │ │ │ │ ├── LICENSE │ │ │ │ ├── LICENSE.APACHE │ │ │ │ ├── LICENSE.BSD │ │ │ │ ├── __init__.py │ │ │ │ ├── _elffile.py │ │ │ │ ├── _manylinux.py │ │ │ │ ├── _musllinux.py │ │ │ │ ├── _parser.py │ │ │ │ ├── _structures.py │ │ │ │ ├── _tokenizer.py │ │ │ │ ├── markers.py │ │ │ │ ├── requirements.py │ │ │ │ ├── specifiers.py │ │ │ │ ├── tags.py │ │ │ │ ├── utils.py │ │ │ │ └── version.py │ │ │ └── vendor.txt │ │ └── wheelfile.py │ ├── zipp-3.19.2.dist-info │ │ ├── INSTALLER │ │ ├── LICENSE │ │ ├── METADATA │ │ ├── RECORD │ │ ├── REQUESTED │ │ ├── WHEEL │ │ └── top_level.txt │ └── zipp │ │ ├── __init__.py │ │ ├── compat │ │ ├── __init__.py │ │ └── py310.py │ │ └── glob.py ├── archive_util.py ├── build_meta.py ├── cli-32.exe ├── cli-64.exe ├── cli-arm64.exe ├── cli.exe ├── command │ ├── __init__.py │ ├── _requirestxt.py │ ├── alias.py │ ├── bdist_egg.py │ ├── bdist_rpm.py │ ├── bdist_wheel.py │ ├── build.py │ ├── build_clib.py │ ├── build_ext.py │ ├── build_py.py │ ├── develop.py │ ├── dist_info.py │ ├── easy_install.py │ ├── editable_wheel.py │ ├── egg_info.py │ ├── install.py │ ├── install_egg_info.py │ ├── install_lib.py │ ├── install_scripts.py │ ├── launcher manifest.xml │ ├── rotate.py │ ├── saveopts.py │ ├── sdist.py │ ├── setopt.py │ └── test.py ├── compat │ ├── __init__.py │ ├── py310.py │ ├── py311.py │ ├── py312.py │ └── py39.py ├── config │ ├── NOTICE │ ├── __init__.py │ ├── _apply_pyprojecttoml.py │ ├── _validate_pyproject │ │ ├── NOTICE │ │ ├── __init__.py │ │ ├── error_reporting.py │ │ ├── extra_validations.py │ │ ├── fastjsonschema_exceptions.py │ │ ├── fastjsonschema_validations.py │ │ └── formats.py │ ├── distutils.schema.json │ ├── expand.py │ ├── pyprojecttoml.py │ ├── setupcfg.py │ └── setuptools.schema.json ├── depends.py ├── discovery.py ├── dist.py ├── errors.py ├── extension.py ├── glob.py ├── gui-32.exe ├── gui-64.exe ├── gui-arm64.exe ├── gui.exe ├── installer.py ├── launch.py ├── logging.py ├── modified.py ├── monkey.py ├── msvc.py ├── namespaces.py ├── script (dev).tmpl ├── script.tmpl ├── tests │ ├── __init__.py │ ├── compat │ │ ├── __init__.py │ │ └── py39.py │ ├── config │ │ ├── __init__.py │ │ ├── downloads │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ └── preload.py │ │ ├── setupcfg_examples.txt │ │ ├── test_apply_pyprojecttoml.py │ │ ├── test_expand.py │ │ ├── test_pyprojecttoml.py │ │ ├── test_pyprojecttoml_dynamic_deps.py │ │ └── test_setupcfg.py │ ├── contexts.py │ ├── environment.py │ ├── fixtures.py │ ├── indexes │ │ └── test_links_priority │ │ │ ├── external.html │ │ │ └── simple │ │ │ └── foobar │ │ │ └── index.html │ ├── integration │ │ ├── __init__.py │ │ ├── helpers.py │ │ ├── test_pbr.py │ │ └── test_pip_install_sdist.py │ ├── mod_with_constant.py │ ├── namespaces.py │ ├── script-with-bom.py │ ├── test_archive_util.py │ ├── test_bdist_deprecations.py │ ├── test_bdist_egg.py │ ├── test_bdist_wheel.py │ ├── test_build.py │ ├── test_build_clib.py │ ├── test_build_ext.py │ ├── test_build_meta.py │ ├── test_build_py.py │ ├── test_config_discovery.py │ ├── test_core_metadata.py │ ├── test_depends.py │ ├── test_develop.py │ ├── test_dist.py │ ├── test_dist_info.py │ ├── test_distutils_adoption.py │ ├── test_editable_install.py │ ├── test_egg_info.py │ ├── test_extern.py │ ├── test_find_packages.py │ ├── test_find_py_modules.py │ ├── test_glob.py │ ├── test_install_scripts.py │ ├── test_logging.py │ ├── test_manifest.py │ ├── test_namespaces.py │ ├── test_scripts.py │ ├── test_sdist.py │ ├── test_setopt.py │ ├── test_setuptools.py │ ├── test_shutil_wrapper.py │ ├── test_unicode_utils.py │ ├── test_virtualenv.py │ ├── test_warnings.py │ ├── test_wheel.py │ ├── test_windows_wrappers.py │ ├── text.py │ └── textwrap.py ├── unicode_utils.py ├── version.py ├── warnings.py ├── wheel.py └── windows_support.py ├── tools ├── build_launchers.py ├── finalize.py ├── generate_validation_code.py └── vendored.py ├── towncrier.toml └── tox.ini /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 80.9.0 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:pyproject.toml] 7 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | coverage: 3 | status: 4 | project: 5 | default: 6 | informational: true # Treat coverage info as informational only 7 | threshold: 0.5% 8 | patch: 9 | default: 10 | informational: true # Treat coverage info as informational only 11 | github_checks: 12 | annotations: false # Codecov may pollute the "files" diff view 13 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | # leading `*/` for pytest-dev/pytest-cov#456 4 | */.tox/* 5 | 6 | # local 7 | */_vendor/* 8 | */tools/* 9 | */setuptools/_distutils/* 10 | # See #4588 for integration tests coverage 11 | */setuptools/tests/integration/* 12 | */setuptools/tests/test_integration.py 13 | 14 | disable_warnings = 15 | couldnt-parse 16 | 17 | # local 18 | */_validate_pyproject/* # generated code, tested in `validate-pyproject` 19 | 20 | [report] 21 | show_missing = True 22 | exclude_also = 23 | # Exclude common false positives per 24 | # https://coverage.readthedocs.io/en/latest/excluding.html#advanced-exclusion 25 | # Ref jaraco/skeleton#97 and jaraco/skeleton#135 26 | class .*\bProtocol\): 27 | if TYPE_CHECKING: 28 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | indent_size = 4 7 | insert_final_newline = true 8 | end_of_line = lf 9 | 10 | [*.py] 11 | indent_style = space 12 | max_line_length = 88 13 | 14 | [*.{yml,yaml}] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.rst] 19 | indent_style = space 20 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | tidelift: pypi/setuptools 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: 🤔 Have questions or need support? 3 | url: https://github.com/pypa/setuptools/discussions 4 | about: This is a place for the community to exchange ideas and recipes 5 | - name: 💬 Discourse 6 | url: https://discuss.python.org/c/packaging 7 | about: | 8 | Please ask typical Q&A here: general ideas for Python packaging, 9 | questions about structuring projects and so on 10 | - name: 💬 Discord (chat) 11 | url: https://discord.com/invite/pypa 12 | about: Chat with devs 13 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## Summary of changes 5 | 6 | 7 | 8 | Closes 9 | 10 | ### Pull Request Checklist 11 | - [ ] Changes have tests 12 | - [ ] News fragment added in [`newsfragments/`]. 13 | _(See [documentation][PR docs] for details)_ 14 | 15 | 16 | [`newsfragments/`]: https://github.com/pypa/setuptools/tree/main/newsfragments 17 | [PR docs]: 18 | https://setuptools.pypa.io/en/latest/development/developer-guide.html#making-a-pull-request 19 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: auto-merge 3 | conditions: 4 | - base=master 5 | - label=auto-merge 6 | - status-success=continuous-integration/appveyor/pr 7 | - status-success=continuous-integration/travis-ci/pr 8 | - status-success=deploy/netlify 9 | actions: 10 | merge: 11 | method: merge 12 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/astral-sh/ruff-pre-commit 3 | rev: v0.9.9 4 | hooks: 5 | - id: ruff 6 | args: [--fix, --unsafe-fixes] 7 | - id: ruff-format 8 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | python: 3 | install: 4 | - path: . 5 | extra_requirements: 6 | - doc 7 | 8 | sphinx: 9 | configuration: docs/conf.py 10 | 11 | # required boilerplate readthedocs/readthedocs.org#10401 12 | build: 13 | os: ubuntu-lts-latest 14 | tools: 15 | python: latest 16 | # post-checkout job to ensure the clone isn't shallow jaraco/skeleton#114 17 | jobs: 18 | post_checkout: 19 | - git fetch --unshallow || true 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include setuptools *.py *.exe *.xml *.tmpl 2 | recursive-include tests *.py 3 | recursive-include setuptools/tests *.html 4 | recursive-include docs *.py *.txt *.rst *.conf *.css *.css_t Makefile indexsidebar.html 5 | recursive-include setuptools/_vendor * 6 | recursive-include pkg_resources *.py *.txt 7 | recursive-include pkg_resources/tests/data * 8 | recursive-include tools * 9 | recursive-include newsfragments * 10 | include *.py 11 | include *.rst 12 | include MANIFEST.in 13 | global-include LICEN[CS]E* COPYING* NOTICE* AUTHORS* 14 | include launcher.c 15 | include msvc-build-launcher.cmd 16 | include mypy.ini 17 | include pytest.ini 18 | include tox.ini 19 | include setuptools/tests/config/setupcfg_examples.txt 20 | include setuptools/config/*.schema.json 21 | global-exclude *.py[cod] __pycache__ 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Contact 2 | 3 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. 4 | -------------------------------------------------------------------------------- /_distutils_hack/override.py: -------------------------------------------------------------------------------- 1 | __import__('_distutils_hack').do_override() 2 | -------------------------------------------------------------------------------- /bootstrap.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Name: setuptools-bootstrap 2 | Version: 1.0 3 | -------------------------------------------------------------------------------- /bootstrap.egg-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [distutils.commands] 2 | egg_info = setuptools.command.egg_info:egg_info 3 | build_py = setuptools.command.build_py:build_py 4 | sdist = setuptools.command.sdist:sdist 5 | editable_wheel = setuptools.command.editable_wheel:editable_wheel 6 | 7 | [distutils.setup_keywords] 8 | include_package_data = setuptools.dist:assert_bool 9 | install_requires = setuptools.dist:check_requirements 10 | extras_require = setuptools.dist:check_extras 11 | entry_points = setuptools.dist:check_entry_points 12 | exclude_package_data = setuptools.dist:check_package_data 13 | namespace_packages = setuptools.dist:check_nsp 14 | 15 | [egg_info.writers] 16 | PKG-INFO = setuptools.command.egg_info:write_pkg_info 17 | dependency_links.txt = setuptools.command.egg_info:overwrite_arg 18 | entry_points.txt = setuptools.command.egg_info:write_entries 19 | requires.txt = setuptools.command.egg_info:write_requirements 20 | -------------------------------------------------------------------------------- /docs/deprecated/distutils/_setuptools_disclaimer.rst: -------------------------------------------------------------------------------- 1 | .. note:: 2 | 3 | This document is being retained solely until the ``setuptools`` documentation 4 | at https://setuptools.pypa.io/en/latest/setuptools.html 5 | independently covers all of the relevant information currently included here. 6 | -------------------------------------------------------------------------------- /docs/deprecated/distutils/index.rst: -------------------------------------------------------------------------------- 1 | .. _distutils-index: 2 | 3 | ############################################## 4 | Distributing Python Modules (Legacy version) 5 | ############################################## 6 | 7 | :Authors: Greg Ward, Anthony Baxter 8 | :Email: distutils-sig@python.org 9 | 10 | .. seealso:: 11 | 12 | :ref:`distributing-index` 13 | The up to date module distribution documentations 14 | 15 | .. include:: ./_setuptools_disclaimer.rst 16 | 17 | .. note:: 18 | 19 | This guide only covers the basic tools for building and distributing 20 | extensions that are provided as part of this version of Python. Third party 21 | tools offer easier to use and more secure alternatives. Refer to the `quick 22 | recommendations section `__ 23 | in the Python Packaging User Guide for more information. 24 | 25 | This document describes the Python Distribution Utilities ("Distutils") from 26 | the module developer's point of view, describing the underlying capabilities 27 | that ``setuptools`` builds on to allow Python developers to make Python modules 28 | and extensions readily available to a wider audience. 29 | 30 | .. toctree:: 31 | :maxdepth: 2 32 | :numbered: 33 | 34 | introduction.rst 35 | setupscript.rst 36 | configfile.rst 37 | sourcedist.rst 38 | builtdist.rst 39 | examples.rst 40 | extending.rst 41 | commandref.rst 42 | apiref.rst 43 | -------------------------------------------------------------------------------- /docs/deprecated/distutils/packageindex.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _package-index: 4 | 5 | ******************************* 6 | The Python Package Index (PyPI) 7 | ******************************* 8 | 9 | The `Python Package Index (PyPI) `_ stores 10 | metadata describing distributions packaged with distutils and 11 | other publishing tools, as well the distribution archives 12 | themselves. 13 | 14 | The best resource for working with PyPI is the 15 | `Python Packaging User Guide `_. 16 | -------------------------------------------------------------------------------- /docs/deprecated/distutils/uploading.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | *************************************** 4 | Uploading Packages to the Package Index 5 | *************************************** 6 | 7 | See the 8 | `Python Packaging User Guide `_ 9 | for the best guidance on uploading packages. 10 | -------------------------------------------------------------------------------- /docs/deprecated/functionalities.rst: -------------------------------------------------------------------------------- 1 | "Eggsecutable" Scripts 2 | ---------------------- 3 | 4 | .. deprecated:: 45.3.0 5 | 6 | Occasionally, there are situations where it's desirable to make an ``.egg`` 7 | file directly executable. You can do this by including an entry point such 8 | as the following:: 9 | 10 | setup( 11 | # other arguments here... 12 | entry_points={ 13 | "setuptools.installation": [ 14 | "eggsecutable = my_package.some_module:main_func", 15 | ] 16 | } 17 | ) 18 | 19 | Any eggs built from the above setup script will include a short executable 20 | prelude that imports and calls ``main_func()`` from ``my_package.some_module``. 21 | The prelude can be run on Unix-like platforms (including Mac and Linux) by 22 | invoking the egg with ``/bin/sh``, or by enabling execute permissions on the 23 | ``.egg`` file. For the executable prelude to run, the appropriate version of 24 | Python must be available via the ``PATH`` environment variable, under its 25 | "long" name. That is, if the egg is built for Python 2.3, there must be a 26 | ``python2.3`` executable present in a directory on ``PATH``. 27 | 28 | IMPORTANT NOTE: Eggs with an "eggsecutable" header cannot be renamed, or 29 | invoked via symlinks. They *must* be invoked using their original filename, in 30 | order to ensure that, once running, ``pkg_resources`` will know what project 31 | and version is in use. The header script will check this and exit with an 32 | error if the ``.egg`` file has been renamed or is invoked via a symlink that 33 | changes its base name. 34 | -------------------------------------------------------------------------------- /docs/deprecated/index.rst: -------------------------------------------------------------------------------- 1 | ====================================================== 2 | Guides on backward compatibility & deprecated practice 3 | ====================================================== 4 | 5 | ``Setuptools`` has undergone tremendous changes since its first debut. As its 6 | development continues to roll forward, many of the practice and mechanisms it 7 | had established are now considered deprecated. But they still remain relevant 8 | as a plethora of libraries continue to depend on them. Many people also find 9 | it necessary to equip themselves with the knowledge to better support backward 10 | compatibility. This guide aims to provide the essential information for such 11 | objectives. 12 | 13 | .. toctree:: 14 | :maxdepth: 1 15 | 16 | changed_keywords 17 | dependency_links 18 | python_eggs 19 | easy_install 20 | zip_safe 21 | resource_extraction 22 | distutils/index 23 | distutils-legacy 24 | functionalities 25 | commands 26 | -------------------------------------------------------------------------------- /docs/development/index.rst: -------------------------------------------------------------------------------- 1 | ------------------------- 2 | Development on Setuptools 3 | ------------------------- 4 | 5 | Setuptools is maintained by the Python community under the Python Packaging 6 | Authority (PyPA) and led by Jason R. Coombs. 7 | 8 | This document describes the process by which Setuptools is developed. 9 | This document assumes the reader has some passing familiarity with 10 | *using* setuptools, the ``pkg_resources`` module, and pip. It 11 | does not attempt to explain basic concepts like inter-project 12 | dependencies, nor does it contain detailed lexical syntax for most 13 | file formats. Neither does it explain concepts like "namespace 14 | packages" or "resources" in any detail, as all of these subjects are 15 | covered at length in the setuptools developer's guide and the 16 | ``pkg_resources`` reference manual. 17 | 18 | Instead, this is **internal** documentation for how those concepts and 19 | features are *implemented* in concrete terms. It is intended for people 20 | who are working on the setuptools code base, who want to be able to 21 | troubleshoot setuptools problems, want to write code that reads the file 22 | formats involved, or want to otherwise tinker with setuptools-generated 23 | files and directories. 24 | 25 | Note, however, that these are all internal implementation details and 26 | are therefore subject to change; stick to the published API if you don't 27 | want to be responsible for keeping your code from breaking when 28 | setuptools changes. You have been warned. 29 | 30 | .. toctree:: 31 | :maxdepth: 1 32 | 33 | developer-guide 34 | releases 35 | -------------------------------------------------------------------------------- /docs/development/releases.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Release Process 3 | =============== 4 | 5 | In order to allow for rapid, predictable releases, Setuptools uses a 6 | mechanical technique for releases, enacted on tagged commits by 7 | continuous integration. 8 | 9 | To finalize a release, run ``tox -e finalize``, review, then push 10 | the changes. 11 | 12 | If tests pass, the release will be uploaded to PyPI. 13 | 14 | Release Frequency 15 | ----------------- 16 | 17 | Some have asked why Setuptools is released so frequently. Because Setuptools 18 | uses a mechanical release process, it's very easy to make releases whenever the 19 | code is stable (tests are passing). As a result, the philosophy is to release 20 | early and often. 21 | 22 | While some find the frequent releases somewhat surprising, they only empower 23 | the user. Although releases are made frequently, users can choose the frequency 24 | at which they use those releases. If instead Setuptools contributions were only 25 | released in batches, the user would be constrained to only use Setuptools when 26 | those official releases were made. With frequent releases, the user can govern 27 | exactly how often he wishes to update. 28 | 29 | Frequent releases also then obviate the need for dev or beta releases in most 30 | cases. Because releases are made early and often, bugs are discovered and 31 | corrected quickly, in many cases before other users have yet to encounter them. 32 | 33 | Release Managers 34 | ---------------- 35 | 36 | Additionally, anyone with push access to the master branch has access to cut 37 | releases. 38 | -------------------------------------------------------------------------------- /docs/history.rst: -------------------------------------------------------------------------------- 1 | :tocdepth: 2 2 | 3 | .. _changes: 4 | 5 | History 6 | ******* 7 | 8 | .. meta:: 9 | :keywords: changelog 10 | 11 | .. towncrier-draft-entries:: DRAFT, unreleased as on |today| 12 | 13 | .. include:: ../NEWS (links).rst 14 | 15 | Credits 16 | ******* 17 | 18 | * The original design for the ``.egg`` format and the ``pkg_resources`` API was 19 | co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first 20 | version of ``pkg_resources``, and supplied the macOS operating system version 21 | compatibility algorithm. 22 | 23 | * Ian Bicking implemented many early "creature comfort" features of 24 | easy_install, including support for downloading via Sourceforge and 25 | Subversion repositories. Ian's comments on the Web-SIG about WSGI 26 | application deployment also inspired the concept of "entry points" in eggs, 27 | and he has given talks at PyCon and elsewhere to inform and educate the 28 | community about eggs and setuptools. 29 | 30 | * Jim Fulton contributed time and effort to build automated tests of various 31 | aspects of ``easy_install``, and supplied the doctests for the command-line 32 | ``.exe`` wrappers on Windows. 33 | 34 | * Phillip J. Eby is the seminal author of setuptools, and 35 | first proposed the idea of an importable binary distribution format for 36 | Python application plug-ins. 37 | 38 | * Significant parts of the implementation of setuptools were funded by the Open 39 | Source Applications Foundation, to provide a plug-in infrastructure for the 40 | Chandler PIM application. In addition, many OSAF staffers (such as Mike 41 | "Code Bear" Taylor) contributed their time and stress as guinea pigs for the 42 | use of eggs and setuptools, even before eggs were "cool". (Thanks, guys!) 43 | 44 | * Tarek Ziadé is the principal author of the Distribute fork, which 45 | re-invigorated the community on the project, encouraged renewed innovation, 46 | and addressed many defects. 47 | 48 | * Jason R. Coombs performed the merge with Distribute, maintaining the 49 | project for several years in coordination with the Python Packaging 50 | Authority (PyPA). 51 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. image:: images/banner-640x320.svg 2 | :align: center 3 | 4 | Documentation 5 | ============= 6 | 7 | Setuptools is a fully-featured, actively-maintained, and stable library 8 | designed to facilitate packaging Python projects. 9 | 10 | It helps developers to easily share reusable code (in the form of a library) 11 | and programs (e.g., CLI/GUI tools implemented in Python), that can be installed 12 | with :pypi:`pip` and uploaded to `PyPI `_. 13 | 14 | .. sidebar-links:: 15 | :home: 16 | :pypi: 17 | 18 | .. toctree:: 19 | :maxdepth: 1 20 | :hidden: 21 | 22 | User guide 23 | build_meta 24 | pkg_resources 25 | references/keywords 26 | setuptools 27 | 28 | .. toctree:: 29 | :caption: Project 30 | :maxdepth: 1 31 | :hidden: 32 | 33 | roadmap 34 | Development guide 35 | Backward compatibility & deprecated practice 36 | Changelog 37 | artwork 38 | 39 | .. tidelift-referral-banner:: 40 | -------------------------------------------------------------------------------- /docs/roadmap.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Roadmap 3 | ======= 4 | 5 | Setuptools maintains a series of `milestones 6 | `_ to track 7 | a roadmap of large-scale goals. 8 | -------------------------------------------------------------------------------- /docs/userguide/index.rst: -------------------------------------------------------------------------------- 1 | ================================================== 2 | Building and Distributing Packages with Setuptools 3 | ================================================== 4 | 5 | The first step towards sharing a Python library or program is to build a 6 | distribution package [#package-overload]_. This includes adding a set of 7 | additional files containing metadata and configuration to not only instruct 8 | ``setuptools`` on how the distribution should be built but also 9 | to help installer (such as :pypi:`pip`) during the installation process. 10 | 11 | This document contains information to help Python developers through this 12 | process. Please check the :doc:`/userguide/quickstart` for an overview of 13 | the workflow. 14 | 15 | Also note that ``setuptools`` is what is known in the community as :pep:`build 16 | backend <517#terminology-and-goals>`, user facing interfaces are provided by tools 17 | such as :pypi:`pip` and :pypi:`build`. To use ``setuptools``, one must 18 | explicitly create a ``pyproject.toml`` file as described :doc:`/build_meta`. 19 | 20 | 21 | Contents 22 | ======== 23 | 24 | .. toctree:: 25 | :maxdepth: 1 26 | 27 | quickstart 28 | interfaces 29 | package_discovery 30 | dependency_management 31 | development_mode 32 | entry_point 33 | datafiles 34 | ext_modules 35 | distribution 36 | miscellaneous 37 | extension 38 | declarative_config 39 | pyproject_config 40 | 41 | --- 42 | 43 | .. rubric:: Notes 44 | 45 | .. [#package-overload] 46 | A :term:`Distribution Package` is also referred in the Python community simply as "package" 47 | Unfortunately, this jargon might be a bit confusing for new users because the term package 48 | can also to refer any :term:`directory ` (or sub directory) used to organize 49 | :term:`modules ` and auxiliary files. 50 | -------------------------------------------------------------------------------- /exercises.py: -------------------------------------------------------------------------------- 1 | def measure_startup_perf(): 2 | # run by pytest_perf 3 | import subprocess 4 | import sys # end warmup 5 | 6 | subprocess.check_call([sys.executable, '-c', 'pass']) 7 | -------------------------------------------------------------------------------- /launcher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.17.0) 2 | set (CMAKE_SYSTEM_VERSION 6.1 CACHE TYPE INTERNAL FORCE) 3 | project (launcher C) 4 | add_definitions(-DGUI=${GUI} -DWIN32_LEAN_AND_MEAN) 5 | add_executable(launcher ../launcher.c) 6 | -------------------------------------------------------------------------------- /newsfragments/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/newsfragments/.gitignore -------------------------------------------------------------------------------- /newsfragments/4530.feature.rst: -------------------------------------------------------------------------------- 1 | Remove post-release tags on setuptools' own build. 2 | -------------------------------------------------------------------------------- /pkg_resources/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/pkg_resources/py.typed -------------------------------------------------------------------------------- /pkg_resources/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/pkg_resources/tests/__init__.py -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package-source/setup.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/pkg_resources/tests/data/my-test-package-source/setup.cfg -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package-source/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | name="my-test-package", 5 | version="1.0", 6 | zip_safe=True, 7 | ) 8 | -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package-zip/my-test-package.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/pkg_resources/tests/data/my-test-package-zip/my-test-package.zip -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: my-test-package 3 | Version: 1.0 4 | Summary: UNKNOWN 5 | Home-page: UNKNOWN 6 | Author: UNKNOWN 7 | Author-email: UNKNOWN 8 | License: UNKNOWN 9 | Description: UNKNOWN 10 | Platform: UNKNOWN 11 | -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.cfg 2 | setup.py 3 | my_test_package.egg-info/PKG-INFO 4 | my_test_package.egg-info/SOURCES.txt 5 | my_test_package.egg-info/dependency_links.txt 6 | my_test_package.egg-info/top_level.txt 7 | my_test_package.egg-info/zip-safe -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg -------------------------------------------------------------------------------- /pkg_resources/tests/test_find_distributions.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | from pathlib import Path 3 | 4 | import pytest 5 | 6 | import pkg_resources 7 | 8 | TESTS_DATA_DIR = Path(__file__).parent / 'data' 9 | 10 | 11 | class TestFindDistributions: 12 | @pytest.fixture 13 | def target_dir(self, tmpdir): 14 | target_dir = tmpdir.mkdir('target') 15 | # place a .egg named directory in the target that is not an egg: 16 | target_dir.mkdir('not.an.egg') 17 | return target_dir 18 | 19 | def test_non_egg_dir_named_egg(self, target_dir): 20 | dists = pkg_resources.find_distributions(str(target_dir)) 21 | assert not list(dists) 22 | 23 | def test_standalone_egg_directory(self, target_dir): 24 | shutil.copytree( 25 | TESTS_DATA_DIR / 'my-test-package_unpacked-egg', 26 | target_dir, 27 | dirs_exist_ok=True, 28 | ) 29 | dists = pkg_resources.find_distributions(str(target_dir)) 30 | assert [dist.project_name for dist in dists] == ['my-test-package'] 31 | dists = pkg_resources.find_distributions(str(target_dir), only=True) 32 | assert not list(dists) 33 | 34 | def test_zipped_egg(self, target_dir): 35 | shutil.copytree( 36 | TESTS_DATA_DIR / 'my-test-package_zipped-egg', 37 | target_dir, 38 | dirs_exist_ok=True, 39 | ) 40 | dists = pkg_resources.find_distributions(str(target_dir)) 41 | assert [dist.project_name for dist in dists] == ['my-test-package'] 42 | dists = pkg_resources.find_distributions(str(target_dir), only=True) 43 | assert not list(dists) 44 | 45 | def test_zipped_sdist_one_level_removed(self, target_dir): 46 | shutil.copytree( 47 | TESTS_DATA_DIR / 'my-test-package-zip', target_dir, dirs_exist_ok=True 48 | ) 49 | dists = pkg_resources.find_distributions( 50 | str(target_dir / "my-test-package.zip") 51 | ) 52 | assert [dist.project_name for dist in dists] == ['my-test-package'] 53 | dists = pkg_resources.find_distributions( 54 | str(target_dir / "my-test-package.zip"), only=True 55 | ) 56 | assert not list(dists) 57 | -------------------------------------------------------------------------------- /pkg_resources/tests/test_integration_zope_interface.py: -------------------------------------------------------------------------------- 1 | import platform 2 | from inspect import cleandoc 3 | 4 | import jaraco.path 5 | import pytest 6 | 7 | pytestmark = pytest.mark.integration 8 | 9 | 10 | # For the sake of simplicity this test uses fixtures defined in 11 | # `setuptools.test.fixtures`, 12 | # and it also exercise conditions considered deprecated... 13 | # So if needed this test can be deleted. 14 | @pytest.mark.skipif( 15 | platform.system() != "Linux", 16 | reason="only demonstrated to fail on Linux in #4399", 17 | ) 18 | def test_interop_pkg_resources_iter_entry_points(tmp_path, venv): 19 | """ 20 | Importing pkg_resources.iter_entry_points on console_scripts 21 | seems to cause trouble with zope-interface, when deprecates installation method 22 | is used. See #4399. 23 | """ 24 | project = { 25 | "pkg": { 26 | "foo.py": cleandoc( 27 | """ 28 | from pkg_resources import iter_entry_points 29 | 30 | def bar(): 31 | print("Print me if you can") 32 | """ 33 | ), 34 | "setup.py": cleandoc( 35 | """ 36 | from setuptools import setup, find_packages 37 | 38 | setup( 39 | install_requires=["zope-interface==6.4.post2"], 40 | entry_points={ 41 | "console_scripts": [ 42 | "foo=foo:bar", 43 | ], 44 | }, 45 | ) 46 | """ 47 | ), 48 | } 49 | } 50 | jaraco.path.build(project, prefix=tmp_path) 51 | cmd = ["pip", "install", "-e", ".", "--no-use-pep517"] 52 | venv.run(cmd, cwd=tmp_path / "pkg") # Needs this version of pkg_resources installed 53 | out = venv.run(["foo"]) 54 | assert "Print me if you can" in out 55 | -------------------------------------------------------------------------------- /pkg_resources/tests/test_markers.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | 3 | from pkg_resources import evaluate_marker 4 | 5 | 6 | @mock.patch('platform.python_version', return_value='2.7.10') 7 | def test_ordering(python_version_mock): 8 | assert evaluate_marker("python_full_version > '2.7.3'") is True 9 | -------------------------------------------------------------------------------- /pyrightconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/pyright/main/packages/vscode-pyright/schemas/pyrightconfig.schema.json", 3 | "exclude": [ 4 | // Avoid scanning Python files in generated folders 5 | "build", 6 | ".tox", 7 | ".eggs", 8 | "setuptools/config/_validate_pyproject/**", 9 | // These are vendored 10 | "**/_vendor", 11 | "setuptools/_distutils", 12 | ], 13 | // Our testing setup doesn't allow passing CLI arguments, so local devs have to set this manually. 14 | // "pythonVersion": "3.9", 15 | // For now we don't mind if mypy's `type: ignore` comments accidentally suppresses pyright issues 16 | "enableTypeIgnoreComments": true, 17 | "typeCheckingMode": "basic", 18 | // Too many issues caused by dynamic patching, still worth fixing when we can 19 | "reportAttributeAccessIssue": "warning", 20 | // Fails on Python 3.12 due to missing distutils 21 | "reportMissingImports": "warning", 22 | // FIXME: A handful of reportOperatorIssue spread throughout the codebase 23 | "reportOperatorIssue": "warning", 24 | // Deferred initialization (initialize_options/finalize_options) causes many "potentially None" issues 25 | // TODO: Fix with type-guards, by changing how it's initialized, or by casting initial assignments 26 | "reportArgumentType": "warning", 27 | "reportCallIssue": "warning", 28 | "reportGeneralTypeIssues": "warning", 29 | "reportOptionalIterable": "warning", 30 | "reportOptionalMemberAccess": "warning", 31 | "reportOptionalOperand": "warning", 32 | } 33 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import textwrap 5 | 6 | import setuptools 7 | from setuptools.command.install import install 8 | 9 | here = os.path.dirname(__file__) 10 | 11 | 12 | class install_with_pth(install): 13 | """ 14 | Custom install command to install a .pth file for distutils patching. 15 | 16 | This hack is necessary because there's no standard way to install behavior 17 | on startup (and it's debatable if there should be one). This hack (ab)uses 18 | the `extra_path` behavior in Setuptools to install a `.pth` file with 19 | implicit behavior on startup to give higher precedence to the local version 20 | of `distutils` over the version from the standard library. 21 | 22 | Please do not replicate this behavior. 23 | """ 24 | 25 | _pth_name = 'distutils-precedence' 26 | _pth_contents = ( 27 | textwrap.dedent( 28 | """ 29 | import os 30 | var = 'SETUPTOOLS_USE_DISTUTILS' 31 | enabled = os.environ.get(var, 'local') == 'local' 32 | enabled and __import__('_distutils_hack').add_shim() 33 | """ 34 | ) 35 | .lstrip() 36 | .replace('\n', '; ') 37 | ) 38 | 39 | def initialize_options(self): 40 | install.initialize_options(self) 41 | self.extra_path = self._pth_name, self._pth_contents 42 | 43 | def finalize_options(self): 44 | install.finalize_options(self) 45 | self._restore_install_lib() 46 | 47 | def _restore_install_lib(self): 48 | """ 49 | Undo secondary effect of `extra_path` adding to `install_lib` 50 | """ 51 | suffix = os.path.relpath(self.install_lib, self.install_libbase) 52 | 53 | if suffix.strip() == self._pth_contents.strip(): 54 | self.install_lib = self.install_libbase 55 | 56 | 57 | setup_params = dict( 58 | cmdclass={'install': install_with_pth}, 59 | ) 60 | 61 | if __name__ == '__main__': 62 | # allow setup.py to run from another directory 63 | # TODO: Use a proper conditional statement here 64 | here and os.chdir(here) # type: ignore[func-returns-value] 65 | dist = setuptools.setup(**setup_params) 66 | -------------------------------------------------------------------------------- /setuptools/_discovery.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import operator 3 | 4 | import packaging.requirements 5 | 6 | 7 | # from coherent.build.discovery 8 | def extras_from_dep(dep): 9 | try: 10 | markers = packaging.requirements.Requirement(dep).marker._markers 11 | except AttributeError: 12 | markers = () 13 | return set( 14 | marker[2].value 15 | for marker in markers 16 | if isinstance(marker, tuple) and marker[0].value == 'extra' 17 | ) 18 | 19 | 20 | def extras_from_deps(deps): 21 | """ 22 | >>> extras_from_deps(['requests']) 23 | set() 24 | >>> extras_from_deps(['pytest; extra == "test"']) 25 | {'test'} 26 | >>> sorted(extras_from_deps([ 27 | ... 'requests', 28 | ... 'pytest; extra == "test"', 29 | ... 'pytest-cov; extra == "test"', 30 | ... 'sphinx; extra=="doc"'])) 31 | ['doc', 'test'] 32 | """ 33 | return functools.reduce(operator.or_, map(extras_from_dep, deps), set()) 34 | -------------------------------------------------------------------------------- /setuptools/_distutils/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import sys 3 | 4 | __version__, _, _ = sys.version.partition(' ') 5 | 6 | 7 | try: 8 | # Allow Debian and pkgsrc (only) to customize system 9 | # behavior. Ref pypa/distutils#2 and pypa/distutils#16. 10 | # This hook is deprecated and no other environments 11 | # should use it. 12 | importlib.import_module('_distutils_system_mod') 13 | except ImportError: 14 | pass 15 | -------------------------------------------------------------------------------- /setuptools/_distutils/_log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | log = logging.getLogger() 4 | -------------------------------------------------------------------------------- /setuptools/_distutils/_macos_compat.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import sys 3 | 4 | 5 | def bypass_compiler_fixup(cmd, args): 6 | return cmd 7 | 8 | 9 | if sys.platform == 'darwin': 10 | compiler_fixup = importlib.import_module('_osx_support').compiler_fixup 11 | else: 12 | compiler_fixup = bypass_compiler_fixup 13 | -------------------------------------------------------------------------------- /setuptools/_distutils/_msvccompiler.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from .compilers.C import msvc 4 | 5 | __all__ = ["MSVCCompiler"] 6 | 7 | MSVCCompiler = msvc.Compiler 8 | 9 | 10 | def __getattr__(name): 11 | if name == '_get_vc_env': 12 | warnings.warn( 13 | "_get_vc_env is private; find an alternative (pypa/distutils#340)" 14 | ) 15 | return msvc._get_vc_env 16 | raise AttributeError(name) 17 | -------------------------------------------------------------------------------- /setuptools/_distutils/ccompiler.py: -------------------------------------------------------------------------------- 1 | from .compat.numpy import ( # noqa: F401 2 | _default_compilers, 3 | compiler_class, 4 | ) 5 | from .compilers.C import base 6 | from .compilers.C.base import ( 7 | gen_lib_options, 8 | gen_preprocess_options, 9 | get_default_compiler, 10 | new_compiler, 11 | show_compilers, 12 | ) 13 | from .compilers.C.errors import CompileError, LinkError 14 | 15 | __all__ = [ 16 | 'CompileError', 17 | 'LinkError', 18 | 'gen_lib_options', 19 | 'gen_preprocess_options', 20 | 'get_default_compiler', 21 | 'new_compiler', 22 | 'show_compilers', 23 | ] 24 | 25 | 26 | CCompiler = base.Compiler 27 | -------------------------------------------------------------------------------- /setuptools/_distutils/command/__init__.py: -------------------------------------------------------------------------------- 1 | """distutils.command 2 | 3 | Package containing implementation of all the standard Distutils 4 | commands.""" 5 | 6 | __all__ = [ 7 | 'build', 8 | 'build_py', 9 | 'build_ext', 10 | 'build_clib', 11 | 'build_scripts', 12 | 'clean', 13 | 'install', 14 | 'install_lib', 15 | 'install_headers', 16 | 'install_scripts', 17 | 'install_data', 18 | 'sdist', 19 | 'bdist', 20 | 'bdist_dumb', 21 | 'bdist_rpm', 22 | 'check', 23 | ] 24 | -------------------------------------------------------------------------------- /setuptools/_distutils/command/_framework_compat.py: -------------------------------------------------------------------------------- 1 | """ 2 | Backward compatibility for homebrew builds on macOS. 3 | """ 4 | 5 | import functools 6 | import os 7 | import subprocess 8 | import sys 9 | import sysconfig 10 | 11 | 12 | @functools.lru_cache 13 | def enabled(): 14 | """ 15 | Only enabled for Python 3.9 framework homebrew builds 16 | except ensurepip and venv. 17 | """ 18 | PY39 = (3, 9) < sys.version_info < (3, 10) 19 | framework = sys.platform == 'darwin' and sys._framework 20 | homebrew = "Cellar" in sysconfig.get_config_var('projectbase') 21 | venv = sys.prefix != sys.base_prefix 22 | ensurepip = os.environ.get("ENSUREPIP_OPTIONS") 23 | return PY39 and framework and homebrew and not venv and not ensurepip 24 | 25 | 26 | schemes = dict( 27 | osx_framework_library=dict( 28 | stdlib='{installed_base}/{platlibdir}/python{py_version_short}', 29 | platstdlib='{platbase}/{platlibdir}/python{py_version_short}', 30 | purelib='{homebrew_prefix}/lib/python{py_version_short}/site-packages', 31 | platlib='{homebrew_prefix}/{platlibdir}/python{py_version_short}/site-packages', 32 | include='{installed_base}/include/python{py_version_short}{abiflags}', 33 | platinclude='{installed_platbase}/include/python{py_version_short}{abiflags}', 34 | scripts='{homebrew_prefix}/bin', 35 | data='{homebrew_prefix}', 36 | ) 37 | ) 38 | 39 | 40 | @functools.lru_cache 41 | def vars(): 42 | if not enabled(): 43 | return {} 44 | homebrew_prefix = subprocess.check_output(['brew', '--prefix'], text=True).strip() 45 | return locals() 46 | 47 | 48 | def scheme(name): 49 | """ 50 | Override the selected scheme for posix_prefix. 51 | """ 52 | if not enabled() or not name.endswith('_prefix'): 53 | return name 54 | return 'osx_framework_library' 55 | -------------------------------------------------------------------------------- /setuptools/_distutils/command/command_template: -------------------------------------------------------------------------------- 1 | """distutils.command.x 2 | 3 | Implements the Distutils 'x' command. 4 | """ 5 | 6 | # created 2000/mm/dd, John Doe 7 | 8 | __revision__ = "$Id$" 9 | 10 | from distutils.core import Command 11 | from typing import ClassVar 12 | 13 | 14 | class x(Command): 15 | # Brief (40-50 characters) description of the command 16 | description = "" 17 | 18 | # List of option tuples: long name, short name (None if no short 19 | # name), and help string. 20 | user_options: ClassVar[list[tuple[str, str, str]]] = [ 21 | ('', '', ""), 22 | ] 23 | 24 | def initialize_options(self): 25 | self. = None 26 | self. = None 27 | self. = None 28 | 29 | def finalize_options(self): 30 | if self.x is None: 31 | self.x = 32 | 33 | def run(self): 34 | -------------------------------------------------------------------------------- /setuptools/_distutils/command/install_headers.py: -------------------------------------------------------------------------------- 1 | """distutils.command.install_headers 2 | 3 | Implements the Distutils 'install_headers' command, to install C/C++ header 4 | files to the Python include directory.""" 5 | 6 | from typing import ClassVar 7 | 8 | from ..core import Command 9 | 10 | 11 | # XXX force is never used 12 | class install_headers(Command): 13 | description = "install C/C++ header files" 14 | 15 | user_options: ClassVar[list[tuple[str, str, str]]] = [ 16 | ('install-dir=', 'd', "directory to install header files to"), 17 | ('force', 'f', "force installation (overwrite existing files)"), 18 | ] 19 | 20 | boolean_options: ClassVar[list[str]] = ['force'] 21 | 22 | def initialize_options(self): 23 | self.install_dir = None 24 | self.force = False 25 | self.outfiles = [] 26 | 27 | def finalize_options(self): 28 | self.set_undefined_options( 29 | 'install', ('install_headers', 'install_dir'), ('force', 'force') 30 | ) 31 | 32 | def run(self): 33 | headers = self.distribution.headers 34 | if not headers: 35 | return 36 | 37 | self.mkpath(self.install_dir) 38 | for header in headers: 39 | (out, _) = self.copy_file(header, self.install_dir) 40 | self.outfiles.append(out) 41 | 42 | def get_inputs(self): 43 | return self.distribution.headers or [] 44 | 45 | def get_outputs(self): 46 | return self.outfiles 47 | -------------------------------------------------------------------------------- /setuptools/_distutils/command/install_scripts.py: -------------------------------------------------------------------------------- 1 | """distutils.command.install_scripts 2 | 3 | Implements the Distutils 'install_scripts' command, for installing 4 | Python scripts.""" 5 | 6 | # contributed by Bastian Kleineidam 7 | 8 | import os 9 | from distutils._log import log 10 | from stat import ST_MODE 11 | from typing import ClassVar 12 | 13 | from ..core import Command 14 | 15 | 16 | class install_scripts(Command): 17 | description = "install scripts (Python or otherwise)" 18 | 19 | user_options = [ 20 | ('install-dir=', 'd', "directory to install scripts to"), 21 | ('build-dir=', 'b', "build directory (where to install from)"), 22 | ('force', 'f', "force installation (overwrite existing files)"), 23 | ('skip-build', None, "skip the build steps"), 24 | ] 25 | 26 | boolean_options: ClassVar[list[str]] = ['force', 'skip-build'] 27 | 28 | def initialize_options(self): 29 | self.install_dir = None 30 | self.force = False 31 | self.build_dir = None 32 | self.skip_build = None 33 | 34 | def finalize_options(self) -> None: 35 | self.set_undefined_options('build', ('build_scripts', 'build_dir')) 36 | self.set_undefined_options( 37 | 'install', 38 | ('install_scripts', 'install_dir'), 39 | ('force', 'force'), 40 | ('skip_build', 'skip_build'), 41 | ) 42 | 43 | def run(self) -> None: 44 | if not self.skip_build: 45 | self.run_command('build_scripts') 46 | self.outfiles = self.copy_tree(self.build_dir, self.install_dir) 47 | if os.name == 'posix': 48 | # Set the executable bits (owner, group, and world) on 49 | # all the scripts we just installed. 50 | for file in self.get_outputs(): 51 | if self.dry_run: 52 | log.info("changing mode of %s", file) 53 | else: 54 | mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 55 | log.info("changing mode of %s to %o", file, mode) 56 | os.chmod(file, mode) 57 | 58 | def get_inputs(self): 59 | return self.distribution.scripts or [] 60 | 61 | def get_outputs(self): 62 | return self.outfiles or [] 63 | -------------------------------------------------------------------------------- /setuptools/_distutils/compat/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Iterable 4 | from typing import TypeVar 5 | 6 | _IterableT = TypeVar("_IterableT", bound="Iterable[str]") 7 | 8 | 9 | def consolidate_linker_args(args: _IterableT) -> _IterableT | str: 10 | """ 11 | Ensure the return value is a string for backward compatibility. 12 | 13 | Retain until at least 2025-04-31. See pypa/distutils#246 14 | """ 15 | 16 | if not all(arg.startswith('-Wl,') for arg in args): 17 | return args 18 | return '-Wl,' + ','.join(arg.removeprefix('-Wl,') for arg in args) 19 | -------------------------------------------------------------------------------- /setuptools/_distutils/compat/numpy.py: -------------------------------------------------------------------------------- 1 | # required for older numpy versions on Pythons prior to 3.12; see pypa/setuptools#4876 2 | from ..compilers.C.base import _default_compilers, compiler_class # noqa: F401 3 | -------------------------------------------------------------------------------- /setuptools/_distutils/compat/py39.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import itertools 3 | import platform 4 | import sys 5 | 6 | 7 | def add_ext_suffix_39(vars): 8 | """ 9 | Ensure vars contains 'EXT_SUFFIX'. pypa/distutils#130 10 | """ 11 | import _imp 12 | 13 | ext_suffix = _imp.extension_suffixes()[0] 14 | vars.update( 15 | EXT_SUFFIX=ext_suffix, 16 | # sysconfig sets SO to match EXT_SUFFIX, so maintain 17 | # that expectation. 18 | # https://github.com/python/cpython/blob/785cc6770588de087d09e89a69110af2542be208/Lib/sysconfig.py#L671-L673 19 | SO=ext_suffix, 20 | ) 21 | 22 | 23 | needs_ext_suffix = sys.version_info < (3, 10) and platform.system() == 'Windows' 24 | add_ext_suffix = add_ext_suffix_39 if needs_ext_suffix else lambda vars: None 25 | 26 | 27 | # from more_itertools 28 | class UnequalIterablesError(ValueError): 29 | def __init__(self, details=None): 30 | msg = 'Iterables have different lengths' 31 | if details is not None: 32 | msg += (': index 0 has length {}; index {} has length {}').format(*details) 33 | 34 | super().__init__(msg) 35 | 36 | 37 | # from more_itertools 38 | def _zip_equal_generator(iterables): 39 | _marker = object() 40 | for combo in itertools.zip_longest(*iterables, fillvalue=_marker): 41 | for val in combo: 42 | if val is _marker: 43 | raise UnequalIterablesError() 44 | yield combo 45 | 46 | 47 | # from more_itertools 48 | def _zip_equal(*iterables): 49 | # Check whether the iterables are all the same size. 50 | try: 51 | first_size = len(iterables[0]) 52 | for i, it in enumerate(iterables[1:], 1): 53 | size = len(it) 54 | if size != first_size: 55 | raise UnequalIterablesError(details=(first_size, i, size)) 56 | # All sizes are equal, we can use the built-in zip. 57 | return zip(*iterables) 58 | # If any one of the iterables didn't have a length, start reading 59 | # them until one runs out. 60 | except TypeError: 61 | return _zip_equal_generator(iterables) 62 | 63 | 64 | zip_strict = ( 65 | _zip_equal if sys.version_info < (3, 10) else functools.partial(zip, strict=True) 66 | ) 67 | -------------------------------------------------------------------------------- /setuptools/_distutils/compilers/C/errors.py: -------------------------------------------------------------------------------- 1 | class Error(Exception): 2 | """Some compile/link operation failed.""" 3 | 4 | 5 | class PreprocessError(Error): 6 | """Failure to preprocess one or more C/C++ files.""" 7 | 8 | 9 | class CompileError(Error): 10 | """Failure to compile one or more C/C++ source files.""" 11 | 12 | 13 | class LibError(Error): 14 | """Failure to create a static library from one or more C/C++ object 15 | files.""" 16 | 17 | 18 | class LinkError(Error): 19 | """Failure to link one or more C/C++ object files into an executable 20 | or shared library file.""" 21 | 22 | 23 | class UnknownFileType(Error): 24 | """Attempt to process an unknown file type.""" 25 | -------------------------------------------------------------------------------- /setuptools/_distutils/compilers/C/tests/test_mingw.py: -------------------------------------------------------------------------------- 1 | from distutils import sysconfig 2 | from distutils.errors import DistutilsPlatformError 3 | from distutils.util import is_mingw, split_quoted 4 | 5 | import pytest 6 | 7 | from .. import cygwin, errors 8 | 9 | 10 | class TestMinGW32Compiler: 11 | @pytest.mark.skipif(not is_mingw(), reason='not on mingw') 12 | def test_compiler_type(self): 13 | compiler = cygwin.MinGW32Compiler() 14 | assert compiler.compiler_type == 'mingw32' 15 | 16 | @pytest.mark.skipif(not is_mingw(), reason='not on mingw') 17 | def test_set_executables(self, monkeypatch): 18 | monkeypatch.setenv('CC', 'cc') 19 | monkeypatch.setenv('CXX', 'c++') 20 | 21 | compiler = cygwin.MinGW32Compiler() 22 | 23 | assert compiler.compiler == split_quoted('cc -O -Wall') 24 | assert compiler.compiler_so == split_quoted('cc -shared -O -Wall') 25 | assert compiler.compiler_cxx == split_quoted('c++ -O -Wall') 26 | assert compiler.linker_exe == split_quoted('cc') 27 | assert compiler.linker_so == split_quoted('cc -shared') 28 | 29 | @pytest.mark.skipif(not is_mingw(), reason='not on mingw') 30 | def test_runtime_library_dir_option(self): 31 | compiler = cygwin.MinGW32Compiler() 32 | with pytest.raises(DistutilsPlatformError): 33 | compiler.runtime_library_dir_option('/usr/lib') 34 | 35 | @pytest.mark.skipif(not is_mingw(), reason='not on mingw') 36 | def test_cygwincc_error(self, monkeypatch): 37 | monkeypatch.setattr(cygwin, 'is_cygwincc', lambda _: True) 38 | 39 | with pytest.raises(errors.Error): 40 | cygwin.MinGW32Compiler() 41 | 42 | @pytest.mark.skipif('sys.platform == "cygwin"') 43 | def test_customize_compiler_with_msvc_python(self): 44 | # In case we have an MSVC Python build, but still want to use 45 | # MinGW32Compiler, then customize_compiler() shouldn't fail at least. 46 | # https://github.com/pypa/setuptools/issues/4456 47 | compiler = cygwin.MinGW32Compiler() 48 | sysconfig.customize_compiler(compiler) 49 | -------------------------------------------------------------------------------- /setuptools/_distutils/cygwinccompiler.py: -------------------------------------------------------------------------------- 1 | from .compilers.C import cygwin 2 | from .compilers.C.cygwin import ( 3 | CONFIG_H_NOTOK, 4 | CONFIG_H_OK, 5 | CONFIG_H_UNCERTAIN, 6 | check_config_h, 7 | get_msvcr, 8 | is_cygwincc, 9 | ) 10 | 11 | __all__ = [ 12 | 'CONFIG_H_NOTOK', 13 | 'CONFIG_H_OK', 14 | 'CONFIG_H_UNCERTAIN', 15 | 'CygwinCCompiler', 16 | 'Mingw32CCompiler', 17 | 'check_config_h', 18 | 'get_msvcr', 19 | 'is_cygwincc', 20 | ] 21 | 22 | 23 | CygwinCCompiler = cygwin.Compiler 24 | Mingw32CCompiler = cygwin.MinGW32Compiler 25 | 26 | 27 | get_versions = None 28 | """ 29 | A stand-in for the previous get_versions() function to prevent failures 30 | when monkeypatched. See pypa/setuptools#2969. 31 | """ 32 | -------------------------------------------------------------------------------- /setuptools/_distutils/debug.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # If DISTUTILS_DEBUG is anything other than the empty string, we run in 4 | # debug mode. 5 | DEBUG = os.environ.get('DISTUTILS_DEBUG') 6 | -------------------------------------------------------------------------------- /setuptools/_distutils/dep_util.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from . import _modified 4 | 5 | 6 | def __getattr__(name): 7 | if name not in ['newer', 'newer_group', 'newer_pairwise']: 8 | raise AttributeError(name) 9 | warnings.warn( 10 | "dep_util is Deprecated. Use functions from setuptools instead.", 11 | DeprecationWarning, 12 | stacklevel=2, 13 | ) 14 | return getattr(_modified, name) 15 | -------------------------------------------------------------------------------- /setuptools/_distutils/log.py: -------------------------------------------------------------------------------- 1 | """ 2 | A simple log mechanism styled after PEP 282. 3 | 4 | Retained for compatibility and should not be used. 5 | """ 6 | 7 | import logging 8 | import warnings 9 | 10 | from ._log import log as _global_log 11 | 12 | DEBUG = logging.DEBUG 13 | INFO = logging.INFO 14 | WARN = logging.WARN 15 | ERROR = logging.ERROR 16 | FATAL = logging.FATAL 17 | 18 | log = _global_log.log 19 | debug = _global_log.debug 20 | info = _global_log.info 21 | warn = _global_log.warning 22 | error = _global_log.error 23 | fatal = _global_log.fatal 24 | 25 | 26 | def set_threshold(level): 27 | orig = _global_log.level 28 | _global_log.setLevel(level) 29 | return orig 30 | 31 | 32 | def set_verbosity(v): 33 | if v <= 0: 34 | set_threshold(logging.WARN) 35 | elif v == 1: 36 | set_threshold(logging.INFO) 37 | elif v >= 2: 38 | set_threshold(logging.DEBUG) 39 | 40 | 41 | class Log(logging.Logger): 42 | """distutils.log.Log is deprecated, please use an alternative from `logging`.""" 43 | 44 | def __init__(self, threshold=WARN): 45 | warnings.warn(Log.__doc__) # avoid DeprecationWarning to ensure warn is shown 46 | super().__init__(__name__, level=threshold) 47 | 48 | @property 49 | def threshold(self): 50 | return self.level 51 | 52 | @threshold.setter 53 | def threshold(self, level): 54 | self.setLevel(level) 55 | 56 | warn = logging.Logger.warning 57 | -------------------------------------------------------------------------------- /setuptools/_distutils/ruff.toml: -------------------------------------------------------------------------------- 1 | exclude = ["*"] 2 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test suite for distutils. 3 | 4 | Tests for the command classes in the distutils.command package are 5 | included in distutils.tests as well, instead of using a separate 6 | distutils.command.tests package, since command identification is done 7 | by import rather than matching pre-defined names. 8 | """ 9 | 10 | import shutil 11 | from collections.abc import Sequence 12 | 13 | 14 | def missing_compiler_executable(cmd_names: Sequence[str] = []): # pragma: no cover 15 | """Check if the compiler components used to build the interpreter exist. 16 | 17 | Check for the existence of the compiler executables whose names are listed 18 | in 'cmd_names' or all the compiler executables when 'cmd_names' is empty 19 | and return the first missing executable or None when none is found 20 | missing. 21 | 22 | """ 23 | from distutils import ccompiler, errors, sysconfig 24 | 25 | compiler = ccompiler.new_compiler() 26 | sysconfig.customize_compiler(compiler) 27 | if compiler.compiler_type == "msvc": 28 | # MSVC has no executables, so check whether initialization succeeds 29 | try: 30 | compiler.initialize() 31 | except errors.DistutilsPlatformError: 32 | return "msvc" 33 | for name in compiler.executables: 34 | if cmd_names and name not in cmd_names: 35 | continue 36 | cmd = getattr(compiler, name) 37 | if cmd_names: 38 | assert cmd is not None, f"the '{name}' executable is not configured" 39 | elif not cmd: 40 | continue 41 | if shutil.which(cmd[0]) is None: 42 | return cmd[0] 43 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_distutils/tests/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/_distutils/tests/compat/py39.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if sys.version_info >= (3, 10): 4 | from test.support.import_helper import ( 5 | CleanImport as CleanImport, 6 | ) 7 | from test.support.import_helper import ( 8 | DirsOnSysPath as DirsOnSysPath, 9 | ) 10 | from test.support.os_helper import ( 11 | EnvironmentVarGuard as EnvironmentVarGuard, 12 | ) 13 | from test.support.os_helper import ( 14 | rmtree as rmtree, 15 | ) 16 | from test.support.os_helper import ( 17 | skip_unless_symlink as skip_unless_symlink, 18 | ) 19 | from test.support.os_helper import ( 20 | unlink as unlink, 21 | ) 22 | else: 23 | from test.support import ( 24 | CleanImport as CleanImport, 25 | ) 26 | from test.support import ( 27 | DirsOnSysPath as DirsOnSysPath, 28 | ) 29 | from test.support import ( 30 | EnvironmentVarGuard as EnvironmentVarGuard, 31 | ) 32 | from test.support import ( 33 | rmtree as rmtree, 34 | ) 35 | from test.support import ( 36 | skip_unless_symlink as skip_unless_symlink, 37 | ) 38 | from test.support import ( 39 | unlink as unlink, 40 | ) 41 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/includetest.rst: -------------------------------------------------------------------------------- 1 | This should be included. 2 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_bdist.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.command.bdist.""" 2 | 3 | from distutils.command.bdist import bdist 4 | from distutils.tests import support 5 | 6 | 7 | class TestBuild(support.TempdirManager): 8 | def test_formats(self): 9 | # let's create a command and make sure 10 | # we can set the format 11 | dist = self.create_dist()[1] 12 | cmd = bdist(dist) 13 | cmd.formats = ['gztar'] 14 | cmd.ensure_finalized() 15 | assert cmd.formats == ['gztar'] 16 | 17 | # what formats does bdist offer? 18 | formats = [ 19 | 'bztar', 20 | 'gztar', 21 | 'rpm', 22 | 'tar', 23 | 'xztar', 24 | 'zip', 25 | 'ztar', 26 | ] 27 | found = sorted(cmd.format_commands) 28 | assert found == formats 29 | 30 | def test_skip_build(self): 31 | # bug #10946: bdist --skip-build should trickle down to subcommands 32 | dist = self.create_dist()[1] 33 | cmd = bdist(dist) 34 | cmd.skip_build = True 35 | cmd.ensure_finalized() 36 | dist.command_obj['bdist'] = cmd 37 | 38 | names = [ 39 | 'bdist_dumb', 40 | ] # bdist_rpm does not support --skip-build 41 | 42 | for name in names: 43 | subcmd = cmd.get_finalized_command(name) 44 | if getattr(subcmd, '_unsupported', False): 45 | # command is not supported on this build 46 | continue 47 | assert subcmd.skip_build, f'{name} should take --skip-build from bdist' 48 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_build.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.command.build.""" 2 | 3 | import os 4 | import sys 5 | from distutils.command.build import build 6 | from distutils.tests import support 7 | from sysconfig import get_config_var, get_platform 8 | 9 | 10 | class TestBuild(support.TempdirManager): 11 | def test_finalize_options(self): 12 | pkg_dir, dist = self.create_dist() 13 | cmd = build(dist) 14 | cmd.finalize_options() 15 | 16 | # if not specified, plat_name gets the current platform 17 | assert cmd.plat_name == get_platform() 18 | 19 | # build_purelib is build + lib 20 | wanted = os.path.join(cmd.build_base, 'lib') 21 | assert cmd.build_purelib == wanted 22 | 23 | # build_platlib is 'build/lib.platform-cache_tag[-pydebug]' 24 | # examples: 25 | # build/lib.macosx-10.3-i386-cpython39 26 | plat_spec = f'.{cmd.plat_name}-{sys.implementation.cache_tag}' 27 | if get_config_var('Py_GIL_DISABLED'): 28 | plat_spec += 't' 29 | if hasattr(sys, 'gettotalrefcount'): 30 | assert cmd.build_platlib.endswith('-pydebug') 31 | plat_spec += '-pydebug' 32 | wanted = os.path.join(cmd.build_base, 'lib' + plat_spec) 33 | assert cmd.build_platlib == wanted 34 | 35 | # by default, build_lib = build_purelib 36 | assert cmd.build_lib == cmd.build_purelib 37 | 38 | # build_temp is build/temp. 39 | wanted = os.path.join(cmd.build_base, 'temp' + plat_spec) 40 | assert cmd.build_temp == wanted 41 | 42 | # build_scripts is build/scripts-x.x 43 | wanted = os.path.join( 44 | cmd.build_base, f'scripts-{sys.version_info.major}.{sys.version_info.minor}' 45 | ) 46 | assert cmd.build_scripts == wanted 47 | 48 | # executable is os.path.normpath(sys.executable) 49 | assert cmd.executable == os.path.normpath(sys.executable) 50 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_clean.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.command.clean.""" 2 | 3 | import os 4 | from distutils.command.clean import clean 5 | from distutils.tests import support 6 | 7 | 8 | class TestClean(support.TempdirManager): 9 | def test_simple_run(self): 10 | pkg_dir, dist = self.create_dist() 11 | cmd = clean(dist) 12 | 13 | # let's add some elements clean should remove 14 | dirs = [ 15 | (d, os.path.join(pkg_dir, d)) 16 | for d in ( 17 | 'build_temp', 18 | 'build_lib', 19 | 'bdist_base', 20 | 'build_scripts', 21 | 'build_base', 22 | ) 23 | ] 24 | 25 | for name, path in dirs: 26 | os.mkdir(path) 27 | setattr(cmd, name, path) 28 | if name == 'build_base': 29 | continue 30 | for f in ('one', 'two', 'three'): 31 | self.write_file(os.path.join(path, f)) 32 | 33 | # let's run the command 34 | cmd.all = 1 35 | cmd.ensure_finalized() 36 | cmd.run() 37 | 38 | # make sure the files where removed 39 | for _name, path in dirs: 40 | assert not os.path.exists(path), f'{path} was not removed' 41 | 42 | # let's run the command again (should spit warnings but succeed) 43 | cmd.all = 1 44 | cmd.ensure_finalized() 45 | cmd.run() 46 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_install_headers.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.command.install_headers.""" 2 | 3 | import os 4 | from distutils.command.install_headers import install_headers 5 | from distutils.tests import support 6 | 7 | import pytest 8 | 9 | 10 | @pytest.mark.usefixtures('save_env') 11 | class TestInstallHeaders( 12 | support.TempdirManager, 13 | ): 14 | def test_simple_run(self): 15 | # we have two headers 16 | header_list = self.mkdtemp() 17 | header1 = os.path.join(header_list, 'header1') 18 | header2 = os.path.join(header_list, 'header2') 19 | self.write_file(header1) 20 | self.write_file(header2) 21 | headers = [header1, header2] 22 | 23 | pkg_dir, dist = self.create_dist(headers=headers) 24 | cmd = install_headers(dist) 25 | assert cmd.get_inputs() == headers 26 | 27 | # let's run the command 28 | cmd.install_dir = os.path.join(pkg_dir, 'inst') 29 | cmd.ensure_finalized() 30 | cmd.run() 31 | 32 | # let's check the results 33 | assert len(cmd.get_outputs()) == 2 34 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_install_scripts.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.command.install_scripts.""" 2 | 3 | import os 4 | from distutils.command.install_scripts import install_scripts 5 | from distutils.core import Distribution 6 | from distutils.tests import support 7 | 8 | from . import test_build_scripts 9 | 10 | 11 | class TestInstallScripts(support.TempdirManager): 12 | def test_default_settings(self): 13 | dist = Distribution() 14 | dist.command_obj["build"] = support.DummyCommand(build_scripts="/foo/bar") 15 | dist.command_obj["install"] = support.DummyCommand( 16 | install_scripts="/splat/funk", 17 | force=True, 18 | skip_build=True, 19 | ) 20 | cmd = install_scripts(dist) 21 | assert not cmd.force 22 | assert not cmd.skip_build 23 | assert cmd.build_dir is None 24 | assert cmd.install_dir is None 25 | 26 | cmd.finalize_options() 27 | 28 | assert cmd.force 29 | assert cmd.skip_build 30 | assert cmd.build_dir == "/foo/bar" 31 | assert cmd.install_dir == "/splat/funk" 32 | 33 | def test_installation(self): 34 | source = self.mkdtemp() 35 | 36 | expected = test_build_scripts.TestBuildScripts.write_sample_scripts(source) 37 | 38 | target = self.mkdtemp() 39 | dist = Distribution() 40 | dist.command_obj["build"] = support.DummyCommand(build_scripts=source) 41 | dist.command_obj["install"] = support.DummyCommand( 42 | install_scripts=target, 43 | force=True, 44 | skip_build=True, 45 | ) 46 | cmd = install_scripts(dist) 47 | cmd.finalize_options() 48 | cmd.run() 49 | 50 | installed = os.listdir(target) 51 | for name in expected: 52 | assert name in installed 53 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_log.py: -------------------------------------------------------------------------------- 1 | """Tests for distutils.log""" 2 | 3 | import logging 4 | from distutils._log import log 5 | 6 | 7 | class TestLog: 8 | def test_non_ascii(self, caplog): 9 | caplog.set_level(logging.DEBUG) 10 | log.debug('Dεbug\tMėssãge') 11 | log.fatal('Fαtal\tÈrrōr') 12 | assert caplog.messages == ['Dεbug\tMėssãge', 'Fαtal\tÈrrōr'] 13 | -------------------------------------------------------------------------------- /setuptools/_distutils/tests/test_versionpredicate.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_distutils/tests/test_versionpredicate.py -------------------------------------------------------------------------------- /setuptools/_distutils/tests/unix_compat.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | try: 4 | import grp 5 | import pwd 6 | except ImportError: 7 | grp = pwd = None 8 | 9 | import pytest 10 | 11 | UNIX_ID_SUPPORT = grp and pwd 12 | UID_0_SUPPORT = UNIX_ID_SUPPORT and sys.platform != "cygwin" 13 | 14 | require_unix_id = pytest.mark.skipif( 15 | not UNIX_ID_SUPPORT, reason="Requires grp and pwd support" 16 | ) 17 | require_uid_0 = pytest.mark.skipif(not UID_0_SUPPORT, reason="Requires UID 0 support") 18 | -------------------------------------------------------------------------------- /setuptools/_distutils/unixccompiler.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | from .compilers.C import unix 4 | 5 | UnixCCompiler = unix.Compiler 6 | 7 | # ensure import of unixccompiler implies ccompiler imported 8 | # (pypa/setuptools#4871) 9 | importlib.import_module('distutils.ccompiler') 10 | -------------------------------------------------------------------------------- /setuptools/_distutils/zosccompiler.py: -------------------------------------------------------------------------------- 1 | from .compilers.C import zos 2 | 3 | zOSCCompiler = zos.Compiler 4 | -------------------------------------------------------------------------------- /setuptools/_importlib.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if sys.version_info < (3, 10): 4 | import importlib_metadata as metadata # pragma: no cover 5 | else: 6 | import importlib.metadata as metadata # noqa: F401 7 | 8 | 9 | import importlib.resources as resources # noqa: F401 10 | -------------------------------------------------------------------------------- /setuptools/_itertools.py: -------------------------------------------------------------------------------- 1 | from more_itertools import consume # noqa: F401 2 | 3 | 4 | # copied from jaraco.itertools 6.1 5 | def ensure_unique(iterable, key=lambda x: x): 6 | """ 7 | Wrap an iterable to raise a ValueError if non-unique values are encountered. 8 | 9 | >>> list(ensure_unique('abc')) 10 | ['a', 'b', 'c'] 11 | >>> consume(ensure_unique('abca')) 12 | Traceback (most recent call last): 13 | ... 14 | ValueError: Duplicate element 'a' encountered. 15 | """ 16 | seen = set() 17 | seen_add = seen.add 18 | for element in iterable: 19 | k = key(element) 20 | if k in seen: 21 | raise ValueError(f"Duplicate element {element!r} encountered.") 22 | seen_add(k) 23 | yield element 24 | -------------------------------------------------------------------------------- /setuptools/_reqs.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Iterable, Iterator 4 | from functools import lru_cache 5 | from typing import TYPE_CHECKING, Callable, TypeVar, Union, overload 6 | 7 | import jaraco.text as text 8 | from packaging.requirements import Requirement 9 | 10 | if TYPE_CHECKING: 11 | from typing_extensions import TypeAlias 12 | 13 | _T = TypeVar("_T") 14 | _StrOrIter: TypeAlias = Union[str, Iterable[str]] 15 | 16 | 17 | parse_req: Callable[[str], Requirement] = lru_cache()(Requirement) 18 | # Setuptools parses the same requirement many times 19 | # (e.g. first for validation than for normalisation), 20 | # so it might be worth to cache. 21 | 22 | 23 | def parse_strings(strs: _StrOrIter) -> Iterator[str]: 24 | """ 25 | Yield requirement strings for each specification in `strs`. 26 | 27 | `strs` must be a string, or a (possibly-nested) iterable thereof. 28 | """ 29 | return text.join_continuation(map(text.drop_comment, text.yield_lines(strs))) 30 | 31 | 32 | # These overloads are only needed because of a mypy false-positive, pyright gets it right 33 | # https://github.com/python/mypy/issues/3737 34 | @overload 35 | def parse(strs: _StrOrIter) -> Iterator[Requirement]: ... 36 | @overload 37 | def parse(strs: _StrOrIter, parser: Callable[[str], _T]) -> Iterator[_T]: ... 38 | def parse(strs: _StrOrIter, parser: Callable[[str], _T] = parse_req) -> Iterator[_T]: # type: ignore[assignment] 39 | """ 40 | Parse requirements. 41 | """ 42 | return map(parser, parse_strings(strs)) 43 | -------------------------------------------------------------------------------- /setuptools/_shutil.py: -------------------------------------------------------------------------------- 1 | """Convenience layer on top of stdlib's shutil and os""" 2 | 3 | import os 4 | import stat 5 | from typing import Callable, TypeVar 6 | 7 | from .compat import py311 8 | 9 | from distutils import log 10 | 11 | try: 12 | from os import chmod # pyright: ignore[reportAssignmentType] 13 | # Losing type-safety w/ pyright, but that's ok 14 | except ImportError: # pragma: no cover 15 | # Jython compatibility 16 | def chmod(*args: object, **kwargs: object) -> None: # type: ignore[misc] # Mypy reuses the imported definition anyway 17 | pass 18 | 19 | 20 | _T = TypeVar("_T") 21 | 22 | 23 | def attempt_chmod_verbose(path, mode): 24 | log.debug("changing mode of %s to %o", path, mode) 25 | try: 26 | chmod(path, mode) 27 | except OSError as e: # pragma: no cover 28 | log.debug("chmod failed: %s", e) 29 | 30 | 31 | # Must match shutil._OnExcCallback 32 | def _auto_chmod( 33 | func: Callable[..., _T], arg: str, exc: BaseException 34 | ) -> _T: # pragma: no cover 35 | """shutils onexc callback to automatically call chmod for certain functions.""" 36 | # Only retry for scenarios known to have an issue 37 | if func in [os.unlink, os.remove] and os.name == 'nt': 38 | attempt_chmod_verbose(arg, stat.S_IWRITE) 39 | return func(arg) 40 | raise exc 41 | 42 | 43 | def rmtree(path, ignore_errors=False, onexc=_auto_chmod): 44 | """ 45 | Similar to ``shutil.rmtree`` but automatically executes ``chmod`` 46 | for well know Windows failure scenarios. 47 | """ 48 | return py311.shutil_rmtree(path, ignore_errors, onexc) 49 | 50 | 51 | def rmdir(path, **opts): 52 | if os.path.isdir(path): 53 | rmtree(path, **opts) 54 | 55 | 56 | def current_umask(): 57 | tmp = os.umask(0o022) 58 | os.umask(tmp) 59 | return tmp 60 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand-2.2.2.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand-2.2.2.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | autocommand-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | autocommand-2.2.2.dist-info/LICENSE,sha256=reeNBJgtaZctREqOFKlPh6IzTdOFXMgDSOqOJAqg3y0,7634 3 | autocommand-2.2.2.dist-info/METADATA,sha256=OADZuR3O6iBlpu1ieTgzYul6w4uOVrk0P0BO5TGGAJk,15006 4 | autocommand-2.2.2.dist-info/RECORD,, 5 | autocommand-2.2.2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92 6 | autocommand-2.2.2.dist-info/top_level.txt,sha256=AzfhgKKS8EdAwWUTSF8mgeVQbXOY9kokHB6kSqwwqu0,12 7 | autocommand/__init__.py,sha256=zko5Rnvolvb-UXjCx_2ArPTGBWwUK5QY4LIQIKYR7As,1037 8 | autocommand/__pycache__/__init__.cpython-312.pyc,, 9 | autocommand/__pycache__/autoasync.cpython-312.pyc,, 10 | autocommand/__pycache__/autocommand.cpython-312.pyc,, 11 | autocommand/__pycache__/automain.cpython-312.pyc,, 12 | autocommand/__pycache__/autoparse.cpython-312.pyc,, 13 | autocommand/__pycache__/errors.cpython-312.pyc,, 14 | autocommand/autoasync.py,sha256=AMdyrxNS4pqWJfP_xuoOcImOHWD-qT7x06wmKN1Vp-U,5680 15 | autocommand/autocommand.py,sha256=hmkEmQ72HtL55gnURVjDOnsfYlGd5lLXbvT4KG496Qw,2505 16 | autocommand/automain.py,sha256=A2b8i754Mxc_DjU9WFr6vqYDWlhz0cn8miu8d8EsxV8,2076 17 | autocommand/autoparse.py,sha256=WVWmZJPcbzUKXP40raQw_0HD8qPJ2V9VG1eFFmmnFxw,11642 18 | autocommand/errors.py,sha256=7aa3roh9Herd6nIKpQHNWEslWE8oq7GiHYVUuRqORnA,886 19 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand-2.2.2.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.38.4) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand-2.2.2.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | autocommand 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2016 Nathan West 2 | # 3 | # This file is part of autocommand. 4 | # 5 | # autocommand is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # autocommand is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with autocommand. If not, see . 17 | 18 | # flake8 flags all these imports as unused, hence the NOQAs everywhere. 19 | 20 | from .automain import automain # NOQA 21 | from .autoparse import autoparse, smart_open # NOQA 22 | from .autocommand import autocommand # NOQA 23 | 24 | try: 25 | from .autoasync import autoasync # NOQA 26 | except ImportError: # pragma: no cover 27 | pass 28 | -------------------------------------------------------------------------------- /setuptools/_vendor/autocommand/errors.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2016 Nathan West 2 | # 3 | # This file is part of autocommand. 4 | # 5 | # autocommand is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # autocommand is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with autocommand. If not, see . 17 | 18 | 19 | class AutocommandError(Exception): 20 | '''Base class for autocommand exceptions''' 21 | pass 22 | 23 | # Individual modules will define errors specific to that module. 24 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/METADATA: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.1 2 | Name: backports.tarfile 3 | Version: 1.2.0 4 | Summary: Backport of CPython tarfile module 5 | Author-email: "Jason R. Coombs" 6 | Project-URL: Homepage, https://github.com/jaraco/backports.tarfile 7 | Classifier: Development Status :: 5 - Production/Stable 8 | Classifier: Intended Audience :: Developers 9 | Classifier: License :: OSI Approved :: MIT License 10 | Classifier: Programming Language :: Python :: 3 11 | Classifier: Programming Language :: Python :: 3 :: Only 12 | Requires-Python: >=3.8 13 | Description-Content-Type: text/x-rst 14 | License-File: LICENSE 15 | Provides-Extra: docs 16 | Requires-Dist: sphinx >=3.5 ; extra == 'docs' 17 | Requires-Dist: jaraco.packaging >=9.3 ; extra == 'docs' 18 | Requires-Dist: rst.linker >=1.9 ; extra == 'docs' 19 | Requires-Dist: furo ; extra == 'docs' 20 | Requires-Dist: sphinx-lint ; extra == 'docs' 21 | Provides-Extra: testing 22 | Requires-Dist: pytest !=8.1.*,>=6 ; extra == 'testing' 23 | Requires-Dist: pytest-checkdocs >=2.4 ; extra == 'testing' 24 | Requires-Dist: pytest-cov ; extra == 'testing' 25 | Requires-Dist: pytest-enabler >=2.2 ; extra == 'testing' 26 | Requires-Dist: jaraco.test ; extra == 'testing' 27 | Requires-Dist: pytest !=8.0.* ; extra == 'testing' 28 | 29 | .. image:: https://img.shields.io/pypi/v/backports.tarfile.svg 30 | :target: https://pypi.org/project/backports.tarfile 31 | 32 | .. image:: https://img.shields.io/pypi/pyversions/backports.tarfile.svg 33 | 34 | .. image:: https://github.com/jaraco/backports.tarfile/actions/workflows/main.yml/badge.svg 35 | :target: https://github.com/jaraco/backports.tarfile/actions?query=workflow%3A%22tests%22 36 | :alt: tests 37 | 38 | .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json 39 | :target: https://github.com/astral-sh/ruff 40 | :alt: Ruff 41 | 42 | .. .. image:: https://readthedocs.org/projects/backportstarfile/badge/?version=latest 43 | .. :target: https://backportstarfile.readthedocs.io/en/latest/?badge=latest 44 | 45 | .. image:: https://img.shields.io/badge/skeleton-2024-informational 46 | :target: https://blog.jaraco.com/skeleton 47 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | backports.tarfile-1.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | backports.tarfile-1.2.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | backports.tarfile-1.2.0.dist-info/METADATA,sha256=ghXFTq132dxaEIolxr3HK1mZqm9iyUmaRANZQSr6WlE,2020 4 | backports.tarfile-1.2.0.dist-info/RECORD,, 5 | backports.tarfile-1.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | backports.tarfile-1.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 7 | backports.tarfile-1.2.0.dist-info/top_level.txt,sha256=cGjaLMOoBR1FK0ApojtzWVmViTtJ7JGIK_HwXiEsvtU,10 8 | backports/__init__.py,sha256=iOEMwnlORWezdO8-2vxBIPSR37D7JGjluZ8f55vzxls,81 9 | backports/__pycache__/__init__.cpython-312.pyc,, 10 | backports/tarfile/__init__.py,sha256=Pwf2qUIfB0SolJPCKcx3vz3UEu_aids4g4sAfxy94qg,108491 11 | backports/tarfile/__main__.py,sha256=Yw2oGT1afrz2eBskzdPYL8ReB_3liApmhFkN2EbDmc4,59 12 | backports/tarfile/__pycache__/__init__.cpython-312.pyc,, 13 | backports/tarfile/__pycache__/__main__.cpython-312.pyc,, 14 | backports/tarfile/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 15 | backports/tarfile/compat/__pycache__/__init__.cpython-312.pyc,, 16 | backports/tarfile/compat/__pycache__/py38.cpython-312.pyc,, 17 | backports/tarfile/compat/py38.py,sha256=iYkyt_gvWjLzGUTJD9TuTfMMjOk-ersXZmRlvQYN2qE,568 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports.tarfile-1.2.0.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | backports 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports/__init__.py: -------------------------------------------------------------------------------- 1 | __path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports/tarfile/__main__.py: -------------------------------------------------------------------------------- 1 | from . import main 2 | 3 | 4 | if __name__ == '__main__': 5 | main() 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/backports/tarfile/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/backports/tarfile/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/backports/tarfile/compat/py38.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | if sys.version_info < (3, 9): 5 | 6 | def removesuffix(self, suffix): 7 | # suffix='' should not call self[:-0]. 8 | if suffix and self.endswith(suffix): 9 | return self[: -len(suffix)] 10 | else: 11 | return self[:] 12 | 13 | def removeprefix(self, prefix): 14 | if self.startswith(prefix): 15 | return self[len(prefix) :] 16 | else: 17 | return self[:] 18 | else: 19 | 20 | def removesuffix(self, suffix): 21 | return self.removesuffix(suffix) 22 | 23 | def removeprefix(self, prefix): 24 | return self.removeprefix(prefix) 25 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata-8.0.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata-8.0.0.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata-8.0.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: setuptools (70.1.1) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata-8.0.0.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | importlib_metadata 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/_collections.py: -------------------------------------------------------------------------------- 1 | import collections 2 | 3 | 4 | # from jaraco.collections 3.3 5 | class FreezableDefaultDict(collections.defaultdict): 6 | """ 7 | Often it is desirable to prevent the mutation of 8 | a default dict after its initial construction, such 9 | as to prevent mutation during iteration. 10 | 11 | >>> dd = FreezableDefaultDict(list) 12 | >>> dd[0].append('1') 13 | >>> dd.freeze() 14 | >>> dd[1] 15 | [] 16 | >>> len(dd) 17 | 1 18 | """ 19 | 20 | def __missing__(self, key): 21 | return getattr(self, '_frozen', super().__missing__)(key) 22 | 23 | def freeze(self): 24 | self._frozen = lambda key: self.default_factory() 25 | 26 | 27 | class Pair(collections.namedtuple('Pair', 'name value')): 28 | @classmethod 29 | def parse(cls, text): 30 | return cls(*map(str.strip, text.split("=", 1))) 31 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/_compat.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import platform 3 | 4 | 5 | __all__ = ['install', 'NullFinder'] 6 | 7 | 8 | def install(cls): 9 | """ 10 | Class decorator for installation on sys.meta_path. 11 | 12 | Adds the backport DistributionFinder to sys.meta_path and 13 | attempts to disable the finder functionality of the stdlib 14 | DistributionFinder. 15 | """ 16 | sys.meta_path.append(cls()) 17 | disable_stdlib_finder() 18 | return cls 19 | 20 | 21 | def disable_stdlib_finder(): 22 | """ 23 | Give the backport primacy for discovering path-based distributions 24 | by monkey-patching the stdlib O_O. 25 | 26 | See #91 for more background for rationale on this sketchy 27 | behavior. 28 | """ 29 | 30 | def matches(finder): 31 | return getattr( 32 | finder, '__module__', None 33 | ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions') 34 | 35 | for finder in filter(matches, sys.meta_path): # pragma: nocover 36 | del finder.find_distributions 37 | 38 | 39 | class NullFinder: 40 | """ 41 | A "Finder" (aka "MetaPathFinder") that never finds any modules, 42 | but may find distributions. 43 | """ 44 | 45 | @staticmethod 46 | def find_spec(*args, **kwargs): 47 | return None 48 | 49 | 50 | def pypy_partial(val): 51 | """ 52 | Adjust for variable stacklevel on partial under PyPy. 53 | 54 | Workaround for #327. 55 | """ 56 | is_pypy = platform.python_implementation() == 'PyPy' 57 | return val + is_pypy 58 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/_meta.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | from typing import Protocol 5 | from typing import Any, Dict, Iterator, List, Optional, TypeVar, Union, overload 6 | 7 | 8 | _T = TypeVar("_T") 9 | 10 | 11 | class PackageMetadata(Protocol): 12 | def __len__(self) -> int: ... # pragma: no cover 13 | 14 | def __contains__(self, item: str) -> bool: ... # pragma: no cover 15 | 16 | def __getitem__(self, key: str) -> str: ... # pragma: no cover 17 | 18 | def __iter__(self) -> Iterator[str]: ... # pragma: no cover 19 | 20 | @overload 21 | def get( 22 | self, name: str, failobj: None = None 23 | ) -> Optional[str]: ... # pragma: no cover 24 | 25 | @overload 26 | def get(self, name: str, failobj: _T) -> Union[str, _T]: ... # pragma: no cover 27 | 28 | # overload per python/importlib_metadata#435 29 | @overload 30 | def get_all( 31 | self, name: str, failobj: None = None 32 | ) -> Optional[List[Any]]: ... # pragma: no cover 33 | 34 | @overload 35 | def get_all(self, name: str, failobj: _T) -> Union[List[Any], _T]: 36 | """ 37 | Return all values associated with a possibly multi-valued key. 38 | """ 39 | 40 | @property 41 | def json(self) -> Dict[str, Union[str, List[str]]]: 42 | """ 43 | A JSON-compatible form of the metadata. 44 | """ 45 | 46 | 47 | class SimplePath(Protocol): 48 | """ 49 | A minimal subset of pathlib.Path required by Distribution. 50 | """ 51 | 52 | def joinpath( 53 | self, other: Union[str, os.PathLike[str]] 54 | ) -> SimplePath: ... # pragma: no cover 55 | 56 | def __truediv__( 57 | self, other: Union[str, os.PathLike[str]] 58 | ) -> SimplePath: ... # pragma: no cover 59 | 60 | @property 61 | def parent(self) -> SimplePath: ... # pragma: no cover 62 | 63 | def read_text(self, encoding=None) -> str: ... # pragma: no cover 64 | 65 | def read_bytes(self) -> bytes: ... # pragma: no cover 66 | 67 | def exists(self) -> bool: ... # pragma: no cover 68 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/importlib_metadata/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/compat/py311.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pathlib 3 | import sys 4 | import types 5 | 6 | 7 | def wrap(path): # pragma: no cover 8 | """ 9 | Workaround for https://github.com/python/cpython/issues/84538 10 | to add backward compatibility for walk_up=True. 11 | An example affected package is dask-labextension, which uses 12 | jupyter-packaging to install JupyterLab javascript files outside 13 | of site-packages. 14 | """ 15 | 16 | def relative_to(root, *, walk_up=False): 17 | return pathlib.Path(os.path.relpath(path, root)) 18 | 19 | return types.SimpleNamespace(relative_to=relative_to) 20 | 21 | 22 | relative_fix = wrap if sys.version_info < (3, 12) else lambda x: x 23 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/compat/py39.py: -------------------------------------------------------------------------------- 1 | """ 2 | Compatibility layer with Python 3.8/3.9 3 | """ 4 | 5 | from typing import TYPE_CHECKING, Any, Optional 6 | 7 | if TYPE_CHECKING: # pragma: no cover 8 | # Prevent circular imports on runtime. 9 | from .. import Distribution, EntryPoint 10 | else: 11 | Distribution = EntryPoint = Any 12 | 13 | 14 | def normalized_name(dist: Distribution) -> Optional[str]: 15 | """ 16 | Honor name normalization for distributions that don't provide ``_normalized_name``. 17 | """ 18 | try: 19 | return dist._normalized_name 20 | except AttributeError: 21 | from .. import Prepared # -> delay to prevent circular imports. 22 | 23 | return Prepared.normalize(getattr(dist, "name", None) or dist.metadata['Name']) 24 | 25 | 26 | def ep_matches(ep: EntryPoint, **params) -> bool: 27 | """ 28 | Workaround for ``EntryPoint`` objects without the ``matches`` method. 29 | """ 30 | try: 31 | return ep.matches(**params) 32 | except AttributeError: 33 | from .. import EntryPoint # -> delay to prevent circular imports. 34 | 35 | # Reconstruct the EntryPoint object to make sure it is compatible. 36 | return EntryPoint(ep.name, ep.value, ep.group).matches(**params) 37 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/diagnose.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from . import Distribution 4 | 5 | 6 | def inspect(path): 7 | print("Inspecting", path) 8 | dists = list(Distribution.discover(path=[path])) 9 | if not dists: 10 | return 11 | print("Found", len(dists), "packages:", end=' ') 12 | print(', '.join(dist.name for dist in dists)) 13 | 14 | 15 | def run(): 16 | for path in sys.path: 17 | inspect(path) 18 | 19 | 20 | if __name__ == '__main__': 21 | run() 22 | -------------------------------------------------------------------------------- /setuptools/_vendor/importlib_metadata/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/importlib_metadata/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/inflect-7.3.1.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect-7.3.1.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect-7.3.1.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | inflect-7.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | inflect-7.3.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | inflect-7.3.1.dist-info/METADATA,sha256=ZgMNY0WAZRs-U8wZiV2SMfjSKqBrMngXyDMs_CAwMwg,21079 4 | inflect-7.3.1.dist-info/RECORD,, 5 | inflect-7.3.1.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91 6 | inflect-7.3.1.dist-info/top_level.txt,sha256=m52ujdp10CqT6jh1XQxZT6kEntcnv-7Tl7UiGNTzWZA,8 7 | inflect/__init__.py,sha256=Jxy1HJXZiZ85kHeLAhkmvz6EMTdFqBe-duvt34R6IOc,103796 8 | inflect/__pycache__/__init__.cpython-312.pyc,, 9 | inflect/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 10 | inflect/compat/__pycache__/__init__.cpython-312.pyc,, 11 | inflect/compat/__pycache__/py38.cpython-312.pyc,, 12 | inflect/compat/py38.py,sha256=oObVfVnWX9_OpnOuEJn1mFbJxVhwyR5epbiTNXDDaso,160 13 | inflect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 14 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect-7.3.1.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: setuptools (70.2.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect-7.3.1.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | inflect 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/inflect/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/inflect/compat/py38.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | if sys.version_info > (3, 9): 5 | from typing import Annotated 6 | else: # pragma: no cover 7 | from typing_extensions import Annotated # noqa: F401 8 | -------------------------------------------------------------------------------- /setuptools/_vendor/inflect/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/inflect/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | jaraco.collections-5.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | jaraco.collections-5.1.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | jaraco.collections-5.1.0.dist-info/METADATA,sha256=IMUaliNsA5X1Ox9MXUWOagch5R4Wwb_3M7erp29dBtg,3933 4 | jaraco.collections-5.1.0.dist-info/RECORD,, 5 | jaraco.collections-5.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | jaraco.collections-5.1.0.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91 7 | jaraco.collections-5.1.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7 8 | jaraco/collections/__init__.py,sha256=Pc1-SqjWm81ad1P0-GttpkwO_LWlnaY6gUq8gcKh2v0,26640 9 | jaraco/collections/__pycache__/__init__.cpython-312.pyc,, 10 | jaraco/collections/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 11 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: setuptools (73.0.1) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.collections-5.1.0.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | jaraco 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.context-5.3.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.context-5.3.0.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.context-5.3.0.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | jaraco.context-5.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | jaraco.context-5.3.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | jaraco.context-5.3.0.dist-info/METADATA,sha256=xDtguJej0tN9iEXCUvxEJh2a7xceIRVBEakBLSr__tY,4020 4 | jaraco.context-5.3.0.dist-info/RECORD,, 5 | jaraco.context-5.3.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 6 | jaraco.context-5.3.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7 7 | jaraco/__pycache__/context.cpython-312.pyc,, 8 | jaraco/context.py,sha256=REoLIxDkO5MfEYowt_WoupNCRoxBS5v7YX2PbW8lIcs,9552 9 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.context-5.3.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.context-5.3.0.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | jaraco 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.functools-4.0.1.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.functools-4.0.1.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.functools-4.0.1.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | jaraco.functools-4.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | jaraco.functools-4.0.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | jaraco.functools-4.0.1.dist-info/METADATA,sha256=i4aUaQDX-jjdEQK5wevhegyx8JyLfin2HyvaSk3FHso,2891 4 | jaraco.functools-4.0.1.dist-info/RECORD,, 5 | jaraco.functools-4.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 6 | jaraco.functools-4.0.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7 7 | jaraco/functools/__init__.py,sha256=hEAJaS2uSZRuF_JY4CxCHIYh79ZpxaPp9OiHyr9EJ1w,16642 8 | jaraco/functools/__init__.pyi,sha256=gk3dsgHzo5F_U74HzAvpNivFAPCkPJ1b2-yCd62dfnw,3878 9 | jaraco/functools/__pycache__/__init__.cpython-312.pyc,, 10 | jaraco/functools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 11 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.functools-4.0.1.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.functools-4.0.1.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | jaraco 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | jaraco.text-3.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | jaraco.text-3.12.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | jaraco.text-3.12.1.dist-info/METADATA,sha256=AzWdm6ViMfDOPoQMfLWn2zgBQSGJScyqeN29TcuWXVI,3658 4 | jaraco.text-3.12.1.dist-info/RECORD,, 5 | jaraco.text-3.12.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | jaraco.text-3.12.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 7 | jaraco.text-3.12.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7 8 | jaraco/text/Lorem ipsum.txt,sha256=N_7c_79zxOufBY9HZ3yzMgOkNv-TkOTTio4BydrSjgs,1335 9 | jaraco/text/__init__.py,sha256=Y2YUqXR_orUoDaY4SkPRe6ZZhb5HUHB_Ah9RCNsVyho,16250 10 | jaraco/text/__pycache__/__init__.cpython-312.pyc,, 11 | jaraco/text/__pycache__/layouts.cpython-312.pyc,, 12 | jaraco/text/__pycache__/show-newlines.cpython-312.pyc,, 13 | jaraco/text/__pycache__/strip-prefix.cpython-312.pyc,, 14 | jaraco/text/__pycache__/to-dvorak.cpython-312.pyc,, 15 | jaraco/text/__pycache__/to-qwerty.cpython-312.pyc,, 16 | jaraco/text/layouts.py,sha256=HTC8aSTLZ7uXipyOXapRMC158juecjK6RVwitfmZ9_w,643 17 | jaraco/text/show-newlines.py,sha256=WGQa65e8lyhb92LUOLqVn6KaCtoeVgVws6WtSRmLk6w,904 18 | jaraco/text/strip-prefix.py,sha256=NfVXV8JVNo6nqcuYASfMV7_y4Eo8zMQqlCOGvAnRIVw,412 19 | jaraco/text/to-dvorak.py,sha256=1SNcbSsvISpXXg-LnybIHHY-RUFOQr36zcHkY1pWFqw,119 20 | jaraco/text/to-qwerty.py,sha256=s4UMQUnPwFn_dB5uZC27BurHOQcYondBfzIpVL5pEzw,119 21 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/jaraco.text-3.12.1.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco.text-3.12.1.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | jaraco 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/collections/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/jaraco/collections/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/functools/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/jaraco/functools/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/Lorem ipsum.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 2 | Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros bibendum elit, nec luctus magna felis sollicitudin mauris. Integer in mauris eu nibh euismod gravida. Duis ac tellus et risus vulputate vehicula. Donec lobortis risus a elit. Etiam tempor. Ut ullamcorper, ligula eu tempor congue, eros est euismod turpis, id tincidunt sapien risus a quam. Maecenas fermentum consequat mi. Donec fermentum. Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque nunc. Nullam arcu. Aliquam consequat. Curabitur augue lorem, dapibus quis, laoreet et, pretium ac, nisi. Aenean magna nisl, mollis quis, molestie eu, feugiat in, orci. In hac habitasse platea dictumst. 3 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/layouts.py: -------------------------------------------------------------------------------- 1 | qwerty = "-=qwertyuiop[]asdfghjkl;'zxcvbnm,./_+QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?" 2 | dvorak = "[]',.pyfgcrl/=aoeuidhtns-;qjkxbmwvz{}\"<>PYFGCRL?+AOEUIDHTNS_:QJKXBMWVZ" 3 | 4 | 5 | to_dvorak = str.maketrans(qwerty, dvorak) 6 | to_qwerty = str.maketrans(dvorak, qwerty) 7 | 8 | 9 | def translate(input, translation): 10 | """ 11 | >>> translate('dvorak', to_dvorak) 12 | 'ekrpat' 13 | >>> translate('qwerty', to_qwerty) 14 | 'x,dokt' 15 | """ 16 | return input.translate(translation) 17 | 18 | 19 | def _translate_stream(stream, translation): 20 | """ 21 | >>> import io 22 | >>> _translate_stream(io.StringIO('foo'), to_dvorak) 23 | urr 24 | """ 25 | print(translate(stream.read(), translation)) 26 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/show-newlines.py: -------------------------------------------------------------------------------- 1 | import autocommand 2 | import inflect 3 | 4 | from more_itertools import always_iterable 5 | 6 | import jaraco.text 7 | 8 | 9 | def report_newlines(filename): 10 | r""" 11 | Report the newlines in the indicated file. 12 | 13 | >>> tmp_path = getfixture('tmp_path') 14 | >>> filename = tmp_path / 'out.txt' 15 | >>> _ = filename.write_text('foo\nbar\n', newline='', encoding='utf-8') 16 | >>> report_newlines(filename) 17 | newline is '\n' 18 | >>> filename = tmp_path / 'out.txt' 19 | >>> _ = filename.write_text('foo\nbar\r\n', newline='', encoding='utf-8') 20 | >>> report_newlines(filename) 21 | newlines are ('\n', '\r\n') 22 | """ 23 | newlines = jaraco.text.read_newlines(filename) 24 | count = len(tuple(always_iterable(newlines))) 25 | engine = inflect.engine() 26 | print( 27 | engine.plural_noun("newline", count), 28 | engine.plural_verb("is", count), 29 | repr(newlines), 30 | ) 31 | 32 | 33 | autocommand.autocommand(__name__)(report_newlines) 34 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/strip-prefix.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import autocommand 4 | 5 | from jaraco.text import Stripper 6 | 7 | 8 | def strip_prefix(): 9 | r""" 10 | Strip any common prefix from stdin. 11 | 12 | >>> import io, pytest 13 | >>> getfixture('monkeypatch').setattr('sys.stdin', io.StringIO('abcdef\nabc123')) 14 | >>> strip_prefix() 15 | def 16 | 123 17 | """ 18 | sys.stdout.writelines(Stripper.strip_prefix(sys.stdin).lines) 19 | 20 | 21 | autocommand.autocommand(__name__)(strip_prefix) 22 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/to-dvorak.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from . import layouts 4 | 5 | 6 | __name__ == '__main__' and layouts._translate_stream(sys.stdin, layouts.to_dvorak) 7 | -------------------------------------------------------------------------------- /setuptools/_vendor/jaraco/text/to-qwerty.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from . import layouts 4 | 5 | 6 | __name__ == '__main__' and layouts._translate_stream(sys.stdin, layouts.to_qwerty) 7 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools-10.3.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools-10.3.0.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Erik Rose 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools-10.3.0.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | more_itertools-10.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | more_itertools-10.3.0.dist-info/LICENSE,sha256=CfHIyelBrz5YTVlkHqm4fYPAyw_QB-te85Gn4mQ8GkY,1053 3 | more_itertools-10.3.0.dist-info/METADATA,sha256=BFO90O-fLNiVQMpj7oIS5ztzgJUUQZ3TA32P5HH3N-A,36293 4 | more_itertools-10.3.0.dist-info/RECORD,, 5 | more_itertools-10.3.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | more_itertools-10.3.0.dist-info/WHEEL,sha256=rSgq_JpHF9fHR1lx53qwg_1-2LypZE_qmcuXbVUq948,81 7 | more_itertools/__init__.py,sha256=dtAbGjTDmn_ghiU5YXfhyDy0phAlXVdt5klZA5fUa-Q,149 8 | more_itertools/__init__.pyi,sha256=5B3eTzON1BBuOLob1vCflyEb2lSd6usXQQ-Cv-hXkeA,43 9 | more_itertools/__pycache__/__init__.cpython-312.pyc,, 10 | more_itertools/__pycache__/more.cpython-312.pyc,, 11 | more_itertools/__pycache__/recipes.cpython-312.pyc,, 12 | more_itertools/more.py,sha256=1E5kzFncRKTDw0cYv1yRXMgDdunstLQd1QStcnL6U90,148370 13 | more_itertools/more.pyi,sha256=iXXeqt48Nxe8VGmIWpkVXuKpR2FYNuu2DU8nQLWCCu0,21484 14 | more_itertools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 15 | more_itertools/recipes.py,sha256=WedhhfhGVgr6zii8fIbGJVmRTw0ZKRiLKnYBDGJv4nY,28591 16 | more_itertools/recipes.pyi,sha256=T_mdGpcFdfrP3JSWbwzYP9JyNV-Go-7RPfpxfftAWlA,4617 17 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools-10.3.0.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/more_itertools-10.3.0.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools-10.3.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: flit 3.8.0 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools/__init__.py: -------------------------------------------------------------------------------- 1 | """More routines for operating on iterables, beyond itertools""" 2 | 3 | from .more import * # noqa 4 | from .recipes import * # noqa 5 | 6 | __version__ = '10.3.0' 7 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools/__init__.pyi: -------------------------------------------------------------------------------- 1 | from .more import * 2 | from .recipes import * 3 | -------------------------------------------------------------------------------- /setuptools/_vendor/more_itertools/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/more_itertools/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | uv -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | This software is made available under the terms of *either* of the licenses 2 | found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made 3 | under the terms of *both* these licenses. 4 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Copyright (c) Donald Stufft and individual contributors. 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 met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | packaging-24.2.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2 2 | packaging-24.2.dist-info/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197 3 | packaging-24.2.dist-info/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174 4 | packaging-24.2.dist-info/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344 5 | packaging-24.2.dist-info/METADATA,sha256=ohH86s6k5mIfQxY2TS0LcSfADeOFa4BiCC-bxZV-pNs,3204 6 | packaging-24.2.dist-info/RECORD,, 7 | packaging-24.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 8 | packaging-24.2.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 9 | packaging/__init__.py,sha256=dk4Ta_vmdVJxYHDcfyhvQNw8V3PgSBomKNXqg-D2JDY,494 10 | packaging/_elffile.py,sha256=cflAQAkE25tzhYmq_aCi72QfbT_tn891tPzfpbeHOwE,3306 11 | packaging/_manylinux.py,sha256=vl5OCoz4kx80H5rwXKeXWjl9WNISGmr4ZgTpTP9lU9c,9612 12 | packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694 13 | packaging/_parser.py,sha256=s_TvTvDNK0NrM2QB3VKThdWFM4Nc0P6JnkObkl3MjpM,10236 14 | packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431 15 | packaging/_tokenizer.py,sha256=J6v5H7Jzvb-g81xp_2QACKwO7LxHQA6ikryMU7zXwN8,5273 16 | packaging/licenses/__init__.py,sha256=1x5M1nEYjcgwEbLt0dXwz2ukjr18DiCzC0sraQqJ-Ww,5715 17 | packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398 18 | packaging/markers.py,sha256=c89TNzB7ZdGYhkovm6PYmqGyHxXlYVaLW591PHUNKD8,10561 19 | packaging/metadata.py,sha256=YJibM7GYe4re8-0a3OlXmGS-XDgTEoO4tlBt2q25Bng,34762 20 | packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 21 | packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947 22 | packaging/specifiers.py,sha256=GG1wPNMcL0fMJO68vF53wKMdwnfehDcaI-r9NpTfilA,40074 23 | packaging/tags.py,sha256=CFqrJzAzc2XNGexerH__T-Y5Iwq7WbsYXsiLERLWxY0,21014 24 | packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050 25 | packaging/version.py,sha256=olfyuk_DPbflNkJ4wBWetXQ17c74x3DB501degUv7DY,16676 26 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/packaging-24.2.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/packaging-24.2.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: flit 3.10.1 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | 5 | __title__ = "packaging" 6 | __summary__ = "Core utilities for Python packages" 7 | __uri__ = "https://github.com/pypa/packaging" 8 | 9 | __version__ = "24.2" 10 | 11 | __author__ = "Donald Stufft and individual contributors" 12 | __email__ = "donald@stufft.io" 13 | 14 | __license__ = "BSD-2-Clause or Apache-2.0" 15 | __copyright__ = f"2014 {__author__}" 16 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging/_structures.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | 5 | 6 | class InfinityType: 7 | def __repr__(self) -> str: 8 | return "Infinity" 9 | 10 | def __hash__(self) -> int: 11 | return hash(repr(self)) 12 | 13 | def __lt__(self, other: object) -> bool: 14 | return False 15 | 16 | def __le__(self, other: object) -> bool: 17 | return False 18 | 19 | def __eq__(self, other: object) -> bool: 20 | return isinstance(other, self.__class__) 21 | 22 | def __gt__(self, other: object) -> bool: 23 | return True 24 | 25 | def __ge__(self, other: object) -> bool: 26 | return True 27 | 28 | def __neg__(self: object) -> "NegativeInfinityType": 29 | return NegativeInfinity 30 | 31 | 32 | Infinity = InfinityType() 33 | 34 | 35 | class NegativeInfinityType: 36 | def __repr__(self) -> str: 37 | return "-Infinity" 38 | 39 | def __hash__(self) -> int: 40 | return hash(repr(self)) 41 | 42 | def __lt__(self, other: object) -> bool: 43 | return True 44 | 45 | def __le__(self, other: object) -> bool: 46 | return True 47 | 48 | def __eq__(self, other: object) -> bool: 49 | return isinstance(other, self.__class__) 50 | 51 | def __gt__(self, other: object) -> bool: 52 | return False 53 | 54 | def __ge__(self, other: object) -> bool: 55 | return False 56 | 57 | def __neg__(self: object) -> InfinityType: 58 | return Infinity 59 | 60 | 61 | NegativeInfinity = NegativeInfinityType() 62 | -------------------------------------------------------------------------------- /setuptools/_vendor/packaging/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/packaging/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs-4.2.2.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs-4.2.2.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | platformdirs-4.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | platformdirs-4.2.2.dist-info/METADATA,sha256=zmsie01G1MtXR0wgIv5XpVeTO7idr0WWvfmxKsKWuGk,11429 3 | platformdirs-4.2.2.dist-info/RECORD,, 4 | platformdirs-4.2.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 5 | platformdirs-4.2.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87 6 | platformdirs-4.2.2.dist-info/licenses/LICENSE,sha256=KeD9YukphQ6G6yjD_czwzv30-pSHkBHP-z0NS-1tTbY,1089 7 | platformdirs/__init__.py,sha256=EMGE8qeHRR9CzDFr8kL3tA8hdZZniYjXBVZd0UGTWK0,22225 8 | platformdirs/__main__.py,sha256=HnsUQHpiBaiTxwcmwVw-nFaPdVNZtQIdi1eWDtI-MzI,1493 9 | platformdirs/__pycache__/__init__.cpython-312.pyc,, 10 | platformdirs/__pycache__/__main__.cpython-312.pyc,, 11 | platformdirs/__pycache__/android.cpython-312.pyc,, 12 | platformdirs/__pycache__/api.cpython-312.pyc,, 13 | platformdirs/__pycache__/macos.cpython-312.pyc,, 14 | platformdirs/__pycache__/unix.cpython-312.pyc,, 15 | platformdirs/__pycache__/version.cpython-312.pyc,, 16 | platformdirs/__pycache__/windows.cpython-312.pyc,, 17 | platformdirs/android.py,sha256=xZXY9Jd46WOsxT2U6-5HsNtDZ-IQqxcEUrBLl3hYk4o,9016 18 | platformdirs/api.py,sha256=QBYdUac2eC521ek_y53uD1Dcq-lJX8IgSRVd4InC6uc,8996 19 | platformdirs/macos.py,sha256=wftsbsvq6nZ0WORXSiCrZNkRHz_WKuktl0a6mC7MFkI,5580 20 | platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 21 | platformdirs/unix.py,sha256=Cci9Wqt35dAMsg6HT9nRGHSBW5obb0pR3AE1JJnsCXg,10643 22 | platformdirs/version.py,sha256=r7F76tZRjgQKzrpx_I0_ZMQOMU-PS7eGnHD7zEK3KB0,411 23 | platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125 24 | -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs-4.2.2.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/platformdirs-4.2.2.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs-4.2.2.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: hatchling 1.24.2 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs-4.2.2.dist-info/licenses/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2010-202x The platformdirs developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs/__main__.py: -------------------------------------------------------------------------------- 1 | """Main entry point.""" 2 | 3 | from __future__ import annotations 4 | 5 | from platformdirs import PlatformDirs, __version__ 6 | 7 | PROPS = ( 8 | "user_data_dir", 9 | "user_config_dir", 10 | "user_cache_dir", 11 | "user_state_dir", 12 | "user_log_dir", 13 | "user_documents_dir", 14 | "user_downloads_dir", 15 | "user_pictures_dir", 16 | "user_videos_dir", 17 | "user_music_dir", 18 | "user_runtime_dir", 19 | "site_data_dir", 20 | "site_config_dir", 21 | "site_cache_dir", 22 | "site_runtime_dir", 23 | ) 24 | 25 | 26 | def main() -> None: 27 | """Run the main entry point.""" 28 | app_name = "MyApp" 29 | app_author = "MyCompany" 30 | 31 | print(f"-- platformdirs {__version__} --") # noqa: T201 32 | 33 | print("-- app dirs (with optional 'version')") # noqa: T201 34 | dirs = PlatformDirs(app_name, app_author, version="1.0") 35 | for prop in PROPS: 36 | print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201 37 | 38 | print("\n-- app dirs (without optional 'version')") # noqa: T201 39 | dirs = PlatformDirs(app_name, app_author) 40 | for prop in PROPS: 41 | print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201 42 | 43 | print("\n-- app dirs (without optional 'appauthor')") # noqa: T201 44 | dirs = PlatformDirs(app_name) 45 | for prop in PROPS: 46 | print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201 47 | 48 | print("\n-- app dirs (with disabled 'appauthor')") # noqa: T201 49 | dirs = PlatformDirs(app_name, appauthor=False) 50 | for prop in PROPS: 51 | print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/platformdirs/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/platformdirs/version.py: -------------------------------------------------------------------------------- 1 | # file generated by setuptools_scm 2 | # don't change, don't track in version control 3 | TYPE_CHECKING = False 4 | if TYPE_CHECKING: 5 | from typing import Tuple, Union 6 | VERSION_TUPLE = Tuple[Union[int, str], ...] 7 | else: 8 | VERSION_TUPLE = object 9 | 10 | version: str 11 | __version__: str 12 | __version_tuple__: VERSION_TUPLE 13 | version_tuple: VERSION_TUPLE 14 | 15 | __version__ = version = '4.2.2' 16 | __version_tuple__ = version_tuple = (4, 2, 2) 17 | -------------------------------------------------------------------------------- /setuptools/_vendor/ruff.toml: -------------------------------------------------------------------------------- 1 | exclude = ["*"] 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli-2.0.1.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli-2.0.1.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Taneli Hukkinen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli-2.0.1.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | tomli-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072 3 | tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875 4 | tomli-2.0.1.dist-info/RECORD,, 5 | tomli-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81 7 | tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396 8 | tomli/__pycache__/__init__.cpython-312.pyc,, 9 | tomli/__pycache__/_parser.cpython-312.pyc,, 10 | tomli/__pycache__/_re.cpython-312.pyc,, 11 | tomli/__pycache__/_types.cpython-312.pyc,, 12 | tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633 13 | tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943 14 | tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254 15 | tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26 16 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli-2.0.1.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/tomli-2.0.1.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/tomli-2.0.1.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: flit 3.6.0 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MIT 2 | # SPDX-FileCopyrightText: 2021 Taneli Hukkinen 3 | # Licensed to PSF under a Contributor Agreement. 4 | 5 | __all__ = ("loads", "load", "TOMLDecodeError") 6 | __version__ = "2.0.1" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT 7 | 8 | from ._parser import TOMLDecodeError, load, loads 9 | 10 | # Pretend this exception was created here. 11 | TOMLDecodeError.__module__ = __name__ 12 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli/_types.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MIT 2 | # SPDX-FileCopyrightText: 2021 Taneli Hukkinen 3 | # Licensed to PSF under a Contributor Agreement. 4 | 5 | from typing import Any, Callable, Tuple 6 | 7 | # Type annotations 8 | ParseFloat = Callable[[str], Any] 9 | Key = Tuple[str, ...] 10 | Pos = int 11 | -------------------------------------------------------------------------------- /setuptools/_vendor/tomli/py.typed: -------------------------------------------------------------------------------- 1 | # Marker file for PEP 561 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard-4.3.0.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard-4.3.0.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | This is the MIT license: http://www.opensource.org/licenses/mit-license.php 2 | 3 | Copyright (c) Alex Grönholm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | software and associated documentation files (the "Software"), to deal in the Software 7 | without restriction, including without limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 9 | to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or 12 | substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 16 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard-4.3.0.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard-4.3.0.dist-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [pytest11] 2 | typeguard = typeguard._pytest_plugin 3 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard-4.3.0.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | typeguard 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Any 3 | 4 | from ._checkers import TypeCheckerCallable as TypeCheckerCallable 5 | from ._checkers import TypeCheckLookupCallback as TypeCheckLookupCallback 6 | from ._checkers import check_type_internal as check_type_internal 7 | from ._checkers import checker_lookup_functions as checker_lookup_functions 8 | from ._checkers import load_plugins as load_plugins 9 | from ._config import CollectionCheckStrategy as CollectionCheckStrategy 10 | from ._config import ForwardRefPolicy as ForwardRefPolicy 11 | from ._config import TypeCheckConfiguration as TypeCheckConfiguration 12 | from ._decorators import typechecked as typechecked 13 | from ._decorators import typeguard_ignore as typeguard_ignore 14 | from ._exceptions import InstrumentationWarning as InstrumentationWarning 15 | from ._exceptions import TypeCheckError as TypeCheckError 16 | from ._exceptions import TypeCheckWarning as TypeCheckWarning 17 | from ._exceptions import TypeHintWarning as TypeHintWarning 18 | from ._functions import TypeCheckFailCallback as TypeCheckFailCallback 19 | from ._functions import check_type as check_type 20 | from ._functions import warn_on_error as warn_on_error 21 | from ._importhook import ImportHookManager as ImportHookManager 22 | from ._importhook import TypeguardFinder as TypeguardFinder 23 | from ._importhook import install_import_hook as install_import_hook 24 | from ._memo import TypeCheckMemo as TypeCheckMemo 25 | from ._suppression import suppress_type_checks as suppress_type_checks 26 | from ._utils import Unset as Unset 27 | 28 | # Re-export imports so they look like they live directly in this package 29 | for value in list(locals().values()): 30 | if getattr(value, "__module__", "").startswith(f"{__name__}."): 31 | value.__module__ = __name__ 32 | 33 | 34 | config: TypeCheckConfiguration 35 | 36 | 37 | def __getattr__(name: str) -> Any: 38 | if name == "config": 39 | from ._config import global_config 40 | 41 | return global_config 42 | 43 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 44 | 45 | 46 | # Automatically load checker lookup functions unless explicitly disabled 47 | if "TYPEGUARD_DISABLE_PLUGIN_AUTOLOAD" not in os.environ: 48 | load_plugins() 49 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard/_exceptions.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | from typing import Deque 3 | 4 | 5 | class TypeHintWarning(UserWarning): 6 | """ 7 | A warning that is emitted when a type hint in string form could not be resolved to 8 | an actual type. 9 | """ 10 | 11 | 12 | class TypeCheckWarning(UserWarning): 13 | """Emitted by typeguard's type checkers when a type mismatch is detected.""" 14 | 15 | def __init__(self, message: str): 16 | super().__init__(message) 17 | 18 | 19 | class InstrumentationWarning(UserWarning): 20 | """Emitted when there's a problem with instrumenting a function for type checks.""" 21 | 22 | def __init__(self, message: str): 23 | super().__init__(message) 24 | 25 | 26 | class TypeCheckError(Exception): 27 | """ 28 | Raised by typeguard's type checkers when a type mismatch is detected. 29 | """ 30 | 31 | def __init__(self, message: str): 32 | super().__init__(message) 33 | self._path: Deque[str] = deque() 34 | 35 | def append_path_element(self, element: str) -> None: 36 | self._path.append(element) 37 | 38 | def __str__(self) -> str: 39 | if self._path: 40 | return " of ".join(self._path) + " " + str(self.args[0]) 41 | else: 42 | return str(self.args[0]) 43 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard/_memo.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | from typeguard._config import TypeCheckConfiguration, global_config 6 | 7 | 8 | class TypeCheckMemo: 9 | """ 10 | Contains information necessary for type checkers to do their work. 11 | 12 | .. attribute:: globals 13 | :type: dict[str, Any] 14 | 15 | Dictionary of global variables to use for resolving forward references. 16 | 17 | .. attribute:: locals 18 | :type: dict[str, Any] 19 | 20 | Dictionary of local variables to use for resolving forward references. 21 | 22 | .. attribute:: self_type 23 | :type: type | None 24 | 25 | When running type checks within an instance method or class method, this is the 26 | class object that the first argument (usually named ``self`` or ``cls``) refers 27 | to. 28 | 29 | .. attribute:: config 30 | :type: TypeCheckConfiguration 31 | 32 | Contains the configuration for a particular set of type checking operations. 33 | """ 34 | 35 | __slots__ = "globals", "locals", "self_type", "config" 36 | 37 | def __init__( 38 | self, 39 | globals: dict[str, Any], 40 | locals: dict[str, Any], 41 | *, 42 | self_type: type | None = None, 43 | config: TypeCheckConfiguration = global_config, 44 | ): 45 | self.globals = globals 46 | self.locals = locals 47 | self.self_type = self_type 48 | self.config = config 49 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard/_union_transformer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Transforms lazily evaluated PEP 604 unions into typing.Unions, for compatibility with 3 | Python versions older than 3.10. 4 | """ 5 | 6 | from __future__ import annotations 7 | 8 | from ast import ( 9 | BinOp, 10 | BitOr, 11 | Index, 12 | Load, 13 | Name, 14 | NodeTransformer, 15 | Subscript, 16 | fix_missing_locations, 17 | parse, 18 | ) 19 | from ast import Tuple as ASTTuple 20 | from types import CodeType 21 | from typing import Any, Dict, FrozenSet, List, Set, Tuple, Union 22 | 23 | type_substitutions = { 24 | "dict": Dict, 25 | "list": List, 26 | "tuple": Tuple, 27 | "set": Set, 28 | "frozenset": FrozenSet, 29 | "Union": Union, 30 | } 31 | 32 | 33 | class UnionTransformer(NodeTransformer): 34 | def __init__(self, union_name: Name | None = None): 35 | self.union_name = union_name or Name(id="Union", ctx=Load()) 36 | 37 | def visit_BinOp(self, node: BinOp) -> Any: 38 | self.generic_visit(node) 39 | if isinstance(node.op, BitOr): 40 | return Subscript( 41 | value=self.union_name, 42 | slice=Index( 43 | ASTTuple(elts=[node.left, node.right], ctx=Load()), ctx=Load() 44 | ), 45 | ctx=Load(), 46 | ) 47 | 48 | return node 49 | 50 | 51 | def compile_type_hint(hint: str) -> CodeType: 52 | parsed = parse(hint, "", "eval") 53 | UnionTransformer().visit(parsed) 54 | fix_missing_locations(parsed) 55 | return compile(parsed, "", "eval", flags=0) 56 | -------------------------------------------------------------------------------- /setuptools/_vendor/typeguard/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/typeguard/py.typed -------------------------------------------------------------------------------- /setuptools/_vendor/typing_extensions-4.12.2.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/typing_extensions-4.12.2.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | __pycache__/typing_extensions.cpython-312.pyc,, 2 | typing_extensions-4.12.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 3 | typing_extensions-4.12.2.dist-info/LICENSE,sha256=Oy-B_iHRgcSZxZolbI4ZaEVdZonSaaqFNzv7avQdo78,13936 4 | typing_extensions-4.12.2.dist-info/METADATA,sha256=BeUQIa8cnYbrjWx-N8TOznM9UGW5Gm2DicVpDtRA8W0,3018 5 | typing_extensions-4.12.2.dist-info/RECORD,, 6 | typing_extensions-4.12.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 7 | typing_extensions.py,sha256=gwekpyG9DVG3lxWKX4ni8u7nk3We5slG98mA9F3DJQw,134451 8 | -------------------------------------------------------------------------------- /setuptools/_vendor/typing_extensions-4.12.2.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: flit 3.9.0 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel-0.45.1.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel-0.45.1.dist-info/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2012 Daniel Holth and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 | OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel-0.45.1.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/wheel-0.45.1.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/wheel-0.45.1.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: flit 3.10.1 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel-0.45.1.dist-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [console_scripts] 2 | wheel=wheel.cli:main 3 | 4 | [distutils.commands] 5 | bdist_wheel=wheel.bdist_wheel:bdist_wheel 6 | 7 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | __version__ = "0.45.1" 4 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/__main__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Wheel command line tool (enable python -m wheel syntax) 3 | """ 4 | 5 | from __future__ import annotations 6 | 7 | import sys 8 | 9 | 10 | def main(): # needed for console script 11 | if __package__ == "": 12 | # To be able to run 'python wheel-0.9.whl/wheel': 13 | import os.path 14 | 15 | path = os.path.dirname(os.path.dirname(__file__)) 16 | sys.path[0:0] = [path] 17 | import wheel.cli 18 | 19 | sys.exit(wheel.cli.main()) 20 | 21 | 22 | if __name__ == "__main__": 23 | sys.exit(main()) 24 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/_setuptools_logging.py: -------------------------------------------------------------------------------- 1 | # copied from setuptools.logging, omitting monkeypatching 2 | from __future__ import annotations 3 | 4 | import logging 5 | import sys 6 | 7 | 8 | def _not_warning(record: logging.LogRecord) -> bool: 9 | return record.levelno < logging.WARNING 10 | 11 | 12 | def configure() -> None: 13 | """ 14 | Configure logging to emit warning and above to stderr 15 | and everything else to stdout. This behavior is provided 16 | for compatibility with distutils.log but may change in 17 | the future. 18 | """ 19 | err_handler = logging.StreamHandler() 20 | err_handler.setLevel(logging.WARNING) 21 | out_handler = logging.StreamHandler(sys.stdout) 22 | out_handler.addFilter(_not_warning) 23 | handlers = err_handler, out_handler 24 | logging.basicConfig( 25 | format="{message}", style="{", handlers=handlers, level=logging.DEBUG 26 | ) 27 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/bdist_wheel.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING 2 | from warnings import warn 3 | 4 | warn( 5 | "The 'wheel' package is no longer the canonical location of the 'bdist_wheel' " 6 | "command, and will be removed in a future release. Please update to setuptools " 7 | "v70.1 or later which contains an integrated version of this command.", 8 | DeprecationWarning, 9 | stacklevel=1, 10 | ) 11 | 12 | if TYPE_CHECKING: 13 | from ._bdist_wheel import bdist_wheel as bdist_wheel 14 | else: 15 | try: 16 | # Better integration/compatibility with setuptools: 17 | # in the case new fixes or PEPs are implemented in setuptools 18 | # there is no need to backport them to the deprecated code base. 19 | # This is useful in the case of old packages in the ecosystem 20 | # that are still used but have low maintenance. 21 | from setuptools.command.bdist_wheel import bdist_wheel 22 | except ImportError: 23 | # Only used in the case of old setuptools versions. 24 | # If the user wants to get the latest fixes/PEPs, 25 | # they are encouraged to address the deprecation warning. 26 | from ._bdist_wheel import bdist_wheel as bdist_wheel 27 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/cli/unpack.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | 5 | from ..wheelfile import WheelFile 6 | 7 | 8 | def unpack(path: str, dest: str = ".") -> None: 9 | """Unpack a wheel. 10 | 11 | Wheel content will be unpacked to {dest}/{name}-{ver}, where {name} 12 | is the package name and {ver} its version. 13 | 14 | :param path: The path to the wheel. 15 | :param dest: Destination directory (default to current directory). 16 | """ 17 | with WheelFile(path) as wf: 18 | namever = wf.parsed_filename.group("namever") 19 | destination = Path(dest) / namever 20 | print(f"Unpacking to: {destination}...", end="", flush=True) 21 | for zinfo in wf.filelist: 22 | wf.extract(zinfo, destination) 23 | 24 | # Set permissions to the same values as they were set in the archive 25 | # We have to do this manually due to 26 | # https://github.com/python/cpython/issues/59999 27 | permissions = zinfo.external_attr >> 16 & 0o777 28 | destination.joinpath(zinfo.filename).chmod(permissions) 29 | 30 | print("OK") 31 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import base64 4 | import logging 5 | 6 | log = logging.getLogger("wheel") 7 | 8 | 9 | def urlsafe_b64encode(data: bytes) -> bytes: 10 | """urlsafe_b64encode without padding""" 11 | return base64.urlsafe_b64encode(data).rstrip(b"=") 12 | 13 | 14 | def urlsafe_b64decode(data: bytes) -> bytes: 15 | """urlsafe_b64decode without padding""" 16 | pad = b"=" * (4 - (len(data) & 3)) 17 | return base64.urlsafe_b64decode(data + pad) 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/wheel/vendored/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/packaging/LICENSE: -------------------------------------------------------------------------------- 1 | This software is made available under the terms of *either* of the licenses 2 | found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made 3 | under the terms of *both* these licenses. 4 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/packaging/LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Copyright (c) Donald Stufft and individual contributors. 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 met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/packaging/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/wheel/vendored/packaging/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/packaging/_structures.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | 5 | 6 | class InfinityType: 7 | def __repr__(self) -> str: 8 | return "Infinity" 9 | 10 | def __hash__(self) -> int: 11 | return hash(repr(self)) 12 | 13 | def __lt__(self, other: object) -> bool: 14 | return False 15 | 16 | def __le__(self, other: object) -> bool: 17 | return False 18 | 19 | def __eq__(self, other: object) -> bool: 20 | return isinstance(other, self.__class__) 21 | 22 | def __gt__(self, other: object) -> bool: 23 | return True 24 | 25 | def __ge__(self, other: object) -> bool: 26 | return True 27 | 28 | def __neg__(self: object) -> "NegativeInfinityType": 29 | return NegativeInfinity 30 | 31 | 32 | Infinity = InfinityType() 33 | 34 | 35 | class NegativeInfinityType: 36 | def __repr__(self) -> str: 37 | return "-Infinity" 38 | 39 | def __hash__(self) -> int: 40 | return hash(repr(self)) 41 | 42 | def __lt__(self, other: object) -> bool: 43 | return True 44 | 45 | def __le__(self, other: object) -> bool: 46 | return True 47 | 48 | def __eq__(self, other: object) -> bool: 49 | return isinstance(other, self.__class__) 50 | 51 | def __gt__(self, other: object) -> bool: 52 | return False 53 | 54 | def __ge__(self, other: object) -> bool: 55 | return False 56 | 57 | def __neg__(self: object) -> InfinityType: 58 | return Infinity 59 | 60 | 61 | NegativeInfinity = NegativeInfinityType() 62 | -------------------------------------------------------------------------------- /setuptools/_vendor/wheel/vendored/vendor.txt: -------------------------------------------------------------------------------- 1 | packaging==24.0 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | pip 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to 3 | deal in the Software without restriction, including without limitation the 4 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 5 | sell copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 16 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 17 | IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/RECORD: -------------------------------------------------------------------------------- 1 | zipp-3.19.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 2 | zipp-3.19.2.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 3 | zipp-3.19.2.dist-info/METADATA,sha256=UIrk_kMIHGSwsKKChYizqMw0MMZpPRZ2ZiVpQAsN_bE,3575 4 | zipp-3.19.2.dist-info/RECORD,, 5 | zipp-3.19.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | zipp-3.19.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92 7 | zipp-3.19.2.dist-info/top_level.txt,sha256=iAbdoSHfaGqBfVb2XuR9JqSQHCoOsOtG6y9C_LSpqFw,5 8 | zipp/__init__.py,sha256=QuI1g00G4fRAcGt-HqbV0oWIkmSgedCGGYsHHYzNa8A,13412 9 | zipp/__pycache__/__init__.cpython-312.pyc,, 10 | zipp/__pycache__/glob.cpython-312.pyc,, 11 | zipp/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 12 | zipp/compat/__pycache__/__init__.cpython-312.pyc,, 13 | zipp/compat/__pycache__/py310.cpython-312.pyc,, 14 | zipp/compat/py310.py,sha256=eZpkW0zRtunkhEh8jjX3gCGe22emoKCBJw72Zt4RkhA,219 15 | zipp/glob.py,sha256=etWpnfEoRyfUvrUsi6sTiGmErvPwe6HzY6pT8jg_lUI,3082 16 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/REQUESTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/zipp-3.19.2.dist-info/REQUESTED -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.43.0) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp-3.19.2.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | zipp 2 | -------------------------------------------------------------------------------- /setuptools/_vendor/zipp/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/_vendor/zipp/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/_vendor/zipp/compat/py310.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import io 3 | 4 | 5 | def _text_encoding(encoding, stacklevel=2, /): # pragma: no cover 6 | return encoding 7 | 8 | 9 | text_encoding = ( 10 | io.text_encoding if sys.version_info > (3, 10) else _text_encoding # type: ignore 11 | ) 12 | -------------------------------------------------------------------------------- /setuptools/cli-32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/cli-32.exe -------------------------------------------------------------------------------- /setuptools/cli-64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/cli-64.exe -------------------------------------------------------------------------------- /setuptools/cli-arm64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/cli-arm64.exe -------------------------------------------------------------------------------- /setuptools/cli.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/cli.exe -------------------------------------------------------------------------------- /setuptools/command/__init__.py: -------------------------------------------------------------------------------- 1 | # mypy: disable_error_code=call-overload 2 | # pyright: reportCallIssue=false, reportArgumentType=false 3 | # Can't disable on the exact line because distutils doesn't exists on Python 3.12 4 | # and type-checkers aren't aware of distutils_hack, 5 | # causing distutils.command.bdist.bdist.format_commands to be Any. 6 | 7 | import sys 8 | 9 | from distutils.command.bdist import bdist 10 | 11 | if 'egg' not in bdist.format_commands: 12 | try: 13 | # format_commands is a dict in vendored distutils 14 | # It used to be a list in older (stdlib) distutils 15 | # We support both for backwards compatibility 16 | bdist.format_commands['egg'] = ('bdist_egg', "Python .egg file") 17 | except TypeError: 18 | bdist.format_command['egg'] = ('bdist_egg', "Python .egg file") 19 | bdist.format_commands.append('egg') 20 | 21 | del bdist, sys 22 | -------------------------------------------------------------------------------- /setuptools/command/bdist_rpm.py: -------------------------------------------------------------------------------- 1 | from ..dist import Distribution 2 | from ..warnings import SetuptoolsDeprecationWarning 3 | 4 | import distutils.command.bdist_rpm as orig 5 | 6 | 7 | class bdist_rpm(orig.bdist_rpm): 8 | """ 9 | Override the default bdist_rpm behavior to do the following: 10 | 11 | 1. Run egg_info to ensure the name and version are properly calculated. 12 | 2. Always run 'install' using --single-version-externally-managed to 13 | disable eggs in RPM distributions. 14 | """ 15 | 16 | distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution 17 | 18 | def run(self) -> None: 19 | SetuptoolsDeprecationWarning.emit( 20 | "Deprecated command", 21 | """ 22 | bdist_rpm is deprecated and will be removed in a future version. 23 | Use bdist_wheel (wheel packages) instead. 24 | """, 25 | see_url="https://github.com/pypa/setuptools/issues/1988", 26 | due_date=(2023, 10, 30), # Deprecation introduced in 22 Oct 2021. 27 | ) 28 | 29 | # ensure distro name is up-to-date 30 | self.run_command('egg_info') 31 | 32 | orig.bdist_rpm.run(self) 33 | 34 | def _make_spec_file(self): 35 | spec = orig.bdist_rpm._make_spec_file(self) 36 | return [ 37 | line.replace( 38 | "setup.py install ", 39 | "setup.py install --single-version-externally-managed ", 40 | ).replace("%setup", "%setup -n %{name}-%{unmangled_version}") 41 | for line in spec 42 | ] 43 | -------------------------------------------------------------------------------- /setuptools/command/develop.py: -------------------------------------------------------------------------------- 1 | import site 2 | import subprocess 3 | import sys 4 | from typing import cast 5 | 6 | from setuptools import Command 7 | from setuptools.warnings import SetuptoolsDeprecationWarning 8 | 9 | 10 | class develop(Command): 11 | """Set up package for development""" 12 | 13 | user_options = [ 14 | ("install-dir=", "d", "install package to DIR"), 15 | ('no-deps', 'N', "don't install dependencies"), 16 | ('user', None, f"install in user site-package '{site.USER_SITE}'"), 17 | ('prefix=', None, "installation prefix"), 18 | ("index-url=", "i", "base URL of Python Package Index"), 19 | ] 20 | boolean_options = [ 21 | 'no-deps', 22 | 'user', 23 | ] 24 | 25 | install_dir = None 26 | no_deps = False 27 | user = False 28 | prefix = None 29 | index_url = None 30 | 31 | def run(self) -> None: 32 | # Casting because mypy doesn't understand bool mult conditionals 33 | cmd = cast( 34 | list[str], 35 | [sys.executable, '-m', 'pip', 'install', '-e', '.', '--use-pep517'] 36 | + ['--target', self.install_dir] * bool(self.install_dir) 37 | + ['--no-deps'] * self.no_deps 38 | + ['--user'] * self.user 39 | + ['--prefix', self.prefix] * bool(self.prefix) 40 | + ['--index-url', self.index_url] * bool(self.index_url), 41 | ) 42 | subprocess.check_call(cmd) 43 | 44 | def initialize_options(self) -> None: 45 | DevelopDeprecationWarning.emit() 46 | 47 | def finalize_options(self) -> None: 48 | pass 49 | 50 | 51 | class DevelopDeprecationWarning(SetuptoolsDeprecationWarning): 52 | _SUMMARY = "develop command is deprecated." 53 | _DETAILS = """ 54 | Please avoid running ``setup.py`` and ``develop``. 55 | Instead, use standards-based tools like pip or uv. 56 | """ 57 | _SEE_URL = "https://github.com/pypa/setuptools/issues/917" 58 | _DUE_DATE = 2025, 10, 31 59 | -------------------------------------------------------------------------------- /setuptools/command/easy_install.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import types 4 | 5 | from setuptools import Command 6 | 7 | from .. import _scripts, warnings 8 | 9 | 10 | class easy_install(Command): 11 | """Stubbed command for temporary pbr compatibility.""" 12 | 13 | 14 | def __getattr__(name): 15 | attr = getattr( 16 | types.SimpleNamespace( 17 | ScriptWriter=_scripts.ScriptWriter, 18 | sys_executable=os.environ.get( 19 | "__PYVENV_LAUNCHER__", os.path.normpath(sys.executable) 20 | ), 21 | ), 22 | name, 23 | ) 24 | warnings.SetuptoolsDeprecationWarning.emit( 25 | summary="easy_install module is deprecated", 26 | details="Avoid accessing attributes of setuptools.command.easy_install.", 27 | due_date=(2025, 10, 31), 28 | see_url="https://github.com/pypa/setuptools/issues/4976", 29 | ) 30 | return attr 31 | -------------------------------------------------------------------------------- /setuptools/command/launcher manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /setuptools/command/saveopts.py: -------------------------------------------------------------------------------- 1 | from setuptools.command.setopt import edit_config, option_base 2 | 3 | 4 | class saveopts(option_base): 5 | """Save command-line options to a file""" 6 | 7 | description = "save supplied options to setup.cfg or other config file" 8 | 9 | def run(self) -> None: 10 | dist = self.distribution 11 | settings: dict[str, dict[str, str]] = {} 12 | 13 | for cmd in dist.command_options: 14 | if cmd == 'saveopts': 15 | continue # don't save our own options! 16 | 17 | for opt, (src, val) in dist.get_option_dict(cmd).items(): 18 | if src == "command line": 19 | settings.setdefault(cmd, {})[opt] = val 20 | 21 | edit_config(self.filename, settings, self.dry_run) 22 | -------------------------------------------------------------------------------- /setuptools/command/test.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import NoReturn 4 | 5 | from setuptools import Command 6 | from setuptools.warnings import SetuptoolsDeprecationWarning 7 | 8 | 9 | # Would restrict to Literal["test"], but mypy doesn't support it: https://github.com/python/mypy/issues/8203 10 | def __getattr__(name: str) -> type[_test]: 11 | if name == 'test': 12 | SetuptoolsDeprecationWarning.emit( 13 | "The test command is disabled and references to it are deprecated.", 14 | "Please remove any references to `setuptools.command.test` in all " 15 | "supported versions of the affected package.", 16 | due_date=(2024, 11, 15), 17 | stacklevel=2, 18 | ) 19 | return _test 20 | raise AttributeError(name) 21 | 22 | 23 | class _test(Command): 24 | """ 25 | Stub to warn when test command is referenced or used. 26 | """ 27 | 28 | description = "stub for old test command (do not use)" 29 | 30 | user_options = [ 31 | ('test-module=', 'm', "Run 'test_suite' in specified module"), 32 | ( 33 | 'test-suite=', 34 | 's', 35 | "Run single test, case or suite (e.g. 'module.test_suite')", 36 | ), 37 | ('test-runner=', 'r', "Test runner to use"), 38 | ] 39 | 40 | def initialize_options(self) -> None: 41 | pass 42 | 43 | def finalize_options(self) -> None: 44 | pass 45 | 46 | def run(self) -> NoReturn: 47 | raise RuntimeError("Support for the test command was removed in Setuptools 72") 48 | -------------------------------------------------------------------------------- /setuptools/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/compat/py310.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | __all__ = ['tomllib'] 4 | 5 | 6 | if sys.version_info >= (3, 11): 7 | import tomllib 8 | else: # pragma: no cover 9 | import tomli as tomllib 10 | 11 | 12 | if sys.version_info >= (3, 11): 13 | 14 | def add_note(ex, note): 15 | ex.add_note(note) 16 | 17 | else: # pragma: no cover 18 | 19 | def add_note(ex, note): 20 | vars(ex).setdefault('__notes__', []).append(note) 21 | -------------------------------------------------------------------------------- /setuptools/compat/py311.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import shutil 4 | import sys 5 | from typing import TYPE_CHECKING, Any, Callable 6 | 7 | if TYPE_CHECKING: 8 | from _typeshed import ExcInfo, StrOrBytesPath 9 | from typing_extensions import TypeAlias 10 | 11 | # Same as shutil._OnExcCallback from typeshed 12 | _OnExcCallback: TypeAlias = Callable[[Callable[..., Any], str, BaseException], object] 13 | 14 | 15 | def shutil_rmtree( 16 | path: StrOrBytesPath, 17 | ignore_errors: bool = False, 18 | onexc: _OnExcCallback | None = None, 19 | ) -> None: 20 | if sys.version_info >= (3, 12): 21 | return shutil.rmtree(path, ignore_errors, onexc=onexc) 22 | 23 | def _handler(fn: Callable[..., Any], path: str, excinfo: ExcInfo) -> None: 24 | if onexc: 25 | onexc(fn, path, excinfo[1]) 26 | 27 | return shutil.rmtree(path, ignore_errors, onerror=_handler) 28 | -------------------------------------------------------------------------------- /setuptools/compat/py312.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import sys 4 | 5 | if sys.version_info >= (3, 12, 4): 6 | # Python 3.13 should support `.pth` files encoded in UTF-8 7 | # See discussion in https://github.com/python/cpython/issues/77102 8 | PTH_ENCODING: str | None = "utf-8" 9 | else: 10 | from .py39 import LOCALE_ENCODING 11 | 12 | # PTH_ENCODING = "locale" 13 | PTH_ENCODING = LOCALE_ENCODING 14 | -------------------------------------------------------------------------------- /setuptools/compat/py39.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # Explicitly use the ``"locale"`` encoding in versions that support it, 4 | # otherwise just rely on the implicit handling of ``encoding=None``. 5 | # Since all platforms that support ``EncodingWarning`` also support 6 | # ``encoding="locale"``, this can be used to suppress the warning. 7 | # However, please try to use UTF-8 when possible 8 | # (.pth files are the notorious exception: python/cpython#77102, pypa/setuptools#3937). 9 | LOCALE_ENCODING = "locale" if sys.version_info >= (3, 10) else None 10 | -------------------------------------------------------------------------------- /setuptools/config/NOTICE: -------------------------------------------------------------------------------- 1 | The following files include code from opensource projects 2 | (either as direct copies or modified versions): 3 | 4 | - `setuptools.schema.json`, `distutils.schema.json`: 5 | - project: `validate-pyproject` - licensed under MPL-2.0 6 | (https://github.com/abravalheri/validate-pyproject): 7 | 8 | This Source Code Form is subject to the terms of the Mozilla Public 9 | License, v. 2.0. If a copy of the MPL was not distributed with this file, 10 | You can obtain one at https://mozilla.org/MPL/2.0/. 11 | -------------------------------------------------------------------------------- /setuptools/config/__init__.py: -------------------------------------------------------------------------------- 1 | """For backward compatibility, expose main functions from 2 | ``setuptools.config.setupcfg`` 3 | """ 4 | 5 | from functools import wraps 6 | from typing import Callable, TypeVar, cast 7 | 8 | from ..warnings import SetuptoolsDeprecationWarning 9 | from . import setupcfg 10 | 11 | Fn = TypeVar("Fn", bound=Callable) 12 | 13 | __all__ = ('parse_configuration', 'read_configuration') 14 | 15 | 16 | def _deprecation_notice(fn: Fn) -> Fn: 17 | @wraps(fn) 18 | def _wrapper(*args, **kwargs): 19 | SetuptoolsDeprecationWarning.emit( 20 | "Deprecated API usage.", 21 | f""" 22 | As setuptools moves its configuration towards `pyproject.toml`, 23 | `{__name__}.{fn.__name__}` became deprecated. 24 | 25 | For the time being, you can use the `{setupcfg.__name__}` module 26 | to access a backward compatible API, but this module is provisional 27 | and might be removed in the future. 28 | 29 | To read project metadata, consider using 30 | ``build.util.project_wheel_metadata`` (https://pypi.org/project/build/). 31 | For simple scenarios, you can also try parsing the file directly 32 | with the help of ``configparser``. 33 | """, 34 | # due_date not defined yet, because the community still heavily relies on it 35 | # Warning introduced in 24 Mar 2022 36 | ) 37 | return fn(*args, **kwargs) 38 | 39 | return cast(Fn, _wrapper) 40 | 41 | 42 | read_configuration = _deprecation_notice(setupcfg.read_configuration) 43 | parse_configuration = _deprecation_notice(setupcfg.parse_configuration) 44 | -------------------------------------------------------------------------------- /setuptools/config/_validate_pyproject/__init__.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | from typing import Any, Callable, Dict 3 | 4 | from . import formats 5 | from .error_reporting import detailed_errors, ValidationError 6 | from .extra_validations import EXTRA_VALIDATIONS 7 | from .fastjsonschema_exceptions import JsonSchemaException, JsonSchemaValueException 8 | from .fastjsonschema_validations import validate as _validate 9 | 10 | __all__ = [ 11 | "validate", 12 | "FORMAT_FUNCTIONS", 13 | "EXTRA_VALIDATIONS", 14 | "ValidationError", 15 | "JsonSchemaException", 16 | "JsonSchemaValueException", 17 | ] 18 | 19 | 20 | FORMAT_FUNCTIONS: Dict[str, Callable[[str], bool]] = { 21 | fn.__name__.replace("_", "-"): fn 22 | for fn in formats.__dict__.values() 23 | if callable(fn) and not fn.__name__.startswith("_") 24 | } 25 | 26 | 27 | def validate(data: Any) -> bool: 28 | """Validate the given ``data`` object using JSON Schema 29 | This function raises ``ValidationError`` if ``data`` is invalid. 30 | """ 31 | with detailed_errors(): 32 | _validate(data, custom_formats=FORMAT_FUNCTIONS) 33 | reduce(lambda acc, fn: fn(acc), EXTRA_VALIDATIONS, data) 34 | return True 35 | -------------------------------------------------------------------------------- /setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | SPLIT_RE = re.compile(r'[\.\[\]]+') 5 | 6 | 7 | class JsonSchemaException(ValueError): 8 | """ 9 | Base exception of ``fastjsonschema`` library. 10 | """ 11 | 12 | 13 | class JsonSchemaValueException(JsonSchemaException): 14 | """ 15 | Exception raised by validation function. Available properties: 16 | 17 | * ``message`` containing human-readable information what is wrong (e.g. ``data.property[index] must be smaller than or equal to 42``), 18 | * invalid ``value`` (e.g. ``60``), 19 | * ``name`` of a path in the data structure (e.g. ``data.property[index]``), 20 | * ``path`` as an array in the data structure (e.g. ``['data', 'property', 'index']``), 21 | * the whole ``definition`` which the ``value`` has to fulfil (e.g. ``{'type': 'number', 'maximum': 42}``), 22 | * ``rule`` which the ``value`` is breaking (e.g. ``maximum``) 23 | * and ``rule_definition`` (e.g. ``42``). 24 | 25 | .. versionchanged:: 2.14.0 26 | Added all extra properties. 27 | """ 28 | 29 | def __init__(self, message, value=None, name=None, definition=None, rule=None): 30 | super().__init__(message) 31 | self.message = message 32 | self.value = value 33 | self.name = name 34 | self.definition = definition 35 | self.rule = rule 36 | 37 | @property 38 | def path(self): 39 | return [item for item in SPLIT_RE.split(self.name) if item != ''] 40 | 41 | @property 42 | def rule_definition(self): 43 | if not self.rule or not self.definition: 44 | return None 45 | return self.definition.get(self.rule) 46 | 47 | 48 | class JsonSchemaDefinitionException(JsonSchemaException): 49 | """ 50 | Exception raised by generator of validation function. 51 | """ 52 | -------------------------------------------------------------------------------- /setuptools/config/distutils.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | 4 | "$id": "https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html", 5 | "title": "``tool.distutils`` table", 6 | "$$description": [ 7 | "**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``", 8 | "subtables to configure arguments for ``distutils`` commands.", 9 | "Originally, ``distutils`` allowed developers to configure arguments for", 10 | "``setup.py`` commands via `distutils configuration files", 11 | "`_.", 12 | "See also `the old Python docs _`." 13 | ], 14 | 15 | "type": "object", 16 | "properties": { 17 | "global": { 18 | "type": "object", 19 | "description": "Global options applied to all ``distutils`` commands" 20 | } 21 | }, 22 | "patternProperties": { 23 | ".+": {"type": "object"} 24 | }, 25 | "$comment": "TODO: Is there a practical way of making this schema more specific?" 26 | } 27 | -------------------------------------------------------------------------------- /setuptools/gui-32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/gui-32.exe -------------------------------------------------------------------------------- /setuptools/gui-64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/gui-64.exe -------------------------------------------------------------------------------- /setuptools/gui-arm64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/gui-arm64.exe -------------------------------------------------------------------------------- /setuptools/gui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/gui.exe -------------------------------------------------------------------------------- /setuptools/launch.py: -------------------------------------------------------------------------------- 1 | """ 2 | Launch the Python script on the command line after 3 | setuptools is bootstrapped via import. 4 | """ 5 | 6 | # Note that setuptools gets imported implicitly by the 7 | # invocation of this script using python -m setuptools.launch 8 | 9 | import sys 10 | import tokenize 11 | 12 | 13 | def run() -> None: 14 | """ 15 | Run the script in sys.argv[1] as if it had 16 | been invoked naturally. 17 | """ 18 | __builtins__ 19 | script_name = sys.argv[1] 20 | namespace = dict( 21 | __file__=script_name, 22 | __name__='__main__', 23 | __doc__=None, 24 | ) 25 | sys.argv[:] = sys.argv[1:] 26 | 27 | open_ = getattr(tokenize, 'open', open) 28 | with open_(script_name) as fid: 29 | script = fid.read() 30 | norm_script = script.replace('\\r\\n', '\\n') 31 | code = compile(norm_script, script_name, 'exec') 32 | exec(code, namespace) 33 | 34 | 35 | if __name__ == '__main__': 36 | run() 37 | -------------------------------------------------------------------------------- /setuptools/logging.py: -------------------------------------------------------------------------------- 1 | import inspect 2 | import logging 3 | import sys 4 | 5 | from . import monkey 6 | 7 | import distutils.log 8 | 9 | 10 | def _not_warning(record): 11 | return record.levelno < logging.WARNING 12 | 13 | 14 | def configure() -> None: 15 | """ 16 | Configure logging to emit warning and above to stderr 17 | and everything else to stdout. This behavior is provided 18 | for compatibility with distutils.log but may change in 19 | the future. 20 | """ 21 | err_handler = logging.StreamHandler() 22 | err_handler.setLevel(logging.WARNING) 23 | out_handler = logging.StreamHandler(sys.stdout) 24 | out_handler.addFilter(_not_warning) 25 | handlers = err_handler, out_handler 26 | logging.basicConfig( 27 | format="{message}", style='{', handlers=handlers, level=logging.DEBUG 28 | ) 29 | if inspect.ismodule(distutils.dist.log): 30 | monkey.patch_func(set_threshold, distutils.log, 'set_threshold') 31 | # For some reason `distutils.log` module is getting cached in `distutils.dist` 32 | # and then loaded again when patched, 33 | # implying: id(distutils.log) != id(distutils.dist.log). 34 | # Make sure the same module object is used everywhere: 35 | distutils.dist.log = distutils.log 36 | 37 | 38 | def set_threshold(level: int) -> int: 39 | logging.root.setLevel(level * 10) 40 | return set_threshold.unpatched(level) 41 | -------------------------------------------------------------------------------- /setuptools/modified.py: -------------------------------------------------------------------------------- 1 | try: 2 | # Ensure a DistutilsError raised by these methods is the same as distutils.errors.DistutilsError 3 | from distutils._modified import ( 4 | newer, 5 | newer_group, 6 | newer_pairwise, 7 | newer_pairwise_group, 8 | ) 9 | except ImportError: 10 | # fallback for SETUPTOOLS_USE_DISTUTILS=stdlib, because _modified never existed in stdlib 11 | from ._distutils._modified import ( 12 | newer, 13 | newer_group, 14 | newer_pairwise, 15 | newer_pairwise_group, 16 | ) 17 | 18 | __all__ = ['newer', 'newer_pairwise', 'newer_group', 'newer_pairwise_group'] 19 | -------------------------------------------------------------------------------- /setuptools/script (dev).tmpl: -------------------------------------------------------------------------------- 1 | # EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r 2 | __requires__ = %(spec)r 3 | __import__('pkg_resources').require(%(spec)r) 4 | __file__ = %(dev_path)r 5 | with open(__file__) as f: 6 | exec(compile(f.read(), __file__, 'exec')) 7 | -------------------------------------------------------------------------------- /setuptools/script.tmpl: -------------------------------------------------------------------------------- 1 | # EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r 2 | __requires__ = %(spec)r 3 | __import__('pkg_resources').run_script(%(spec)r, %(script_name)r) 4 | -------------------------------------------------------------------------------- /setuptools/tests/__init__.py: -------------------------------------------------------------------------------- 1 | import locale 2 | import sys 3 | 4 | import pytest 5 | 6 | __all__ = ['fail_on_ascii'] 7 | 8 | if sys.version_info >= (3, 11): 9 | locale_encoding = locale.getencoding() 10 | else: 11 | locale_encoding = locale.getpreferredencoding(False) 12 | is_ascii = locale_encoding == 'ANSI_X3.4-1968' 13 | fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale") 14 | -------------------------------------------------------------------------------- /setuptools/tests/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/tests/compat/__init__.py -------------------------------------------------------------------------------- /setuptools/tests/compat/py39.py: -------------------------------------------------------------------------------- 1 | from jaraco.test.cpython import from_test_support, try_import 2 | 3 | os_helper = try_import('os_helper') or from_test_support('can_symlink') 4 | -------------------------------------------------------------------------------- /setuptools/tests/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/tests/config/__init__.py -------------------------------------------------------------------------------- /setuptools/tests/config/downloads/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !__init__.py 4 | !preload.py 5 | -------------------------------------------------------------------------------- /setuptools/tests/config/downloads/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import re 4 | import time 5 | from pathlib import Path 6 | from urllib.error import HTTPError 7 | from urllib.request import urlopen 8 | 9 | __all__ = ["DOWNLOAD_DIR", "retrieve_file", "output_file", "urls_from_file"] 10 | 11 | 12 | NAME_REMOVE = ("http://", "https://", "github.com/", "/raw/") 13 | DOWNLOAD_DIR = Path(__file__).parent 14 | 15 | 16 | # ---------------------------------------------------------------------- 17 | # Please update ./preload.py accordingly when modifying this file 18 | # ---------------------------------------------------------------------- 19 | 20 | 21 | def output_file(url: str, download_dir: Path = DOWNLOAD_DIR) -> Path: 22 | file_name = url.strip() 23 | for part in NAME_REMOVE: 24 | file_name = file_name.replace(part, '').strip().strip('/:').strip() 25 | return Path(download_dir, re.sub(r"[^\-_\.\w\d]+", "_", file_name)) 26 | 27 | 28 | def retrieve_file(url: str, download_dir: Path = DOWNLOAD_DIR, wait: float = 5) -> Path: 29 | path = output_file(url, download_dir) 30 | if path.exists(): 31 | print(f"Skipping {url} (already exists: {path})") 32 | else: 33 | download_dir.mkdir(exist_ok=True, parents=True) 34 | print(f"Downloading {url} to {path}") 35 | try: 36 | download(url, path) 37 | except HTTPError: 38 | time.sleep(wait) # wait a few seconds and try again. 39 | download(url, path) 40 | return path 41 | 42 | 43 | def urls_from_file(list_file: Path) -> list[str]: 44 | """``list_file`` should be a text file where each line corresponds to a URL to 45 | download. 46 | """ 47 | print(f"file: {list_file}") 48 | content = list_file.read_text(encoding="utf-8") 49 | return [url for url in content.splitlines() if not url.startswith("#")] 50 | 51 | 52 | def download(url: str, dest: Path): 53 | with urlopen(url) as f: 54 | data = f.read() 55 | 56 | with open(dest, "wb") as f: 57 | f.write(data) 58 | 59 | assert Path(dest).exists() 60 | -------------------------------------------------------------------------------- /setuptools/tests/config/downloads/preload.py: -------------------------------------------------------------------------------- 1 | """This file can be used to preload files needed for testing. 2 | 3 | For example you can use:: 4 | 5 | cd setuptools/tests/config 6 | python -m downloads.preload setupcfg_examples.txt 7 | 8 | to make sure the `setup.cfg` examples are downloaded before starting the tests. 9 | """ 10 | 11 | import sys 12 | from pathlib import Path 13 | 14 | from . import retrieve_file, urls_from_file 15 | 16 | if __name__ == "__main__": 17 | urls = urls_from_file(Path(sys.argv[1])) 18 | list(map(retrieve_file, urls)) 19 | -------------------------------------------------------------------------------- /setuptools/tests/config/setupcfg_examples.txt: -------------------------------------------------------------------------------- 1 | # ==================================================================== 2 | # Some popular packages that use setup.cfg (and others not so popular) 3 | # Reference: https://hugovk.github.io/top-pypi-packages/ 4 | # ==================================================================== 5 | https://github.com/pypa/setuptools/raw/52c990172fec37766b3566679724aa8bf70ae06d/setup.cfg 6 | https://github.com/pypa/wheel/raw/0acd203cd896afec7f715aa2ff5980a403459a3b/setup.cfg 7 | https://github.com/python/importlib_metadata/raw/2f05392ca980952a6960d82b2f2d2ea10aa53239/setup.cfg 8 | https://github.com/jaraco/skeleton/raw/d9008b5c510cd6969127a6a2ab6f832edddef296/setup.cfg 9 | https://github.com/jaraco/zipp/raw/700d3a96390e970b6b962823bfea78b4f7e1c537/setup.cfg 10 | https://github.com/pallets/jinja/raw/7d72eb7fefb7dce065193967f31f805180508448/setup.cfg 11 | https://github.com/tkem/cachetools/raw/2fd87a94b8d3861d80e9e4236cd480bfdd21c90d/setup.cfg 12 | https://github.com/aio-libs/aiohttp/raw/5e0e6b7080f2408d5f1dd544c0e1cf88378b7b10/setup.cfg 13 | https://github.com/pallets/flask/raw/9486b6cf57bd6a8a261f67091aca8ca78eeec1e3/setup.cfg 14 | https://github.com/pallets/click/raw/6411f425fae545f42795665af4162006b36c5e4a/setup.cfg 15 | https://github.com/sqlalchemy/sqlalchemy/raw/533f5718904b620be8d63f2474229945d6f8ba5d/setup.cfg 16 | https://github.com/pytest-dev/pluggy/raw/461ef63291d13589c4e21aa182cd1529257e9a0a/setup.cfg 17 | https://github.com/pytest-dev/pytest/raw/c7be96dae487edbd2f55b561b31b68afac1dabe6/setup.cfg 18 | https://github.com/platformdirs/platformdirs/raw/7b7852128dd6f07511b618d6edea35046bd0c6ff/setup.cfg 19 | https://github.com/pandas-dev/pandas/raw/bc17343f934a33dc231c8c74be95d8365537c376/setup.cfg 20 | https://github.com/django/django/raw/4e249d11a6e56ca8feb4b055b681cec457ef3a3d/setup.cfg 21 | https://github.com/pyscaffold/pyscaffold/raw/de7aa5dc059fbd04307419c667cc4961bc9df4b8/setup.cfg 22 | https://github.com/pypa/virtualenv/raw/f92eda6e3da26a4d28c2663ffb85c4960bdb990c/setup.cfg 23 | -------------------------------------------------------------------------------- /setuptools/tests/indexes/test_links_priority/external.html: -------------------------------------------------------------------------------- 1 | 2 | bad old link 3 | 4 | -------------------------------------------------------------------------------- /setuptools/tests/indexes/test_links_priority/simple/foobar/index.html: -------------------------------------------------------------------------------- 1 | 2 | foobar-0.1.tar.gz
3 | external homepage
4 | 5 | -------------------------------------------------------------------------------- /setuptools/tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pypa/setuptools/c3f486f0f7ebf8fa141dfd7314cbcaba7370db0b/setuptools/tests/integration/__init__.py -------------------------------------------------------------------------------- /setuptools/tests/integration/test_pbr.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | import pytest 4 | 5 | 6 | @pytest.mark.uses_network 7 | def test_pbr_integration(pbr_package, venv): 8 | """Ensure pbr packages install.""" 9 | cmd = [ 10 | 'python', 11 | '-m', 12 | 'pip', 13 | '-v', 14 | 'install', 15 | '--no-build-isolation', 16 | pbr_package, 17 | ] 18 | venv.run(cmd, stderr=subprocess.STDOUT) 19 | out = venv.run(["python", "-c", "import mypkg.hello"]) 20 | assert "Hello world!" in out 21 | -------------------------------------------------------------------------------- /setuptools/tests/mod_with_constant.py: -------------------------------------------------------------------------------- 1 | value = 'three, sir!' 2 | -------------------------------------------------------------------------------- /setuptools/tests/script-with-bom.py: -------------------------------------------------------------------------------- 1 | result = 'passed' 2 | -------------------------------------------------------------------------------- /setuptools/tests/test_archive_util.py: -------------------------------------------------------------------------------- 1 | import io 2 | import tarfile 3 | 4 | import pytest 5 | 6 | from setuptools import archive_util 7 | 8 | 9 | @pytest.fixture 10 | def tarfile_with_unicode(tmpdir): 11 | """ 12 | Create a tarfile containing only a file whose name is 13 | a zero byte file called testimäge.png. 14 | """ 15 | tarobj = io.BytesIO() 16 | 17 | with tarfile.open(fileobj=tarobj, mode="w:gz") as tgz: 18 | data = b"" 19 | 20 | filename = "testimäge.png" 21 | 22 | t = tarfile.TarInfo(filename) 23 | t.size = len(data) 24 | 25 | tgz.addfile(t, io.BytesIO(data)) 26 | 27 | target = tmpdir / 'unicode-pkg-1.0.tar.gz' 28 | with open(str(target), mode='wb') as tf: 29 | tf.write(tarobj.getvalue()) 30 | return str(target) 31 | 32 | 33 | @pytest.mark.xfail(reason="#710 and #712") 34 | def test_unicode_files(tarfile_with_unicode, tmpdir): 35 | target = tmpdir / 'out' 36 | archive_util.unpack_archive(tarfile_with_unicode, str(target)) 37 | -------------------------------------------------------------------------------- /setuptools/tests/test_bdist_deprecations.py: -------------------------------------------------------------------------------- 1 | """develop tests""" 2 | 3 | import sys 4 | from unittest import mock 5 | 6 | import pytest 7 | 8 | from setuptools import SetuptoolsDeprecationWarning 9 | from setuptools.dist import Distribution 10 | 11 | 12 | @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only') 13 | @pytest.mark.xfail(reason="bdist_rpm is long deprecated, should we remove it? #1988") 14 | @mock.patch('distutils.command.bdist_rpm.bdist_rpm') 15 | def test_bdist_rpm_warning(distutils_cmd, tmpdir_cwd): 16 | dist = Distribution( 17 | dict( 18 | script_name='setup.py', 19 | script_args=['bdist_rpm'], 20 | name='foo', 21 | py_modules=['hi'], 22 | ) 23 | ) 24 | dist.parse_command_line() 25 | with pytest.warns(SetuptoolsDeprecationWarning): 26 | dist.run_commands() 27 | 28 | distutils_cmd.run.assert_called_once() 29 | -------------------------------------------------------------------------------- /setuptools/tests/test_bdist_egg.py: -------------------------------------------------------------------------------- 1 | """develop tests""" 2 | 3 | import os 4 | import re 5 | import zipfile 6 | 7 | import pytest 8 | 9 | from setuptools.dist import Distribution 10 | 11 | from . import contexts 12 | 13 | SETUP_PY = """\ 14 | from setuptools import setup 15 | 16 | setup(py_modules=['hi']) 17 | """ 18 | 19 | 20 | @pytest.fixture 21 | def setup_context(tmpdir): 22 | with (tmpdir / 'setup.py').open('w') as f: 23 | f.write(SETUP_PY) 24 | with (tmpdir / 'hi.py').open('w') as f: 25 | f.write('1\n') 26 | with tmpdir.as_cwd(): 27 | yield tmpdir 28 | 29 | 30 | class Test: 31 | @pytest.mark.usefixtures("user_override") 32 | @pytest.mark.usefixtures("setup_context") 33 | def test_bdist_egg(self): 34 | dist = Distribution( 35 | dict( 36 | script_name='setup.py', 37 | script_args=['bdist_egg'], 38 | name='foo', 39 | py_modules=['hi'], 40 | ) 41 | ) 42 | os.makedirs(os.path.join('build', 'src')) 43 | with contexts.quiet(): 44 | dist.parse_command_line() 45 | dist.run_commands() 46 | 47 | # let's see if we got our egg link at the right place 48 | [content] = os.listdir('dist') 49 | assert re.match(r'foo-0.0.0-py[23].\d+.egg$', content) 50 | 51 | @pytest.mark.xfail( 52 | os.environ.get('PYTHONDONTWRITEBYTECODE', False), 53 | reason="Byte code disabled", 54 | ) 55 | @pytest.mark.usefixtures("user_override") 56 | @pytest.mark.usefixtures("setup_context") 57 | def test_exclude_source_files(self): 58 | dist = Distribution( 59 | dict( 60 | script_name='setup.py', 61 | script_args=['bdist_egg', '--exclude-source-files'], 62 | py_modules=['hi'], 63 | ) 64 | ) 65 | with contexts.quiet(): 66 | dist.parse_command_line() 67 | dist.run_commands() 68 | [dist_name] = os.listdir('dist') 69 | dist_filename = os.path.join('dist', dist_name) 70 | zip = zipfile.ZipFile(dist_filename) 71 | names = list(zi.filename for zi in zip.filelist) 72 | assert 'hi.pyc' in names 73 | assert 'hi.py' not in names 74 | -------------------------------------------------------------------------------- /setuptools/tests/test_build.py: -------------------------------------------------------------------------------- 1 | from setuptools import Command 2 | from setuptools.command.build import build 3 | from setuptools.dist import Distribution 4 | 5 | 6 | def test_distribution_gives_setuptools_build_obj(tmpdir_cwd): 7 | """ 8 | Check that the setuptools Distribution uses the 9 | setuptools specific build object. 10 | """ 11 | 12 | dist = Distribution( 13 | dict( 14 | script_name='setup.py', 15 | script_args=['build'], 16 | packages=[], 17 | package_data={'': ['path/*']}, 18 | ) 19 | ) 20 | assert isinstance(dist.get_command_obj("build"), build) 21 | 22 | 23 | class Subcommand(Command): 24 | """Dummy command to be used in tests""" 25 | 26 | def initialize_options(self): 27 | pass 28 | 29 | def finalize_options(self): 30 | pass 31 | 32 | def run(self): 33 | raise NotImplementedError("just to check if the command runs") 34 | -------------------------------------------------------------------------------- /setuptools/tests/test_depends.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from setuptools import depends 4 | 5 | 6 | class TestGetModuleConstant: 7 | def test_basic(self): 8 | """ 9 | Invoke get_module_constant on a module in 10 | the test package. 11 | """ 12 | mod_name = 'setuptools.tests.mod_with_constant' 13 | val = depends.get_module_constant(mod_name, 'value') 14 | assert val == 'three, sir!' 15 | assert 'setuptools.tests.mod_with_constant' not in sys.modules 16 | -------------------------------------------------------------------------------- /setuptools/tests/test_extern.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import pickle 3 | 4 | import packaging 5 | 6 | from setuptools import Distribution 7 | 8 | 9 | def test_reimport_extern(): 10 | packaging2 = importlib.import_module(packaging.__name__) 11 | assert packaging is packaging2 12 | 13 | 14 | def test_distribution_picklable(): 15 | pickle.loads(pickle.dumps(Distribution())) 16 | -------------------------------------------------------------------------------- /setuptools/tests/test_glob.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from jaraco import path 3 | 4 | from setuptools.glob import glob 5 | 6 | 7 | @pytest.mark.parametrize( 8 | ('tree', 'pattern', 'matches'), 9 | ( 10 | ('', b'', []), 11 | ('', '', []), 12 | ( 13 | """ 14 | appveyor.yml 15 | CHANGES.rst 16 | LICENSE 17 | MANIFEST.in 18 | pyproject.toml 19 | README.rst 20 | setup.cfg 21 | setup.py 22 | """, 23 | '*.rst', 24 | ('CHANGES.rst', 'README.rst'), 25 | ), 26 | ( 27 | """ 28 | appveyor.yml 29 | CHANGES.rst 30 | LICENSE 31 | MANIFEST.in 32 | pyproject.toml 33 | README.rst 34 | setup.cfg 35 | setup.py 36 | """, 37 | b'*.rst', 38 | (b'CHANGES.rst', b'README.rst'), 39 | ), 40 | ), 41 | ) 42 | def test_glob(monkeypatch, tmpdir, tree, pattern, matches): 43 | monkeypatch.chdir(tmpdir) 44 | path.build({name: '' for name in tree.split()}) 45 | assert list(sorted(glob(pattern))) == list(sorted(matches)) 46 | -------------------------------------------------------------------------------- /setuptools/tests/test_scripts.py: -------------------------------------------------------------------------------- 1 | from setuptools import _scripts 2 | 3 | 4 | class TestWindowsScriptWriter: 5 | def test_header(self): 6 | hdr = _scripts.WindowsScriptWriter.get_header('') 7 | assert hdr.startswith('#!') 8 | assert hdr.endswith('\n') 9 | hdr = hdr.lstrip('#!') 10 | hdr = hdr.rstrip('\n') 11 | # header should not start with an escaped quote 12 | assert not hdr.startswith('\\"') 13 | -------------------------------------------------------------------------------- /setuptools/tests/test_setopt.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | 3 | from setuptools.command import setopt 4 | 5 | 6 | class TestEdit: 7 | @staticmethod 8 | def parse_config(filename): 9 | parser = configparser.ConfigParser() 10 | with open(filename, encoding='utf-8') as reader: 11 | parser.read_file(reader) 12 | return parser 13 | 14 | @staticmethod 15 | def write_text(file, content): 16 | with open(file, 'wb') as strm: 17 | strm.write(content.encode('utf-8')) 18 | 19 | def test_utf8_encoding_retained(self, tmpdir): 20 | """ 21 | When editing a file, non-ASCII characters encoded in 22 | UTF-8 should be retained. 23 | """ 24 | config = tmpdir.join('setup.cfg') 25 | self.write_text(str(config), '[names]\njaraco=джарако') 26 | setopt.edit_config(str(config), dict(names=dict(other='yes'))) 27 | parser = self.parse_config(str(config)) 28 | assert parser.get('names', 'jaraco') == 'джарако' 29 | assert parser.get('names', 'other') == 'yes' 30 | 31 | def test_case_retained(self, tmpdir): 32 | """ 33 | When editing a file, case of keys should be retained. 34 | """ 35 | config = tmpdir.join('setup.cfg') 36 | self.write_text(str(config), '[names]\nFoO=bAr') 37 | setopt.edit_config(str(config), dict(names=dict(oTher='yes'))) 38 | actual = config.read_text(encoding='ascii') 39 | assert 'FoO' in actual 40 | assert 'oTher' in actual 41 | -------------------------------------------------------------------------------- /setuptools/tests/test_shutil_wrapper.py: -------------------------------------------------------------------------------- 1 | import stat 2 | import sys 3 | from unittest.mock import Mock 4 | 5 | from setuptools import _shutil 6 | 7 | 8 | def test_rmtree_readonly(monkeypatch, tmp_path): 9 | """Verify onerr works as expected""" 10 | 11 | tmp_dir = tmp_path / "with_readonly" 12 | tmp_dir.mkdir() 13 | some_file = tmp_dir.joinpath("file.txt") 14 | some_file.touch() 15 | some_file.chmod(stat.S_IREAD) 16 | 17 | expected_count = 1 if sys.platform.startswith("win") else 0 18 | chmod_fn = Mock(wraps=_shutil.attempt_chmod_verbose) 19 | monkeypatch.setattr(_shutil, "attempt_chmod_verbose", chmod_fn) 20 | 21 | _shutil.rmtree(tmp_dir) 22 | assert chmod_fn.call_count == expected_count 23 | assert not tmp_dir.is_dir() 24 | -------------------------------------------------------------------------------- /setuptools/tests/test_unicode_utils.py: -------------------------------------------------------------------------------- 1 | from setuptools import unicode_utils 2 | 3 | 4 | def test_filesys_decode_fs_encoding_is_None(monkeypatch): 5 | """ 6 | Test filesys_decode does not raise TypeError when 7 | getfilesystemencoding returns None. 8 | """ 9 | monkeypatch.setattr('sys.getfilesystemencoding', lambda: None) 10 | unicode_utils.filesys_decode(b'test') 11 | -------------------------------------------------------------------------------- /setuptools/tests/text.py: -------------------------------------------------------------------------------- 1 | class Filenames: 2 | unicode = 'smörbröd.py' 3 | latin_1 = unicode.encode('latin-1') 4 | utf_8 = unicode.encode('utf-8') 5 | -------------------------------------------------------------------------------- /setuptools/tests/textwrap.py: -------------------------------------------------------------------------------- 1 | import textwrap 2 | 3 | 4 | def DALS(s): 5 | "dedent and left-strip" 6 | return textwrap.dedent(s).lstrip() 7 | -------------------------------------------------------------------------------- /setuptools/version.py: -------------------------------------------------------------------------------- 1 | from ._importlib import metadata 2 | 3 | try: 4 | __version__ = metadata.version('setuptools') or '0.dev0+unknown' 5 | except Exception: 6 | __version__ = '0.dev0+unknown' 7 | -------------------------------------------------------------------------------- /setuptools/windows_support.py: -------------------------------------------------------------------------------- 1 | import platform 2 | 3 | 4 | def windows_only(func): 5 | if platform.system() != 'Windows': 6 | return lambda *args, **kwargs: None 7 | return func 8 | 9 | 10 | @windows_only 11 | def hide_file(path: str) -> None: 12 | """ 13 | Set the hidden attribute on a file or directory. 14 | 15 | From https://stackoverflow.com/questions/19622133/ 16 | 17 | `path` must be text. 18 | """ 19 | import ctypes 20 | import ctypes.wintypes 21 | 22 | SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW 23 | SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD 24 | SetFileAttributes.restype = ctypes.wintypes.BOOL 25 | 26 | FILE_ATTRIBUTE_HIDDEN = 0x02 27 | 28 | ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN) 29 | if not ret: 30 | raise ctypes.WinError() 31 | -------------------------------------------------------------------------------- /tools/finalize.py: -------------------------------------------------------------------------------- 1 | """ 2 | Finalize the repo for a release. Invokes towncrier and bumpversion. 3 | """ 4 | 5 | __requires__ = ['bump2version', 'towncrier', 'jaraco.develop>=7.21'] 6 | 7 | 8 | import pathlib 9 | import re 10 | import subprocess 11 | import sys 12 | 13 | from jaraco.develop import towncrier 14 | 15 | bump_version_command = [ 16 | sys.executable, 17 | '-m', 18 | 'bumpversion', 19 | towncrier.release_kind(), 20 | ] 21 | 22 | 23 | def get_version(): 24 | cmd = bump_version_command + ['--dry-run', '--verbose'] 25 | out = subprocess.check_output(cmd, text=True, encoding='utf-8') 26 | return re.search('^new_version=(.*)', out, re.MULTILINE).group(1) 27 | 28 | 29 | def update_changelog(): 30 | towncrier.run('build', '--yes') 31 | _repair_changelog() 32 | 33 | 34 | def _repair_changelog(): 35 | """ 36 | Workaround for #2666 37 | """ 38 | changelog_fn = pathlib.Path('NEWS.rst') 39 | changelog = changelog_fn.read_text(encoding='utf-8') 40 | fixed = re.sub(r'^(v[0-9.]+)v[0-9.]+$', r'\1', changelog, flags=re.MULTILINE) 41 | changelog_fn.write_text(fixed, encoding='utf-8') 42 | subprocess.check_output(['git', 'add', changelog_fn]) 43 | 44 | 45 | def bump_version(): 46 | cmd = bump_version_command + ['--allow-dirty'] 47 | subprocess.check_call(cmd) 48 | 49 | 50 | def ensure_config(): 51 | """ 52 | Double-check that Git has an e-mail configured. 53 | """ 54 | subprocess.check_output(['git', 'config', 'user.email']) 55 | 56 | 57 | if __name__ == '__main__': 58 | print("Cutting release at", get_version()) 59 | ensure_config() 60 | towncrier.check_changes() 61 | update_changelog() 62 | bump_version() 63 | -------------------------------------------------------------------------------- /tools/generate_validation_code.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import itertools 4 | import subprocess 5 | import sys 6 | from collections.abc import Iterable 7 | from pathlib import Path 8 | 9 | 10 | def generate_pyproject_validation(dest: Path, schemas: Iterable[Path]) -> bool: 11 | """ 12 | Generates validation code for ``pyproject.toml`` based on JSON schemas and the 13 | ``validate-pyproject`` library. 14 | """ 15 | schema_args = (("-t", f"{f.name.partition('.')[0]}={f}") for f in schemas) 16 | cmd = [ 17 | sys.executable, 18 | "-m", 19 | "validate_pyproject.pre_compile", 20 | f"--output-dir={dest}", 21 | "--enable-plugins", 22 | "setuptools", 23 | "distutils", 24 | "--very-verbose", 25 | *itertools.chain.from_iterable(schema_args), 26 | ] 27 | subprocess.check_call(cmd) 28 | print(f"Validation code generated at: {dest}") 29 | return True 30 | 31 | 32 | def main() -> bool: 33 | return generate_pyproject_validation( 34 | Path("setuptools/config/_validate_pyproject"), 35 | schemas=Path("setuptools/config").glob("*.schema.json"), 36 | ) 37 | 38 | 39 | __name__ == '__main__' and main() 40 | -------------------------------------------------------------------------------- /tools/vendored.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import re 3 | import subprocess 4 | 5 | import jaraco.packaging.metadata 6 | from path import Path 7 | 8 | 9 | def remove_all(paths): 10 | for path in paths: 11 | path.rmtree() if path.is_dir() else path.remove() 12 | 13 | 14 | def update_vendored(): 15 | update_setuptools() 16 | 17 | 18 | def clean(vendor): 19 | """ 20 | Remove all files out of the vendor directory except the meta 21 | data (as pip uninstall doesn't support -t). 22 | """ 23 | ignored = ['ruff.toml'] 24 | remove_all(path for path in vendor.glob('*') if path.basename() not in ignored) 25 | 26 | 27 | @functools.lru_cache 28 | def metadata(): 29 | return jaraco.packaging.metadata.load('.') 30 | 31 | 32 | def upgrade_core(dep): 33 | """ 34 | Remove 'extra == "core"' from any dependency. 35 | """ 36 | return re.sub('''(;| and) extra == ['"]core['"]''', '', dep) 37 | 38 | 39 | def load_deps(): 40 | """ 41 | Read the dependencies from `.[core]`. 42 | """ 43 | return list(map(upgrade_core, metadata().get_all('Requires-Dist'))) 44 | 45 | 46 | def min_python(): 47 | return metadata()['Requires-Python'].removeprefix('>=').strip() 48 | 49 | 50 | def install_deps(deps, vendor): 51 | """ 52 | Install the deps to vendor. 53 | """ 54 | install_args = [ 55 | 'uv', 56 | 'pip', 57 | 'install', 58 | '--target', 59 | str(vendor), 60 | '--python-version', 61 | min_python(), 62 | '--only-binary', 63 | ':all:', 64 | ] + list(deps) 65 | subprocess.check_call(install_args) 66 | 67 | 68 | def update_setuptools(): 69 | vendor = Path('setuptools/_vendor') 70 | deps = load_deps() 71 | clean(vendor) 72 | install_deps(deps, vendor) 73 | 74 | 75 | __name__ == '__main__' and update_vendored() 76 | -------------------------------------------------------------------------------- /towncrier.toml: -------------------------------------------------------------------------------- 1 | [tool.towncrier] 2 | title_format = "{version}" 3 | # workaround for sphinx-contrib/sphinxcontrib-towncrier#83 4 | directory = "newsfragments" 5 | --------------------------------------------------------------------------------