Dear Maintainer, lintian looks for documentation outside /usr/share/doc and emits the package-contains-documentation-outside-usr-share-doc tag if it finds some. Of course there are some files that might look like documentation but are actually in the right place and so should not cause this tag to be emitted. One such set of files are in the `dist-info` directory of a python module, where various pieces of metadata that represent how the module was built, its dependencies (for the Python world) and licence data are stored. For example: /usr/lib/python3/dist-packages/python_debian-1.1.1.dist-info /usr/lib/python3/dist-packages/python_debian-1.1.1.dist-info/INSTALLER /usr/lib/python3/dist-packages/python_debian-1.1.1.dist-info/METADATA /usr/lib/python3/dist-packages/python_debian-1.1.1.dist-info/top_level.txt However, lintian has started flagging these files with package-contains-documentation-outside-usr-share-doc. I: python3-debian: package-contains-documentation-outside-usr-share-doc [usr/lib/python3/dist-packages/python_debian-1.1.1.dist-info/top_level.txt] N: N: This package ships a documentation file outside /usr/share/doc N: Documentation files are normally installed inside /usr/share/doc. N: N: If this file doesn't describe the contents or purpose of the directory it N: is in, please consider moving this file to /usr/share/doc/ or maybe even N: removing it. If this file does describe the contents or purpose of the N: directory it is in, please add a lintian override. N: N: Visibility: info N: Show-Always: no N: Check: documentation N: N: Screen: python/egg/metadata N: Advocates: "Scott Kitterman" <debian@kitterman.com> N: Reason: The folders XXX.dist-info/ and XXX.egg-info/ hold metadata for N: Python modules. Those files are not documentation even though N: some of their names carry the .txt file extension. N: N: Python modules can be both public and private. N: N: Read more in N: https://www.python.org/dev/peps/pep-0427/#the-dist-info-directory, N: https://www.python.org/dev/peps/pep-0376/#id16, N: https://www.python.org/dev/peps/pep-0610/, N: https://www.python.org/dev/peps/pep-0639/, N: https://setuptools.pypa.io/en/latest/deprecated/python_eggs.html, N: and Bug#1003913. (I leave the details of the intended streen in the output.) This is a regression - up until recently, lintian did not complain about these text files within the Python module definition. thanks for your work on lintian! Stuart
I looked into this.
(What follows is the AI-generated summary of a long human-driven
discussion with an agent)
TL;DR: This is not a regression in lintian itself - 2.122.0, 2.136.1, 2.139.0 and
2.140.0 all behave identically for your package. What changed is the package:
python3-debian 1.1.1 no longer ships a WHEEL file in its .dist-info directory
(1.0.1 and 1.1.0 did). That newly surfaces two long-standing lintian bugs. The
report is valid - these files should not be flagged - but it's not a recent
regression.
--------------------------------------------------
Problem analysis
The tag package-contains-documentation-outside-usr-share-doc is suppressed for
Python metadata by two independent mechanisms, and both fail for your package:
1. The screen requires a WHEEL file.
lib/Lintian/Screen/Python/Egg/Metadata.pm suppresses a .dist-info/ directory
only when it contains both METADATA and WHEEL:
return 1
if $item->dirname =~ m{ [^/] [.] dist-info / $}x
&& defined $item->parent_dir->child('METADATA')
&& defined $item->parent_dir->child('WHEEL');
WHEEL is only produced for packages built as wheels. A package installed via
setup.py install (like python_debian-1.1.1) has METADATA but no WHEEL - your
dist-info contains INSTALLER, METADATA, top_level.txt, and nothing else.
Earlier package versions (1.0.1, 1.1.0) happened to ship a WHEEL file, so the
screen worked for them. The METADATA file is the real, definitive marker of a
dist-info directory (PEP 427/376), so requiring WHEEL is too strict.
Required change: drop the WHEEL check so a .dist-info/ directory is recognized
by METADATA alone (keep the egg-info/PKG-INFO branch as-is):
return 1
if $item->dirname =~ m{ [^/] [.] dist-info / $}x
&& defined $item->parent_dir->child('METADATA');
2. The exclusion filename list never actually takes effect.
lib/Lintian/Check/Documentation.pm already lists top_level.txt (and robots.txt,
entry_points.txt, etc.) in @NOT_DOCUMENTATION_FILE_REGEXES, but the guard is
written as:
and any { $item->basename !~ m{$_}xi } @NOT_DOCUMENTATION_FILE_REGEXES)
any { BLOCK } LIST returns true if the block is true for at least one element
of the list. Here the block is "the basename does not match this regex", so the
whole test asks: "Is there at least one exclusion regex that the basename does
not match?"
The list holds ten different regexes (e.g. ^top_level[.]txt$, ^robots[.]txt$,
^entry_points[.]txt$, ...). A single basename can match at most a couple of
them. So for top_level.txt, although it matches ^top_level[.]txt$, it does not
match ^robots[.]txt$, ^entry_points[.]txt$, ^dependency_links[.]txt$, etc.
Because there are many regexes it does not match, the answer to "is there at
least one it doesn't match?" is almost always yes - so the test is true in
nearly every case, and the exclusion never actually excludes anything.
What was intended is the opposite: a file should only be flagged if it matches
none of the exclusion regexes - i.e. "the basename should not match any of the
exclusion regexes." The bug is that any { !~ } tests the wrong thing.
Required change: invert the test so a filename is only flagged when it matches
none of the exclusion regexes:
and none { $item->basename =~ m{$_}xi } @NOT_DOCUMENTATION_FILE_REGEXES)
(none is already exported by List::SomeUtils elsewhere in the codebase.)
--------------------------------------------------
Why it looked like a regression
I tested your exact scenario across multiple lintian releases:
Package 2.122.0 2.136.1 2.139.0 2.140.0
python3-debian 1.1.1 (no WHEEL) flagged flagged flagged flagged
python3-debian 1.0.1 (has WHEEL) suppress suppress suppress suppress
plain top_level.txt flagged flagged flagged flagged
The WHEEL-dependent screen logic and the broken exclusion guard are both
present in all these versions. The behavior is constant - what changed is the
package. Since you "up until recently" had a version of python3-debian that
shipped WHEEL, lintian suppressed these files; upgrading to 1.1.1 exposed the
latent bugs.
Verification considerations for the fix
- A legitimate documentation file such as user-guide.txt must still be flagged
(no false negatives).
- A .dist-info/ directory without METADATA should still be flagged (don't
over-suppress).
- Add a regression test for a .dist-info/ directory containing METADATA but no
WHEEL (e.g. under t/recipes/checks/documentation/)
Best,
Lucas
Hi Lucas Thanks for the analysis. (That assertion that python_debian-1.1.1 used `setup.py install` is incorrect, but that's tangential to the analysis.) The actual change is in dh-python 7.20260606 which is about improving support for multi-arch with Python modules (#1137616) by deleting the WHEEL file at the end of the build. That leaves the lintian check generating the false-positives and so lintian needs to catch up. The included solution sounds right (I've not looked at the code, and the included code is the sort of perl that reminds me that it's a long time since I wrote any serious perl. I had also observed dist-info/top_level.txt being flagged today, so yes, that is also happening. thanks Stuart
I did notice this earlier and came to the same conclusion back then but did not dig in if `WHEEL` is needed or not - I presumed it was and there is some problem with the package instead. But I looked closely now and https://packaging.python.org/en/latest/specifications/recording-installed-packages/#recording-installed-packages says | The METADATA file is mandatory. All other files may be omitted at the installing tool’s | discretion. Additional installer-specific files may be present. So yes, it makes sense to remove `WHEEL`. And yes, this looks absolutely wrong. I did some more cleanups here (top_level.txt is not quite needed here as it is already being cared for in python check) and opened MR https://salsa.debian.org/lintian/lintian/-/merge_requests/793 Thank for your help with this, Lucas! Best, Nilesh
Hello, Bug #1147187 in lintian reported by you has been fixed in the Git repository and is awaiting an upload. You can see the commit message below and you can check the diff of the fix at: https://salsa.debian.org/lintian/lintian/-/commit/579c425a21d7aa85e4e813858e52a7e27d036237 https://packaging.python.org/en/latest/specifications/recording-installed-packages/#recording-installed-packages Says | The METADATA file is mandatory. All other files may be omitted at the installing tool’s | discretion. Additional installer-specific files may be present. ------------------------------------------------------------------------ (this message was generated automatically) -- Greetings https://bugs.debian.org/1147187
We believe that the bug you reported is fixed in the latest version of
lintian, which is due to be installed in the Debian FTP archive.
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to 1147187@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Louis-Philippe Véronneau <pollo@debian.org> (supplier of updated lintian package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Sat, 12 Sep 2026 12:38:47 -0400
Source: lintian
Architecture: source
Version: 2.141.0
Distribution: unstable
Urgency: medium
Maintainer: Debian Lintian Maintainers <lintian-maint@debian.org>
Changed-By: Louis-Philippe Véronneau <pollo@debian.org>
Closes: 1017064 1145776 1147142 1147187 1147483
Changes:
lintian (2.141.0) unstable; urgency=medium
.
[ Louis-Philippe Véronneau ]
* Remove deprecated XS-Python-Version and X-Python-Version fields
.
[ Nilesh Patra ]
* Lintian::Screen::Python::Egg::Metadata - Do not check for `WHEEL` in
`dist-info` (Closes: #1147187)
* Lintian::Check::Documentation - Drop `dist-info` related files from
`NOT_DOCUMENTATION_FILE_REGEXES` and fix condition for exclusion of these.
Thanks to Lucas Nussbaum <lucas@debian.org>
* Rename Golang/ImportPath.pm -> Golang/ModulePath.pm to incorporate for
more module path related checks
* new tags: "go-library-package-does-not-include-version" and
"go-source-package-does-not-include-version" (Closes: #1147142)
* new tag: deprecated-debian-control-field (Closes: #1145776)
* Change severity level of `no-dep5-copyright` to `warning` (Closes:
#1147483)
* Unknown.pm, data: Add XB- prefixes for binary stanza fields in `data/` and
remove XB-* prefix in known binary fields checking for unknown fields
(Closes: #1017064)
* tags/tests/checks: Minor fixes in URLs (See: #1146466)
.
[ Scott Talbert ]
* Add more GHC path exclusions to RPATH check
.
[ Lucas Nussbaum ]
* Trim spelling text with builtin::trim
* Remove unused ELF section header fields
* Drop bignum for the ELF section Size decoding
.
[ Sylvestre Ledru ]
* Precompile the provider regexes for Javascript/Embedded.pm, Php/Embedded.pm
and Php/Pear/Embedded.pm.
* Documentation.pm: match the file name lists as compiled regexes
* Spelling.pm: gate the multi-word corrections on a single regex
Checksums-Sha1:
0aa6b8a008fe111be27fd9d8be5185ff4d21af5e 3694 lintian_2.141.0.dsc
c05d05f10626fed4eedb8397e725faf0170f2634 2079044 lintian_2.141.0.tar.xz
3b7d95797cf3b473af90b48806bd7456dc0a831d 21231 lintian_2.141.0_amd64.buildinfo
Checksums-Sha256:
a907ec9a63f3d67ac6f83c1f90e28242a4169e428f08c233bdc1c6eaf6066d2c 3694 lintian_2.141.0.dsc
c92ae6ca1e42bc9800292e0e108433c769f89c524531b9acb63603d1d4b134b5 2079044 lintian_2.141.0.tar.xz
4e9316668b4562dffeb1e9d89d2a8323f64ef9bde349f75e575042063d970194 21231 lintian_2.141.0_amd64.buildinfo
Files:
bbe1099f86ce349acb30e38f30d5ce08 3694 devel optional lintian_2.141.0.dsc
e3b56954d0f301cda8e4607632fbde66 2079044 devel optional lintian_2.141.0.tar.xz
581d1dfb7b1fa4eae49858d67a226340 21231 devel optional lintian_2.141.0_amd64.buildinfo
-----BEGIN PGP SIGNATURE-----
iHUEARYKAB0WIQTKp0AHB6gWsCAvw830JXpQshz6hQUCaqWK9AAKCRD0JXpQshz6
hcWUAP9LutZw8e4cVmoLknNwFW2i69W9Bb9dBB2Y2M7jANSC9AEAzOaoVFpHTywN
VgRIiUWHaz0p8oZvKWYA6sRJH+wioQc=
=G5Ev
-----END PGP SIGNATURE-----