check-wheel-contents


Namecheck-wheel-contents JSON
Version 0.6.0 PyPI version JSON
download
home_pagehttps://github.com/jwodder/check-wheel-contents
SummaryCheck your wheels have the right contents
upload_time2023-10-31 21:20:45
maintainer
docs_urlNone
authorJohn Thorvald Wodder II
requires_python>=3.7
licenseMIT
keywords linter packaging wheel
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: http://www.repostatus.org/badges/latest/active.svg
    :target: http://www.repostatus.org/#active
    :alt: Project Status: Active — The project has reached a stable, usable
          state and is being actively developed.

.. image:: https://github.com/jwodder/check-wheel-contents/workflows/Test/badge.svg?branch=master
    :target: https://github.com/jwodder/check-wheel-contents/actions?workflow=Test
    :alt: CI Status

.. image:: https://codecov.io/gh/jwodder/check-wheel-contents/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/jwodder/check-wheel-contents

.. image:: https://img.shields.io/pypi/pyversions/check-wheel-contents.svg
    :target: https://pypi.org/project/check-wheel-contents/

.. image:: https://img.shields.io/github/license/jwodder/check-wheel-contents.svg
    :target: https://opensource.org/licenses/MIT
    :alt: MIT License

`GitHub <https://github.com/jwodder/check-wheel-contents>`_
| `PyPI <https://pypi.org/project/check-wheel-contents/>`_
| `Issues <https://github.com/jwodder/check-wheel-contents/issues>`_
| `Changelog <https://github.com/jwodder/check-wheel-contents/blob/master/CHANGELOG.md>`_

Getting the right files into your wheel is tricky, and sometimes we mess up and
publish a wheel containing ``__pycache__`` directories or ``tests/``.  Do we
have to manually check the contents of every wheel we build before uploading it
to PyPI?  How about letting this program check for you?  Just run
``check-wheel-contents`` on your wheel, and it'll fail and notify you if any of
several common errors & mistakes are detected.  The errors are described below,
along with common causes and corresponding fixes.

Installation
============
``check-wheel-contents`` requires Python 3.7 or higher.  Just use `pip
<https://pip.pypa.io>`_ for Python 3 (You have pip, right?) to install
``check-wheel-contents`` and its dependencies::

    python3 -m pip install check-wheel-contents


Usage
=====

::

    check-wheel-contents [<options>] <wheel or directory> ...

``check-wheel-contents`` takes zero or more paths as arguments, each pointing
to either a wheel to analyze or a directory that will be traversed for wheels
to analyze.  If a given wheel fails any checks, a message will be printed for
each check along with (if applicable) a list of filepaths in the wheel causing
the check to fail, and the command will exit with a nonzero status.  If a wheel
passes all checks, the program will print ``{path_to_wheel}: OK``.

Options
-------

-c FILE, --config FILE  Read configuration from the given file; see below for
                        more information

--no-config             Disable reading from the configuration file

-h, --help              Display a usage message and exit

-V, --version           Display the program version and exit

The remaining options can be given either on the command line or in the
configuration file; see "`Configuration Options`_" for more information.


Configuration
=============

Configuration File
------------------

If a configuration file is specified on the command line with the ``--config``
option, ``check-wheel-contents`` reads its configuration from the given file.
Files with a ``.toml`` extension are parsed as TOML files, and the
configuration is read from the ``tool.check-wheel-contents`` table.  All other
files are parsed as INI files, and their configuration is read from the
``[check-wheel-contents]`` section (unless the file is named ``setup.cfg``, in
which case the section ``[tool:check-wheel-contents]`` is used instead).

If no configuration file is specified on the command line, the program begins
searching for a file named ``pyproject.toml``, ``tox.ini``, ``setup.cfg``,
``check-wheel-contents.cfg``, or ``.check-wheel-contents.cfg``, starting in the
current directory and going up.  The files are read using the same rules as for
the ``--config`` option, and the first file in the list that contains the
appropriate section is used.  Searching stops once a directory containing any
of the named files is found, even if none of them contain the relevant section.

Configuration Options
---------------------

The following options may be set either on the command line or in the
configuration file.  Settings given on the command line override those in the
configuration file.  Unknown keys in configuration files are ignored.

