diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f4819f2a5f77891d39c237113ae29705f2b4292c..d3f4baffd36d85f8c682d52d337cdb2dad33f6dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.2.0 hooks: - id: check-executables-have-shebangs - id: check-merge-conflict @@ -10,13 +10,13 @@ repos: - id: trailing-whitespace - repo: https://github.com/Yelp/detect-secrets - rev: v0.14.3 + rev: v1.2.0 hooks: - id: detect-secrets exclude: Pipfile\.lock|\.rst$ - repo: https://github.com/adrienverge/yamllint - rev: v1.25.0 + rev: v1.26.3 hooks: - id: yamllint @@ -28,7 +28,7 @@ repos: exclude: LICENSE - repo: https://github.com/ambv/black - rev: 20.8b1 + rev: 22.3.0 hooks: - id: black args: @@ -47,7 +47,7 @@ repos: - id: rstcheck - repo: https://github.com/PyCQA/prospector - rev: 1.3.1 + rev: 1.7.7 hooks: - id: prospector args: @@ -74,7 +74,7 @@ repos: - pyroma - repo: https://gitlab.com/pycqa/flake8.git - rev: 3.8.4 + rev: 3.9.2 hooks: - id: flake8 args: @@ -84,7 +84,7 @@ repos: - flake8-bugbear - repo: https://github.com/executablebooks/mdformat.git - rev: 0.7.9 + rev: 0.7.14 hooks: - id: mdformat diff --git a/content/pep-621-and-setuptools.rst b/content/pep-621-and-setuptools.rst new file mode 100644 index 0000000000000000000000000000000000000000..90e9bb3c1ae9a4dbe08486b79a52fe5b72e2d41a --- /dev/null +++ b/content/pep-621-and-setuptools.rst @@ -0,0 +1,104 @@ +PEP 621 and Setuptools +###################### +:date: 2022-04-28 +:summary: PEP 621 and Setuptools + +In the world of Python packaging, the trend is moving to using +:code:`pyproject.toml` to store all of the package's metadata as well as +settings for different tools. Until recently, this trend meant adding another +tool like `Poetry <https://python-poetry.org/>`_, `Flit +<https://flit.pypa.io/>`_ or `PDM <https://pdm.fming.dev/>`_ instead of using +the regular Setuptools (and maybe `build +<https://pypa-build.readthedocs.io/>`_). But with Setuptools 61.0.0, you can +still use Setuptools and have a modern Python package. + +Why? +---- + +- Avoid having a plethora of Python package managers installed. This is more + noticeable when some are wrappers or replacements of virtualenv and then you + need to insall them globally. + +- With Setuptools you keep close to the state of `PEP 621 + <https://peps.python.org/pep-0621/>`_ and your :code:`pyproject.toml` generic + +Why not? +-------- + +- You still need to manage virtual environments manually. + +- You need a very recent version of Setuptools. At the time of writing this + post I didn't find a distribution that had a new enough version of Setuptools + pacakged. + +- You need a supported version of Python. Currently this means Python 3.7 or + later. + +- You can get very close with an equivalent :code:`setup.cfg` and get backwards + compatibility. + +How? +---- + +I created a `sample Python project +<https://git.shore.co.il/nimrod/samplepyproject>`_ that has everything you need +to get started. It's tested to make sure a valid and working package, that +editable installation work, etc. You can skip directly to the `pyproject.toml +<https://git.shore.co.il/nimrod/samplepyproject/-/blob/main/pyproject.toml>`_ +file. + +A few notes. The only part that's Setuptools specific is specifying the +attribute for getting the version dynamically. You can specify the version +explicitly and be totally generic. The other settings that can be set +dynamically need to be read from other files which isn't great. I would like to +see the description be an attribute like version so I can point it to the +docstring like Flit does. For editable installations you still need a +:code:`setup.py` file but it's a 2 line file that calls :code:`setup()`. You +don't need a :code:`setup.cfg` file at all. + +Looking forward +--------------- + +I'm pretty sure that once PEP 621 is approved, other package managers will +adapt and tool specific configuration will be dropped. Also, support for using +:code:`pyproject.toml` in Setuptools will stop being experimental. I think that +once that's done and the only difference will be the 2 lines specifying the +build system we will see projects that want easier onboarding adopt Setuptools +to avoid forcing more tools on users. Over time distributions will package +newer versions of Setuptools and you will be able to have a working Python +environment just with the distribution packages. + +Appendix - PEP 582 +------------------ + +Another PEP that's yet to be approved is `PEP 582 +<https://peps.python.org/pep-0582/>`_. This propsal is for a package directory +that's local to a project (in the spirit of :code:`node_modules`). The reason I +mention it here is that this removes the need for virtual environments (and +thus the other major selling point for the different package managers). Now, +while it's not been approved and there's no version of Python that supports it +out of the box, we can mimic it with a little creative shell scripting: + +.. code:: shell + + PYTHON_VERSION="$(python3 -c 'from sys import version_info as v; print(f"{v[0]}.{v[1]}")')" + export PYTHONPATH="$PWD/__pypackages__/$PYTHON_VERSION:${PYTHONPATH:-}" + export PATH="$PWD/__pypackages__/$PYTHON_VERSION/bin:$PATH" + +With the above snippet we point Python to load packages from the +:code:`__pypackages__` directory and add the :code:`bin` directory to the +:code:`PATH` so executables are available. Lastly to install packages in that +location we run :code:`python3 -m pip install -t +"__pypackages__/$PYTHON_VERSION" foo`. I use `direnv <https://direnv.net/>`_ +quite a lot and I have the following snippet in a few projects: + +.. code:: shell + + PYTHON_VERSION="$(python3 -c 'from sys import version_info as v; print(f"{v[0]}.{v[1]}")')" + export PYTHONPATH="$PWD/__pypackages__/$PYTHON_VERSION:${PYTHONPATH:-}" + export PATH="$PWD/__pypackages__/$PYTHON_VERSION/bin:$PATH" + python3 -m pip install "__pypackages__/$PYTHON_VERSION" -e . + +This performs an editable installation of the package and all it dependencies, +so from that moment on I'm set and I don't any other package manager or even a +virtual environment. diff --git a/pelicanconf.py b/pelicanconf.py index 9f875b6fa6c3dcafb7b3f473467fb8877f9279c6..2ea3f0a054d54ce16adcb16c243ac928c2443520 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # # pylint: disable=import-error +"""Pelican configuration.""" from __future__ import unicode_literals import seafoam diff --git a/publishconf.py b/publishconf.py index 77f6416b7e14049fb3f1349f926ddaf905cd0bd9..c2eb85fd06cb8892e41d4025e0f53de5cac3d5e8 100644 --- a/publishconf.py +++ b/publishconf.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- # +"""Pelican configuration for publishing to the production site.""" from __future__ import unicode_literals # This file is only used if you explicitly specify it as your config file.