Skip to content

Commit

Permalink
Introduce packaging.tags (pypa#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
brettcannon authored and ptmcg committed Aug 6, 2019
1 parent e78164b commit a3116c8
Show file tree
Hide file tree
Showing 9 changed files with 1,016 additions and 2 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ omit = packaging/_compat.py

[report]
exclude_lines =
pragma: no cover
@abc.abstractmethod
@abc.abstractproperty
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.cache/
.coverage
.idea
.venv
.venv*

__pycache__/
_build/
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Changelog
~~~~~~~~~~~~~~~~~

* Fix string representation of PEP 508 direct URL requirements with markers.
* Add the `packaging.tags` module.

* Better handling of file URLs

Expand Down
4 changes: 4 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Install our development requirements
black; python_version >= '3.6'
coverage
flake8
pep8-naming
pretend
pytest
tox
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ API
specifiers
markers
requirements
tags
utils


Expand Down
101 changes: 101 additions & 0 deletions docs/tags.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Tags
====

.. currentmodule:: packaging.tags

Wheels encode the Python interpreter, ABI, and platform that they support in
their filenames using *`platform compatibility tags`_*. This module provides
support for both parsing these tags as well as discovering what tags the
running Python interpreter supports.

Usage
-----

.. doctest::

>>> from packaging.tags import Tag, sys_tags
>>> import sys
>>> looking_for = Tag("py{major}".format(major=sys.version_info.major), "none", "any")
>>> supported_tags = list(sys_tags())
>>> looking_for in supported_tags
True
>>> really_old = Tag("py1", "none", "any")
>>> wheels = {really_old, looking_for}
>>> best_wheel = None
>>> for supported_tag in supported_tags:
... for wheel_tag in wheels:
... if supported_tag == wheel_tag:
... best_wheel = wheel_tag
... break
>>> best_wheel == looking_for
True

Reference
---------

.. attribute:: INTERPRETER_SHORT_NAMES

A dictionary mapping interpreter names to their `abbreviation codes`_
(e.g. ``"cpython"`` is ``"cp"``). All interpreter names are lower-case.

.. class:: Tag(interpreter, abi, platform)

A representation of the tag triple for a wheel. Instances are considered
immutable and thus are hashable. Equality checking is also supported.

:param str interpreter: The interpreter name, e.g. ``"py"``
(see :attr:`INTERPRETER_SHORT_NAMES` for mapping
well-known interpreter names to their short names).
:param str abi: The ABI that a wheel supports, e.g. ``"cp37m"``.
:param str platform: The OS/platform the wheel supports,
e.g. ``"win_amd64"``.

.. attribute:: interpreter

The interpreter name.

.. attribute:: abi

The supported ABI.

.. attribute:: platform

The OS/platform.


.. function:: parse_tag(tag)

Parse the provided *tag* into a set of :class:`Tag` instances.

The returning of a set is required due to the possibility that the tag is a
`compressed tag set`_, e.g. ``"py2.py3-none-any"``.

:param str tag: The tag to parse, e.g. ``"py3-none-any"``.


.. function:: sys_tags()

Create an iterable of tags that the running interpreter supports.

The iterable is ordered so that the best-matching tag is first in the
sequence. The exact preferential order to tags is interpreter-specific, but
in general the tag importance is in the order of:

1. Interpreter
2. Platform
3. ABI

This order is due to the fact that an ABI is inherently tied to the
platform, but platform-specific code is not necessarily tied to the ABI. The
interpreter is the most important tag as it dictates basic support for any
wheel.

The function returns an iterable in order to allow for the possible
short-circuiting of tag generation if the entire sequence is not necessary
and calculating some tags happens to be expensive.


.. _abbreviation codes: https://www.python.org/dev/peps/pep-0425/#python-tag
.. _compressed tag set: https://www.python.org/dev/peps/pep-0425/#compressed-tag-sets
.. _platform compatibility tags: https://packaging.python.org/specifications/platform-compatibility-tags/
.. _PEP 425: https://www.python.org/dev/peps/pep-0425/
Loading

0 comments on commit a3116c8

Please sign in to comment.