``--select <checks>`` / ``select = <checks>``
   Select/enable only the given checks.  ``<checks>`` is a comma-separated list
   of check IDs and/or check ID prefixes (to select all checks beginning with
   the given prefixes).

   In a TOML file, ``<checks>`` may alternatively be given as a list of
   strings.

   By default, all checks are selected (though some checks are no-ops when
   certain other options are/aren't given).

``--ignore <checks>`` / ``ignore = <checks>``
   Ignore/skip the given checks.  ``<checks>`` is a comma-separated list of
   check IDs and/or check ID prefixes (to ignore all checks beginning with the
   given prefixes).

   In a TOML file, ``<checks>`` may alternatively be given as a list of
   strings.

   By default, no checks are ignored.

``--toplevel <names>`` / ``toplevel = <names>``
   Tell ``check-wheel-contents`` to check that the toplevel library entries of
   the wheel equal the set of names in the comma-separated list ``<names>``;
   e.g., ``--toplevel foo.py,bar/`` checks that ``foo.py``, ``bar``, and
   nothing else is at the top level of your wheel.  Trailing slashes on
   directory names are optional.

   In a TOML file, ``<names>`` may alternatively be given as a list of strings.

   This option disables check W009 and enables checks W201 and W202.  It is
   also used by check W005 to prevent failure on common names that are
   intentionally used as toplevel names.

``--package <path>`` / ``package = <paths>``
   Tell ``check-wheel-contents`` to check that the wheel's library sections
   contain the file tree rooted at ``<path>``.

   Paths given on the command line are resolved relative to the current working
   directory.  Paths given in a configuration file are resolved relative to the
   directory containing the configuration file.

   On the command line, multiple paths can be specified by supplying
   ``--package`` multiple times.  In a configuration file, multiple paths can
   be specified by setting ``package`` to a comma-separated list of paths.  In
   a TOML file, ``<paths>`` may alternatively be given as a list of strings.

   This option disables check W009 and enables checks W101 and W102.

``--src-dir <path>`` / ``src_dir = <paths>``
   The same as ``--package``, except that only the contents of ``<path>``
   (which must be a directory) and not ``<path>`` itself are checked against
   the wheel's contents.

``--package-omit <patterns>`` / ``package_omit = <patterns>``
   Ignore files & directories inside ``--package`` or ``--src-dir`` arguments
   that match any of the glob patterns in the comma-separated list
   ``<patterns>``.  Ignored files will not be looked for in wheels for check
   W101, and if any of them do show up in a wheel, it will cause check W102 to
   fail.

   In a TOML file, ``<patterns>`` may alternatively be given as a list of
   strings.

   The default set of ignored patterns is ``.*, CVS, RCS, *.pyc, *.pyo,
   *.egg-info``.


Checks
======

**Note**: Unless otherwise stated, the common causes and their fixes listed
here are specific to projects developed using setuptools.  Users of other tools
like flit and poetry will have to consult those projects' documentation in
order to resolve failed checks.

**Note**: When rebuilding a wheel with setuptools, it is a good idea to delete
the ``build/`` directory first.  (This can be done in a single command with
``python setup.py clean --all bdist_wheel``.)  Not doing this can cause various
checks to continue to fail or new ones to start failing.


W001 — Wheel contains .pyc/.pyo files
-------------------------------------
This check fails if there are any files in the wheel with a ``.pyc`` or
``.pyo`` extension.  Such files are compiled Python bytecode files, and they do
not belong in wheels, because (a) they are platform-specific and thus useless
to many of your users, and (b) pip generates ``.pyc`` files for the ``.py``
files in your wheel automatically.

Common causes:

- You have ``include_package_data`` set to ``True``, your ``MANIFEST.in``
  contains ``graft packagename`` or ``recursive-include packagename *``, and
  the line ``global-exclude *.py[co]`` or similar is either missing from the
  ``MANIFEST.in`` or else in the wrong location.

  **Solution**: Ensure that ``global-exclude *.py[co]`` appears in your
  ``MANIFEST.in`` file *after* all ``include``, ``recursive-include``,
  ``global-include``, and ``graft`` commands.

- You have ``[install]optimize = 1`` set in ``setup.cfg`` (or, equivalently,
  ``options={"install": {"optimize": "1"}}`` set in ``setup.py``).

  **Solution**: Remove this setting.  It's only useful when using ``setup.py
  install`` anyway, which is deprecated.


W002 — Wheel contains duplicate files
-------------------------------------
This check fails if any two files in the wheel have the same contents.  Common
file contents, such as files that are empty or just contain the line "``# -*-
coding: utf-8 -*-``", are excluded from this check.

Common causes:

- *(Build tool agnostic)* You copied a file or directory when you actually
  meant to rename it.

  **Solution**: Delete the original copy of the file or directory.

- You built a wheel, renamed a file or directory, and then built a wheel again
  without first deleting the ``build/`` directory.

  **Solution**: Delete the ``build/`` directory and build the wheel again.


W003 — Wheel contains non-module at library toplevel
----------------------------------------------------
This check fails if there are any files at the root of the purelib or platlib
section of the wheel that are not Python modules or ``.pth`` files.
Non-modules belong elsewhere in a wheel:

- Licenses and similar notices should be stored in the wheel's ``*.dist-info``
  directory using ``wheel``'s ``license_files`` option.

- Package data/resource files belong inside a package directory so that they
  can be located with ``pkg_resources`` or ``importlib-resources``.

- A project's ``README`` should already be used as the project's
  ``long_description``, in which case the text of the ``README`` is already
  included in the wheel inside the ``*.dist-info/METADATA`` file.  There should
  thus be no need to store the ``README`` in the wheel's library sections.


W004 — Module is not located at importable path
-----------------------------------------------
This check fails if there are any Python modules in the purelib or platlib
section of the wheel that cannot be imported due to one or more of their path
components being invalid Python identifiers.

Common causes:

- *(Build tool agnostic)* You gave a package directory or module a name
  containing a hyphen or other character not allowed in Python identifiers.

  **Solution**: Rename the offending directory or module to remove the
  offending character, most likely by changing it to an underscore.

- *(Build tool agnostic)* You gave a package directory or module the name of a
  Python keyword.

  **Solution**: Rename the offending directory or module.

- *(Build tool agnostic)* Your package contains database migration files
  generated by alembic or Django, which (may) begin with numbers and thus do
  not have valid Python identifiers as names.

  **Solution**: Ignore this check.  (Ignoring checks only for specific files is
  not yet implemented.)


W005 — Wheel contains common toplevel name in library
-----------------------------------------------------
This check fails if there are any files or directories named ``.eggs``,
``.nox``, ``.tox``, ``.venv``, ``app``, ``build``, ``cli``, ``data``, ``dist``,
``doc``, ``docs``, ``example``, ``examples``, ``lib``, ``scripts``, ``src``,
``test``, ``tests``, or ``venv`` located at the root of the purelib or platlib
section of the wheel.  These names are conventionally used for directories that
don't belong in wheels (aside from ``src``, whose contents belong in wheels but
itself does not belong in a wheel).  Projects should only use toplevel names
that resemble the project name; using common names will cause different
projects' files to overwrite each other on installation.

If the ``--toplevel`` option is set, the names listed in the option will not
cause this check to fail.

