Q: can flit take care of documentation and test suite?
I've jsut started working on package as rpm package https://github.com/pexpect/ptyprocess/.
Tis module uses flit. In the source tree is as well documentation and test suite however flit build does not produce sdist tar ball without those two directories.
I cannot find anything in flit documentation about documentation and test suite description.
Q: Is it possible to describe in project.toml/setup.cfg documentation and test suite?
If yes: how to add necessary description in project.toml/setup.cfg?
If not: is it possible to generate setup.py but which will be importing setuptools instead distutils.core?
If that woud be possible such setup.py would be possible to use python setup.py build_sphinx
Normally, everything which is checked into git should be included in the sdist made by flit build. That should include tests and docs (source files).
Flit does not concern itself with running tests or building documentation, and it doesn't provide any extension points to do those things. I've never seen the attraction of running tools like Sphinx through setup.py, as if it was some ugly Makefile equivalent.
Please don't rely on the generated setup.py in sdists. It's there so old versions of pip can install packages made by Flit automatically, and it's going to go away fairly soon now that PEP 517 is well adopted.
Flit does not concern itself with running tests or building documentation, and it doesn't provide any extension points to do those things. I've never seen the attraction of running tools like Sphinx through
setup.py, as if it was some ugly Makefile equivalent.
python setup.py build_sphinx -b <format> is still most frequently used way of generating documentation.
I have rpm macro %py3_build_sphinx_man which looks like that:
[tkloczko@barrel SPECS]$ rpm -E %py3_build_sphinx_man
\
PBR_VERSION=%{version} \
SETUPTOOLS_SCM_PRETEND_VERSION=%{version} \
SPHINXOPTS="-j48" \
/usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
Which I'm usin g in almost half of my pythom packaginfg procedures:
[tkloczko@barrel SPECS]$ grep %py3_build_sphinx_man python-* | wc -l; ls -1 python-*|wc -l
230
577
and still +100 modules in that set can be enriched to add build and install documentation that way.
Quoting from gawk info page: "Documentation is like sex. Wen it is good it is really good. When it is bad it is better than nothing" :)
It would be good if flit like setuptools would provide possibility to pug in extensions like it has that module.
setuptools build_sphinx command is available when setuptools and sphinx are installed and it is very useful because it allows do not care where in source tree is sphinx copy.py file and as well allows store results of building documentation in exact location. Only missing bit in that duet is that setuptools install command does not know anything about generated documentation to install it.
It would be good if on flit on build would allow choose documentation format and according to what have bee chosen install for example man pages in standard location.
Without that setuptools will still have more actual useful functionalities than flit.
From point of test suite bits.
Sometimes test suite needs to be executed in venv or wrapped over tox. Sometime still it is python setup.py test, and sometimes it needs to be sued one of many test suit frameworks like pytest, unitest, nose, ntox, nox ..
All that details about testing methodology should be IMO possible to describe somehow in project.toml/setup.cfg.
I'm not arguing with the need for tests or docs. But I don't see them as part of packaging. If you want to try to push standard ways for projects to define how to run their tests or build their docs, by all means do so. You can write your own tool to be the entry point, and try to persuade people to use it. Or you can propose a PEP for official standard entry points for these things. It can use information stored in pyproject.toml if you like (any project foo on PyPI can define a [tool.foo] table for other projects to use). I don't see any reason to try to do that within Flit.
Really it would be nice if flit would be able to handle sphinx integration in which is possibe to add in setyp.cfg
https://www.sphinx-doc.org/en/master/usage/advanced/setuptools.html
Without that flit is now nothing more than just plain archivig tool which adds some checksums in .dist-info metadata :/
From my point of view, insisting that a packaging tool should have a way to build documentation is like saying that a toaster should be able to boil water - boiling water is useful, but you get a kettle for that and use it alongside the toaster. In the same way, Sphinx is great, you can use it alongside Flit, but I don't see any need to connect them together. If you want to build docs, run make -C doc html, or the equivalent sphinx-build command. What do you gain from running some hypothetical flit sphinx command instead?
I'm not interested in the fact that it's possible with setuptools, because I'm not trying to copy setuptools.
Your argument above seems to amount to "it should be possible to build docs without knowing the path to the docs folder". Which is fine, but all the Sphinx setuptools integration does is look for a folder called either doc or docs. So if that's what you need, you can write about 5 lines of Python or shell code, no need to integrate with Flit, and it will work regardless of whether a package uses Setuptools, Flit, Poetry, Enscons, or anything else.
Analogy is not tool of proving thesis. It can only make easier to understand some aspect which is hard to understand straight.
Issue is that setuptools module it is not packaging but build/install/testing framework. Part of the processes which is possible to define using setuptools is generate wheel or sdist archives.
If flit, poetry want to replace setuptools it cannot be dine selectively by provide only achieving functionality.
Without taking over these areas flit or poetry never would be able to replace setuptools.
I'm not aware of any issues of the setuptools on area of generating wheel or sdists archive. More .. looking on all my currently cleaned python modules I see that ((% of those modules packaging procedures are able successfully use setuptools as build/install framework.
[tkloczko@barrel SPECS]$ grep -wl %py3_build python-* |wc -l; ls -1 python-*|wc -l
587
591
In that situation all what can be used is so called McGyver rule "If it ain't broke, don't fix it."
If you want to build docs, run
make -C doc html, or the equivalentsphinx-buildcommand. What do you gain from running some hypotheticalflit sphinxcommand instead?
Issue is that already ~halt of my packages is using setuptools<>sphinx integration and flit cannot provide anything on that area to standardise such processes.
[tkloczko@barrel SPECS]$ grep -w %py3_build_sphinx_man python-* |wc -l; ls -1 python-*|wc -l
256
591
[tkloczko@barrel SPECS]$ rpm -E %py3_build_sphinx_man
\
PBR_VERSION=%{version} \
SETUPTOOLS_SCM_PRETEND_VERSION=%{version} \
SPHINXOPTS="-j48" \
/usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
Result of that is:
[tkloczko@barrel SPECS]$ man python-<tab><tab>
Display all 248 possibilities? (y or n)
python-amqp python-httplib2 python-path python-sos
python-anyiodoc python-hypercorn python-pathspec python-sphinx-argparse
python-anytree python-hyperframe python-pillow python-sphinx-click
python-argcomplete python-hyperlink python-platformdirs python-sphinxcontrib-asyncio
python-arrow python-hypothesis python-pluggy python-sphinxcontrib-autoprogram
python-asgi python-ifaddr python-polib python-sphinxcontrib-bibtex
python-aspectlib python-importlib-metadata python-prb python-sphinxcontrib-httpdomain
python-astor python-inflect python-priority python-sphinxcontrib-programoutput
python-astroid python-ipykernel python-productmd-compose python-sphinxcontrib-trio
python-async_generator python-ipythonparallel python-productmd-composeinfo python-sphinxcopybutton
python-atomicwrites python-itsdangerous python-productmd-discinfo python-sphinxext-opengraph
python-attrs python-jaraco-classes python-productmd-images python-sphinx-inline-tabs
python-augeas python-jaraco-collections python-productmd-rpms python-sphinx-removed-in
python-autodocsumm python-jaraco-envs python-productmd-terminology python-sphinx_rtd_theme
python-babel python-jaraco-functools python-productmd-treeinfo python-sphinx-tabs
python-backcall python-jaraco.itertools python-prompt_toolkit python-sphinx-typlog-theme
python-backports.entry-points-selectable python-jaraco-packaging python-ptyprocess python-sphobjinv
python-benchmark python-jaraco-path python-purl python-sqlparse
python-betamax python-jaraco-text python-py python-stdlib-list
python-billiard python-jedi python-pyasn1 python-stem
python-bleach python-Jinja python-pybtex python-sure
python-blinker python-jinja2_pluralize python-pybtex-docutils python-sybil
python-boto3 python-jmespath python-pycodestyle python-systemd
python-botocore python-jsonschema python-pydocstyle python-tempora
python-bottle python-jupyter_client python-pyfakefs python-terminado
python-breathe python-jupyter_core python-pyftpdlib python-testpath
python-cachetools python-jupytext python-pygal python-test_server
python-cffi python-kiwi python-pygments python-testtools
python-characteristic python-kombu python-pyhamcrest python-tidy
python-chardet python-lark python-pylama python-tinycss2
python-cheroot python-latexcodec python-pylint python-toolz
python-click python-lazy-object-proxy python-pymeeus python-tornado
python-click-log python-libevdev python-pynacl python-traitlets
python-contextlib2 python-linkify-it-py python-pyopenssl python-transaction
python-convertdate python-lockfile python-pyrad python-trio
python-coveragepy python-lxml python-pyrsistent python-trustme
python-coveralls python-mako python-pyscss python-twisted
python-cppy python-markupsafe python-pytest python-uritemplate
python-cssselect2 python-mdit-py-plugins python-pytest-cov python-urllib3
python-cython python-metaextract python-pytest-regressions python-validators
python-dateutil python-mistune python-pytest-runner python-vine
python-dictdiffer python-mock python-pytest-trio python-virtualenv
python-dpkt python-more-itertools python-pytest-xprocess python-waitress
python-dulwich python-msgpack python-python-sphinx-contribspelling python-wcwidth
python-elementpath python-multidict python-pyudev python-webcolors
python-evdev python-multipledispatch python-pyxattr python-webencodings
python-eventlet python-mypy python-pyxdg python-webob
python-execnet python-myst-parser python-requests-mock python-websocket-client
python-faker python-nbclient python-requests_toolbelt python-websockets
python-fields python-nbformat python-rich python-webtest
python-flake8 python-netaddr python-rsa python-werkzeug
python-flask python-nose2 python-rst.linker python-wheel
python-flit python-notebook python-scons python-Whoosh
python-fonttools python-numpydoc python-scripttest python-wrapt
python-gcovr python-olefile python-selenium python-WSGIProxy2
python-gidocgen python-openstackdocstheme python-semantic-version python-wsproto
python-gitdb python-outcome python-service-identity python-xmlschema
python-gitpython python-paramiko python-setuptools python-yamlloader
python-greenlet python-parso python-six python-yarl
python-h2 python-parver python-smartypants python-zeroconf
python-hacking python-paste python-smmap.tex python-zipp
python-hpack python-paste-deploy python-sniffio python-zope-event
In case of generating man page for flit module I was not able to use that approach. Here is part of my python-flit.spec
%build
cd flit_core
FLIT_NO_NETWORK=1 \
%__python3 -Bm build --no-isolation
cd -
PYTHONPATH=$PWD/flit_core \
%__python3 -Bm build --no-isolation --skip-dependency-check
sphinx-build -b man -d %{name} doc .
%install
%py3_install_wheel *.whl
cd flit_core
%py3_install_wheel *.whl
cd -
%__install *.3 -Dt %{buildroot}%{_mandir}/man3
%check
%pytest
Exactly the same in case of using setuptools<>sphinx integration looks like below
%build
%py3_build
%py3_build_sphinx_man
%install
%py3_install
%__install build/sphinx/man/*.3 -Dt %{buildroot}%{_mandir}/man3
%check
%pytest
In other words using flit or build does not make anything simpler but only more complicated.
~halt of my packages is using setuptools<>sphinx integration
That's a choice that you've made. Those projects can equivalently be built with Sphinx directly as well.
I agree with Thomas that I don‘t see a good reason why a new packaging tool would concern itself with running unrelated tasks.
Long version:
distutils was a build tool and an install tool, setuptools added dependencies and download.
At one point, some python devs liked to use setup.py as a task runner for all dev tools, such as running tests or building and uploading docs. It was not universally used in that way, and today that is a mostly obsolete practice (meaning not recommended in guides and not used by devs, even though it is used in some pipelines like the one you’re describing).
About tests: I don’t know how popular python setup.py test was in the end. I guess one reason to use setup.py was that it was aware of the location of the code; I suspect this was always more useful as an automation command (you don’t have to know what to install for tests and what to run) than as a command run by devs (simpler and faster to run the real test command, and gives you options, help, completion, etc). tox has mostly taken over the role of universal test runner (and in a lesser extent, is used by projects as a task runner for development too), and there is no benefit in mixing packaging tool and testing tool.
About docs: the benefits are even smaller there; the build_docs command was not doing much and had even less relation to the packaging options, I think it’s the upload_docs command that was really attractive to people. I think this was created because Sphinx docs were becoming popular and if you already had the knowledge of writing setuptools command, it seemed easy to write one to zip docs and send them over HTTP, so one distribute dev did that. Now we have replaced packages.python.org with readthedocs and other hosting systems, and building and uploading docs uses doc tooling.
I do sympathize with OS packagers that have developed tooling over the last decades to handle hundred of upstream packages. I understand it’s nice if you can have a uniform interface and let your generic scripts run python setup.py test or python setup.py build_sphinx. But the packaging tools have changed (for the better!), setup.py is on its way out, and there is no universal interface that lets us define once that a project is using poetry or flit so we can run poetry build_sphinx or flit test. Downstream packaging scripts need to be configured to run build-sphinx param -B param -C etc or pytest --no-network.
I'm going to close this now. I hope that you've found satisfactory ways to work with packages that don't have setup.py files.
I think there could still be an interesting conversation about standardising a test runner hook so people working with many different packages can test them all without needing to know about each project's test setup. But Flit's issue tracker isn't the place for that - the packaging category on discuss.python.org is the best place I can think of to start.
[I don't want to start that discussion here, but I imagine the main question is what the hook would be expected to do. Run tests in the current environment, like invoking pytest? Or set up testing environments like tox & nox? Is it allowed to fetch dependencies from PyPI? Should it check multiple Python versions? Is it meant to test a source tree of the package, building it if needed, or a package that was already built and installed? I'm saying this to set expectations: if you want to come up with a proposal for this, expect a lengthy discussion where it's hard to reach a consensus.]