Control: tags -1 +patch -help Ok. It turns out staying at a BSP helps finding the brain space to fix such things.
Le dimanche, 29 janvier 2023, 00.01:26 h CET Didier 'OdyX' Raboud a écrit : > The crux of the issue is that python3-setuptools from 54.0.0 > (https://setuptools.pypa.io/en/latest/history.html#v54-0-0) does _not_ build > the .egg-info as single file, but _only_ as directory [0]. > > This has the direct consequence that all tests fail for either of these > reasons: > * the .egg-info is not a file, and cannot be compared with the expected > version > * the .egg-info directory is not cleaned in clean() , hence the snapshot-vs- > result directory comparison is always going to flag the .egg-info directory > as resulting cruft. Here comes a patch to fix 1 issue in the code itself, and fix all the tests to match that new reality. I've also pushed this to https://salsa.debian.org/python-team/packages/python-distutils-extra/-/merge_requests/7 for review, but given the freeze and as I've tested building python-apt with that code and don't see any regressions, I'll upload a Team upload to DELAYED/5 later today. Best, OdyX
diff --git a/DistUtilsExtra/auto.py b/DistUtilsExtra/auto.py index 7b3cce1..6376c5e 100644 --- a/DistUtilsExtra/auto.py +++ b/DistUtilsExtra/auto.py @@ -85,6 +85,9 @@ def setup(**attrs): for d in ignore_dirs: if f.startswith(d + os.path.sep): src.remove(f) + # Also remove files from the .egg-info directory + if '.egg-info/' in f: + src.remove(f) __cmdclass(attrs) __modules(attrs, src) diff --git a/debian/changelog b/debian/changelog index 6147f2f..7209f57 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-distutils-extra (2.47.1) UNRELEASED; urgency=medium + + * Adapt tests to distutils 54+; fixes FTBFS (Closes: #1026568) + + -- Didier Raboud <o...@debian.org> Sun, 29 Jan 2023 12:05:51 +0100 + python-distutils-extra (2.47) unstable; urgency=medium * Team upload. diff --git a/test/auto.py b/test/auto.py index 61286d1..17bb81a 100755 --- a/test/auto.py +++ b/test/auto.py @@ -51,6 +51,17 @@ setup( self.snapshot = None self.install_tree = None + def assert_egg_info_directory_is_present_and_well(self): + '''Check that no .egg-info file is present, that an egg_info directory is present and that it contains the expected files''' + + f = self.installed_files() + # All files are in an .egg-info directory; no .egg-info file is created + self.assertFalse(any([_.endswith('.egg-info') for _ in f ])) + # There are 4 files in said directory + self.assertEqual(len(f), 4) + # Check that the four exist + self.assertTrue(all([any([_.endswith(c) for c in ['PKG-INFO', 'SOURCES.txt', 'dependency_links.txt', 'top_level.txt']]) for _ in f])) + # # actual tests come here # @@ -63,10 +74,7 @@ setup( self.assertEqual(s, 0) self.assertNotIn('following files are not recognized', o) - f = self.installed_files() - # just installs the .egg_info - self.assertEqual(len(f), 1) - self.assertTrue(f[0].endswith('.egg-info')) + self.assert_egg_info_directory_is_present_and_well() def test_vcs(self): '''Ignores revision control files''' @@ -81,10 +89,7 @@ setup( self.assertEqual(s, 0) self.assertNotIn('following files are not recognized', o) - f = self.installed_files() - # just installs the .egg_info - self.assertEqual(len(f), 1) - self.assertTrue(f[0].endswith('.egg-info')) + self.assert_egg_info_directory_is_present_and_well() def test_modules(self): '''Python modules''' @@ -157,7 +162,7 @@ Exec=/usr/bin/foo-gtk self.assertIn('\n stuff/super.service\n', o) f = self.installed_files() - self.assertEqual(len(f), 4) # 3 D-BUS files plus .egg-info + self.assertEqual(len(f), 7) # 3 D-BUS files plus 4 files in egg-info directory self.assertIn('/etc/dbus-1/system.d/com.example.foo.conf', f) self.assertIn('/usr/share/dbus-1/system-services/com.example.foo.service', f) self.assertIn('/usr/share/dbus-1/services/com.example.foo.gui.service', f) @@ -178,7 +183,7 @@ Exec=/usr/bin/foo-gtk self.assertEqual(s, 0) f = self.installed_files() - self.assertEqual(len(f), 3) # 2 schema files plus .egg-info + self.assertEqual(len(f), 6) # 2 schema files plus 4 files in .egg-info directory self.assertIn('/usr/share/glib-2.0/schemas/org.test.myapp.gschema.xml', f) self.assertNotIn('gschemas.compiled', '\n'.join(f)) @@ -201,7 +206,7 @@ def add_info(report): self.assertNotIn('following files are not recognized', o) f = self.installed_files() - self.assertEqual(len(f), 3, f) # 2 hook files plus .egg-info + self.assertEqual(len(f), 6, f) # 2 hook files plus 4 in .egg-info self.assertIn('/usr/share/apport/package-hooks/foo.py', f) self.assertIn('/usr/share/apport/package-hooks/source_foo.py', f) @@ -513,7 +518,7 @@ setup( self._mksrc('LICENSE') self._mksrc('COPYING.LIB') self._mksrc('README.txt') - self._mksrc('MANIFEST.in') + self._mksrc('MANIFEST.in', content="# dummy") self._mksrc('MANIFEST') self._mksrc('NEWS') self._mksrc('TODO') @@ -731,22 +736,23 @@ print ('import iamnota.module') if 'template.py' in f or 'shiny' in f: self.assertNotIn('packages', f) - # parse .egg-info + # parse .egg-info directory (o, e, s) = self.setup_py(['install_egg_info', '-d', self.install_tree]) self.assertEqual(e, 'ERROR: Python module unknown not found\n') - egg_paths = [x for x in inst if x.endswith('.egg-info')] - self.assertEqual(len(egg_paths), 1) - egg = self._installed_contents(egg_paths[0].strip(os.path.sep)).splitlines() - self.assertIn('Name: foo', egg) + in_egg_paths = [x for x in inst if '.egg-info/' in x] + self.assertEqual(len(in_egg_paths), 4) # Always 4 files in .egg-info directory + + pkginfo = self._installed_contents([x for x in in_egg_paths if x.endswith('PKG-INFO')][0].strip(os.path.sep)).splitlines() + self.assertIn('Name: foo', pkginfo) # check provides - prov = [prop.split(' ', 1)[1] for prop in egg if prop.startswith('Provides: ')] + prov = [prop.split(' ', 1)[1] for prop in pkginfo if prop.startswith('Provides: ')] self.assertEqual(set(prov), set(['foo', 'mymod', 'broken', 'grab_cli', 'pygi'])) # check requires - req = [prop.split(' ', 1)[1] for prop in egg if prop.startswith('Requires: ')] + req = [prop.split(' ', 1)[1] for prop in pkginfo if prop.startswith('Requires: ')] self.assertEqual(set(req), set(['httplib2', 'pkg_resources', - 'gi.repository.GLib', 'gi.repository.GObject'])) + 'gi.repository.GLib', 'gi.repository.GObject', 'distutils.command.register'])) def test_help_docbook(self): '''Docbook XML help''' @@ -815,9 +821,7 @@ print ('import iamnota.module') self.assertIn('following files are not recognized', o) self.assertIn('\n binary_trap\n', o) - f = self.installed_files() - self.assertEqual(len(f), 1, f) - self.assertIn('egg-info', f[0]) + self.assert_egg_info_directory_is_present_and_well() def test_utf8_filenames(self): '''UTF-8 file names''' @@ -830,9 +834,7 @@ print ('import iamnota.module') self.assertEqual(e, '') self.assertEqual(s, 0) - f = self.installed_files() - self.assertEqual(len(f), 1, f) - self.assertIn('egg-info', f[0]) + self.assert_egg_info_directory_is_present_and_well() self.assertIn('following files are not recognized', o) # this might not be the correct file name when the locale is e. g. C @@ -880,7 +882,10 @@ print ('import iamnota.module') self.setup_py(['build']) return self.setup_py(['install', '--no-compile', '--skip-build', - '--prefix=/usr', '--root=' + self.install_tree]) + '--prefix=/usr', + '--install-data=/usr', + '--install-scripts=/usr/bin', + '--root=' + self.install_tree]) def installed_files(self): '''Return list of file paths in install tree.''' @@ -921,12 +926,17 @@ print ('import iamnota.module') shutil.copytree(self.src, os.path.join(self.snapshot, 's'), symlinks=True) def diff_snapshot(self): - '''Compare source tree to snapshot. + '''Compare source tree to snapshot, excluding known offenders. + + Check https://github.com/pypa/setuptools/issues/1347 for reference Return diff -Nur output. ''' assert self.snapshot, 'no snapshot taken' - diff = subprocess.Popen(['diff', '-x', 'foo.pot', '-x', '*.pyc', + diff = subprocess.Popen(['diff', + '-x', 'foo.pot', + '-x', '*.pyc', + '-x', '*.egg-info', '-Nur', os.path.join(self.snapshot, 's'), self.src], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = diff.communicate()
signature.asc
Description: This is a digitally signed message part.