Common causes:

- For ``src``: You failed to set up your ``src/`` layout correctly.  ``src``
  should not contain an ``__init__.py`` file, ``where='src'`` needs to be
  passed to ``setuptools.find_packages()`` in ``setup.py``, and
  ``package_dir={"": "src"}`` needs to be passed to ``setup()`` in
  ``setup.py``.

- For directories other than ``src``: The directory contains an ``__init__.py``
  file, and the directory is not listed in the ``exclude`` argument to
  ``setuptools.find_packages()`` in ``setup.py``.

  **Solution**: Include ``'DIRNAME'`` and ``'DIRNAME.*'`` in the list passed to
  the ``exclude`` argument of ``find_packages()``.

- For directories other than ``src``: The directory is listed in the
  ``exclude`` argument to ``find_packages()``, but ``'DIRNAME.*'`` is not, and
  a subdirectory of the directory contains an ``__init__.py`` file.

  **Solution**: Include ``'DIRNAME.*'`` in the list passed to the ``exclude``
  argument of ``find_packages()``.

- You actually want to include your tests or examples in your wheel.

  **Solution**: Move the tests or whatever to inside your main package
  directory (e.g., move ``tests/`` to ``somepackage/tests/``) so that they
  won't collide with other projects' files on installation.

- You are actually making a package whose name is one of the listed names.

  **Solution**: Include the name of your package in the ``--toplevel`` option
  so that ``check-wheel-contents`` knows it's meant to be there.


W006 — ``__init__.py`` at top level of library
----------------------------------------------
This check fails if there is a file named ``__init__.py`` at the root of the
purelib or platlib section of the wheel.  ``__init__.py`` files only belong
inside package directories, not at the root of an installation.

Common causes:

- You failed to set up your ``src/`` layout correctly.  ``src`` should not
  contain an ``__init__.py`` file, ``where='src'`` needs to be passed to
  ``setuptools.find_packages()`` in ``setup.py``, and ``package_dir={"":
  "src"}`` needs to be passed to ``setup()`` in ``setup.py``.

- You created an ``__init__.py`` file at the root of your project and set
  ``packages='.'`` in ``setup.py``.

  **Solution**: Configure your project's packages correctly.  For single-file
  modules, pass a list of their names (without the ``.py`` extension) to the
  ``py_modules`` argument to ``setup()``.  For package modules (directories),
  pass a list of their names and the dotted names of their descendant
  subpackages (possibly obtained by calling ``setuptools.find_packages()``) to
  ``packages``.


W007 — Wheel library is empty
-----------------------------
This check fails if the wheel contains no files in either its purelib or
platlib section.

Common causes:

- Your project consists of a single-file ``.py`` module, but you declared it to
  ``setup()`` in ``setup.py`` using the ``packages`` keyword.

  **Solution**: Single-file modules must be declared to ``setup()`` using the
  ``py_modules`` keyword.  Pass it a list of the names of your single-file
  modules without the ``.py`` extension.

- You are using ``setuptools.find_packages()`` to list your packages for
  ``setup()``, but your package does not contain an ``__init__.py`` file.

  **Solution**: Create an ``__init__.py`` file in your package.  If this is not
  an option because you are building a namespace package, use
  ``setuptools.find_namespace_packages()`` instead of ``find_packages()``.  Be
  sure to set the arguments appropriately so that the function only finds your
  main package; `see the documentation for further information
  <https://setuptools.readthedocs.io/en/latest/setuptools.html#find-namespace-packages>`_.

- You're deliberately creating a wheel that only contains scripts, headers, or
  other data files.

  **Solution**: Ignore this check.


W008 — Wheel is empty
---------------------
This check fails if the wheel contains no files other than the ``*.dist-info``
metadata directory.  It is a stronger check than W007, intended for users who
are creating wheels that only contain scripts, headers, and other data files
and thus need to ignore W007.

Common causes:

- Same causes as for W007

- You're deliberately creating an empty wheel whose only function is to cause a
  set of dependencies to be installed.

  **Solution**: Ignore this check.


W009 — Wheel contains multiple toplevel library entries
-------------------------------------------------------
This check fails if the wheel's purelib and platlib sections contain more than
one toplevel entry between them, excluding ``.pth`` files and files &
directories that begin with an underscore.  This is generally a sign that
something has gone wrong in packaging your project, as very few projects want
to distribute code with multiple top-level modules or packages.

This check is disabled if the ``--toplevel``, ``--package``, or ``--src-dir``
option is given either on the command line or in the configuration file.

Common causes:

- You built a wheel, renamed a toplevel file or directory, and then built a
  wheel again without first deleting the ``build/`` directory.

  **Solution**: Delete the ``build/`` directory and build the wheel again.

- You are using ``setuptools.find_packages()`` in your ``setup.py``, your
  project contains multiple directories with ``__init__.py`` files, and one or
  more of these directories (other than your main package) is not listed in the
  ``exclude`` argument to ``find_packages()``.

  **Solution**: Pass a list of all ``__init__.py``-having directories in your
  project other than your main package to the ``exclude`` argument of
  ``find_packages()``.  For proper exclusion, each directory ``DIRNAME`` should
  correspond to two elements of this list, ``'DIRNAME'`` and ``'DIRNAME.*'``,
  in order to ensure that the directory and all of its subdirectories are
  excluded.

- You are deliberately creating a wheel with multiple top-level Python modules
  or packages.

  **Solution**: Use the ``--toplevel`` option to let ``check-wheel-contents``
  know what toplevel entries to expect.


W010 — Toplevel library directory contains no Python modules
------------------------------------------------------------
This check fails if a directory tree rooted at the root of the purelib or
platlib section of the wheel contains no Python modules.  ``*-stubs``
directories are excluded from this check.


