Core utilities for Python packages

Overview

packaging

Reusable core utilities for various Python Packaging interoperability specifications.

This library provides utilities that implement the interoperability specifications which have clearly one correct behaviour (eg: PEP 440) or benefit greatly from having a single shared implementation (eg: PEP 425).

The packaging project includes the following: version handling, specifiers, markers, requirements, tags, utilities.

Documentation

The documentation provides information and the API for the following:

  • Version Handling
  • Specifiers
  • Markers
  • Requirements
  • Tags
  • Utilities

Installation

Use pip to install these utilities:

pip install packaging

Discussion

If you run into bugs, you can file them in our issue tracker.

You can also join #pypa on Freenode to ask questions or get involved.

Code of Conduct

Everyone interacting in the packaging project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the PSF Code of Conduct.

Contributing

The CONTRIBUTING.rst file outlines how to contribute to this project as well as how to report a potential security issue. The documentation for this project also covers information about project development and security.

Project History

Please review the CHANGELOG.rst file or the Changelog documentation for recent changes and project history.

Comments
  • Add a metadata API

    Add a metadata API

    This is related to #147, but not quite since I want to go beyond validation and have read/write support for things like TOML, METADATA, etc.

    I see two potential API forms. One is a dataclass-like object that stores the data with some methods to help read/write to various formats. The other form is a dict with various functions to manage the reading/writing.

    I actually think the dict approach might be the best and easiest to work with for two reasons. One, I don't see anything inherent in the potential design that will require OOP (i.e. method overriding to influence results). I have not thought of an API that would call other methods where overriding would be necessary.

    Two, it makes representing the explicit lack of data versus what goes into dynamic ala PEP 621 more obvious. If the lack of a key means "information is explicitly not provided", then that can be expressed in a dict. If we make the existence of a key with a None value represent something that would go into dynamic, then we don't have to maintain dynamic details separately. Using a dataclass doesn't buy us anything over this as it makes representing no data a little trickier as we would have to add some way to delineate that (e.g. some other false value that isn't None?). Best benefit to a dataclass I can think of is a property to dynamically calculate dynamic (😁 ) which could also be done with a function.

    There's also no loss in typing as a partial TypedDict would work in this instance.

    So for me, the simplicity of using a dict for storing data in the appropriate formats and using the lack of key to delineate purposefully missing data is the way to go.

    enhancement 
    opened by brettcannon 119
  • refactor _generic_api to use EXT_SUFFIX

    refactor _generic_api to use EXT_SUFFIX

    Fixes #606 where PyPy would like to change its non-compliant SOABI tag (pypy36-pp73) to a compliant one (pypy39-pp73-x86_64-linux-gnu).

    The basic code is ~taken from wheel.bdist_wheel's version.~ changed to use EXT_SUFFIX instead of SOABI.

    A few other changes:

    • return a list instead of a iterator, since all uses of the function converted to a list anyway ~- add a fallback for older cpython to call _cpython_abis, which means passing in PythonVersion~
    • clarify the typical value of interpreter_name, since it actually is the 'cp' or 'pp' short name.

    If I was starting over, PyPy's ABI tag would be pp39_73 rather than pypy39_73 to save two letters. Maybe someday ...

    Edit (11-Nov-2022): refactored to use EXT_SUFFIX

    packaging.tags 
    opened by mattip 49
  • Release 22.0

    Release 22.0

    @pypa/packaging-committers Any concerns with me putting on the RM hat for making this release, and cutting it sometime in the next few weeks?

    I think we can make this, once #484 merges.

    /cc @sbidoul, to flag that I'd like this to be in time for pip 22.2. :)

    infrastructure 
    opened by pradyunsg 38
  • add support for macos 11.0, arm64, universal2

    add support for macos 11.0, arm64, universal2

    This updates packaging to know about Mac OS version 11.0, which supports both x86_64 and arm64 arches.

    It will allow pip to install x86_64 wheels built for previous versions of Mac OS onto 11.0

    see: https://github.com/pypa/packaging/issues/318 see: https://discuss.python.org/t/apple-silicon-and-packaging/4516 see: https://github.com/python/cpython/pull/21246

    enhancement packaging.tags 
    opened by lawrence-danna-apple 34
  • Modify AIX platform_tag so it provides PEP425 needs

    Modify AIX platform_tag so it provides PEP425 needs

    Provide an adequate platform tag for AIX. The generic tag provided by distutils.util.get_platform() is insufficient - besides missing "bitness" it does not provide any information regarding Technology Level, nor build date.

    enhancement packaging.tags 
    opened by aixtools 32
  • Support PEP 600 tags

    Support PEP 600 tags

    xref gh-280. This adds a whole bunch of PEP 600 tags (my python reports `os.confstr('CS_GNU_LIBC_VERSION') of 2.27): EDIT: after reversing the order in f432bcd93f4

    >>> from packaging import tags
    >>> print ('\n'.join([str(t) for t in tags.sys_tags()]))
    cp37-cp37m-manylinux_2_27_x86_64
    cp37-cp37m-manylinux_2_26_x86_64
    cp37-cp37m-manylinux_2_25_x86_64
    cp37-cp37m-manylinux_2_24_x86_64
    cp37-cp37m-manylinux_2_23_x86_64
    cp37-cp37m-manylinux_2_22_x86_64
    cp37-cp37m-manylinux_2_21_x86_64
    cp37-cp37m-manylinux_2_20_x86_64
    cp37-cp37m-manylinux_2_19_x86_64
    cp37-cp37m-manylinux_2_18_x86_64
    cp37-cp37m-manylinux_2_17_x86_64
    cp37-cp37m-manylinux2014_x86_64
    cp37-cp37m-manylinux_2_16_x86_64
    cp37-cp37m-manylinux_2_15_x86_64
    cp37-cp37m-manylinux_2_14_x86_64
    cp37-cp37m-manylinux_2_13_x86_64
    cp37-cp37m-manylinux_2_12_x86_64
    cp37-cp37m-manylinux2010_x86_64
    cp37-cp37m-manylinux_2_11_x86_64
    cp37-cp37m-manylinux_2_10_x86_64
    cp37-cp37m-manylinux_2_9_x86_64
    cp37-cp37m-manylinux_2_8_x86_64
    cp37-cp37m-manylinux_2_7_x86_64
    cp37-cp37m-manylinux_2_6_x86_64
    cp37-cp37m-manylinux_2_5_x86_64
    cp37-cp37m-manylinux1_x86_64
    cp37-cp37m-linux_x86_64
    cp37-abi3-manylinux_2_27_x86_64
    ...
    
    packaging.tags 
    opened by mattip 30
  • packaging does not know that macOS 10.16 and 11.0 are the same

    packaging does not know that macOS 10.16 and 11.0 are the same

    In python 3.9.9, as provided by the python.org macOS installer,

    $ /Library/Frameworks/Python.framework/Versions/3.9/bin/python3
    Python 3.9.9 (v3.9.9:ccb0e6a345, Nov 15 2021, 13:29:20) 
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import platform
    >>> platform.mac_ver()
    ('10.16', ('', '', ''), 'x86_64')
    

    As a result, packaging 21.3 (and packaging main HEAD) do not include ...11_0... in packaging.tags.sys_tags(). However, wheel happily builds wheels with this tag, which pip (e.g. latest, 21.3.1) then refuses to install.

    As platform.mac_ver() cannot be retroactively changed for released versions of Python, this should be addressed in packaging to make the support for macOS 11.x from #319 more robust.

    Reference: https://trac.sagemath.org/ticket/33155

    enhancement packaging.tags 
    opened by mkoeppe 27
  • Reliance on flit makes packaging incompatible with Void, Arch and Alpine Linux package systems

    Reliance on flit makes packaging incompatible with Void, Arch and Alpine Linux package systems

    The switch to flit in #352 has left the packaging source tarball without a setup.py. While one can use flit install to install packaging, the flit install command provides a means to choose between installing to the system site-packages (possibly in a virtualenv, by providing a custom path to the python executable) or to a per-user site-packages.

    Void Linux xbps-src, Arch Build System and Alpine apk-tools package builders all expect to install Python packages into a specific destination directory that is empty except for the contents of the Python package; the distribution package is derived from the contents of this directory. For setuptools-based projects like packaging<20.5, this is accomplished by passing, e.g., --root $DESTDIR for Void Linux. flit install provides no similar mechanism. The closest one could come would be to construct a virtualenv at the $DESTDIR, then use flit install to populate, and then carefully remove all pieces of the virtualenv from $DESTDIR except for the installed package. It should be self evident that this is a horrible workaround.

    If you are use flit build and flit publish to build wheels and source tarballs on PyPI, this problem should take care of itself, because both flit subcommands appear to create a setup.py in the source tarball by default. (Note, however, that the generated setup.py appears incorrect because it imports distutils.core.setup, then uses the install_requires and python_requires keywords that seem to be only recognized by setuptools.setup.) However, the PyPI source tarballs for packaging==20.5, packaging==20.6 and packaging==20.7 do not include setup.py. Thus, you are either creating a source tarball by some other means, or invoking flit build --no-setup-py or flit publish --no-setup-py.

    Without a setup.py in the source tarball (either generated by flit build or flit publish, or manually created to parallel the package definition in pyproject.toml), new versions of packaging cannot be properly packaged for Void, Arch, Alpine and, I imagine, several other Linux distributions.

    opened by ahesford 27
  • Dealing with legacy version parsing functionality being removed

    Dealing with legacy version parsing functionality being removed

    PR #407 dropped LegacyVersion, but at the same time it broke the API of packaging.version.parse in a way that makes it very hard to support parse from both packaging 21 and 22.

    In 21 if one called parse("...") it would return LegacyVersion instead of raising an error. So if code wanted to use parse but check that the version was correct it has to check whether the returned type was LegacyVersion.

    In 22, LegacyVersion is now gone, and an exception is raised instead.

    The deprecations raised for LegacyVersion were only raised when a LegacyVersion was created, so code that called parse and checked the return type didn't raise any warnings.

    packaging.version 
    opened by hodgestar 26
  • Python 3.10: _version_nodot, interpreter_version disagree on how to format it

    Python 3.10: _version_nodot, interpreter_version disagree on how to format it

    There is a problem building and using wheels for python 3.10 xref pypa/wheel#354 and pypa/pip#8312. I think the source of the problem is that wheel's bdist_wheel calls tags.interpreter_version. But tags.interpreter_version seems to be producing 310, which it will take from sysconfig.get_config_var("py_version_nodot") (if it exists), and there is no check that is conformant with the 3_10 format.

    Internally, packaging uses tags._version_nodot which will always produce 3_10, this is the "correct" value used by pip and in tags.sys_tags.

    This is the code that generates that value for CPython master. Note there is no '_'

    bug packaging.tags 
    opened by mattip 26
  • Add functions for parsing wheel and sdist filenames

    Add functions for parsing wheel and sdist filenames

    I finally got fed up of writing the same code to parse wheel and sdist filenames, so I thought it might be worth having a "standard" version.

    As written, the code only handles sdist filenames in the form described in the packaging standards (.tar.gz files with the form {name}-{version}.tar.gz). It could be extended to handle more of the cases in use on PyPI (e.g., .zip format sdists) but I chose in the first instance to stick with the stricter definition that's the current de facto standard.

    opened by pfmoore 25
  • Spaces missing in Requirement string representation

    Spaces missing in Requirement string representation

    Given the example, Requirement('enlighten >= 1.10.2') The string output of this is 'enlighten>=1.10.2' rather than 'enlighten >= 1.10.2'

    I believe the lack of spaces between the specifier operators and versions as well as the requirement components reduces readability.

    While the lack of spaces could be considered a stylistic choice, there's no option to modify it without additional code and it's inconsistent with the examples in PEP 440 and PEP 508. And while this isn't Python code, it's not consistent with the recommendation in PEP 8 that binary operators are surrounded by single spaces.

    opened by avylove 0
  • Spaces in platform names are problematic

    Spaces in platform names are problematic

    On some platforms, sysconfig.get_platform() returns a value with a space in it (e.g. isilon onefs). This causes problems for wheel building/handling.

    First, there is an issue trying to build a platform-specific wheel:

    # venv/bin/pip install -I --no-cache pyyaml
    Collecting pyyaml
      Downloading PyYAML-6.0.tar.gz (124 kB)
         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 125.0/125.0 KB 13.3 MB/s eta 0:00:00
      Installing build dependencies ... done
      Getting requirements to build wheel ... done
      Preparing metadata (pyproject.toml) ... done
    Building wheels for collected packages: pyyaml
      Building wheel for pyyaml (pyproject.toml) ... error
      error: subprocess-exited-with-error
    
      Γ— Building wheel for pyyaml (pyproject.toml) did not run successfully.
      β”‚ exit code: 1
      ╰─> [101 lines of output]
    ...
          wheel.cli.WheelError: Bad wheel filename 'PyYAML-6.0-cp38-cp38-isilon onefs_9_5_0_0_amd64.whl'
          [end of output]
    
      note: This error originates from a subprocess, and is likely not a problem with pip.
      ERROR: Failed building wheel for pyyaml
    

    I created https://github.com/pypa/wheel/pull/491 to address this.

    Even with that patch in place, though, pip is unable to install the built wheel because packaging does not recognize that the platform name has had its spaces replaced with underscores:

    # python3 -m pip install dist/PyYAML-6.0-cp38-cp38-isilon_onefs_9_5_0_0_amd64.whl
    ...
    ERROR: PyYAML-6.0-cp38-cp38-isilon_onefs_9_5_0_0_amd64.whl is not a supported wheel on this platform.
    
    opened by tucked 2
  • Add PEP 621 project table parsing and validation module

    Add PEP 621 project table parsing and validation module

    As prototyped in #646, I believe this repo is a nice place to house a general parsing and validation function for the PEP 621 [project] table in the pyproject.toml.

    This returns a list of (build tool independent) validation errors and a TypedDict of the project data.

    enhancement 
    opened by chrisjsewell 9
  • Add PEP 621 project table parsing and validation

    Add PEP 621 project table parsing and validation

    Heya,

    This module takes a pyproject.toml dict (pre-parsed by a TOML library) and parses/validates the [project] table, according to PEP 621.

    I feel this could be generically useful, for packaging tools?

    If you agree, I can clean up the code a bit and add more tests, etc

    opened by chrisjsewell 2
  • Wildcard in setup.py install_requires list causing parsing error

    Wildcard in setup.py install_requires list causing parsing error

    In packaging 21.3 having a wildcard in the install_requires section of a setup.py worked fine. Example:

    setup(
    ...
        install_requires=["hwtypes>=1.0.*"],
    ...
    )
    

    In version 22.0 it throws this error:

      File "/aha/lib/python3.8/site-packages/packaging/requirements.py", line 35, in __init__
    
        parsed = parse_requirement(requirement_string)
    
      File "/aha/lib/python3.8/site-packages/packaging/_parser.py", line 64, in parse_requirement
    
        return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES))
    
      File "/aha/lib/python3.8/site-packages/packaging/_parser.py", line 82, in _parse_requirement
    
        url, specifier, marker = _parse_requirement_details(tokenizer)
    
      File "/aha/lib/python3.8/site-packages/packaging/_parser.py", line 122, in _parse_requirement_details
    
        marker = _parse_requirement_marker(
    
      File "/aha/lib/python3.8/site-packages/packaging/_parser.py", line 143, in _parse_requirement_marker
    
        tokenizer.raise_syntax_error(
    
      File "/aha/lib/python3.8/site-packages/packaging/_tokenizer.py", line 161, in raise_syntax_error
    
        raise ParserSyntaxError(
    
    packaging._tokenizer.ParserSyntaxError: Expected end or semicolon (after version specifier)
    
        hwtypes>=1.0.*
    
               ~~~~~^
    
    packaging.requirements 
    opened by jack-melchert 5
Releases(23.0)
  • 23.0(Jan 8, 2023)

    What's Changed

    • Remove unused LPAREN token from tokenizer by @hrnciar in https://github.com/pypa/packaging/pull/630
    • Reorganise the project layout and version management by @pradyunsg in https://github.com/pypa/packaging/pull/626
    • Correctly handle non-normalised specifiers in requirements by @pradyunsg in https://github.com/pypa/packaging/pull/634
    • Use stable Python 3.11 in tests by @153957 in https://github.com/pypa/packaging/pull/641
    • Fix typing for specifiers.BaseSpecifier.filter() by @henryiii in https://github.com/pypa/packaging/pull/643
    • Correctly handle trailing whitespace on URL requirements by @pradyunsg in https://github.com/pypa/packaging/pull/642
    • refactor _generic_api to use EXT_SUFFIX by @mattip in https://github.com/pypa/packaging/pull/607
    • Allow "extra" to be None in the marker environment by @pradyunsg in https://github.com/pypa/packaging/pull/650
    • Fix typos by @kianmeng in https://github.com/pypa/packaging/pull/648
    • Update changelog for release by @pradyunsg in https://github.com/pypa/packaging/pull/656

    New Contributors

    • @153957 made their first contribution in https://github.com/pypa/packaging/pull/641
    • @kianmeng made their first contribution in https://github.com/pypa/packaging/pull/648

    Full Changelog: https://github.com/pypa/packaging/compare/22.0...23.0

    Source code(tar.gz)
    Source code(zip)
  • 22.0(Dec 7, 2022)

    What's Changed

    • Fix compatible version specifier incorrectly strip trailing '0' by @kasium in https://github.com/pypa/packaging/pull/493
    • Remove support for Python 3.6 by @abravalheri in https://github.com/pypa/packaging/pull/500
    • Use concurrency limit in ci by @blink1073 in https://github.com/pypa/packaging/pull/510
    • Fix issue link in changelog. by @bdice in https://github.com/pypa/packaging/pull/509
    • chore: test with PyPy 3.8 & 3.9 by @mayeut in https://github.com/pypa/packaging/pull/512
    • Accept locally installed prereleases by @q0w in https://github.com/pypa/packaging/pull/515
    • Always run GHA workflows when they change by @mayeut in https://github.com/pypa/packaging/pull/516
    • Add __hash__/__eq__ to requirements by @abravalheri in https://github.com/pypa/packaging/pull/499
    • Upgrade to setup-python v3 and use caching for GHA by @brettcannon in https://github.com/pypa/packaging/pull/521
    • allow pre-release versions in marker evaluation by @graingert in https://github.com/pypa/packaging/pull/523
    • Error out from workflow on missing interpreter by @mayeut in https://github.com/pypa/packaging/pull/525
    • chore: update pre-commit config to the latest repos' versions by @mayeut in https://github.com/pypa/packaging/pull/534
    • chore: remove Windows PyPy 3.9 workaround on GHA by @mayeut in https://github.com/pypa/packaging/pull/533
    • Use pipx to run nox / build in GHA workflows by @mayeut in https://github.com/pypa/packaging/pull/517
    • Run tests with all PyPy versions locally by @mayeut in https://github.com/pypa/packaging/pull/535
    • Adhere to PEP 685 when evaluating markers with extras by @hroncok in https://github.com/pypa/packaging/pull/545
    • chore: update mypy and move to toml by @henryiii in https://github.com/pypa/packaging/pull/547
    • Normalize extra comparison in markers for output by @brettcannon in https://github.com/pypa/packaging/pull/549
    • Evaluate markers under environment with empty "extra" by @MrMino in https://github.com/pypa/packaging/pull/550
    • Do not set extra in default_environment() by @sbidoul in https://github.com/pypa/packaging/pull/554
    • Update extlinks strings to use a format string by @mayeut in https://github.com/pypa/packaging/pull/555
    • Update CI test workflow to use setup-python@v4 by @mayeut in https://github.com/pypa/packaging/pull/556
    • CI: Update actions/* to their latest major versions by @mayeut in https://github.com/pypa/packaging/pull/557
    • Fix a spelling mistake by @venthur in https://github.com/pypa/packaging/pull/558
    • fix: macOS platform tags with old macOS SDK by @mayeut in https://github.com/pypa/packaging/pull/513
    • Correctly parse ELF for musllinux on Big Endian by @uranusjr in https://github.com/pypa/packaging/pull/538
    • A metadata module with a data class for core metadata by @brettcannon in https://github.com/pypa/packaging/pull/518
    • Document utils.NormalizedName by @brettcannon in https://github.com/pypa/packaging/pull/565
    • Drop LegacySpecifier and LegacyVersion by @pradyunsg in https://github.com/pypa/packaging/pull/407
    • Move metadata, versions and specifiers API documentation to sphinx.ext.autodoc by @pradyunsg in https://github.com/pypa/packaging/pull/572
    • Demonstrate behaviour of SpecifierSet.__iter__ by @hauntsaninja in https://github.com/pypa/packaging/pull/575
    • Handwritten parser for parsing requirements by @hrnciar in https://github.com/pypa/packaging/pull/484
    • Add changelog entry for removal of pyparsing dependency by @hroncok in https://github.com/pypa/packaging/pull/581
    • Use Iterator instead of Iterable for specifier filter methods by @ichard26 in https://github.com/pypa/packaging/pull/584
    • Better output on linter failure by @henryiii in https://github.com/pypa/packaging/pull/478
    • Add a "cpNNN-none-any" tag by @joonis in https://github.com/pypa/packaging/pull/541
    • Document exceptions raised by functions in utils by @MrMino in https://github.com/pypa/packaging/pull/544
    • Refactor ELF parsing logic to standlone class by @uranusjr in https://github.com/pypa/packaging/pull/553
    • Forbid prefix version matching on pre-release/post-release segments by @mayeut in https://github.com/pypa/packaging/pull/563
    • Update coverage to >=5.0.0 by @mayeut in https://github.com/pypa/packaging/pull/586
    • Normalize specifier version for prefix matching by @mayeut in https://github.com/pypa/packaging/pull/561
    • Add python 3.11 by @mayeut in https://github.com/pypa/packaging/pull/587
    • Fix prefix version matching by @mayeut in https://github.com/pypa/packaging/pull/564
    • Remove duplicate namedtuple by @layday in https://github.com/pypa/packaging/pull/589
    • Update changelog by @pradyunsg in https://github.com/pypa/packaging/pull/595
    • Change email-related fields in Metadata to str by @brettcannon in https://github.com/pypa/packaging/pull/596
    • Add versionchanged for 21.3 by @brettcannon in https://github.com/pypa/packaging/pull/599
    • refactor: use flit as a backend by @henryiii in https://github.com/pypa/packaging/pull/546
    • Remove packaging.metadata by @pradyunsg in https://github.com/pypa/packaging/pull/603
    • Refactor nox requirements to use requirements files (#601) by @strokirk in https://github.com/pypa/packaging/pull/609
    • Improve Requirement/Marker parser with context-sensitive tokenisation by @pradyunsg in https://github.com/pypa/packaging/pull/624

    New Contributors

    • @kasium made their first contribution in https://github.com/pypa/packaging/pull/493
    • @abravalheri made their first contribution in https://github.com/pypa/packaging/pull/500
    • @blink1073 made their first contribution in https://github.com/pypa/packaging/pull/510
    • @bdice made their first contribution in https://github.com/pypa/packaging/pull/509
    • @q0w made their first contribution in https://github.com/pypa/packaging/pull/515
    • @graingert made their first contribution in https://github.com/pypa/packaging/pull/523
    • @hrnciar made their first contribution in https://github.com/pypa/packaging/pull/484
    • @ichard26 made their first contribution in https://github.com/pypa/packaging/pull/584
    • @joonis made their first contribution in https://github.com/pypa/packaging/pull/541
    • @strokirk made their first contribution in https://github.com/pypa/packaging/pull/609

    Full Changelog: https://github.com/pypa/packaging/compare/21.3...22.0

    Source code(tar.gz)
    Source code(zip)
  • 21.3(Nov 18, 2021)

  • 21.2(Oct 29, 2021)

  • 21.1(Oct 29, 2021)

    What's Changed

    • Update branch names in release process in https://github.com/pypa/packaging/pull/444
    • Update changelog for 21.0 in https://github.com/pypa/packaging/pull/449
    • tags: make _platform_tags public in https://github.com/pypa/packaging/pull/446
    • Add support for Python 3.10 in https://github.com/pypa/packaging/pull/461
    • Update PyPy CI Specifier in https://github.com/pypa/packaging/pull/467
    • Limit pyparsing to major version 2 in https://github.com/pypa/packaging/pull/471

    New Contributors

    • @moyiz made their first contribution in https://github.com/pypa/packaging/pull/471

    Full Changelog: https://github.com/pypa/packaging/compare/21.0...21.1

    Source code(tar.gz)
    Source code(zip)
  • 21.0(Jul 23, 2021)

    • PEP 656: musllinux support (:issue:411)
    • Drop support for Python 2.7, Python 3.4 and Python 3.5.
    • Replace distutils usage with sysconfig (:issue:396)
    • Add support for zip files in parse_sdist_filename (:issue:429)
    • Use cached _hash attribute to short-circuit tag equality comparisons (:issue:417)
    • Specify the default value for the specifier argument to SpecifierSet (:issue:437)
    • Proper keyword-only "warn" argument in packaging.tags (:issue:403)
    • Correctly remove prerelease suffixes from ~= check (:issue:366)
    • Fix type hints for Version.post and Version.dev (:issue:393)
    • Use typing alias UnparsedVersion (:issue:398)
    • Improve type inference for packaging.specifiers.filter() (:issue:430)
    • Tighten the return type of canonicalize_version() (:issue:402)
    Source code(tar.gz)
    Source code(zip)
  • 20.9(Jan 29, 2021)

  • 20.8(Dec 12, 2020)

  • 20.1(Jan 25, 2020)

  • 20.0(Jan 6, 2020)

    • Add type hints (:issue:191)

    • Add proper trove classifiers for PyPy support (:issue:198)

    • Scale back depending on ctypes for manylinux support detection (:issue:171)

    • Use sys.implementation.name where appropriate for packaging.tags (:issue:193)

    • Expand upon the API provded by packaging.tags: interpreter_name(), mac_platforms(), compatible_tags(), cpython_tags(), generic_tags() (:issue:187)

    • Officially support Python 3.8 (:issue:232)

    • Add major, minor, and micro aliases to packaging.version.Version (:issue:226)

    • Properly mark packaging has being fully typed by adding a py.typed file (:issue:226)

    Source code(tar.gz)
    Source code(zip)
Owner
Python Packaging Authority
Python Packaging Authority
tool for creating installers from conda packages

(conda) Constructor Description Constructor is a tool which allows constructing an installer for a collection of conda packages. It solves needed pack

Conda 386 Jan 4, 2023
Install .deb packages on any distribution:)

Install .deb packages on any distribution:) Install Dependencies The project needs dependencies Python python is often installed by default on linux d

GGroup 1 Mar 31, 2022
Nuitka Organization 8k Jan 7, 2023
py2app is a Python setuptools command which will allow you to make standalone Mac OS X application bundles and plugins from Python scripts.

py2app is a Python setuptools command which will allow you to make standalone Mac OS X application bundles and plugins from Python scripts. py2app is

Ronald Oussoren 222 Dec 30, 2022
A tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts.

PyArmor Homepage (δΈ­ζ–‡η‰ˆη½‘η«™) Documentation(δΈ­ζ–‡η‰ˆ) PyArmor is a command line tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine

Dashingsoft 1.9k Jan 1, 2023
Freeze (package) Python programs into stand-alone executables

PyInstaller Overview PyInstaller bundles a Python application and all its dependencies into a single package. The user can run the packaged app withou

PyInstaller 9.9k Jan 8, 2023
shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included.

shiv shiv is a command line utility for building fully self-contained Python zipapps as outlined in PEP 441, but with all their dependencies included!

LinkedIn 1.5k Dec 28, 2022
A library and tool for generating .pex (Python EXecutable) files

PEX Contents Overview Installation Simple Examples Integrating pex into your workflow Documentation Development Contributing Overview pex is a library

Pants Build 2.2k Jan 1, 2023
A distutils extension to create standalone Windows programs from Python code

py2exe for Python 3 py2exe is a distutils extension which allows to build standalone Windows executable programs (32-bit and 64-bit) from Python scrip

py2exe 526 Jan 4, 2023
Create standalone executables from Python scripts, with the same performance and is cross-platform.

About cx_Freeze cx_Freeze creates standalone executables from Python scripts, with the same performance, is cross-platform and should work on any plat

Marcelo Duarte 1k Jan 4, 2023
Build Windows installers for Python applications

Pynsist is a tool to build Windows installers for your Python applications. The installers bundle Python itself, so you can distribute your applicatio

Thomas Kluyver 818 Jan 5, 2023
A modern Python application packaging and distribution tool

PyOxidizer PyOxidizer is a utility for producing binaries that embed Python. The over-arching goal of PyOxidizer is to make complex packaging and dist

Gregory Szorc 4.5k Jan 7, 2023
Subpar is a utility for creating self-contained python executables. It is designed to work well with Bazel.

Subpar Subpar is a utility for creating self-contained python executables. It is designed to work well with Bazel. Status Subpar is currently owned by

Google 550 Dec 27, 2022
Python Wheel Obfuscator

pywhlobf obfuscates your wheel distribution by compiling python source file to shared library.

Hunt Zhan 79 Dec 22, 2022
FreezeUI is a python package that creates applications using cx_freeze and GUI by converting .py to .exe .

FreezeUI is a python package use to create cx_Freeze setup files and run them to create applications and msi from python scripts (converts .py to .exe or .msi .

null 4 Aug 25, 2022
Psgcompiler A PySimpleGUI Application - Transform your Python programs in Windows, Mac, and Linux binary executables

psgcompiler A PySimpleGUI Application "Compile" your Python programs into an EXE for Windows, an APP for Mac, and a binary for Linux Installation Old-

PySimpleGUI 77 Jan 7, 2023
Python-easy-pack For Linux/Unix, Changed by laman28

Python-easy-pack For Linux/Unix, Changed by laman28

LMFS 2 Jan 28, 2022
A library which implements low-level functions that relate to packaging and distribution of Python

What is it? Distlib is a library which implements low-level functions that relate to packaging and distribution of Python software. It is intended to

Python Packaging Authority 29 Oct 11, 2022
Core ML tools contain supporting tools for Core ML model conversion, editing, and validation.

Core ML Tools Use coremltools to convert machine learning models from third-party libraries to the Core ML format. The Python package contains the sup

Apple 3k Jan 8, 2023