diff options
| author | Jason R. Coombs <jaraco@jaraco.com> | 2020-05-26 18:20:51 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-26 18:20:51 -0400 |
| commit | 62f810175d7303476ca6d692ae4d743677b36272 (patch) | |
| tree | d0cb0b6b0cefbeac8358a1515e466d21545833f9 | |
| parent | 044ea4089f31cc0e66eef12bf8cd06df28e7bd17 (diff) | |
| parent | b13e4a2a96c2d88890157fdd0b116619436761c4 (diff) | |
| download | external_python_setuptools-62f810175d7303476ca6d692ae4d743677b36272.tar.gz external_python_setuptools-62f810175d7303476ca6d692ae4d743677b36272.tar.bz2 external_python_setuptools-62f810175d7303476ca6d692ae4d743677b36272.zip | |
Merge pull request #2146 from alvyjudy/doc
Step 4: A PEP517-styled quickstart user guide and room for collaboration
| -rw-r--r-- | docs/userguide/quickstart.txt | 284 |
1 files changed, 141 insertions, 143 deletions
diff --git a/docs/userguide/quickstart.txt b/docs/userguide/quickstart.txt index e75d74e1..52829751 100644 --- a/docs/userguide/quickstart.txt +++ b/docs/userguide/quickstart.txt @@ -2,211 +2,209 @@ ``setuptools`` Quickstart ========================== +.. contents:: + Installation ============ -.. _Installing Packages: https://packaging.python.org/tutorials/installing-packages/ - To install the latest version of setuptools, use:: pip install --upgrade setuptools -Refer to `Installing Packages`_ guide for more information. + +Python packaging at a glance +============================ +The landscape of Python packaging is shifting and ``Setuptools`` has evolved to +only provide backend support, no longer being the de-facto packaging tool in +the market. All python package must provide a ``pyproject.toml`` and specify +the backend (build system) it wants to use. The distribution can then +be generated with whatever tools that provides a ``build sdist``-alike +functionality. While this may appear cumbersome, given the added pieces, +it in fact tremendously enhances the portability of your package. The +change is driven under `PEP 517 <https://www.python.org/dev/peps/pep-0517/# +build-requirements>``. To learn more about Python packaging in general, +navigate to the `bottom <Resources on python packaging>`_ of this page. + Basic Use ========= +For basic use of setuptools, you will need a ``pyproject.toml`` with the +exact following info, which declares you want to use ``setuptools`` to +package your project: + +.. code-block:: toml + + [build-system] + requires = ["setuptools", "wheel"] + build-backend = "setuptools.build_meta" + +Then, you will need a ``setup.cfg`` to specify your package information, +such as metadata, contents, dependencies, etc. Here we demonstrate the minimum + +.. code-block:: ini -For basic use of setuptools, just import things from setuptools. Here's a -minimal setup script using setuptools:: + [metadata] + name = "mypackage" + version = 0.0.1 - from setuptools import setup, find_packages - setup( - name="HelloWorld", - version="0.1", - packages=find_packages(), - ) + [options] + packages = "mypackage" + install_requires = + requests + importlib; python_version == "2.6" -As you can see, it doesn't take much to use setuptools in a project. -Run that script in your project folder, alongside the Python packages -you have developed. +This is what your project would look like:: -Invoke that script to produce distributions and automatically include all -packages in the directory where the setup.py lives. See the `Command -Reference`_ section below to see what commands you can give to this setup -script. For example, to produce a source distribution, simply invoke:: + ~/mypackage/ + pyproject.toml + setup.cfg + mypackage/__init__.py - setup.py sdist +Then, you need an installer, such as `pep517 <https://pypi.org/project/pep517/>`_ +which you can obtain via ``pip install pep517``. After downloading it, invoke +the installer:: + + python -m pep517.build + +You now have your distribution ready (e.g. a ``tar.gz`` file and a ``.whl`` +file in the ``dist`` directory), which you can upload to PyPI! Of course, before you release your project to PyPI, you'll want to add a bit more information to your setup script to help people find or learn about your project. And maybe your project will have grown by then to include a few -dependencies, and perhaps some data files and scripts:: - - from setuptools import setup, find_packages - setup( - name="HelloWorld", - version="0.1", - packages=find_packages(), - scripts=["say_hello.py"], - - # Project uses reStructuredText, so ensure that the docutils get - # installed or upgraded on the target machine - install_requires=["docutils>=0.3"], - - package_data={ - # If any package contains *.txt or *.rst files, include them: - "": ["*.txt", "*.rst"], - # And include any *.msg files found in the "hello" package, too: - "hello": ["*.msg"], - }, - - # metadata to display on PyPI - author="Me", - author_email="me@example.com", - description="This is an Example Package", - keywords="hello world example examples", - url="http://example.com/HelloWorld/", # project home page, if any - project_urls={ - "Bug Tracker": "https://bugs.example.com/HelloWorld/", - "Documentation": "https://docs.example.com/HelloWorld/", - "Source Code": "https://code.example.com/HelloWorld/", - }, - classifiers=[ - "License :: OSI Approved :: Python Software Foundation License" - ] - - # could also include long_description, download_url, etc. - ) +dependencies, and perhaps some data files and scripts. In the next few section, +we will walk through those additional but essential information you need +to specify to properly package your project. + Automatic package discovery =========================== - For simple projects, it's usually easy enough to manually add packages to -the ``packages`` argument of ``setup()``. However, for very large projects -, it can be a big burden to keep the package list updated. setuptools therefore -provides tools to ease the burden. +the ``packages`` keyword in ``setup.cfg``. However, for very large projects +, it can be a big burden to keep the package list updated. ``setuptools`` +therefore provides two convenient tools to ease the burden: ``find: `` and +``find_namespace: ``. To use it in your project: -``find_packages()`` takes a source directory and two lists of package name -patterns to exclude and include. It then walks the target directory, filtering -by inclusion patterns, and return a list of Python packages (any directory). -Finally, exclusion patterns are applied to remove matching packages. +.. code-block:: ini -For example:: - #... - from setuptools import find_packages() + [options] + packages = find: - setup( - #..., - packages = find_packages() - ) + [options.packages.find] #optional + include=pkg1, pkg2 + exclude=pk3, pk4 + +When you pass the above information, alongside other necessary ones, +``setuptools`` walks through the directory specified in ``where`` (omitted +here as the package reside in current directory) and filters the packages +it can find following the ``include`` (default to none), then remove +those that match the ``exclude`` and return a list of Python packages. Note +that each entry in the ``[options.packages.find]`` is optional. The above +setup also allows you to adopt a ``src/`` layout. For more details and advanced +use, go to :ref:`package_discovery` -For more details and advanced use, go to :ref:`package_discovery` Entry points and automatic script creation =========================================== - Setuptools support automatic creation of scripts upon installation, that runs code within your package if you specify them with the ``entry_point`` keyword. This is what allows you to run commands like ``pip install`` instead of having -to type ``python -m pip install``. To accomplish this, consider the following -example:: - - setup( - #.... - entry_points={ - "console_scripts": [ - "foo = my_package.some_module:main_func", - ], - } - ) - -When this project is installed, a ``foo`` script will be installed and will -invoke the ``main_func`` when called by the user. For detailed usage, including -managing the additional or optional dependencies, go to :ref:`entry_point`. +to type ``python -m pip install``. To accomplish this, add the entry_points +keyword in your ``setup.cfg``: + +.. code-block:: ini + + [options] + entry_points = + [console_script] + main = mypkg:some_func + +When this project is installed, a ``main`` script will be installed and will +invoke the ``some_func`` in the ``__init__.py`` file when called by the user. +For detailed usage, including managing the additional or optional dependencies, +go to :ref:`entry_point`. + Dependency management ===================== - ``setuptools`` supports automatically installing dependencies when a package is installed. The simplest way to include requirement specifiers is to use the -``install_requires`` argument to ``setup()``. It takes a string or list of -strings containing requirement specifiers:: +``install_requires`` argument to ``setup.cfg``. It takes a string or list of +strings containing requirement specifiers (A version specifier is one of the +operators <, >, <=, >=, == or !=, followed by a version identifier): - setup( - #... - install_requires = "docutils >= 0.3" - ) +.. code-block:: ini -When your project is installed, either by using pip, ``setup.py install``, -or ``setup.py develop``, all of the dependencies not already installed will -be located (via PyPI), downloaded, built (if necessary), and installed. + [options] + install_requires = + docutils >= 0.3 + requests <= 0.4 + +When your project is installed, all of the dependencies not already installed +will be located (via PyPI), downloaded, built (if necessary), and installed. +This, of course, is a simplified scenarios. ``setuptools`` also provide +additional keywords such as ``setup_requires`` that allows you to install +dependencies before running the script, and ``extras_requires`` that take +care of those needed by automatically generated scripts. It also provides +mechanisms to handle dependencies that are not in PyPI. For more advanced use, +see :ref:`dependency_management` -For more advanced use, see :ref:`dependency_management` Including Data Files ==================== - The distutils have traditionally allowed installation of "data files", which are placed in a platform-specific location. Setuptools offers three ways to specify data files to be included in your packages. For the simpliest use, you -can simply use the ``include_package_data`` keyword e.g.:: +can simply use the ``include_package_data`` keyword: - setup( - ... - include_package_data=True - ) +.. code-block:: ini + + [options] + include_package_data = True This tells setuptools to install any data files it finds in your packages. The data files must be specified via the distutils' ``MANIFEST.in`` file. - For more details, see :ref:`datafiles` + Development mode ================ +``setuptools`` allows you to install a package without copying any files +to your interpretor directory (e.g. the ``site-packages`` directory). This +allows you to modify your source code and have the changes take effect without +you having to rebuild and reinstall. This is currently incompatible with +PEP 517 and therefore it requires a ``setup.py`` script with the following +content:: -Setuptools allows you to deploy your projects for use in a common directory or -staging area, but without copying any files. Thus, you can edit each project's -code in its checkout directory, and only need to run build commands when you -change a project's C extensions or similarly compiled files. - -To do this, use the ``setup.py develop`` command. It works very similarly to -``setup.py install``, except that it doesn't actually install anything. -Instead, it creates a special ``.egg-link`` file in the deployment directory, -that links to your project's source code. And, if your deployment directory is -Python's ``site-packages`` directory, it will also update the -``easy-install.pth`` file to include your project's source code, thereby making -it available on ``sys.path`` for all programs using that Python installation. - -for more information, go to :ref:`development_mode` - -Distributing a ``setuptools``-based project -=========================================== -Before you begin, make sure you have the latest versions of setuptools and wheel:: - - pip install --upgrade setuptools wheel - -To build a setuptools project, run this command from the same directory where -setup.py is located:: + import setuptools + setuptools.setup() - setup.py sdist bdist_wheel +Then:: -This will generate distribution archives in the `dist` directory. + pip install --editable . -Before you upload the generated archives make sure you're registered on -https://test.pypi.org/account/register/. You will also need to verify your email -to be able to upload any packages. -You should install twine to be able to upload packages:: +This creates a link file in your interpretor site package directory which +associate with your source code. For more information, see: (WIP) - pip install --upgrade twine -Now, to upload these archives, run:: +Uploading your package to PyPI +============================== +After generating the distribution files, next step would be to upload your +distribution so others can use it. This functionality is provided by +``twine <https://pypi.org/project/twine/>`` and we will only demonstrate the +basic use here. - twine upload --repository-url https://test.pypi.org/legacy/ dist/* -To install your newly uploaded package ``example_pkg``, you can use pip:: +Transitioning from ``setup.py`` to ``setup.cfg`` +================================================== +To avoid executing arbitary scripts and boilerplate code, we are transitioning +into a full-fledged ``setup.cfg`` to declare your package information instead +of running ``setup()``. This inevitably brings challenges due to a different +syntax. Here we provide a quick guide to understanding how ``setup.cfg`` is +parsed by ``setuptool`` to ease the pain of transition. - pip install --index-url https://test.pypi.org/simple/ example_pkg -The next following sections will walk you through all of the available functions -``setuptools`` offers in excrutiating details (including those already mentioned) -for more advanced use. +Resources on Python packaging +============================= +Packaging in Python is hard. Here we provide a list of links for those that +want to learn more. |