W101 — Wheel library is missing files in package tree
-----------------------------------------------------
This check is only enabled if the ``--package`` or ``--src-dir`` option is set.
This check fails if a path in a tree rooted at an argument to ``--package`` or
inside an argument to ``--src-dir`` does not appear in the wheel's purelib or
platlib section.  Empty directories and local files & directories that match
any of the patterns specified with ``--package-omit`` or its default value are
excluded from this check.

Note that this check only checks file paths, i.e., names of files &
directories.  File contents are not examined.

For example, given the below local tree::

    /usr/src/project/
    ├── foo/
    │   ├── .gitignore
    │   ├── __init__.py
    │   └── foo.py
    └── src/
        ├── bar/
        │   ├── __init__.py
        │   ├── bar.py
        │   ├── empty/
        │   └── quux/
        │       └── data.dat
        └── bar.egg-info/
            └── PKG-INFO

If the options ``--package /usr/src/project/foo`` and ``--src-dir
/usr/src/project/src`` are supplied and ``--package-omit`` is left at its
default value, then ``check-wheel-contents`` will look for the following paths
in the wheel, and the check will fail if any of them do not appear in either
the purelib or platlib section::

    foo/__init__.py
    foo/foo.py
    bar/__init__.py
    bar/bar.py
    bar/quux/data.dat

Note that ``foo/.gitignore`` and ``src/bar.egg-info`` are omitted from this
check (and if they do appear in the wheel, it will cause check W102 to fail).
Empty directories are ignored altogether.

Common causes:

- For Python files: You failed to pass all of your project's packages &
  subpackages to ``setup()``'s ``packages`` argument.  If you are using
  ``setuptools.find_packages()``, all of your packages & subpackages need to
  contain ``__init__.py`` files.

- For non-Python files: You failed to declare your project's package data
  appropriately.  `See the setuptools documentation for information on how to
  do this`__.

__ https://setuptools.pypa.io/en/latest/userguide/datafiles.html


W102 — Wheel library contains files not in package tree
-------------------------------------------------------
This check is only enabled if the ``--package`` or ``--src-dir`` option is set.
This check fails if the purelib or platlib section of the wheel contains any
files at paths that do not exist in any of the file trees specified with
``--package`` or ``--src-dir``.

Note that this check only checks file paths, i.e., names of files &
directories.  File contents are not examined.

For example, given the local tree and options shown in the example under W101,
this check will fail if the wheel contains any files in its purelib or platlib
section other than the following::

    foo/__init__.py
    foo/foo.py
    bar/__init__.py
    bar/bar.py
    bar/quux/data.dat

Note that files & directories that match any of the patterns specified with
``--package-omit`` or its default value are ignored in local trees, and so any
entries with those names in the wheel will cause this check to fail.  Empty
directories are ignored altogether.

Common causes: See common causes of W009


W201 — Wheel library is missing specified toplevel entry
--------------------------------------------------------
This check is only enabled if the ``--toplevel`` option is set.  This check
fails if one or more of the names given in the ``--toplevel`` option does not
appear at the root of the purelib or platlib section of the wheel.

Common causes: See common causes of W007


W202 — Wheel library has undeclared toplevel entry
--------------------------------------------------
This check is only enabled if the ``--toplevel`` option is set.  This check
fails if there is a file or directory at the root of the purelib or platlib
section of the wheel that is not listed in the ``--toplevel`` option.
``*.pth`` files are ignored for the purposes of this check.

Common causes: See common causes of W009

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/jwodder/check-wheel-contents",
    "name": "check-wheel-contents",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "linter,packaging,wheel",
    "author": "John Thorvald Wodder II",
    "author_email": "check-wheel-contents@varonathe.org",
    "download_url": "https://files.pythonhosted.org/packages/53/06/30db4d32c297d90ca10b95bf3b5640898d894d9ed77cb53aad493e279e34/check-wheel-contents-0.6.0.tar.gz",
    "platform": null,
    "description": ".. image:: http://www.repostatus.org/badges/latest/active.svg\n    :target: http://www.repostatus.org/#active\n    :alt: Project Status: Active \u2014 The project has reached a stable, usable\n          state and is being actively developed.\n\n.. image:: https://github.com/jwodder/check-wheel-contents/workflows/Test/badge.svg?branch=master\n    :target: https://github.com/jwodder/check-wheel-contents/actions?workflow=Test\n    :alt: CI Status\n\n.. image:: https://codecov.io/gh/jwodder/check-wheel-contents/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/jwodder/check-wheel-contents\n\n.. image:: https://img.shields.io/pypi/pyversions/check-wheel-contents.svg\n    :target: https://pypi.org/project/check-wheel-contents/\n\n.. image:: https://img.shields.io/github/license/jwodder/check-wheel-contents.svg\n    :target: https://opensource.org/licenses/MIT\n    :alt: MIT License\n\n`GitHub <https://github.com/jwodder/check-wheel-contents>`_\n| `PyPI <https://pypi.org/project/check-wheel-contents/>`_\n| `Issues <https://github.com/jwodder/check-wheel-contents/issues>`_\n| `Changelog <https://github.com/jwodder/check-wheel-contents/blob/master/CHANGELOG.md>`_\n\nGetting the right files into your wheel is tricky, and sometimes we mess up and\npublish a wheel containing ``__pycache__`` directories or ``tests/``.  Do we\nhave to manually check the contents of every wheel we build before uploading it\nto PyPI?  How about letting this program check for you?  Just run\n``check-wheel-contents`` on your wheel, and it'll fail and notify you if any of\nseveral common errors & mistakes are detected.  The errors are described below,\nalong with common causes and corresponding fixes.\n\nInstallation\n============\n``check-wheel-contents`` requires Python 3.7 or higher.  Just use `pip\n<https://pip.pypa.io>`_ for Python 3 (You have pip, right?) to install\n``check-wheel-contents`` and its dependencies::\n\n    python3 -m pip install check-wheel-contents\n\n\nUsage\n=====\n\n::\n\n    check-wheel-contents [<options>] <wheel or directory> ...\n\n``check-wheel-contents`` takes zero or more paths as arguments, each pointing\nto either a wheel to analyze or a directory that will be traversed for wheels\nto analyze.  If a given wheel fails any checks, a message will be printed for\neach check along with (if applicable) a list of filepaths in the wheel causing\nthe check to fail, and the command will exit with a nonzero status.  If a wheel\npasses all checks, the program will print ``{path_to_wheel}: OK``.\n\nOptions\n-------\n\n-c FILE, --config FILE  Read configuration from the given file; see below for\n                        more information\n\n--no-config             Disable reading from the configuration file\n\n-h, --help              Display a usage message and exit\n\n-V, --version           Display the program version and exit\n\nThe remaining options can be given either on the command line or in the\nconfiguration file; see \"`Configuration Options`_\" for more information.\n\n\nConfiguration\n=============\n\nConfiguration File\n------------------\n\nIf a configuration file is specified on the command line with the ``--config``\noption, ``check-wheel-contents`` reads its configuration from the given file.\nFiles with a ``.toml`` extension are parsed as TOML files, and the\nconfiguration is read from the ``tool.check-wheel-contents`` table.  All other\nfiles are parsed as INI files, and their configuration is read from the\n``[check-wheel-contents]`` section (unless the file is named ``setup.cfg``, in\nwhich case the section ``[tool:check-wheel-contents]`` is used instead).\n\nIf no configuration file is specified on the command line, the program begins\nsearching for a file named ``pyproject.toml``, ``tox.ini``, ``setup.cfg``,\n``check-wheel-contents.cfg``, or ``.check-wheel-contents.cfg``, starting in the\ncurrent directory and going up.  The files are read using the same rules as for\nthe ``--config`` option, and the first file in the list that contains the\nappropriate section is used.  Searching stops once a directory containing any\nof the named files is found, even if none of them contain the relevant section.\n\nConfiguration Options\n---------------------\n\nThe following options may be set either on the command line or in the\nconfiguration file.  Settings given on the command line override those in the\nconfiguration file.  Unknown keys in configuration files are ignored.\n\n``--select <checks>`` / ``select = <checks>``\n   Select/enable only the given checks.  ``<checks>`` is a comma-separated list\n   of check IDs and/or check ID prefixes (to select all checks beginning with\n   the given prefixes).\n\n   In a TOML file, ``<checks>`` may alternatively be given as a list of\n   strings.\n\n   By default, all checks are selected (though some checks are no-ops when\n   certain other options are/aren't given).\n\n``--ignore <checks>`` / ``ignore = <checks>``\n   Ignore/skip the given checks.  ``<checks>`` is a comma-separated list of\n   check IDs and/or check ID prefixes (to ignore all checks beginning with the\n   given prefixes).\n\n   In a TOML file, ``<checks>`` may alternatively be given as a list of\n   strings.\n\n   By default, no checks are ignored.\n\n``--toplevel <names>`` / ``toplevel = <names>``\n   Tell ``check-wheel-contents`` to check that the toplevel library entries of\n   the wheel equal the set of names in the comma-separated list ``<names>``;\n   e.g., ``--toplevel foo.py,bar/`` checks that ``foo.py``, ``bar``, and\n   nothing else is at the top level of your wheel.  Trailing slashes on\n   directory names are optional.\n\n   In a TOML file, ``<names>`` may alternatively be given as a list of strings.\n\n   This option disables check W009 and enables checks W201 and W202.  It is\n   also used by check W005 to prevent failure on common names that are\n   intentionally used as toplevel names.\n\n``--package <path>`` / ``package = <paths>``\n   Tell ``check-wheel-contents`` to check that the wheel's library sections\n   contain the file tree rooted at ``<path>``.\n\n   Paths given on the command line are resolved relative to the current working\n   directory.  Paths given in a configuration file are resolved relative to the\n   directory containing the configuration file.\n\n   On the command line, multiple paths can be specified by supplying\n   ``--package`` multiple times.  In a configuration file, multiple paths can\n   be specified by setting ``package`` to a comma-separated list of paths.  In\n   a TOML file, ``<paths>`` may alternatively be given as a list of strings.\n\n   This option disables check W009 and enables checks W101 and W102.\n\n``--src-dir <path>`` / ``src_dir = <paths>``\n   The same as ``--package``, except that only the contents of ``<path>``\n   (which must be a directory) and not ``<path>`` itself are checked against\n   the wheel's contents.\n\n``--package-omit <patterns>`` / ``package_omit = <patterns>``\n   Ignore files & directories inside ``--package`` or ``--src-dir`` arguments\n   that match any of the glob patterns in the comma-separated list\n   ``<patterns>``.  Ignored files will not be looked for in wheels for check\n   W101, and if any of them do show up in a wheel, it will cause check W102 to\n   fail.\n\n   In a TOML file, ``<patterns>`` may alternatively be given as a list of\n   strings.\n\n   The default set of ignored patterns is ``.*, CVS, RCS, *.pyc, *.pyo,\n   *.egg-info``.\n\n\nChecks\n======\n\n**Note**: Unless otherwise stated, the common causes and their fixes listed\nhere are specific to projects developed using setuptools.  Users of other tools\nlike flit and poetry will have to consult those projects' documentation in\norder to resolve failed checks.\n\n**Note**: When rebuilding a wheel with setuptools, it is a good idea to delete\nthe ``build/`` directory first.  (This can be done in a single command with\n``python setup.py clean --all bdist_wheel``.)  Not doing this can cause various\nchecks to continue to fail or new ones to start failing.\n\n\nW001 \u2014 Wheel contains .pyc/.pyo files\n-------------------------------------\nThis check fails if there are any files in the wheel with a ``.pyc`` or\n``.pyo`` extension.  Such files are compiled Python bytecode files, and they do\nnot belong in wheels, because (a) they are platform-specific and thus useless\nto many of your users, and (b) pip generates ``.pyc`` files for the ``.py``\nfiles in your wheel automatically.\n\nCommon causes:\n\n- You have ``include_package_data`` set to ``True``, your ``MANIFEST.in``\n  contains ``graft packagename`` or ``recursive-include packagename *``, and\n  the line ``global-exclude *.py[co]`` or similar is either missing from the\n  ``MANIFEST.in`` or else in the wrong location.\n\n  **Solution**: Ensure that ``global-exclude *.py[co]`` appears in your\n  ``MANIFEST.in`` file *after* all ``include``, ``recursive-include``,\n  ``global-include``, and ``graft`` commands.\n\n- You have ``[install]optimize = 1`` set in ``setup.cfg`` (or, equivalently,\n  ``options={\"install\": {\"optimize\": \"1\"}}`` set in ``setup.py``).\n\n  **Solution**: Remove this setting.  It's only useful when using ``setup.py\n  install`` anyway, which is deprecated.\n\n\nW002 \u2014 Wheel contains duplicate files\n-------------------------------------\nThis check fails if any two files in the wheel have the same contents.  Common\nfile contents, such as files that are empty or just contain the line \"``# -*-\ncoding: utf-8 -*-``\", are excluded from this check.\n\nCommon causes:\n\n- *(Build tool agnostic)* You copied a file or directory when you actually\n  meant to rename it.\n\n  **Solution**: Delete the original copy of the file or directory.\n\n- You built a wheel, renamed a file or directory, and then built a wheel again\n  without first deleting the ``build/`` directory.\n\n  **Solution**: Delete the ``build/`` directory and build the wheel again.\n\n\nW003 \u2014 Wheel contains non-module at library toplevel\n----------------------------------------------------\nThis check fails if there are any files at the root of the purelib or platlib\nsection of the wheel that are not Python modules or ``.pth`` files.\nNon-modules belong elsewhere in a wheel:\n\n- Licenses and similar notices should be stored in the wheel's ``*.dist-info``\n  directory using ``wheel``'s ``license_files`` option.\n\n- Package data/resource files belong inside a package directory so that they\n  can be located with ``pkg_resources`` or ``importlib-resources``.\n\n- A project's ``README`` should already be used as the project's\n  ``long_description``, in which case the text of the ``README`` is already\n  included in the wheel inside the ``*.dist-info/METADATA`` file.  There should\n  thus be no need to store the ``README`` in the wheel's library sections.\n\n\nW004 \u2014 Module is not located at importable path\n-----------------------------------------------\nThis check fails if there are any Python modules in the purelib or platlib\nsection of the wheel that cannot be imported due to one or more of their path\ncomponents being invalid Python identifiers.\n\nCommon causes:\n\n- *(Build tool agnostic)* You gave a package directory or module a name\n  containing a hyphen or other character not allowed in Python identifiers.\n\n  **Solution**: Rename the offending directory or module to remove the\n  offending character, most likely by changing it to an underscore.\n\n- *(Build tool agnostic)* You gave a package directory or module the name of a\n  Python keyword.\n\n  **Solution**: Rename the offending directory or module.\n\n- *(Build tool agnostic)* Your package contains database migration files\n  generated by alembic or Django, which (may) begin with numbers and thus do\n  not have valid Python identifiers as names.\n\n  **Solution**: Ignore this check.  (Ignoring checks only for specific files is\n  not yet implemented.)\n\n\nW005 \u2014 Wheel contains common toplevel name in library\n-----------------------------------------------------\nThis check fails if there are any files or directories named ``.eggs``,\n``.nox``, ``.tox``, ``.venv``, ``app``, ``build``, ``cli``, ``data``, ``dist``,\n``doc``, ``docs``, ``example``, ``examples``, ``lib``, ``scripts``, ``src``,\n``test``, ``tests``, or ``venv`` located at the root of the purelib or platlib\nsection of the wheel.  These names are conventionally used for directories that\ndon't belong in wheels (aside from ``src``, whose contents belong in wheels but\nitself does not belong in a wheel).  Projects should only use toplevel names\nthat resemble the project name; using common names will cause different\nprojects' files to overwrite each other on installation.\n\nIf the ``--toplevel`` option is set, the names listed in the option will not\ncause this check to fail.\n\nCommon causes:\n\n- For ``src``: You failed to set up your ``src/`` layout correctly.  ``src``\n  should not contain an ``__init__.py`` file, ``where='src'`` needs to be\n  passed to ``setuptools.find_packages()`` in ``setup.py``, and\n  ``package_dir={\"\": \"src\"}`` needs to be passed to ``setup()`` in\n  ``setup.py``.\n\n- For directories other than ``src``: The directory contains an ``__init__.py``\n  file, and the directory is not listed in the ``exclude`` argument to\n  ``setuptools.find_packages()`` in ``setup.py``.\n\n  **Solution**: Include ``'DIRNAME'`` and ``'DIRNAME.*'`` in the list passed to\n  the ``exclude`` argument of ``find_packages()``.\n\n- For directories other than ``src``: The directory is listed in the\n  ``exclude`` argument to ``find_packages()``, but ``'DIRNAME.*'`` is not, and\n  a subdirectory of the directory contains an ``__init__.py`` file.\n\n  **Solution**: Include ``'DIRNAME.*'`` in the list passed to the ``exclude``\n  argument of ``find_packages()``.\n\n- You actually want to include your tests or examples in your wheel.\n\n  **Solution**: Move the tests or whatever to inside your main package\n  directory (e.g., move ``tests/`` to ``somepackage/tests/``) so that they\n  won't collide with other projects' files on installation.\n\n- You are actually making a package whose name is one of the listed names.\n\n  **Solution**: Include the name of your package in the ``--toplevel`` option\n  so that ``check-wheel-contents`` knows it's meant to be there.\n\n\nW006 \u2014 ``__init__.py`` at top level of library\n----------------------------------------------\nThis check fails if there is a file named ``__init__.py`` at the root of the\npurelib or platlib section of the wheel.  ``__init__.py`` files only belong\ninside package directories, not at the root of an installation.\n\nCommon causes:\n\n- You failed to set up your ``src/`` layout correctly.  ``src`` should not\n  contain an ``__init__.py`` file, ``where='src'`` needs to be passed to\n  ``setuptools.find_packages()`` in ``setup.py``, and ``package_dir={\"\":\n  \"src\"}`` needs to be passed to ``setup()`` in ``setup.py``.\n\n- You created an ``__init__.py`` file at the root of your project and set\n  ``packages='.'`` in ``setup.py``.\n\n  **Solution**: Configure your project's packages correctly.  For single-file\n  modules, pass a list of their names (without the ``.py`` extension) to the\n  ``py_modules`` argument to ``setup()``.  For package modules (directories),\n  pass a list of their names and the dotted names of their descendant\n  subpackages (possibly obtained by calling ``setuptools.find_packages()``) to\n  ``packages``.\n\n\nW007 \u2014 Wheel library is empty\n-----------------------------\nThis check fails if the wheel contains no files in either its purelib or\nplatlib section.\n\nCommon causes:\n\n- Your project consists of a single-file ``.py`` module, but you declared it to\n  ``setup()`` in ``setup.py`` using the ``packages`` keyword.\n\n  **Solution**: Single-file modules must be declared to ``setup()`` using the\n  ``py_modules`` keyword.  Pass it a list of the names of your single-file\n  modules without the ``.py`` extension.\n\n- You are using ``setuptools.find_packages()`` to list your packages for\n  ``setup()``, but your package does not contain an ``__init__.py`` file.\n\n  **Solution**: Create an ``__init__.py`` file in your package.  If this is not\n  an option because you are building a namespace package, use\n  ``setuptools.find_namespace_packages()`` instead of ``find_packages()``.  Be\n  sure to set the arguments appropriately so that the function only finds your\n  main package; `see the documentation for further information\n  <https://setuptools.readthedocs.io/en/latest/setuptools.html#find-namespace-packages>`_.\n\n- You're deliberately creating a wheel that only contains scripts, headers, or\n  other data files.\n\n  **Solution**: Ignore this check.\n\n\nW008 \u2014 Wheel is empty\n---------------------\nThis check fails if the wheel contains no files other than the ``*.dist-info``\nmetadata directory.  It is a stronger check than W007, intended for users who\nare creating wheels that only contain scripts, headers, and other data files\nand thus need to ignore W007.\n\nCommon causes:\n\n- Same causes as for W007\n\n- You're deliberately creating an empty wheel whose only function is to cause a\n  set of dependencies to be installed.\n\n  **Solution**: Ignore this check.\n\n\nW009 \u2014 Wheel contains multiple toplevel library entries\n-------------------------------------------------------\nThis check fails if the wheel's purelib and platlib sections contain more than\none toplevel entry between them, excluding ``.pth`` files and files &\ndirectories that begin with an underscore.  This is generally a sign that\nsomething has gone wrong in packaging your project, as very few projects want\nto distribute code with multiple top-level modules or packages.\n\nThis check is disabled if the ``--toplevel``, ``--package``, or ``--src-dir``\noption is given either on the command line or in the configuration file.\n\nCommon causes:\n\n- You built a wheel, renamed a toplevel file or directory, and then built a\n  wheel again without first deleting the ``build/`` directory.\n\n  **Solution**: Delete the ``build/`` directory and build the wheel again.\n\n- You are using ``setuptools.find_packages()`` in your ``setup.py``, your\n  project contains multiple directories with ``__init__.py`` files, and one or\n  more of these directories (other than your main package) is not listed in the\n  ``exclude`` argument to ``find_packages()``.\n\n  **Solution**: Pass a list of all ``__init__.py``-having directories in your\n  project other than your main package to the ``exclude`` argument of\n  ``find_packages()``.  For proper exclusion, each directory ``DIRNAME`` should\n  correspond to two elements of this list, ``'DIRNAME'`` and ``'DIRNAME.*'``,\n  in order to ensure that the directory and all of its subdirectories are\n  excluded.\n\n- You are deliberately creating a wheel with multiple top-level Python modules\n  or packages.\n\n  **Solution**: Use the ``--toplevel`` option to let ``check-wheel-contents``\n  know what toplevel entries to expect.\n\n\nW010 \u2014 Toplevel library directory contains no Python modules\n------------------------------------------------------------\nThis check fails if a directory tree rooted at the root of the purelib or\nplatlib section of the wheel contains no Python modules.  ``*-stubs``\ndirectories are excluded from this check.\n\n\nW101 \u2014 Wheel library is missing files in package tree\n-----------------------------------------------------\nThis check is only enabled if the ``--package`` or ``--src-dir`` option is set.\nThis check fails if a path in a tree rooted at an argument to ``--package`` or\ninside an argument to ``--src-dir`` does not appear in the wheel's purelib or\nplatlib section.  Empty directories and local files & directories that match\nany of the patterns specified with ``--package-omit`` or its default value are\nexcluded from this check.\n\nNote that this check only checks file paths, i.e., names of files &\ndirectories.  File contents are not examined.\n\nFor example, given the below local tree::\n\n    /usr/src/project/\n    \u251c\u2500\u2500 foo/\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 .gitignore\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 foo.py\n    \u2514\u2500\u2500 src/\n        \u251c\u2500\u2500 bar/\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 bar.py\n        \u2502\u00a0\u00a0 \u251c\u2500\u2500 empty/\n        \u2502\u00a0\u00a0 \u2514\u2500\u2500 quux/\n        \u2502\u00a0\u00a0     \u2514\u2500\u2500 data.dat\n        \u2514\u2500\u2500 bar.egg-info/\n            \u2514\u2500\u2500 PKG-INFO\n\nIf the options ``--package /usr/src/project/foo`` and ``--src-dir\n/usr/src/project/src`` are supplied and ``--package-omit`` is left at its\ndefault value, then ``check-wheel-contents`` will look for the following paths\nin the wheel, and the check will fail if any of them do not appear in either\nthe purelib or platlib section::\n\n    foo/__init__.py\n    foo/foo.py\n    bar/__init__.py\n    bar/bar.py\n    bar/quux/data.dat\n\nNote that ``foo/.gitignore`` and ``src/bar.egg-info`` are omitted from this\ncheck (and if they do appear in the wheel, it will cause check W102 to fail).\nEmpty directories are ignored altogether.\n\nCommon causes:\n\n- For Python files: You failed to pass all of your project's packages &\n  subpackages to ``setup()``'s ``packages`` argument.  If you are using\n  ``setuptools.find_packages()``, all of your packages & subpackages need to\n  contain ``__init__.py`` files.\n\n- For non-Python files: You failed to declare your project's package data\n  appropriately.  `See the setuptools documentation for information on how to\n  do this`__.\n\n__ https://setuptools.pypa.io/en/latest/userguide/datafiles.html\n\n\nW102 \u2014 Wheel library contains files not in package tree\n-------------------------------------------------------\nThis check is only enabled if the ``--package`` or ``--src-dir`` option is set.\nThis check fails if the purelib or platlib section of the wheel contains any\nfiles at paths that do not exist in any of the file trees specified with\n``--package`` or ``--src-dir``.\n\nNote that this check only checks file paths, i.e., names of files &\ndirectories.  File contents are not examined.\n\nFor example, given the local tree and options shown in the example under W101,\nthis check will fail if the wheel contains any files in its purelib or platlib\nsection other than the following::\n\n    foo/__init__.py\n    foo/foo.py\n    bar/__init__.py\n    bar/bar.py\n    bar/quux/data.dat\n\nNote that files & directories that match any of the patterns specified with\n``--package-omit`` or its default value are ignored in local trees, and so any\nentries with those names in the wheel will cause this check to fail.  Empty\ndirectories are ignored altogether.\n\nCommon causes: See common causes of W009\n\n\nW201 \u2014 Wheel library is missing specified toplevel entry\n--------------------------------------------------------\nThis check is only enabled if the ``--toplevel`` option is set.  This check\nfails if one or more of the names given in the ``--toplevel`` option does not\nappear at the root of the purelib or platlib section of the wheel.\n\nCommon causes: See common causes of W007\n\n\nW202 \u2014 Wheel library has undeclared toplevel entry\n--------------------------------------------------\nThis check is only enabled if the ``--toplevel`` option is set.  This check\nfails if there is a file or directory at the root of the purelib or platlib\nsection of the wheel that is not listed in the ``--toplevel`` option.\n``*.pth`` files are ignored for the purposes of this check.\n\nCommon causes: See common causes of W009\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Check your wheels have the right contents",
    "version": "0.6.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/jwodder/check-wheel-contents/issues",
        "Homepage": "https://github.com/jwodder/check-wheel-contents",
        "Source Code": "https://github.com/jwodder/check-wheel-contents"
    },
    "split_keywords": [
        "linter",
        "packaging",
        "wheel"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7416bb5228a8651247449d11a24ed72ff18413283fd34b8fdee0db60cc4ba950",
                "md5": "e43bb0f06952b9d777d3773cf316a2cd",
                "sha256": "f3430c5ae633026e15902e3153fa14a6bac2a8ae7bbc7044117712be667821da"
            },
            "downloads": -1,
            "filename": "check_wheel_contents-0.6.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e43bb0f06952b9d777d3773cf316a2cd",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 27755,
            "upload_time": "2023-10-31T21:20:43",
            "upload_time_iso_8601": "2023-10-31T21:20:43.800603Z",
            "url": "https://files.pythonhosted.org/packages/74/16/bb5228a8651247449d11a24ed72ff18413283fd34b8fdee0db60cc4ba950/check_wheel_contents-0.6.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "530630db4d32c297d90ca10b95bf3b5640898d894d9ed77cb53aad493e279e34",
                "md5": "b7d7a45797e4da9cd49d4f7334ef350b",
                "sha256": "64419c4e150e1de6f2d0bce7d4c7668eebfac127f0274014dd1a56ba07525364"
            },
            "downloads": -1,
            "filename": "check-wheel-contents-0.6.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b7d7a45797e4da9cd49d4f7334ef350b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 597014,
            "upload_time": "2023-10-31T21:20:45",
            "upload_time_iso_8601": "2023-10-31T21:20:45.733544Z",
            "url": "https://files.pythonhosted.org/packages/53/06/30db4d32c297d90ca10b95bf3b5640898d894d9ed77cb53aad493e279e34/check-wheel-contents-0.6.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-31 21:20:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jwodder",
    "github_project": "check-wheel-contents",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "check-wheel-contents"
}
        
Elapsed time: 0.13870s