summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile20
-rw-r--r--tests/common.mk19
-rw-r--r--tests/common.py18
-rw-r--r--tests/t301/Makefile15
-rw-r--r--tests/t301/debian/changelog5
-rw-r--r--tests/t301/debian/compat1
-rw-r--r--tests/t301/debian/control18
-rw-r--r--tests/t301/debian/copyright2
-rw-r--r--tests/t301/debian/py3dist-overrides5
-rw-r--r--tests/t301/debian/python3-foo.pydist1
-rwxr-xr-xtests/t301/debian/rules25
-rw-r--r--tests/t301/debian/source/format1
-rw-r--r--tests/t301/lib/foo/__init__.py1
-rw-r--r--tests/t301/lib/foo/bar/__init__.py1
-rw-r--r--tests/t301/lib/foo/baz.py1
l---------tests/t301/lib/foo/jquery.js1
-rw-r--r--tests/t301/setup.py17
-rw-r--r--tests/t302/Makefile18
-rw-r--r--tests/t302/debian/changelog5
-rw-r--r--tests/t302/debian/compat1
-rw-r--r--tests/t302/debian/control18
-rw-r--r--tests/t302/debian/copyright2
-rw-r--r--tests/t302/debian/install2
-rwxr-xr-xtests/t302/debian/rules30
-rw-r--r--tests/t302/debian/source/format1
-rw-r--r--tests/t302/lib/__init__.py0
-rw-r--r--tests/t302/lib/bar.c0
-rw-r--r--tests/t302/lib/foo.py6
-rwxr-xr-xtests/t302/setup.py13
-rw-r--r--tests/t303/Makefile12
-rw-r--r--tests/t303/debian/changelog5
-rw-r--r--tests/t303/debian/compat1
-rw-r--r--tests/t303/debian/control12
-rw-r--r--tests/t303/debian/copyright2
-rwxr-xr-xtests/t303/debian/rules23
-rw-r--r--tests/t303/debian/source/format1
-rw-r--r--tests/t304/Makefile23
-rwxr-xr-xtests/t304/bar.py2
-rwxr-xr-xtests/t304/baz.py2
-rw-r--r--tests/t304/debian/changelog5
-rw-r--r--tests/t304/debian/compat1
-rw-r--r--tests/t304/debian/control19
-rw-r--r--tests/t304/debian/copyright2
-rw-r--r--tests/t304/debian/examples1
-rw-r--r--tests/t304/debian/install7
-rw-r--r--tests/t304/debian/overrides.install2
-rwxr-xr-xtests/t304/debian/rules26
-rw-r--r--tests/t304/debian/source/format1
-rwxr-xr-xtests/t304/foo.py2
-rw-r--r--tests/t304/setup.py0
-rw-r--r--tests/t304/spam.py1
-rw-r--r--tests/t305/Makefile14
-rw-r--r--tests/t305/debian/changelog5
-rw-r--r--tests/t305/debian/compat1
-rw-r--r--tests/t305/debian/control43
-rw-r--r--tests/t305/debian/copyright2
-rw-r--r--tests/t305/debian/foo5a.install1
-rw-r--r--tests/t305/debian/foo5b.install1
-rw-r--r--tests/t305/debian/foo5c.install1
-rw-r--r--tests/t305/debian/foo5d.install1
-rwxr-xr-xtests/t305/debian/rules22
-rw-r--r--tests/t305/debian/source/format1
-rwxr-xr-xtests/t305/foo5a2
-rwxr-xr-xtests/t305/foo5b2
-rwxr-xr-xtests/t305/foo5c2
-rwxr-xr-xtests/t305/foo5d2
-rw-r--r--tests/t306/Makefile17
-rw-r--r--tests/t306/debian/changelog5
-rw-r--r--tests/t306/debian/compat1
-rw-r--r--tests/t306/debian/control13
-rw-r--r--tests/t306/debian/copyright2
-rwxr-xr-xtests/t306/debian/rules14
-rw-r--r--tests/t306/debian/source/format1
-rw-r--r--tests/t306/lib/__init__.py0
-rw-r--r--tests/t306/lib/bar.c0
-rw-r--r--tests/t306/lib/foo.py6
-rwxr-xr-xtests/t306/setup.py12
-rw-r--r--tests/ta01/Makefile39
-rw-r--r--tests/ta01/debian/changelog5
-rw-r--r--tests/ta01/debian/control15
-rwxr-xr-xtests/ta01/debian/rules33
-rw-r--r--tests/ta01/foo/__init__.py1
-rw-r--r--tests/ta01/pyproject.toml3
-rw-r--r--tests/ta01/setup.cfg10
-rw-r--r--tests/ta01/tests/__init__.py0
-rw-r--r--tests/ta01/tests/test_foo.py7
-rw-r--r--tests/ta02/Makefile17
-rw-r--r--tests/ta02/debian/changelog5
-rw-r--r--tests/ta02/debian/control16
-rwxr-xr-xtests/ta02/debian/rules28
-rw-r--r--tests/ta02/foo/__init__.py1
-rw-r--r--tests/ta02/pyproject.toml3
-rw-r--r--tests/ta02/setup.cfg10
-rw-r--r--tests/ta02/tests/__init__.py0
-rw-r--r--tests/ta02/tests/test_foo.py7
-rwxr-xr-xtests/test-package-show-info16
-rw-r--r--tests/test_debhelper.py192
-rw-r--r--tests/test_depends.py726
-rw-r--r--tests/test_fs.py145
-rw-r--r--tests/test_interpreter.py250
-rw-r--r--tests/test_tools.py44
-rw-r--r--tests/tpb01/Makefile9
-rw-r--r--tests/tpb01/debian/changelog5
-rw-r--r--tests/tpb01/debian/control16
-rw-r--r--tests/tpb01/debian/copyright2
-rwxr-xr-xtests/tpb01/debian/rules26
-rw-r--r--tests/tpb01/debian/source/format1
-rw-r--r--tests/tpb01/foo.py1
-rw-r--r--tests/tpb01/setup.cfg9
-rw-r--r--tests/tpb01/setup.py3
-rw-r--r--tests/tpb02/Makefile19
-rw-r--r--tests/tpb02/data/share/man/man1/foo.18
-rw-r--r--tests/tpb02/debian/changelog5
-rw-r--r--tests/tpb02/debian/control16
-rw-r--r--tests/tpb02/debian/copyright2
-rw-r--r--tests/tpb02/debian/pybuild.testfiles3
-rwxr-xr-xtests/tpb02/debian/rules26
-rw-r--r--tests/tpb02/debian/source/format1
-rw-r--r--tests/tpb02/foo/__init__.py6
-rw-r--r--tests/tpb02/foo/test_foo.py11
-rw-r--r--tests/tpb02/nested/testfile2.txt0
-rw-r--r--tests/tpb02/pyproject.toml22
-rw-r--r--tests/tpb02/testdir/testfile3.txt0
-rw-r--r--tests/tpb02/testfile1.txt0
-rw-r--r--tests/tpb03/Makefile10
-rw-r--r--tests/tpb03/debian/changelog5
-rw-r--r--tests/tpb03/debian/control15
-rw-r--r--tests/tpb03/debian/copyright2
-rwxr-xr-xtests/tpb03/debian/rules26
-rw-r--r--tests/tpb03/debian/source/format1
-rw-r--r--tests/tpb03/foo.py1
-rw-r--r--tests/tpb03/setup.cfg7
-rw-r--r--tests/tpb03/setup.py3
-rw-r--r--tests/tpb04/Makefile10
-rw-r--r--tests/tpb04/_foo.c0
-rw-r--r--tests/tpb04/debian/changelog5
-rw-r--r--tests/tpb04/debian/control23
-rw-r--r--tests/tpb04/debian/copyright2
-rwxr-xr-xtests/tpb04/debian/rules27
-rw-r--r--tests/tpb04/debian/source/format1
-rw-r--r--tests/tpb04/foo.py1
-rw-r--r--tests/tpb04/setup.cfg5
-rw-r--r--tests/tpb04/setup.py9
-rw-r--r--tests/tpb04/test_foo.py6
-rw-r--r--tests/tpb04/tox.ini6
-rw-r--r--tests/tpb05/LICENSE17
-rw-r--r--tests/tpb05/Makefile19
-rw-r--r--tests/tpb05/debian/changelog5
-rw-r--r--tests/tpb05/debian/control16
-rw-r--r--tests/tpb05/debian/copyright2
-rwxr-xr-xtests/tpb05/debian/rules28
-rw-r--r--tests/tpb05/debian/source/format1
-rw-r--r--tests/tpb05/foo/__init__.py4
-rw-r--r--tests/tpb05/foo/test_foo.py6
-rw-r--r--tests/tpb05/pyproject.toml17
-rw-r--r--tests/tpb05/setup.py5
-rw-r--r--tests/tpb06/LICENSE17
-rw-r--r--tests/tpb06/Makefile20
-rw-r--r--tests/tpb06/debian/changelog5
-rw-r--r--tests/tpb06/debian/control15
-rw-r--r--tests/tpb06/debian/copyright2
-rwxr-xr-xtests/tpb06/debian/rules26
-rw-r--r--tests/tpb06/debian/source/format1
-rw-r--r--tests/tpb06/foo/__init__.py4
-rw-r--r--tests/tpb06/foo/ext.c0
-rw-r--r--tests/tpb06/foo/test_foo.py13
-rw-r--r--tests/tpb06/man/foo.18
-rw-r--r--tests/tpb06/pyproject.toml3
-rw-r--r--tests/tpb06/setup.cfg21
-rw-r--r--tests/tpb06/setup.py12
-rw-r--r--tests/tpb07/Makefile11
-rw-r--r--tests/tpb07/bar/LICENSE17
-rw-r--r--tests/tpb07/bar/bar/__init__.py4
-rw-r--r--tests/tpb07/bar/pyproject.toml3
-rw-r--r--tests/tpb07/bar/setup.cfg17
-rw-r--r--tests/tpb07/debian/changelog5
-rw-r--r--tests/tpb07/debian/control21
-rw-r--r--tests/tpb07/debian/copyright2
-rwxr-xr-xtests/tpb07/debian/rules30
-rw-r--r--tests/tpb07/debian/source/format1
-rw-r--r--tests/tpb07/foo/LICENSE17
-rw-r--r--tests/tpb07/foo/foo/__init__.py4
-rw-r--r--tests/tpb07/foo/pyproject.toml3
-rw-r--r--tests/tpb07/foo/setup.cfg17
184 files changed, 2916 insertions, 0 deletions
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..55f0c9e
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,20 @@
+#!/usr/bin/make -f
+
+# enable or disable tests here:
+#TESTS := test301 test302 test303 test304 test305 test306 testpb01 testpb02 testpb03 testpb04 testpb05 testpb06 testpb07 testa01 testa02
+TESTS := test301 test302 test303 test304 test305 test306
+
+all: $(TESTS)
+
+test%:
+ make -C t$* run
+ make -C t$* check
+
+clean-test%:
+ make -C t$* clean
+
+clean: $(TESTS:%=clean-%)
+ rm -f *\.dsc *\.tar\.gz *\.build *\.changes *\.deb *\.buildinfo
+ @find . -prune -name '*.egg-info' -exec rm -rf '{}' ';' || true
+
+.PHONY: clean
diff --git a/tests/common.mk b/tests/common.mk
new file mode 100644
index 0000000..b4d4f02
--- /dev/null
+++ b/tests/common.mk
@@ -0,0 +1,19 @@
+#!/usr/bin/make -f
+
+export DEBPYTHON3_DEFAULT ?= $(shell python3 ../../dhpython/_defaults.py default cpython3)
+export DEBPYTHON3_SUPPORTED ?= $(shell python3 ../../dhpython/_defaults.py supported cpython3)
+export DEB_HOST_MULTIARCH=my_multiarch-triplet
+export DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+export DH_INTERNAL_OPTIONS=
+
+all: run check
+
+run: clean
+ @echo ============================================================
+ @echo ==== TEST: `basename $$PWD`
+ dpkg-buildpackage -b -us -uc \
+ --no-check-builddeps \
+ --check-command="../test-package-show-info"
+
+clean-common:
+ ./debian/rules clean
diff --git a/tests/common.py b/tests/common.py
new file mode 100644
index 0000000..7e974fc
--- /dev/null
+++ b/tests/common.py
@@ -0,0 +1,18 @@
+class FakeOptions:
+ def __init__(self, **kwargs):
+ opts = {
+ 'depends': (),
+ 'depends_section': (),
+ 'guess_deps': False,
+ 'no_ext_rename': False,
+ 'recommends': (),
+ 'recommends_section': (),
+ 'requires': (),
+ 'suggests': (),
+ 'suggests_section': (),
+ 'vrange': None,
+ 'accept_upstream_versions': False,
+ }
+ opts.update(kwargs)
+ for k, v in opts.items():
+ setattr(self, k, v)
diff --git a/tests/t301/Makefile b/tests/t301/Makefile
new file mode 100644
index 0000000..4be460f
--- /dev/null
+++ b/tests/t301/Makefile
@@ -0,0 +1,15 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ grep -qe "Depends: .*python3\(:any\)\? (<< 3.9)" debian/python3-foo/DEBIAN/control
+ grep -q "Recommends: .*python3-mako" debian/python3-foo/DEBIAN/control
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py
+ test ! -f debian/python3-foo/usr/lib/python3/dist-packages/foo/spam.py
+ grep -q 'py3compile -p python3-foo -V 3\.1-3\.9' debian/python3-foo/DEBIAN/postinst
+ grep -q 'pypy3compile -p python3-foo -V 3\.1-3\.9' debian/python3-foo/DEBIAN/postinst
+ grep -q 'py3clean -p python3-foo\s*$$' debian/python3-foo/DEBIAN/prerm
+
+clean:
+ ./debian/rules clean
+ rm -rf lib/Foo.egg-info
diff --git a/tests/t301/debian/changelog b/tests/t301/debian/changelog
new file mode 100644
index 0000000..0f9a168
--- /dev/null
+++ b/tests/t301/debian/changelog
@@ -0,0 +1,5 @@
+foo (0.1.1) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ożarowski <piotr@debian.org> Sat, 27 Feb 2010 20:42:17 +0100
diff --git a/tests/t301/debian/compat b/tests/t301/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/tests/t301/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/tests/t301/debian/control b/tests/t301/debian/control
new file mode 100644
index 0000000..fc18d76
--- /dev/null
+++ b/tests/t301/debian/control
@@ -0,0 +1,18 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper (>= 7.0.50~), python3-all
+Standards-Version: 3.9.0
+X-Python3-Version: >= 3.1, << 3.9
+
+Architecture: all
+Package: python3-foo
+Depends: ${python3:Depends}, ${misc:Depends}
+Recommends: ${python3:Recommends}
+Suggests: ${python3:Suggests}
+Enhances: ${python3:Enhances}
+Breaks: ${python3:Breaks}
+Provides: ${python3:Provides}
+Description: foo to rule them all
+ example package #1
diff --git a/tests/t301/debian/copyright b/tests/t301/debian/copyright
new file mode 100644
index 0000000..6382944
--- /dev/null
+++ b/tests/t301/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2010, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/t301/debian/py3dist-overrides b/tests/t301/debian/py3dist-overrides
new file mode 100644
index 0000000..ab3ccb8
--- /dev/null
+++ b/tests/t301/debian/py3dist-overrides
@@ -0,0 +1,5 @@
+Mako python3-mako (>= 0.2)
+SQLAlchemy python3-sqlalchemy (>= 0.6)
+Foo python3-foo
+Bar python3-bar
+Baz \ No newline at end of file
diff --git a/tests/t301/debian/python3-foo.pydist b/tests/t301/debian/python3-foo.pydist
new file mode 100644
index 0000000..82849da
--- /dev/null
+++ b/tests/t301/debian/python3-foo.pydist
@@ -0,0 +1 @@
+SQLAlchemy 3.2- python3-sqlalchemy; PEP386 s/^/1:/
diff --git a/tests/t301/debian/rules b/tests/t301/debian/rules
new file mode 100755
index 0000000..9c1bdff
--- /dev/null
+++ b/tests/t301/debian/rules
@@ -0,0 +1,25 @@
+#!/usr/bin/make -f
+%:
+ dh $@ --buildsystem=python_distutils
+
+override_dh_auto_install:
+ python3 setup.py install --root=debian/python3-foo/
+
+override_dh_install:
+ dh_install
+ find debian/ -name jquery.js -exec \
+ ln -fs /usr/share/javascript/jquery/jquery.js '{}' \;
+ DH_VERBOSE=1 ../../dh_python3\
+ --depends 'SQLAlchemy >= 0.6.1'\
+ --recommends Mako\
+ --suggests 'Foo >= 0.1'\
+ --suggests 'bar >= 1.0'
+
+clean:
+ rm -rf build
+ dh clean
+
+override_dh_auto_build:
+
+override_dh_auto_clean:
+ #python3 setup.py clean
diff --git a/tests/t301/debian/source/format b/tests/t301/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t301/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t301/lib/foo/__init__.py b/tests/t301/lib/foo/__init__.py
new file mode 100644
index 0000000..9df03f8
--- /dev/null
+++ b/tests/t301/lib/foo/__init__.py
@@ -0,0 +1 @@
+print("you just imported foo from %s" % __file__)
diff --git a/tests/t301/lib/foo/bar/__init__.py b/tests/t301/lib/foo/bar/__init__.py
new file mode 100644
index 0000000..669df66
--- /dev/null
+++ b/tests/t301/lib/foo/bar/__init__.py
@@ -0,0 +1 @@
+print("you just imported foo.bar from %s" % __file__)
diff --git a/tests/t301/lib/foo/baz.py b/tests/t301/lib/foo/baz.py
new file mode 100644
index 0000000..934dcfe
--- /dev/null
+++ b/tests/t301/lib/foo/baz.py
@@ -0,0 +1 @@
+print("you just imported foo.baz from %s" % __file__)
diff --git a/tests/t301/lib/foo/jquery.js b/tests/t301/lib/foo/jquery.js
new file mode 120000
index 0000000..b77fd86
--- /dev/null
+++ b/tests/t301/lib/foo/jquery.js
@@ -0,0 +1 @@
+/usr/share/javascript/jquery/jquery.js \ No newline at end of file
diff --git a/tests/t301/setup.py b/tests/t301/setup.py
new file mode 100644
index 0000000..bb7f37d
--- /dev/null
+++ b/tests/t301/setup.py
@@ -0,0 +1,17 @@
+#! /usr/bin/python3
+from distutils.core import setup
+
+setup(name='Foo',
+ version='0.2',
+ description="package with public modules only",
+ long_description="TODO",
+ keywords='foo bar baz',
+ author='Piotr Ożarowski',
+ author_email='piotr@debian.org',
+ url='http://www.debian.org/',
+ license='MIT',
+ packages=['foo'],
+ package_dir={'foo': 'lib/foo'},
+ package_data={'foo': ['jquery.js']},
+ zip_safe=False,
+)
diff --git a/tests/t302/Makefile b/tests/t302/Makefile
new file mode 100644
index 0000000..2fc6b11
--- /dev/null
+++ b/tests/t302/Makefile
@@ -0,0 +1,18 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ grep -q "py3compile -p python3-foo:$(DEB_HOST_ARCH) /usr/lib/python3-foo"\
+ debian/python3-foo/DEBIAN/postinst
+ grep -q "pypy3compile -p python3-foo:$(DEB_HOST_ARCH) /usr/lib/python3-foo"\
+ debian/python3-foo/DEBIAN/postinst
+ grep -q "py3clean -p python3-foo:$(DEB_HOST_ARCH)" debian/python3-foo/DEBIAN/prerm
+ [ "`find debian/python3-foo/usr/lib/python3/dist-packages/foo -name 'bar.cpython-*.so'`" != "" ]
+ test -e debian/python3-foo/usr/lib/python3-foo/empty-private-dir
+ test ! -e debian/python3-foo/usr/lib/python3/dist-packages/empty-public-dir
+ # test if moved from include/python3.X/ to include/python3.Xm/ (for Python << 3.8)
+ #test -f debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)m/foo.h
+
+clean:
+ ./debian/rules clean
+ rm -rf lib/Foo.egg-info build
diff --git a/tests/t302/debian/changelog b/tests/t302/debian/changelog
new file mode 100644
index 0000000..d91e7a7
--- /dev/null
+++ b/tests/t302/debian/changelog
@@ -0,0 +1,5 @@
+foo (0.1.1) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ożarowski <piotr@debian.org> Sun, 19 Dec 2010 19:40:33 +0100
diff --git a/tests/t302/debian/compat b/tests/t302/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/tests/t302/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/tests/t302/debian/control b/tests/t302/debian/control
new file mode 100644
index 0000000..01a7656
--- /dev/null
+++ b/tests/t302/debian/control
@@ -0,0 +1,18 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper (>= 7.0.50~), python3-all-dev
+Standards-Version: 3.9.1
+X-Python3-Version: >= 3.2
+
+Package: python3-foo
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Recommends: ${python3:Recommends}
+Suggests: ${python3:Suggests}
+Enhances: ${python3:Enhances}
+Breaks: ${python3:Breaks}
+Provides: ${python3:Provides}
+Description: package with public and private Python 3 extension
+ example package #3 - Python extensions
diff --git a/tests/t302/debian/copyright b/tests/t302/debian/copyright
new file mode 100644
index 0000000..6382944
--- /dev/null
+++ b/tests/t302/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2010, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/t302/debian/install b/tests/t302/debian/install
new file mode 100644
index 0000000..61f42c3
--- /dev/null
+++ b/tests/t302/debian/install
@@ -0,0 +1,2 @@
+# private module in architecture dependent dir
+lib/foo.py /usr/lib/python3-foo/
diff --git a/tests/t302/debian/rules b/tests/t302/debian/rules
new file mode 100755
index 0000000..a85d729
--- /dev/null
+++ b/tests/t302/debian/rules
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@ --buildsystem=python_distutils
+
+override_dh_install:
+ dh_install
+ # install also as private extension
+ dh_install debian/python3-foo/usr/local/lib/python3*/dist-packages/foo/bar*.so \
+ /usr/lib/python3-foo/
+ mkdir -p debian/python3-foo/usr/lib/python3/dist-packages/empty-public-dir
+ mkdir -p debian/python3-foo/usr/lib/python3-foo/empty-private-dir
+ DH_VERBOSE=1 ../../dh_python3
+
+comma:=,
+empty:=
+space:= $(empty) $(empty)
+PYTHONS=$(subst $(comma),$(space),$(DEBPYTHON3_SUPPORTED))
+override_dh_auto_build:
+ for ver in $(PYTHONS); do\
+ python$$ver setup.py build; done
+
+override_dh_auto_install:
+ for ver in $(PYTHONS); do\
+ python$$ver setup.py install --root=debian/python3-foo;\
+ done
+ mkdir -p debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)/
+ touch debian/python3-foo/usr/include/python$(DEBPYTHON3_DEFAULT)/foo.h
+
+override_dh_auto_clean:
diff --git a/tests/t302/debian/source/format b/tests/t302/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t302/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t302/lib/__init__.py b/tests/t302/lib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/t302/lib/__init__.py
diff --git a/tests/t302/lib/bar.c b/tests/t302/lib/bar.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/t302/lib/bar.c
diff --git a/tests/t302/lib/foo.py b/tests/t302/lib/foo.py
new file mode 100644
index 0000000..9dd52e6
--- /dev/null
+++ b/tests/t302/lib/foo.py
@@ -0,0 +1,6 @@
+import foo.bar
+
+
+class Foo(object):
+ def __init__(self):
+ foo.bar
diff --git a/tests/t302/setup.py b/tests/t302/setup.py
new file mode 100755
index 0000000..1208046
--- /dev/null
+++ b/tests/t302/setup.py
@@ -0,0 +1,13 @@
+#! /usr/bin/python3
+from distutils.core import setup, Extension
+
+setup(name='Foo',
+ version='0.1',
+ description="package with Python extension",
+ author='Piotr Ożarowski',
+ author_email='piotr@debian.org',
+ url='http://www.debian.org/',
+ ext_modules=[Extension('foo/bar', ['lib/bar.c'])],
+ #py_modules=['package'],
+ packages=['foo'],
+ package_dir={'foo': 'lib'})
diff --git a/tests/t303/Makefile b/tests/t303/Makefile
new file mode 100644
index 0000000..9f2c71b
--- /dev/null
+++ b/tests/t303/Makefile
@@ -0,0 +1,12 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py
+ test ! -d debian/python3-foo/usr/lib/python3.*/site-packages
+ grep -q 'py3compile -p python3-foo\s*$$' debian/python3-foo/DEBIAN/postinst
+ grep -q 'pypy3compile -p python3-foo\s*||\s*true$$' debian/python3-foo/DEBIAN/postinst
+ grep -q 'py3clean -p python3-foo\s*$$' debian/python3-foo/DEBIAN/prerm
+
+clean:
+ ./debian/rules clean
diff --git a/tests/t303/debian/changelog b/tests/t303/debian/changelog
new file mode 100644
index 0000000..1a796a1
--- /dev/null
+++ b/tests/t303/debian/changelog
@@ -0,0 +1,5 @@
+foo (0.1.1) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ożarowski <piotr@debian.org> Thu, 06 Jan 2011 17:23:23 +0100
diff --git a/tests/t303/debian/compat b/tests/t303/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/tests/t303/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/tests/t303/debian/control b/tests/t303/debian/control
new file mode 100644
index 0000000..beb1372
--- /dev/null
+++ b/tests/t303/debian/control
@@ -0,0 +1,12 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper (>= 7.0.50~), python3-all-dev
+Standards-Version: 3.9.1
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public Python 3 modules
+ example package #4 - fix_locations test
diff --git a/tests/t303/debian/copyright b/tests/t303/debian/copyright
new file mode 100644
index 0000000..69cea75
--- /dev/null
+++ b/tests/t303/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2011, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/t303/debian/rules b/tests/t303/debian/rules
new file mode 100755
index 0000000..8f0c8be
--- /dev/null
+++ b/tests/t303/debian/rules
@@ -0,0 +1,23 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@
+
+override_dh_install:
+ dh_install
+ DH_VERBOSE=1 ../../dh_python3
+
+override_dh_auto_build:
+override_dh_auto_test:
+
+comma:=,
+empty:=
+space:= $(empty) $(empty)
+PYTHONS=$(subst $(comma),$(space),$(DEBPYTHON3_SUPPORTED))
+override_dh_auto_install:
+ set -e; for ver in $(PYTHONS); do\
+ mkdir -p debian/python3-foo/usr/lib/python$$ver/site-packages/;\
+ echo "print('foo')" > debian/python3-foo/usr/lib/python$$ver/site-packages/foo.py;\
+ done
+
+override_dh_auto_clean:
diff --git a/tests/t303/debian/source/format b/tests/t303/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t303/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t304/Makefile b/tests/t304/Makefile
new file mode 100644
index 0000000..d69cdc9
--- /dev/null
+++ b/tests/t304/Makefile
@@ -0,0 +1,23 @@
+#!/usr/bin/make -f
+
+include ../common.mk
+clean: clean-common
+
+check:
+ # python3.2 hardcoded via `dh_python3 --shebang ...python3.2`
+ grep -q '#! /usr/bin/python3.2 -OO' debian/foo/usr/share/baz32/baz.py
+ # python3.4 hardcoded via shebang
+ grep -q '/usr/share/foo \-V 3.4' debian/foo/DEBIAN/postinst
+ # /env removed from shebang
+ grep -q '#! /usr/bin/python3' debian/foo/usr/share/bar/bar.py
+ # /local removed from shebang
+ grep -q '#! /usr/bin/python3' debian/foo/usr/share/foo/baz.py
+ grep -q '#! /usr/bin/python3.4' debian/foo/usr/share/foo/foo.py
+ # make sure /usr/share/doc/ is ignored
+ grep -q -v "py3compile -p foo /usr/share/doc"\
+ debian/foo/DEBIAN/postinst
+ # -X made it into the postinst
+ grep -qF "/usr/share/bar -X 'spam.py'" debian/foo/DEBIAN/postinst
+ # Check argument parsing order
+ grep -q '#! /usr/bin/python3-dbg' debian/overrides/usr/share/overrides1/foo.py
+ grep -q '#! /usr/bin/python3-dbg' debian/overrides/usr/share/overrides2/foo.py
diff --git a/tests/t304/bar.py b/tests/t304/bar.py
new file mode 100755
index 0000000..edecee7
--- /dev/null
+++ b/tests/t304/bar.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python3
+"env in shebang"
diff --git a/tests/t304/baz.py b/tests/t304/baz.py
new file mode 100755
index 0000000..eff389f
--- /dev/null
+++ b/tests/t304/baz.py
@@ -0,0 +1,2 @@
+#!/usr/local/bin/python3
+"/usr/local in shebang"
diff --git a/tests/t304/debian/changelog b/tests/t304/debian/changelog
new file mode 100644
index 0000000..c1ed13c
--- /dev/null
+++ b/tests/t304/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.0) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ożarowski <piotr@debian.org> Sun, 10 Jun 2012 14:09:45 +0200
diff --git a/tests/t304/debian/compat b/tests/t304/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/tests/t304/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/tests/t304/debian/control b/tests/t304/debian/control
new file mode 100644
index 0000000..4dd38b0
--- /dev/null
+++ b/tests/t304/debian/control
@@ -0,0 +1,19 @@
+Source: foo
+Section: misc
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper (>= 7.0.50~)
+Build-Depends-Indep: python3
+Standards-Version: 3.9.3
+
+Package: foo
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 4 - shebangs
+ example package #4 - shebang related tests
+
+Package: overrides
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 4 - command line parsing
+ example package #4 - command line argument parsing
diff --git a/tests/t304/debian/copyright b/tests/t304/debian/copyright
new file mode 100644
index 0000000..bf78fd0
--- /dev/null
+++ b/tests/t304/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2012, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/t304/debian/examples b/tests/t304/debian/examples
new file mode 100644
index 0000000..fe8826b
--- /dev/null
+++ b/tests/t304/debian/examples
@@ -0,0 +1 @@
+foo.py
diff --git a/tests/t304/debian/install b/tests/t304/debian/install
new file mode 100644
index 0000000..a106b6e
--- /dev/null
+++ b/tests/t304/debian/install
@@ -0,0 +1,7 @@
+foo.py /usr/share/foo/
+baz.py /usr/share/foo/
+spam.py /usr/share/foo/
+bar.py /usr/share/bar/
+spam.py /usr/share/bar/
+baz.py /usr/share/baz32/
+spam.py /usr/share/baz32/
diff --git a/tests/t304/debian/overrides.install b/tests/t304/debian/overrides.install
new file mode 100644
index 0000000..23e1322
--- /dev/null
+++ b/tests/t304/debian/overrides.install
@@ -0,0 +1,2 @@
+foo.py /usr/share/overrides1/
+foo.py /usr/share/overrides2/
diff --git a/tests/t304/debian/rules b/tests/t304/debian/rules
new file mode 100755
index 0000000..5de6e3d
--- /dev/null
+++ b/tests/t304/debian/rules
@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+%:
+ dh $@ --buildsystem=python_distutils
+
+override_dh_auto_build:
+override_dh_auto_install:
+
+override_dh_install:
+ dh_install
+ DH_VERBOSE=1 ../../dh_python3 -p foo
+ DH_VERBOSE=1 ../../dh_python3 -p foo /usr/share/bar -X spam.py
+ DH_VERBOSE=1 ../../dh_python3 -p foo /usr/share/baz32 --shebang '/usr/bin/python3.2 -OO'
+
+ # Argument priority: -O > regular args > DH_OPTIONS
+ DH_VERBOSE=1 DH_OPTIONS=--shebang=/usr/bin/python3.0 \
+ ../../dh_python3 -p overrides \
+ --shebang=/usr/bin/python3-dbg \
+ /usr/share/overrides1
+ DH_VERBOSE=1 ../../dh_python3 -p overrides \
+ --shebang=/usr/bin/python3.0 \
+ -O=--shebang=/usr/bin/python3-dbg \
+ -O=--foo=bar \
+ /usr/share/overrides2
+
+clean:
+ dh_clean
diff --git a/tests/t304/debian/source/format b/tests/t304/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t304/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t304/foo.py b/tests/t304/foo.py
new file mode 100755
index 0000000..fef29a7
--- /dev/null
+++ b/tests/t304/foo.py
@@ -0,0 +1,2 @@
+#!/usr/local/bin/python3.4
+"/usr/local/bin/python3.4 hardcoded in shebang"
diff --git a/tests/t304/setup.py b/tests/t304/setup.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/t304/setup.py
diff --git a/tests/t304/spam.py b/tests/t304/spam.py
new file mode 100644
index 0000000..c8b0fd9
--- /dev/null
+++ b/tests/t304/spam.py
@@ -0,0 +1 @@
+print('spam')
diff --git a/tests/t305/Makefile b/tests/t305/Makefile
new file mode 100644
index 0000000..1ee30fc
--- /dev/null
+++ b/tests/t305/Makefile
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+
+include ../common.mk
+clean: clean-common
+
+check:
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5a/DEBIAN/control
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5b/DEBIAN/control
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5c/DEBIAN/control
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5d/DEBIAN/control
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5e/DEBIAN/control
+ grep -qe "Depends: .*python3\(:any\)\?" debian/foo5f/DEBIAN/control
+ grep -Fxq dh_python3 debian/foo5a.debhelper.log.end_dh_install
+ grep -Fxc dh_python3 debian/foo5a.debhelper.log.end_dh_install | grep -Fxq 1
diff --git a/tests/t305/debian/changelog b/tests/t305/debian/changelog
new file mode 100644
index 0000000..d30d06c
--- /dev/null
+++ b/tests/t305/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.0) unstable; urgency=low
+
+ * Initial release
+
+ -- Maximilian Engelhardt <maxi@daemonizer.de> Fri, 02 Apr 2021 14:30:25 +0200
diff --git a/tests/t305/debian/compat b/tests/t305/debian/compat
new file mode 100644
index 0000000..48082f7
--- /dev/null
+++ b/tests/t305/debian/compat
@@ -0,0 +1 @@
+12
diff --git a/tests/t305/debian/control b/tests/t305/debian/control
new file mode 100644
index 0000000..8eafc3e
--- /dev/null
+++ b/tests/t305/debian/control
@@ -0,0 +1,43 @@
+Source: foo
+Section: misc
+Priority: optional
+Maintainer: Maximilian Engelhardt <maxi@daemonizer.de>
+Build-Depends: debhelper (>= 12.9)
+Build-Depends-Indep: python3
+Standards-Version: 4.5.1
+
+Package: foo5a
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5a - private shebangs
+ example package #5 - shebang related tests in private dirs
+
+Package: foo5b
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5b - private shebangs
+ example package #5 - shebang related tests in private dirs
+
+Package: foo5c
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5c - private shebangs
+ example package #5 - shebang related tests in private dirs
+
+Package: foo5d
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5d - private shebangs
+ example package #5 - shebang related tests in private dirs
+
+Package: foo5e
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5e - private shebangs
+ example package #5 - shebang related tests in private dirs
+
+Package: foo5f
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: example 5f - private shebangs
+ example package #5 - shebang related tests in private dirs
diff --git a/tests/t305/debian/copyright b/tests/t305/debian/copyright
new file mode 100644
index 0000000..32bbc0d
--- /dev/null
+++ b/tests/t305/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2021, Maximilian Engelhardt <maxi@daemonizer.de> and
+is licensed under the MIT License.
diff --git a/tests/t305/debian/foo5a.install b/tests/t305/debian/foo5a.install
new file mode 100644
index 0000000..38009bc
--- /dev/null
+++ b/tests/t305/debian/foo5a.install
@@ -0,0 +1 @@
+foo5a /usr/share/foo/
diff --git a/tests/t305/debian/foo5b.install b/tests/t305/debian/foo5b.install
new file mode 100644
index 0000000..0fd0869
--- /dev/null
+++ b/tests/t305/debian/foo5b.install
@@ -0,0 +1 @@
+foo5b /usr/share/foo/
diff --git a/tests/t305/debian/foo5c.install b/tests/t305/debian/foo5c.install
new file mode 100644
index 0000000..a40b010
--- /dev/null
+++ b/tests/t305/debian/foo5c.install
@@ -0,0 +1 @@
+foo5c /usr/share/foo/
diff --git a/tests/t305/debian/foo5d.install b/tests/t305/debian/foo5d.install
new file mode 100644
index 0000000..e6e2aea
--- /dev/null
+++ b/tests/t305/debian/foo5d.install
@@ -0,0 +1 @@
+foo5d /usr/share/foo/
diff --git a/tests/t305/debian/rules b/tests/t305/debian/rules
new file mode 100755
index 0000000..c43eaae
--- /dev/null
+++ b/tests/t305/debian/rules
@@ -0,0 +1,22 @@
+#!/usr/bin/make -f
+%:
+ dh $@ --buildsystem=none
+
+override_dh_auto_install:
+ dh_auto_install
+ mkdir -p debian/foo5e/usr/share/foo/
+ echo "#! /usr/bin/env $(shell py3versions -d)\n\"/usr/bin/env DEFAULT_PYTHON shebang\"" > debian/foo5e/usr/share/foo/foo5e
+ chmod +x debian/foo5e/usr/share/foo/foo5e
+ mkdir -p debian/foo5f/usr/share/foo/
+ echo "#! /usr/bin/$(shell py3versions -d)\n\"/usr/bin/DEFAULT_PYTHON shebang\"" > debian/foo5f/usr/share/foo/foo5f
+ chmod +x debian/foo5f/usr/share/foo/foo5f
+
+override_dh_install:
+ dh_install
+ DH_VERBOSE=1 ../../dh_python3 -p foo5a /usr/share/foo
+ DH_VERBOSE=1 ../../dh_python3 --remaining-packages /usr/share/foo
+ cp debian/foo5a.debhelper.log debian/foo5a.debhelper.log.end_dh_install
+
+clean:
+ rm -f debian/foo5a.debhelper.log.end_dh_install
+ dh_clean
diff --git a/tests/t305/debian/source/format b/tests/t305/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t305/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t305/foo5a b/tests/t305/foo5a
new file mode 100755
index 0000000..3045ad0
--- /dev/null
+++ b/tests/t305/foo5a
@@ -0,0 +1,2 @@
+#! /usr/bin/python3
+"/usr/bin/python3 shebang"
diff --git a/tests/t305/foo5b b/tests/t305/foo5b
new file mode 100755
index 0000000..49352f5
--- /dev/null
+++ b/tests/t305/foo5b
@@ -0,0 +1,2 @@
+#! /usr/bin/python
+"/usr/bin/python shebang"
diff --git a/tests/t305/foo5c b/tests/t305/foo5c
new file mode 100755
index 0000000..2ee0891
--- /dev/null
+++ b/tests/t305/foo5c
@@ -0,0 +1,2 @@
+#! /usr/bin/env python3
+"/usr/bin/env python3 shebang"
diff --git a/tests/t305/foo5d b/tests/t305/foo5d
new file mode 100755
index 0000000..b698372
--- /dev/null
+++ b/tests/t305/foo5d
@@ -0,0 +1,2 @@
+#! /usr/bin/env python
+"/usr/bin/env python shebang"
diff --git a/tests/t306/Makefile b/tests/t306/Makefile
new file mode 100644
index 0000000..9dbf8c4
--- /dev/null
+++ b/tests/t306/Makefile
@@ -0,0 +1,17 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+all: run check
+
+run: clean
+ dpkg-buildpackage -b -us -uc
+
+check:
+ grep -qe "^Depends: .*python3\(:any\)\? (<< 3\.[0-9]\+)" \
+ debian/foo/DEBIAN/control
+ grep -qe "^Depends: .*python3\(:any\)\? (>= 3\.[0-9]\+~)" \
+ debian/foo/DEBIAN/control
+
+clean:
+ ./debian/rules clean
+ rm -rf lib/Foo.egg-info build
diff --git a/tests/t306/debian/changelog b/tests/t306/debian/changelog
new file mode 100644
index 0000000..874dc1d
--- /dev/null
+++ b/tests/t306/debian/changelog
@@ -0,0 +1,5 @@
+foo (0.1) unstable; urgency=low
+
+ * Initial release
+
+ -- Maximilian Engelhardt <maxi@daemonizer.de> Sun, 04 Apr 2021 13:09:48 +0200
diff --git a/tests/t306/debian/compat b/tests/t306/debian/compat
new file mode 100644
index 0000000..48082f7
--- /dev/null
+++ b/tests/t306/debian/compat
@@ -0,0 +1 @@
+12
diff --git a/tests/t306/debian/control b/tests/t306/debian/control
new file mode 100644
index 0000000..79446f3
--- /dev/null
+++ b/tests/t306/debian/control
@@ -0,0 +1,13 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Maximilian Engelhardt <maxi@daemonizer.de>
+Build-Depends: debhelper (>= 12.9), python3-all-dev:any
+Standards-Version: 4.5.1
+
+Package: foo
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with python3-all-dev dependency using :any
+ example package #6 - private Python extensions and python3-all-dev:any
+ dependency
diff --git a/tests/t306/debian/copyright b/tests/t306/debian/copyright
new file mode 100644
index 0000000..32bbc0d
--- /dev/null
+++ b/tests/t306/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2021, Maximilian Engelhardt <maxi@daemonizer.de> and
+is licensed under the MIT License.
diff --git a/tests/t306/debian/rules b/tests/t306/debian/rules
new file mode 100755
index 0000000..d1ffc6a
--- /dev/null
+++ b/tests/t306/debian/rules
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+
+%:
+ dh $@ --buildsystem=none
+
+override_dh_install:
+ dh_install
+ DH_VERBOSE=1 ../../dh_python3
+
+override_dh_auto_build:
+ python3 setup.py build
+
+override_dh_auto_install:
+ python3 setup.py install --root=debian/foo/ --install-lib=/usr/share/foo/python
diff --git a/tests/t306/debian/source/format b/tests/t306/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/t306/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/t306/lib/__init__.py b/tests/t306/lib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/t306/lib/__init__.py
diff --git a/tests/t306/lib/bar.c b/tests/t306/lib/bar.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/t306/lib/bar.c
diff --git a/tests/t306/lib/foo.py b/tests/t306/lib/foo.py
new file mode 100644
index 0000000..9dd52e6
--- /dev/null
+++ b/tests/t306/lib/foo.py
@@ -0,0 +1,6 @@
+import foo.bar
+
+
+class Foo(object):
+ def __init__(self):
+ foo.bar
diff --git a/tests/t306/setup.py b/tests/t306/setup.py
new file mode 100755
index 0000000..25727f2
--- /dev/null
+++ b/tests/t306/setup.py
@@ -0,0 +1,12 @@
+#! /usr/bin/python3
+from distutils.core import setup, Extension
+
+setup(name='Foo',
+ version='0.1',
+ description="package with private Python extension",
+ author='Maximilian Engelhardt',
+ author_email='maxi@daemonizer.de',
+ url='http://www.debian.org/',
+ ext_modules=[Extension('foo/bar', ['lib/bar.c'])],
+ packages=['foo'],
+ package_dir={'foo': 'lib'})
diff --git a/tests/ta01/Makefile b/tests/ta01/Makefile
new file mode 100644
index 0000000..65c9796
--- /dev/null
+++ b/tests/ta01/Makefile
@@ -0,0 +1,39 @@
+all: run check
+
+run:
+ @echo No build needed
+ifeq ($(AUTOPKGTEST_TMP),)
+ @echo NOTE this test uses the system pybuild-autopkgtest, not the working directory
+endif
+
+check: pass fail
+
+pass:
+ @echo "=============================================================="
+ @echo "= pybuild-autopkgtest passes when tests pass ="
+ @echo "=============================================================="
+ @echo
+ pybuild-autopkgtest
+ test -f marker-before-pybuild-autopkgtest
+ test -f marker-after-pybuild-autopkgtest
+ grep '^1$$' marker-PYBUILD_AUTOPKGTEST
+ @echo '------------------------------'
+ @echo "OK: pybuild-autopkgtest passed"
+ @echo '------------------------------'
+ @echo
+
+fail:
+ @echo "=============================================================="
+ @echo "= pybuild-autopkgtest fails when tests fail ="
+ @echo "=============================================================="
+ @echo
+ ! FAILS=1 pybuild-autopkgtest
+ @echo '------------------------------'
+ @echo "OK: pybuild-autopkgtest failed"
+ @echo '------------------------------'
+ @echo
+
+clean:
+ifneq ($(AUTOPKGTEST_TMP),)
+ rm -r $(AUTOPKGTEST_TMP)/*
+endif
diff --git a/tests/ta01/debian/changelog b/tests/ta01/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/ta01/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/ta01/debian/control b/tests/ta01/debian/control
new file mode 100644
index 0000000..f8922fc
--- /dev/null
+++ b/tests/ta01/debian/control
@@ -0,0 +1,15 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , pybuild-plugin-pyproject
+ , python3-all
+ , python3-setuptools
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #8
diff --git a/tests/ta01/debian/rules b/tests/ta01/debian/rules
new file mode 100755
index 0000000..e53f0aa
--- /dev/null
+++ b/tests/ta01/debian/rules
@@ -0,0 +1,33 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build --verbose
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean --verbose
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
+
+before-pybuild-autopkgtest:
+ echo $(PYBUILD_AUTOPKGTEST) > marker-PYBUILD_AUTOPKGTEST
+ touch marker-before-pybuild-autopkgtest
+
+after-pybuild-autopkgtest:
+ touch marker-after-pybuild-autopkgtest
diff --git a/tests/ta01/foo/__init__.py b/tests/ta01/foo/__init__.py
new file mode 100644
index 0000000..92d9a9a
--- /dev/null
+++ b/tests/ta01/foo/__init__.py
@@ -0,0 +1 @@
+"Nothing here"
diff --git a/tests/ta01/pyproject.toml b/tests/ta01/pyproject.toml
new file mode 100644
index 0000000..9787c3b
--- /dev/null
+++ b/tests/ta01/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/tests/ta01/setup.cfg b/tests/ta01/setup.cfg
new file mode 100644
index 0000000..877dcf7
--- /dev/null
+++ b/tests/ta01/setup.cfg
@@ -0,0 +1,10 @@
+[metadata]
+name = foo
+version = 0.1
+description = My package description
+long_description = My long description
+license = Expat
+
+[options]
+zip_safe = False
+packages = find:
diff --git a/tests/ta01/tests/__init__.py b/tests/ta01/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/ta01/tests/__init__.py
diff --git a/tests/ta01/tests/test_foo.py b/tests/ta01/tests/test_foo.py
new file mode 100644
index 0000000..263a9fb
--- /dev/null
+++ b/tests/ta01/tests/test_foo.py
@@ -0,0 +1,7 @@
+import os
+import unittest
+
+class TestPybuildAutopkgtest(unittest.TestCase):
+
+ def test_pass_or_fails(self):
+ self.assertIsNone(os.environ.get("FAILS"))
diff --git a/tests/ta02/Makefile b/tests/ta02/Makefile
new file mode 100644
index 0000000..f6c26ed
--- /dev/null
+++ b/tests/ta02/Makefile
@@ -0,0 +1,17 @@
+all: run check
+
+run:
+ @echo No build needed
+ifeq ($(AUTOPKGTEST_TMP),)
+ @echo NOTE this test uses the system pybuild-autopkgtest, not the working directory
+endif
+
+check:
+ DH_VERBOSE=1 pybuild-autopkgtest
+ test -e custom-test-executed
+
+clean:
+ ./debian/rules clean
+ifneq ($(AUTOPKGTEST_TMP),)
+ rm -r $(AUTOPKGTEST_TMP)/*
+endif
diff --git a/tests/ta02/debian/changelog b/tests/ta02/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/ta02/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/ta02/debian/control b/tests/ta02/debian/control
new file mode 100644
index 0000000..648c259
--- /dev/null
+++ b/tests/ta02/debian/control
@@ -0,0 +1,16 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , pybuild-plugin-pyproject
+ , python3-all
+ , python3-pytest
+ , python3-setuptools
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #8
diff --git a/tests/ta02/debian/rules b/tests/ta02/debian/rules
new file mode 100755
index 0000000..b612080
--- /dev/null
+++ b/tests/ta02/debian/rules
@@ -0,0 +1,28 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+export PYBUILD_TEST_CUSTOM=1
+export PYBUILD_TEST_ARGS=touch {dir}/custom-test-executed
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build --verbose
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean --verbose
+ rm -rf custom-test-executed foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/ta02/foo/__init__.py b/tests/ta02/foo/__init__.py
new file mode 100644
index 0000000..92d9a9a
--- /dev/null
+++ b/tests/ta02/foo/__init__.py
@@ -0,0 +1 @@
+"Nothing here"
diff --git a/tests/ta02/pyproject.toml b/tests/ta02/pyproject.toml
new file mode 100644
index 0000000..9787c3b
--- /dev/null
+++ b/tests/ta02/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/tests/ta02/setup.cfg b/tests/ta02/setup.cfg
new file mode 100644
index 0000000..877dcf7
--- /dev/null
+++ b/tests/ta02/setup.cfg
@@ -0,0 +1,10 @@
+[metadata]
+name = foo
+version = 0.1
+description = My package description
+long_description = My long description
+license = Expat
+
+[options]
+zip_safe = False
+packages = find:
diff --git a/tests/ta02/tests/__init__.py b/tests/ta02/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/ta02/tests/__init__.py
diff --git a/tests/ta02/tests/test_foo.py b/tests/ta02/tests/test_foo.py
new file mode 100644
index 0000000..2cac2b2
--- /dev/null
+++ b/tests/ta02/tests/test_foo.py
@@ -0,0 +1,7 @@
+import unittest
+
+class TestThatWeDontRunTheseTests(unittest.TestCase):
+
+ def test_fail(self):
+ # We want the custom test runner to run, not this test suite
+ self.assertTrue(False)
diff --git a/tests/test-package-show-info b/tests/test-package-show-info
new file mode 100755
index 0000000..bdea2b4
--- /dev/null
+++ b/tests/test-package-show-info
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -ue
+
+changes=$1
+testname=$(basename $PWD)
+basedir=$(dirname $changes)
+
+echo "--------------------------------------------------"
+echo "Test $testname has created the following packages:"
+for deb in $(sed -nr 's/.* ([^ ]*\.deb)$/\1/p' $changes | sort -u); do
+ echo "--------------------------------------------------"
+ echo "PACKAGE $deb:"
+ dpkg-deb --info "$basedir/$deb"
+done
+echo "--------------------------------------------------"
diff --git a/tests/test_debhelper.py b/tests/test_debhelper.py
new file mode 100644
index 0000000..285440c
--- /dev/null
+++ b/tests/test_debhelper.py
@@ -0,0 +1,192 @@
+from tempfile import TemporaryDirectory
+import unittest
+import os
+
+from dhpython.debhelper import DebHelper, build_options
+
+
+class DebHelperTestCase(unittest.TestCase):
+ impl = 'cpython3'
+ control = []
+ options = {}
+ parse_control = True
+
+ def build_options(self):
+ return build_options(**self.options)
+
+ def setUp(self):
+ self.tempdir = TemporaryDirectory()
+ self.addCleanup(self.tempdir.cleanup)
+
+ old_wd = os.getcwd()
+ os.chdir(self.tempdir.name)
+ self.addCleanup(os.chdir, old_wd)
+
+ os.mkdir('debian')
+ with open('debian/control', 'w') as f:
+ f.write('\n'.join(self.control))
+ if self.parse_control:
+ self.dh = DebHelper(self.build_options(), impl=self.impl)
+
+
+CONTROL = [
+ 'Source: foo-src',
+ 'Build-Depends: python3-all,',
+ ' python-all,',
+ ' bar (<< 2) [amd64],',
+ ' baz (>= 1.0)',
+ 'X-Python3-Version: >= 3.1, << 3.10',
+ '',
+ 'Architecture: all',
+ 'Package: python3-foo',
+ 'Depends: ${python3:Depends}',
+ '',
+ 'Package: python3-foo-ext',
+ 'Architecture: any',
+ 'Depends: ${python3:Depends}, '
+ '# COMMENT',
+ ' ${shlibs:Depends},',
+ '',
+ 'Package: python-foo',
+ 'Architecture: all',
+ 'Depends: ${python:Depends}',
+ '',
+ '',
+ 'Package: foo',
+ 'Architecture: all',
+ 'Depends: ${python3:Depends}',
+ '',
+ '',
+ 'Package: recfoo',
+ 'Architecture: all',
+ 'Recommends: ${python3:Depends}',
+ '',
+ '',
+]
+
+class TestControlBlockParsing(DebHelperTestCase):
+ control = CONTROL
+
+ def test_parses_source(self):
+ self.assertEqual(self.dh.source_name, 'foo-src')
+
+ def test_parses_build_depends(self):
+ self.assertEqual(self.dh.build_depends, {
+ 'python3-all': {None: None},
+ 'python-all': {None: None},
+ 'bar': {'amd64': '<< 2'},
+ 'baz': {None: '>= 1.0'},
+ })
+
+ def test_parses_XPV(self):
+ self.assertEqual(self.dh.python_version, '>= 3.1, << 3.10')
+
+ def test_parses_packages(self):
+ self.assertEqual(list(self.dh.packages.keys()),
+ ['python3-foo', 'python3-foo-ext', 'foo', 'recfoo'])
+
+ def test_parses_arch(self):
+ self.assertEqual(self.dh.packages['python3-foo-ext']['arch'], 'any')
+
+ def test_parses_arch_all(self):
+ self.assertEqual(self.dh.packages['python3-foo']['arch'], 'all')
+
+
+class TestControlSkipIndep(DebHelperTestCase):
+ control = CONTROL
+ options = {
+ 'arch': True,
+ }
+
+ def test_skip_indep(self):
+ self.assertEqual(list(self.dh.packages.keys()), ['python3-foo-ext'])
+
+
+class TestControlSkipArch(DebHelperTestCase):
+ control = CONTROL
+ options = {
+ 'arch': False,
+ }
+
+ def test_skip_arch(self):
+ self.assertEqual(list(self.dh.packages.keys()),
+ ['python3-foo', 'foo', 'recfoo'])
+
+
+class TestControlSinglePkg(DebHelperTestCase):
+ control = CONTROL
+ options = {
+ 'package': ['python3-foo'],
+ }
+
+ def test_parses_packages(self):
+ self.assertEqual(list(self.dh.packages.keys()), ['python3-foo'])
+
+
+class TestControlSkipSinglePkg(DebHelperTestCase):
+ control = CONTROL
+ options = {
+ 'no_package': ['python3-foo'],
+ }
+
+ def test_parses_packages(self):
+ self.assertEqual(list(self.dh.packages.keys()),
+ ['python3-foo-ext', 'foo', 'recfoo'])
+
+
+class TestControlBlockParsingPy2(DebHelperTestCase):
+ control = CONTROL
+ impl = 'cpython2'
+
+ def test_parses_packages(self):
+ self.assertEqual(list(self.dh.packages.keys()), ['python-foo'])
+
+
+class TestControlNoBinaryPackages(DebHelperTestCase):
+ control = [
+ 'Source: foo-src',
+ 'Build-Depends: python3-all',
+ '',
+ ]
+ parse_control = False
+
+ def test_throws_error(self):
+ msg = ('Unable to parse debian/control, found less than 2 paragraphs')
+ with self.assertRaisesRegex(Exception, msg):
+ DebHelper(self.build_options())
+
+
+class TestControlMissingPackage(DebHelperTestCase):
+ control = [
+ 'Source: foo-src',
+ 'Build-Depends: python3-all',
+ '',
+ 'Architecture: all',
+ ]
+ parse_control = False
+
+ def test_parses_packages(self):
+ msg = ('Unable to parse debian/control, paragraph 2 missing Package '
+ 'field')
+ with self.assertRaisesRegex(Exception, msg):
+ DebHelper(self.build_options())
+
+
+class TestRemainingPackages(DebHelperTestCase):
+ control = CONTROL
+ options = {
+ 'remaining_packages': True,
+ }
+ parse_control = False
+
+ def setUp(self):
+ super().setUp()
+ with open('debian/python3-foo.debhelper.log', 'w') as f:
+ f.write('dh_python3\n')
+ with open('debian/python3-foo-ext.debhelper.log', 'w') as f:
+ f.write('dh_foobar\n')
+ self.dh = DebHelper(self.build_options(), impl=self.impl)
+
+ def test_skips_logged_packages(self):
+ self.assertEqual(list(self.dh.packages.keys()),
+ ['python3-foo-ext', 'foo', 'recfoo'])
diff --git a/tests/test_depends.py b/tests/test_depends.py
new file mode 100644
index 0000000..d208438
--- /dev/null
+++ b/tests/test_depends.py
@@ -0,0 +1,726 @@
+import os
+import logging
+import platform
+import unittest
+from copy import deepcopy
+from pickle import dumps
+from tempfile import TemporaryDirectory
+
+from dhpython.depends import Dependencies
+from dhpython.version import Version
+
+from tests.common import FakeOptions
+
+
+def pep386(d):
+ """Mark all pydist entries as being PEP386"""
+ for k, v in d.items():
+ if isinstance(v, str):
+ d[k] = {'dependency': v}
+ d[k].setdefault('standard', 'PEP386')
+ return d
+
+
+def py27(d):
+ """Mark all pydist entries as being for Python 2.7"""
+ for k, v in d.items():
+ if isinstance(v, str):
+ d[k] = {'dependency': v}
+ d[k].setdefault('versions', {Version('2.7')})
+ return d
+
+
+def prime_pydist(impl, pydist):
+ """Fake the pydist data for impl. Returns a cleanup function"""
+ from dhpython.pydist import load
+
+ for name, entries in pydist.items():
+ if not isinstance(entries, list):
+ pydist[name] = entries = [entries]
+ for i, entry in enumerate(entries):
+ if isinstance(entry, str):
+ entries[i] = entry = {'dependency': entry}
+ entry.setdefault('name', name)
+ entry.setdefault('standard', '')
+ entry.setdefault('rules', [])
+ entry.setdefault('versions', set())
+
+ key = dumps(((impl,), {}))
+ load.cache[key] = pydist
+ return lambda: load.cache.pop(key)
+
+
+class DependenciesTestCase(unittest.TestCase):
+ pkg = 'foo'
+ impl = 'cpython3'
+ pydist = {}
+ stats = {
+ 'compile': False,
+ 'dist-info': set(),
+ 'egg-info': set(),
+ 'ext_no_version': set(),
+ 'ext_vers': set(),
+ 'nsp.txt': set(),
+ 'private_dirs': {},
+ 'public_vers': set(),
+ 'requires.txt': set(),
+ 'shebangs': set(),
+ }
+ requires = {}
+ dist_info_metadata = {}
+ options = FakeOptions()
+ parse = True
+
+ def setUp(self):
+ self.d = Dependencies(self.pkg, self.impl)
+
+ stats = deepcopy(self.stats)
+ write_files = {}
+ if self.requires:
+ for fn, lines in self.requires.items():
+ write_files[fn] = lines
+ stats['requires.txt'].add(fn)
+
+ if self.dist_info_metadata:
+ for fn, lines in self.dist_info_metadata.items():
+ write_files[fn] = lines
+ stats['dist-info'].add(fn)
+
+ if write_files:
+ self.tempdir = TemporaryDirectory()
+ self.addCleanup(self.tempdir.cleanup)
+ old_wd = os.getcwd()
+ os.chdir(self.tempdir.name)
+ self.addCleanup(os.chdir, old_wd)
+
+ for fn, lines in write_files.items():
+ os.makedirs(os.path.dirname(fn))
+ with open(fn, 'w') as f:
+ f.write('\n'.join(lines))
+
+ cleanup = prime_pydist(self.impl, self.pydist)
+ self.addCleanup(cleanup)
+
+ if self.parse:
+ self.d.parse(stats, self.options)
+ else:
+ self.prepared_stats = stats
+
+ def assertNotInDepends(self, pkg):
+ """Assert that pkg doesn't appear *anywhere* in self.d.depends"""
+ for dep in self.d.depends:
+ for alt in dep.split('|'):
+ alt = alt.strip().split('(', 1)[0].strip()
+ if pkg == alt:
+ raise AssertionError(f'{pkg} appears in {alt}')
+
+
+class TestRequiresCPython3(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True)
+ pydist = {
+ 'bar': 'python3-bar',
+ 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'},
+ 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'},
+ }
+ requires = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': (
+ 'bar',
+ 'baz >= 1.0',
+ 'quux',
+ ),
+ }
+
+ def test_depends_on_bar(self):
+ self.assertIn('python3-bar', self.d.depends)
+
+ def test_depends_on_baz(self):
+ self.assertIn('python3-baz (>= 1.0)', self.d.depends)
+
+
+class TestRequiresPyPy(DependenciesTestCase):
+ impl = 'pypy'
+ options = FakeOptions(guess_deps=True)
+ pydist = {
+ 'bar': 'pypy-bar',
+ 'baz': {'dependency': 'pypy-baz', 'standard': 'PEP386'},
+ 'quux': {'dependency': 'pypy-quux', 'standard': 'PEP386'},
+ }
+ requires = {
+ 'debian/foo/usr/lib/pypy/dist-packages/foo.egg-info/requires.txt': (
+ 'bar',
+ 'baz >= 1.0',
+ 'quux',
+ )
+ }
+
+ def test_depends_on_bar(self):
+ self.assertIn('pypy-bar', self.d.depends)
+
+ def test_depends_on_baz(self):
+ self.assertIn('pypy-baz (>= 1.0)', self.d.depends)
+
+
+class TestRequiresCompatible(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True)
+ pydist = {
+ 'bar': 'python3-bar',
+ 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'},
+ 'qux': {'dependency': 'python3-qux', 'standard': 'PEP386'},
+ 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'},
+ }
+ requires = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': (
+ 'bar',
+ 'baz ~= 1.1',
+ 'qux == 1.*',
+ 'quux',
+ ),
+ }
+
+ def test_depends_on_bar(self):
+ self.assertIn('python3-bar', self.d.depends)
+
+ def test_depends_on_baz(self):
+ self.assertIn('python3-baz (>= 1.1), python3-baz (<< 2)', self.d.depends)
+
+ def test_depends_on_qux(self):
+ self.assertIn('python3-qux (>= 1.0), python3-qux (<< 2)', self.d.depends)
+
+
+class TestRequiresDistPython3(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True)
+ pydist = {
+ 'bar': 'python3-bar',
+ 'baz': {'dependency': 'python3-baz', 'standard': 'PEP386'},
+ 'qux': {'dependency': 'python3-qux', 'standard': 'PEP386'},
+ 'quux': {'dependency': 'python3-quux', 'standard': 'PEP386'},
+ }
+ dist_info_metadata = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': (
+ 'Requires-Dist: bar',
+ 'Requires-Dist: baz >= 1.0',
+ 'Requires-Dist: qux == 1.*',
+ 'Requires-Dist: quux ~= 1.1',
+ ),
+ }
+
+ def test_depends_on_bar(self):
+ self.assertIn('python3-bar', self.d.depends)
+
+ def test_depends_on_baz(self):
+ self.assertIn('python3-baz (>= 1.0)', self.d.depends)
+
+ def test_depends_on_qux(self):
+ self.assertIn('python3-qux (>= 1.0), python3-qux (<< 2)',
+ self.d.depends)
+
+ def test_depends_on_quux(self):
+ self.assertIn('python3-quux (>= 1.1), python3-quux (<< 2)',
+ self.d.depends)
+
+
+class TestEnvironmentMarkersDistInfo(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True, depends_section=['feature'])
+ pydist = pep386({
+ 'no_markers': 'python3-no-markers',
+ 'os_posix': 'python3-os-posix',
+ 'os_java': 'python3-os-java',
+ 'sys_platform_linux': 'python3-sys-platform-linux',
+ 'sys_platform_darwin': 'python3-sys-platform-darwin',
+ 'platform_machine_x86_64': 'python3-platform-machine-x86-64',
+ 'platform_machine_mips64': 'python3-platform-machine-mips64',
+ 'platform_python_implementation_cpython':
+ 'python3-platform-python-implementation-cpython',
+ 'platform_python_implementation_jython':
+ 'python3-platform-python-implementation-jython',
+ 'platform_release_lt2': 'python3-platform-release-lt2',
+ 'platform_release_ge2': 'python3-platform-release-ge2',
+ 'platform_system_linux': 'python3-platform-system-linux',
+ 'platform_system_windows': 'python3-platform-system-windows',
+ 'platform_version_lt1': 'python3-platform-version-lt1',
+ 'platform_version_ge1': 'python3-platform-version-ge1',
+ 'python_version_ge3': 'python3-python-version-ge3',
+ 'python_version_gt3': 'python3-python-version-gt3',
+ 'python_version_lt3': 'python3-python-version-lt3',
+ 'python_version_lt30': 'python3-python-version-lt30',
+ 'python_version_lt35': 'python3-python-version-lt35',
+ 'python_version_le35': 'python3-python-version-le35',
+ 'python_version_ge27': 'python3-python-version-ge27',
+ 'python_version_ge35': 'python3-python-version-ge35',
+ 'python_version_gt35': 'python3-python-version-gt35',
+ 'python_version_eq35': 'python3-python-version-eq35',
+ 'python_version_ne35': 'python3-python-version-ne35',
+ 'python_version_aeq35': 'python3-python-version-aeq35',
+ 'python_version_ceq35': 'python3-python-version-ceq35',
+ 'python_version_weq35': 'python3-python-version-weq35',
+ 'python_version_full_lt300': 'python3-python-version-full-lt300',
+ 'python_version_full_lt351': 'python3-python-version-full-lt351',
+ 'python_version_full_le351': 'python3-python-version-full-le351',
+ 'python_version_full_ge351': 'python3-python-version-full-ge351',
+ 'python_version_full_ge351a1': 'python3-python-version-full-ge351a1',
+ 'python_version_full_ge351b1post1':
+ 'python3-python-version-full-ge351b1post1',
+ 'python_version_full_gt351': 'python3-python-version-full-gt351',
+ 'python_version_full_eq351': 'python3-python-version-full-eq351',
+ 'python_version_full_ne351': 'python3-python-version-full-ne351',
+ 'python_version_full_aeq351': 'python3-python-version-full-aeq351',
+ 'python_version_full_ceq351': 'python3-python-version-full-ceq351',
+ 'python_version_full_weq35': 'python3-python-version-full-weq35',
+ 'implementation_name_cpython': 'python3-implementation-name-cpython',
+ 'implementation_name_pypy': 'python3-implementation-name-pypy',
+ 'implementation_version_lt35': 'python3-implementation-version-lt35',
+ 'implementation_version_ge35': 'python3-implementation-version-ge35',
+ 'invalid_marker': 'python3-invalid-marker',
+ 'extra_feature': 'python3-extra-feature',
+ 'extra_test': 'python3-extra-test',
+ 'complex_marker': 'python3-complex-marker',
+ 'complex_marker_2': 'python3-complex-marker-2',
+ 'no_markers_2': 'python3-no-markers-2',
+ })
+ dist_info_metadata = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': (
+ "Requires-Dist: no_markers",
+ "Requires-Dist: os_posix; (os_name == 'posix')",
+ 'Requires-Dist: os_java; os_name == "java"',
+ "Requires-Dist: sys_platform_linux ; sys_platform == 'linux'",
+ "Requires-Dist: sys_platform_darwin;sys_platform == 'darwin'",
+ "Requires-Dist: platform_machine_x86_64; "
+ "platform_machine == 'x86_64'",
+ "Requires-Dist: platform_machine_mips64; "
+ "platform_machine == 'mips64'",
+ "Requires-Dist: platform_python_implementation_cpython; "
+ "platform_python_implementation == 'CPython'",
+ "Requires-Dist: platform_python_implementation_jython; "
+ "platform_python_implementation == 'Jython'",
+ "Requires-Dist: platform_release_lt2; platform_release < '2.0'",
+ "Requires-Dist: platform_release_ge2; platform_release >= '2.0'",
+ "Requires-Dist: platform_system_linux; platform_system == 'Linux'",
+ "Requires-Dist: platform_system_windows; "
+ "platform_system == 'Windows'",
+ "Requires-Dist: platform_version_lt1; platform_version < '1'",
+ "Requires-Dist: platform_version_ge1; platform_version >= '1'",
+ "Requires-Dist: python_version_ge3; python_version >= '3'",
+ "Requires-Dist: python_version_gt3; python_version > '3'",
+ "Requires-Dist: python_version_lt3; python_version < '3'",
+ "Requires-Dist: python_version_lt30; python_version < '3.0'",
+ "Requires-Dist: python_version_lt35; python_version < '3.5'",
+ "Requires-Dist: python_version_le35; python_version <= '3.5'",
+ "Requires-Dist: python_version_gt35; python_version > '3.5'",
+ "Requires-Dist: python_version_ge27; python_version >= '2.7'",
+ "Requires-Dist: python_version_ge35; python_version >= '3.5'",
+ "Requires-Dist: python_version_eq35; python_version == '3.5'",
+ "Requires-Dist: python_version_ne35; python_version != '3.5'",
+ "Requires-Dist: python_version_aeq35; python_version === '3.5'",
+ "Requires-Dist: python_version_ceq35; python_version ~= '3.5'",
+ "Requires-Dist: python_version_weq35; python_version == '3.5.*'",
+ "Requires-Dist: python_version_full_lt300; "
+ "python_full_version < '3.0.0'",
+ "Requires-Dist: python_version_full_lt351; "
+ "python_full_version < '3.5.1'",
+ "Requires-Dist: python_version_full_le351; "
+ "python_full_version <= '3.5.1'",
+ "Requires-Dist: python_version_full_gt351; "
+ "python_full_version > '3.5.1'",
+ "Requires-Dist: python_version_full_ge351; "
+ "python_full_version >= '3.5.1'",
+ "Requires-Dist: python_version_full_ge351a1; "
+ "python_full_version >= '3.5.1a1'",
+ "Requires-Dist: python_version_full_ge351b1post1; "
+ "python_full_version >= '3.5.1b1.post1'",
+ "Requires-Dist: python_version_full_eq351; "
+ "python_full_version == '3.5.1'",
+ "Requires-Dist: python_version_full_ne351; "
+ "python_full_version != '3.5.1'",
+ "Requires-Dist: python_version_full_aeq351; "
+ "python_full_version === '3.5.1'",
+ "Requires-Dist: python_version_full_ceq351; "
+ "python_full_version ~= '3.5.1'",
+ "Requires-Dist: python_version_full_weq35; "
+ "python_full_version == '3.5.*'",
+ "Requires-Dist: implementation_name_cpython; "
+ "implementation_name == 'cpython'",
+ "Requires-Dist: implementation_name_pypy; "
+ "implementation_name == 'pypy'",
+ "Requires-Dist: implementation_version_lt35; "
+ "implementation_version < '3.5'",
+ "Requires-Dist: implementation_version_ge35; "
+ "implementation_version >= '3.5'",
+ "Requires-Dist: invalid_marker; invalid_marker > '1'",
+ "Requires-Dist: extra_feature; extra == 'feature'",
+ "Requires-Dist: extra_test; extra == 'test'",
+ "Requires-Dist: complex_marker; os_name != 'windows' "
+ "and implementation_name == 'cpython'",
+ "Requires-Dist: complex_marker_2; (python_version > \"3.4\") "
+ "and extra == 'test'",
+ "Requires-Dist: no_markers_2",
+ ),
+ }
+
+ def test_depends_on_unmarked_packages(self):
+ self.assertIn('python3-no-markers', self.d.depends)
+
+ def test_depends_on_posix_packages(self):
+ self.assertIn('python3-os-posix', self.d.depends)
+
+ def test_skips_non_posix_packages(self):
+ self.assertNotInDepends('python3-os-java')
+
+ def test_depends_on_linux_packages(self):
+ self.assertIn('python3-sys-platform-linux', self.d.depends)
+
+ def test_skips_darwin_packages(self):
+ self.assertNotInDepends('python3-sys-platform-darwin')
+
+ def test_depends_on_x86_64_packages_on_x86_64(self):
+ if platform.machine() == 'x86_64':
+ self.assertIn('python3-platform-machine-x86-64', self.d.depends)
+ else:
+ self.assertNotInDepends('python3-platform-machine-x86-64')
+
+ def test_depends_on_mips64_packages_on_mips64(self):
+ if platform.machine() == 'mips64':
+ self.assertIn('python3-platform-machine-mips64', self.d.depends)
+ else:
+ self.assertNotInDepends('python3-platform-machine-mips64')
+
+ def test_depends_on_plat_cpython_packages(self):
+ self.assertIn('python3-platform-python-implementation-cpython',
+ self.d.depends)
+
+ def test_skips_plat_jython_packages(self):
+ self.assertNotInDepends('python3-platform-python-implementation-jython')
+
+ def test_skips_release_lt_2_packages(self):
+ self.assertNotInDepends('python3-platform-release-lt2')
+
+ def test_skips_release_gt_2_packages(self):
+ self.assertNotInDepends('python3-platform-release-ge2')
+
+ def test_depends_on_platform_linux_packages(self):
+ self.assertIn('python3-platform-system-linux', self.d.depends)
+
+ def test_skips_platform_windows_packages(self):
+ self.assertNotInDepends('python3-platform-system-windows')
+
+ def test_skips_platfrom_version_lt_1_packages(self):
+ self.assertNotInDepends('python3-platform-version-lt1')
+
+ def test_skips_platform_version_ge_1_packages(self):
+ self.assertNotInDepends('python3-platform-version-ge1')
+
+ def test_skips_py_version_lt_3_packages(self):
+ self.assertNotInDepends('python3-python-version-lt3')
+
+ def test_elides_py_version_ge_3(self):
+ self.assertIn('python3-python-version-ge3', self.d.depends)
+
+ def test_elides_py_version_gt_3(self):
+ self.assertIn('python3-python-version-gt3', self.d.depends)
+
+ def test_skips_py_version_lt_30_packages(self):
+ self.assertNotInDepends('python3-python-version-lt30')
+
+ def test_depends_on_py_version_lt_35_packages(self):
+ self.assertIn('python3-python-version-lt35 | python3 (>> 3.5)',
+ self.d.depends)
+
+ def test_depends_on_py_version_le_35_packages(self):
+ self.assertIn('python3-python-version-le35 | python3 (>> 3.6)',
+ self.d.depends)
+
+ def test_depends_on_py_version_ge_27_packages(self):
+ self.assertIn('python3-python-version-ge27',
+ self.d.depends)
+
+ def test_depends_on_py_version_ge_35_packages(self):
+ self.assertIn('python3-python-version-ge35 | python3 (<< 3.5)',
+ self.d.depends)
+
+ def test_depends_on_py_version_gt_35_packages(self):
+ self.assertIn('python3-python-version-gt35 | python3 (<< 3.6)',
+ self.d.depends)
+
+ def test_depends_on_py_version_eq_35_packages(self):
+ self.assertIn('python3-python-version-eq35 | python3 (<< 3.5) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_depends_on_py_version_ne_35_packages(self):
+ # Can't be represented in Debian depends
+ self.assertIn('python3-python-version-ne35', self.d.depends)
+
+ def test_depends_on_py_version_aeq_35_packages(self):
+ self.assertIn('python3-python-version-aeq35 | python3 (<< 3.5) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_depends_on_py_version_ceq_35_packages(self):
+ self.assertIn('python3-python-version-ceq35 | python3 (<< 3.5) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_depends_on_py_version_weq_35_packages(self):
+ self.assertIn('python3-python-version-weq35 | python3 (<< 3.5) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_skips_py_version_full_lt_300_packages(self):
+ self.assertNotInDepends('python3-python-version-full-lt300')
+
+ def test_depends_on_py_version_full_lt_351_packages(self):
+ self.assertIn('python3-python-version-full-lt351 | python3 (>> 3.5.1)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_le_351_packages(self):
+ self.assertIn('python3-python-version-full-le351 | python3 (>> 3.5.2)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_ge_351_packages(self):
+ self.assertIn('python3-python-version-full-ge351 | python3 (<< 3.5.1)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_ge_351a1_packages(self):
+ # With full PEP-440 parsing this should be (<< 3.5.1~a1)
+ self.assertIn(
+ 'python3-python-version-full-ge351a1 | python3 (<< 3.5.0)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_ge_351b1post1_packages(self):
+ # With full PEP-440 parsing this should be (<< 3.5.1~b1.post1)
+ self.assertIn('python3-python-version-full-ge351a1 '
+ '| python3 (<< 3.5.0)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_gt_351_packages(self):
+ self.assertIn('python3-python-version-full-gt351 | python3 (<< 3.5.2)',
+ self.d.depends)
+
+ def test_depends_on_py_version_full_eq_351_packages(self):
+ self.assertIn('python3-python-version-full-eq351 | python3 (<< 3.5.1) '
+ '| python3 (>> 3.5.2)', self.d.depends)
+
+ def test_depends_on_py_version_full_ne_351_packages(self):
+ # Can't be represented in Debian depends
+ self.assertIn('python3-python-version-full-ne351', self.d.depends)
+
+ def test_skips_py_version_full_aeq_351_packages(self):
+ # Can't be represented in Debian depends
+ self.assertNotInDepends('python3-python-version-full-aeq351')
+
+ def test_depends_on_py_version_full_ceq_351_packages(self):
+ self.assertIn('python3-python-version-full-ceq351 | python3 (<< 3.5.1) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_depends_on_py_version_full_weq_35_packages(self):
+ self.assertIn('python3-python-version-full-weq35 | python3 (<< 3.5) '
+ '| python3 (>> 3.6)', self.d.depends)
+
+ def test_depends_on_sys_cpython_packages(self):
+ self.assertIn('python3-implementation-name-cpython', self.d.depends)
+
+ def test_depends_on_sys_pypy_packages(self):
+ self.assertIn('python3-implementation-name-pypy', self.d.depends)
+
+ def test_depends_on_sys_implementation_lt35_packages(self):
+ self.assertIn('python3-implementation-version-lt35 | python3 (>> 3.5)',
+ self.d.depends)
+
+ def test_depends_on_sys_implementation_ge35_packages(self):
+ self.assertIn('python3-implementation-version-ge35 | python3 (<< 3.5)',
+ self.d.depends)
+
+ def test_ignores_invalid_marker(self):
+ self.assertNotInDepends('python3-invalid-marker')
+
+ def test_depends_on_extra_feature_packages(self):
+ self.assertIn('python3-extra-feature', self.d.depends)
+
+ def test_skips_extra_test_packages(self):
+ self.assertNotInDepends('python3-extra-test')
+
+ def test_ignores_complex_environment_markers(self):
+ self.assertNotInDepends('python3-complex-marker')
+ self.assertNotInDepends('python3-complex-marker-2')
+
+ def test_depends_on_un_marked_dependency_after_extra(self):
+ self.assertIn('python3-no-markers-2', self.d.depends)
+
+
+class TestEnvironmentMarkersEggInfo(TestEnvironmentMarkersDistInfo):
+ dist_info_metadata = None
+ requires = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': (
+ "no_markers",
+ "[:(os_name == 'posix')]",
+ "os_posix",
+ '[:os_name == "java"]',
+ "os_java",
+ "[:sys_platform == 'linux']",
+ "sys_platform_linux",
+ "[:sys_platform == 'darwin']",
+ "sys_platform_darwin",
+ "[:platform_machine == 'x86_64']",
+ "platform_machine_x86_64",
+ "[:platform_machine == 'mips64']",
+ "platform_machine_mips64",
+ "[:platform_python_implementation == 'CPython']",
+ "platform_python_implementation_cpython",
+ "[:platform_python_implementation == 'Jython']",
+ "platform_python_implementation_jython",
+ "[:platform_release < '2.0']",
+ "platform_release_lt2",
+ "[:platform_release >= '2.0']",
+ "platform_release_ge2",
+ "[:platform_system == 'Linux']",
+ "platform_system_linux",
+ "[:platform_system == 'Windows']",
+ "platform_system_windows",
+ "[:platform_version < '1']",
+ "platform_version_lt1",
+ "[:platform_version >= '1']",
+ "platform_version_ge1",
+ "[:python_version >= '3']",
+ "python_version_ge3",
+ "[:python_version > '3']",
+ "python_version_gt3",
+ "[:python_version < '3']",
+ "python_version_lt3",
+ "[:python_version < '3.0']",
+ "python_version_lt30",
+ "[:python_version < '3.5']",
+ "python_version_lt35",
+ "[:python_version <= '3.5']",
+ "python_version_le35",
+ "[:python_version > '3.5']",
+ "python_version_gt35",
+ "[:python_version >= '2.7']",
+ "python_version_ge27",
+ "[:python_version >= '3.5']",
+ "python_version_ge35",
+ "[:python_version == '3.5']",
+ "python_version_eq35",
+ "[:python_version != '3.5']",
+ "python_version_ne35",
+ "[:python_version === '3.5']",
+ "python_version_aeq35",
+ "[:python_version ~= '3.5']",
+ "python_version_ceq35",
+ "[:python_version == '3.5.*']",
+ "python_version_weq35",
+ "[:python_full_version < '3.0.0']",
+ "python_version_full_lt300",
+ "[:python_full_version < '3.5.1']",
+ "python_version_full_lt351",
+ "[:python_full_version <= '3.5.1']",
+ "python_version_full_le351",
+ "[:python_full_version > '3.5.1']",
+ "python_version_full_gt351",
+ "[:python_full_version >= '3.5.1']",
+ "python_version_full_ge351",
+ "[:python_full_version >= '3.5.1a1']",
+ "python_version_full_ge351a1",
+ "[:python_full_version >= '3.5.1b1.post1']",
+ "python_version_full_ge351b1post1",
+ "[:python_full_version == '3.5.1']",
+ "python_version_full_eq351",
+ "[:python_full_version != '3.5.1']",
+ "python_version_full_ne351",
+ "[:python_full_version === '3.5.1']",
+ "python_version_full_aeq351",
+ "[:python_full_version ~= '3.5.1']",
+ "python_version_full_ceq351",
+ "[:python_full_version == '3.5.*']",
+ "python_version_full_weq35",
+ "[:implementation_name == 'cpython']",
+ "implementation_name_cpython",
+ "[:implementation_name == 'pypy']",
+ "implementation_name_pypy",
+ "[:implementation_version < '3.5']",
+ "implementation_version_lt35",
+ "[:implementation_version >= '3.5']",
+ "implementation_version_ge35",
+ "[:invalid_marker > '1']",
+ "invalid_marker",
+ "[feature]",
+ "extra_feature",
+ "[test]",
+ "extra_test",
+ "[:os_name != 'windows' and implementation_name == 'cpython']",
+ "complex_marker",
+ "[test:(os_name != 'windows')]",
+ "complex_marker_2",
+ ),
+ }
+
+ def test_depends_on_un_marked_dependency_after_extra(self):
+ raise unittest.SkipTest('Not possible in requires.txt')
+
+
+class TestEnvironmentMarkers27EggInfo(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True)
+ impl = 'cpython2'
+ requires = {
+ 'debian/foo/usr/lib/python2.7/dist-packages/foo.egg-info/requires.txt': (
+ "no_markers",
+ "[:os_name == 'posix']",
+ "os_posix",
+ "[:python_version >= '2.6']",
+ "python_version_ge26",
+ )
+ }
+ pydist = py27({
+ 'no_markers': 'python-no-markers',
+ 'os_posix': 'python-os-posix',
+ 'python_version_ge26': 'python-python-version-ge26',
+ })
+
+ def test_depends_on_unmarked_packages(self):
+ self.assertIn('python-no-markers', self.d.depends)
+
+ def test_ignores_posix_packages(self):
+ self.assertNotInDepends('python-os-posix')
+
+ def test_ignores_pyversion_packages(self):
+ self.assertNotInDepends('python-python-version-ge26')
+
+
+class TestIgnoresUnusedModulesDistInfo(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True, depends_section=['feature'])
+ dist_info_metadata = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.dist-info/METADATA': (
+ "Requires-Dist: unusued-complex-module ; "
+ "(sys_platform == \"darwin\") and extra == 'nativelib'",
+ "Requires-Dist: unused-win-module ; (sys_platform == \"win32\")",
+ "Requires-Dist: unused-extra-module ; extra == 'unused'",
+ ),
+ }
+ parse = False
+
+ def test_ignores_unused_dependencies(self):
+ if not hasattr(self, 'assertLogs'):
+ raise unittest.SkipTest("Requires Python >= 3.4")
+ with self.assertLogs(logger='dhpython', level=logging.INFO) as logs:
+ self.d.parse(self.prepared_stats, self.options)
+ for line in logs.output:
+ self.assertTrue(
+ line.startswith(
+ 'INFO:dhpython:Ignoring complex environment marker'),
+ 'Expecting only complex environment marker messages, but '
+ 'got: {}'.format(line))
+
+
+class TestIgnoresUnusedModulesEggInfo(DependenciesTestCase):
+ options = FakeOptions(guess_deps=True, depends_section=['feature'])
+ requires = {
+ 'debian/foo/usr/lib/python3/dist-packages/foo.egg-info/requires.txt': (
+ "[nativelib:(sys_platform == 'darwin')]",
+ "unusued-complex-module",
+ "[:sys_platform == 'win32']",
+ "unused-win-module",
+ "[unused]",
+ "unused-extra-module",
+ )
+ }
+ parse = False
+
+ def test_ignores_unused_dependencies(self):
+ if not hasattr(self, 'assertNoLogs'):
+ raise unittest.SkipTest("Requires Python >= 3.10")
+ with self.assertNoLogs(logger='dhpython', level=logging.INFO):
+ self.d.parse(self.prepared_stats, self.options)
diff --git a/tests/test_fs.py b/tests/test_fs.py
new file mode 100644
index 0000000..c458fe8
--- /dev/null
+++ b/tests/test_fs.py
@@ -0,0 +1,145 @@
+from tempfile import TemporaryDirectory
+from pathlib import Path
+from unittest import TestCase
+
+from dhpython.interpreter import Interpreter
+from dhpython.fs import (
+ fix_merged_RECORD, merge_RECORD, merge_WHEEL, missing_lines, share_files)
+
+from tests.common import FakeOptions
+
+
+class MergeWheelTestCase(TestCase):
+ files = {}
+ def setUp(self):
+ self.tempdir = TemporaryDirectory()
+ self.addCleanup(self.tempdir.cleanup)
+ temp_path = Path(self.tempdir.name)
+ for fn, contents in self.files.items():
+ path = temp_path / fn
+ setattr(self, path.name, path)
+ path.parent.mkdir(parents=True, exist_ok=True)
+ with path.open('w') as f:
+ f.write('\n'.join(contents))
+ f.write('\n')
+
+ def assertFileContents(self, path, contents):
+ """Assert that the contents of path is contents
+
+ Contents may be specified as a list of strings, one per line, without
+ line-breaks.
+ """
+ if isinstance(contents, (list, tuple)):
+ contents = '\n'.join(contents) + '\n'
+ with path.open('r') as f:
+ self.assertMultiLineEqual(contents, f.read())
+
+
+class SimpleCombinationTest(MergeWheelTestCase):
+ files = {
+ 'a': ('abc', 'def'),
+ 'b': ('abc', 'ghi'),
+ }
+ def test_missing_lines(self):
+ r = missing_lines(self.a, self.b)
+ self.assertEqual(r, ['def\n'])
+
+ def test_merge_record(self):
+ merge_RECORD(self.a, self.b)
+ self.assertFileContents(self.b, ('abc', 'ghi', 'def'))
+
+
+class MergeTagsTest(MergeWheelTestCase):
+ files = {
+ 'a': ('foo', 'Tag: A'),
+ 'b': ('foo', 'Tag: B'),
+ }
+
+ def test_merge_wheel(self):
+ merge_WHEEL(self.a, self.b)
+ self.assertFileContents(self.b, ('foo', 'Tag: B', 'Tag: A'))
+
+
+class UpdateRecordTest(MergeWheelTestCase):
+ files = {
+ 'dist-info/RECORD': ('dist-info/FOO,sha256=b5bb9d8014a0f9b1d61e21e796d7'
+ '8dccdf1352f23cd32812f4850b878ae4944c,4',),
+ 'dist-info/WHEEL': ('foo'),
+ }
+
+ def test_fix_merged_record(self):
+ fix_merged_RECORD(self.RECORD.parent)
+ self.assertFileContents(self.RECORD, (
+ 'dist-info/FOO,sha256=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32'
+ '812f4850b878ae4944c,4',
+ 'dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53eac85d'
+ '1844f5940f51c1fcba725,6',
+ ))
+
+
+class ShareFilesTestCase(MergeWheelTestCase):
+ impl = 'cpython3'
+ options = {}
+
+ def setUp(self):
+ super().setUp()
+ self.destdir = TemporaryDirectory()
+ self.addCleanup(self.destdir.cleanup)
+ share_files(self.tempdir.name, self.destdir.name,
+ Interpreter(self.impl),
+ FakeOptions(**self.options))
+
+ def destPath(self, name):
+ return Path(self.destdir.name) / name
+
+
+class HatchlingLicenseTest(ShareFilesTestCase):
+ files = {
+ 'foo.dist-info/license_files/LICENSE.txt': ('foo'),
+ 'foo.dist-info/licenses/COPYING': ('foo'),
+ 'foo.dist-info/RECORD': (
+ 'foo.dist-info/license_files/LICENSE.txt,sha256=2c26b46b68ffc68ff99'
+ 'b453c1d30413413422d706483bfa0f98a5e886266e7ae,4',
+ 'foo.dist-info/licenses/COPYING,sha256=2c26b46b68ffc68ff99b453c1d30'
+ '413413422d706483bfa0f98a5e886266e7ae,4',
+ 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea'
+ 'c85d1844f5940f51c1fcba725,6'),
+ 'foo.dist-info/WHEEL': ('foo'),
+ }
+
+ def test_removes_license_files(self):
+ self.assertFalse(
+ self.destPath('foo.dist-info/license_files/LICENSE.txt').exists())
+ self.assertFalse(
+ self.destPath('foo.dist-info/licenses/COPYING').exists())
+
+ def test_removes_license_files_from_record(self):
+ print("Checking", self.destPath('foo.dist-info/RECORD'))
+ self.assertFileContents(self.destPath('foo.dist-info/RECORD'),
+ 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea'
+ 'c85d1844f5940f51c1fcba725,6\n')
+
+
+class FlitLicenseTest(ShareFilesTestCase):
+ files = {
+ 'foo.dist-info/COPYING': ('foo'),
+ 'foo.dist-info/COPYING.LESSER': ('foo'),
+ 'foo.dist-info/RECORD': (
+ 'foo.dist-info/COPYING,sha256=2c26b46b68ffc68ff99b453c1d30413413422'
+ 'd706483bfa0f98a5e886266e7ae,4',
+ 'foo.dist-info/COPYING.LESSER,sha256=2c26b46b68ffc68ff99b453c1d3041'
+ '3413422d706483bfa0f98a5e886266e7ae,4',
+ 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea'
+ 'c85d1844f5940f51c1fcba725,6'),
+ 'foo.dist-info/WHEEL': ('foo'),
+ }
+
+ def test_removes_license_files(self):
+ self.assertFalse(self.destPath('foo.dist-info/COPYING.LESSER').exists())
+ self.assertFalse(self.destPath('foo.dist-info/COPYING').exists())
+
+ def test_removes_license_files_from_record(self):
+ print("Checking", self.destPath('foo.dist-info/RECORD'))
+ self.assertFileContents(self.destPath('foo.dist-info/RECORD'),
+ 'foo.dist-info/WHEEL,sha256=447fb61fa39a067229e1cce8fc0953bfced53ea'
+ 'c85d1844f5940f51c1fcba725,6\n')
diff --git a/tests/test_interpreter.py b/tests/test_interpreter.py
new file mode 100644
index 0000000..ff9bdd2
--- /dev/null
+++ b/tests/test_interpreter.py
@@ -0,0 +1,250 @@
+import unittest
+from os import environ
+from os.path import exists
+from dhpython.interpreter import Interpreter
+
+
+class TestInterpreter(unittest.TestCase):
+ def setUp(self):
+ self._triplet = environ.get('DEB_HOST_MULTIARCH')
+ environ['DEB_HOST_MULTIARCH'] = 'MYARCH'
+
+ def tearDown(self):
+ if self._triplet:
+ environ['DEB_HOST_MULTIARCH'] = self._triplet
+
+ @unittest.skipUnless(exists('/usr/bin/pypy'), 'pypy is not installed')
+ def test_pypy(self):
+ sorted(Interpreter.parse('pypy').items()) == \
+ [('debug', None), ('name', 'pypy'), ('options', ()), ('path', ''), ('version', None)]
+ sorted(Interpreter.parse('#! /usr/bin/pypy --foo').items()) == \
+ [('debug', None), ('name', 'pypy'), ('options', ('--foo',)), ('path', '/usr/bin/'), ('version', None)]
+ Interpreter('pypy').sitedir(version='2.0') == '/usr/lib/pypy/dist-packages/'
+
+ @unittest.skipUnless(exists('/usr/bin/python2.6'), 'python2.6 is not installed')
+ def test_python26(self):
+ i = Interpreter('python2.6')
+ self.assertEqual(i.soabi(), '')
+ self.assertIsNone(i.check_extname('foo.so'))
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertIsNone(i.check_extname('foo/bar/bazmodule.so'))
+
+ @unittest.skipUnless(exists('/usr/bin/python2.6-dbg'), 'python2.6-dbg is not installed')
+ def test_python26dbg(self):
+ i = Interpreter('python2.6-dbg')
+ self.assertEqual(i.soabi(), '')
+ self.assertIsNone(i.check_extname('foo_d.so'))
+ self.assertEqual(i.check_extname('foo.so'), 'foo_d.so')
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/bazmodule_d.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python2.7'), 'python2.7 is not installed')
+ def test_python27(self):
+ i = Interpreter('python2.7')
+ self.assertEqual(i.soabi(), '')
+ self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.MYARCH_d.so'))
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertIsNone(i.check_extname('foo.OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/baz.MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python2.7-dbg'), 'python2.7-dbg is not installed')
+ def test_python27dbg(self):
+ i = Interpreter('python2.7-dbg')
+ self.assertEqual(i.soabi(), '')
+ self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH_d.so')
+ self.assertEqual(i.check_extname('foo_d.so'), 'foo.MYARCH_d.so')
+ self.assertIsNone(i.check_extname('foo.MYARCH_d.so'))
+ self.assertIsNone(i.check_extname('foo.OTHER_d.so')) # different architecture
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/baz.MYARCH_d.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.1'), 'python3.1 is not installed')
+ def test_python31(self):
+ i = Interpreter('python3.1')
+ self.assertEqual(i.soabi(), '')
+ self.assertIsNone(i.check_extname('foo.so'))
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertIsNone(i.check_extname('foo/bar/bazmodule.so'))
+
+ @unittest.skipUnless(exists('/usr/bin/python3.1-dbg'), 'python3.1-dbg is not installed')
+ def test_python31dbg(self):
+ i = Interpreter('python3.1-dbg')
+ self.assertEqual(i.soabi(), '')
+ self.assertIsNone(i.check_extname('foo.so'))
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertIsNone(i.check_extname('foo/bar/bazmodule.so'))
+
+ @unittest.skipUnless(exists('/usr/bin/python3.2'), 'python3.2 is not installed')
+ def test_python32(self):
+ i = Interpreter('python3.2')
+ self.assertEqual(i.soabi(), 'cpython-32mu')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32mu.so')
+ self.assertIsNone(i.check_extname('foo.cpython-33m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-32mu-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/bazmodule.cpython-32mu.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.2-dbg'), 'python3.2-dbg is not installed')
+ def test_python32dbg(self):
+ i = Interpreter('python3.2-dbg')
+ self.assertEqual(i.soabi(), 'cpython-32dmu')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32dmu.so')
+ self.assertIsNone(i.check_extname('foo.cpython-33m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-32dmu-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/bazmodule.cpython-32dmu.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.4'), 'python3.4 is not installed')
+ def test_python34(self):
+ i = Interpreter('python3.4')
+ self.assertEqual(i.soabi(), 'cpython-34m')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-34m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-34m-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-34m.so'), r'foo.cpython-34m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-34m-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.4-dbg'), 'python3.4-dbg is not installed')
+ def test_python34dbg(self):
+ i = Interpreter('python3.4-dbg')
+ self.assertEqual(i.soabi(), 'cpython-34dm')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-34dm-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-34m-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-34dm-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.5'), 'python3.5 is not installed')
+ def test_python35(self):
+ i = Interpreter('python3.5')
+ self.assertEqual(i.soabi(), 'cpython-35m')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-35m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-35m-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-35m.so'), r'foo.cpython-35m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-35m-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.5-dbg'), 'python3.5-dbg is not installed')
+ def test_python35dbg(self):
+ i = Interpreter('python3.5-dbg')
+ self.assertEqual(i.soabi(), 'cpython-35dm')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-35dm-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-35m-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-35dm-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.6'), 'python3.6 is not installed')
+ def test_python36(self):
+ i = Interpreter('python3.6')
+ self.assertEqual(i.soabi(), 'cpython-36m')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-36m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-36m-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-36m.so'), r'foo.cpython-36m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-36m-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.6-dbg'), 'python3.6-dbg is not installed')
+ def test_python36dbg(self):
+ i = Interpreter('python3.6-dbg')
+ self.assertEqual(i.soabi(), 'cpython-36dm')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-36dm-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-36m-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-36dm-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.7'), 'python3.7 is not installed')
+ def test_python37(self):
+ i = Interpreter('python3.7')
+ self.assertEqual(i.soabi(), 'cpython-37m')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-37m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-37m-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-37m.so'), r'foo.cpython-37m-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-37m-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.7-dbg'), 'python3.7-dbg is not installed')
+ def test_python37dbg(self):
+ i = Interpreter('python3.7-dbg')
+ self.assertEqual(i.soabi(), 'cpython-37dm')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-37dm-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-37m-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-37dm-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.8'), 'python3.8 is not installed')
+ def test_python38(self):
+ i = Interpreter('python3.8')
+ self.assertEqual(i.soabi(), 'cpython-38')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-38-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-38-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-38.so'), r'foo.cpython-38-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-38-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.8-dbg'), 'python3.8-dbg is not installed')
+ def test_python38dbg(self):
+ i = Interpreter('python3.8-dbg')
+ self.assertEqual(i.soabi(), 'cpython-38d')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-38d-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-38-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-38d-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.9'), 'python3.9 is not installed')
+ def test_python39(self):
+ i = Interpreter('python3.9')
+ self.assertEqual(i.soabi(), 'cpython-39')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-39-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-39-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-39.so'), r'foo.cpython-39-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-39-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.9-dbg'), 'python3.9-dbg is not installed')
+ def test_python39dbg(self):
+ i = Interpreter('python3.9-dbg')
+ self.assertEqual(i.soabi(), 'cpython-39d')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-39d-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-39-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-39d-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.10'), 'python3.10 is not installed')
+ def test_python310(self):
+ i = Interpreter('python3.10')
+ self.assertEqual(i.soabi(), 'cpython-310')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-310-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-310-OTHER.so')) # different architecture
+ self.assertEqual(i.check_extname('foo.cpython-310.so'), r'foo.cpython-310-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-310-MYARCH.so')
+
+ @unittest.skipUnless(exists('/usr/bin/python3.10-dbg'), 'python3.10-dbg is not installed')
+ def test_python310dbg(self):
+ i = Interpreter('python3.10-dbg')
+ self.assertEqual(i.soabi(), 'cpython-310d')
+ self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-310d-MYARCH.so')
+ self.assertIsNone(i.check_extname('foo.cpython-32m.so')) # different version
+ self.assertIsNone(i.check_extname('foo.cpython-310-OTHER.so')) # different architecture
+ self.assertIsNone(i.check_extname('foo.abi3.so'))
+ self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-310d-MYARCH.so')
+
+
+ def test_version(self):
+ i = Interpreter(impl='cpython2')
+ self.assertEqual(str(i), 'python')
+ self.assertEqual(i.binary('2.7'), '/usr/bin/python2.7')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_tools.py b/tests/test_tools.py
new file mode 100644
index 0000000..55097e8
--- /dev/null
+++ b/tests/test_tools.py
@@ -0,0 +1,44 @@
+from tempfile import TemporaryDirectory
+import os
+import unittest
+
+from dhpython.tools import relpath, move_matching_files
+
+
+class TestRelpath(unittest.TestCase):
+ def test_common_parent_dir(self):
+ r = relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo')
+ self.assertEqual(r, '../share/python-foo/foo.py')
+
+ def test_strips_common_prefix(self):
+ r = relpath('/usr/share/python-foo/foo.py', '/usr/share')
+ self.assertEqual(r, 'python-foo/foo.py')
+
+ def test_trailing_slash_ignored(self):
+ r = relpath('/usr/share/python-foo/foo.py', '/usr/share/')
+ self.assertEqual(r, 'python-foo/foo.py')
+
+
+class TestMoveMatchingFiles(unittest.TestCase):
+ def setUp(self):
+ self.tmpdir = TemporaryDirectory()
+ self.addCleanup(self.tmpdir.cleanup)
+ os.makedirs(self.tmppath('foo/bar/a/b/c/spam'))
+ for path in ('foo/bar/a/b/c/spam/file.so',
+ 'foo/bar/a/b/c/spam/file.py'):
+ open(self.tmppath(path), 'w').close()
+
+ move_matching_files(self.tmppath('foo/bar/'),
+ self.tmppath('foo/baz/'),
+ 'spam/.*\.so$')
+
+ def tmppath(self, *path):
+ return os.path.join(self.tmpdir.name, *path)
+
+ def test_moved_matching_file(self):
+ self.assertTrue(os.path.exists(
+ self.tmppath('foo/baz/a/b/c/spam/file.so')))
+
+ def test_left_non_matching_file(self):
+ self.assertTrue(os.path.exists(
+ self.tmppath('foo/bar/a/b/c/spam/file.py')))
diff --git a/tests/tpb01/Makefile b/tests/tpb01/Makefile
new file mode 100644
index 0000000..b33b698
--- /dev/null
+++ b/tests/tpb01/Makefile
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py
+ grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb01/debian/changelog b/tests/tpb01/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb01/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb01/debian/control b/tests/tpb01/debian/control
new file mode 100644
index 0000000..8b2e05f
--- /dev/null
+++ b/tests/tpb01/debian/control
@@ -0,0 +1,16 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all
+ , python3-setuptools
+ , python3-tomli
+# , dh-python
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
diff --git a/tests/tpb01/debian/copyright b/tests/tpb01/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb01/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb01/debian/rules b/tests/tpb01/debian/rules
new file mode 100755
index 0000000..e8953b0
--- /dev/null
+++ b/tests/tpb01/debian/rules
@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb01/debian/source/format b/tests/tpb01/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb01/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb01/foo.py b/tests/tpb01/foo.py
new file mode 100644
index 0000000..810c96e
--- /dev/null
+++ b/tests/tpb01/foo.py
@@ -0,0 +1 @@
+"foo"
diff --git a/tests/tpb01/setup.cfg b/tests/tpb01/setup.cfg
new file mode 100644
index 0000000..112fd6c
--- /dev/null
+++ b/tests/tpb01/setup.cfg
@@ -0,0 +1,9 @@
+[metadata]
+name = foo
+
+[options]
+py_modules = foo
+install_requires =
+ tomli
+ mock; python_version < '3.1'
+ docutils; python_version >= '3.0'
diff --git a/tests/tpb01/setup.py b/tests/tpb01/setup.py
new file mode 100644
index 0000000..6068493
--- /dev/null
+++ b/tests/tpb01/setup.py
@@ -0,0 +1,3 @@
+from setuptools import setup
+
+setup()
diff --git a/tests/tpb02/Makefile b/tests/tpb02/Makefile
new file mode 100644
index 0000000..3a86c66
--- /dev/null
+++ b/tests/tpb02/Makefile
@@ -0,0 +1,19 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py
+ test -f debian/python3-foo/usr/bin/foo
+ grep -q ^foo/__init__.py, $(DI)/RECORD
+ test ! -f $(DI)/direct_url.json
+ grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD
+ grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control
+ grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control
+ grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control
+ find .pybuild -name test-executed | grep -q test-executed
+ test -f debian/python3-foo/usr/share/man/man1/foo.1.gz
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb02/data/share/man/man1/foo.1 b/tests/tpb02/data/share/man/man1/foo.1
new file mode 100644
index 0000000..3bf5dce
--- /dev/null
+++ b/tests/tpb02/data/share/man/man1/foo.1
@@ -0,0 +1,8 @@
+.TH foo 1 "December 5 2022"
+.SH NAME
+foo \- An example
+.SH SYNOPSIS
+.B foo
+.SH DESCRIPTION
+.B foo
+says hi.
diff --git a/tests/tpb02/debian/changelog b/tests/tpb02/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb02/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb02/debian/control b/tests/tpb02/debian/control
new file mode 100644
index 0000000..c775ede
--- /dev/null
+++ b/tests/tpb02/debian/control
@@ -0,0 +1,16 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , flit
+ , python3-all
+ , pybuild-plugin-pyproject
+# , dh-python
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
diff --git a/tests/tpb02/debian/copyright b/tests/tpb02/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb02/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb02/debian/pybuild.testfiles b/tests/tpb02/debian/pybuild.testfiles
new file mode 100644
index 0000000..58c4d14
--- /dev/null
+++ b/tests/tpb02/debian/pybuild.testfiles
@@ -0,0 +1,3 @@
+testfile1.txt
+nested/testfile2.txt
+testdir
diff --git a/tests/tpb02/debian/rules b/tests/tpb02/debian/rules
new file mode 100755
index 0000000..e8953b0
--- /dev/null
+++ b/tests/tpb02/debian/rules
@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb02/debian/source/format b/tests/tpb02/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb02/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb02/foo/__init__.py b/tests/tpb02/foo/__init__.py
new file mode 100644
index 0000000..f29ed43
--- /dev/null
+++ b/tests/tpb02/foo/__init__.py
@@ -0,0 +1,6 @@
+"""An amazing sample package!"""
+
+__version__ = '0.1'
+
+def main():
+ print("Hello There")
diff --git a/tests/tpb02/foo/test_foo.py b/tests/tpb02/foo/test_foo.py
new file mode 100644
index 0000000..174b86b
--- /dev/null
+++ b/tests/tpb02/foo/test_foo.py
@@ -0,0 +1,11 @@
+from unittest import TestCase
+
+
+class RequiredTest(TestCase):
+ def test_tests_are_executed(self):
+ open('test-executed', 'w').close()
+
+ def test_testfiles_exist(self):
+ open('testfile1.txt').close()
+ open('testfile2.txt').close()
+ open('testdir/testfile3.txt').close()
diff --git a/tests/tpb02/nested/testfile2.txt b/tests/tpb02/nested/testfile2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tpb02/nested/testfile2.txt
diff --git a/tests/tpb02/pyproject.toml b/tests/tpb02/pyproject.toml
new file mode 100644
index 0000000..a20e0e7
--- /dev/null
+++ b/tests/tpb02/pyproject.toml
@@ -0,0 +1,22 @@
+[build-system]
+requires = ["flit_core >=2,<4"]
+build-backend = "flit_core.buildapi"
+
+[tool.flit.metadata]
+module = "foo"
+author = "Stefano Rivera"
+requires = [
+ "tomli",
+ "importlib-metadata ; python_version < '3.5'"
+]
+
+[tool.flit.metadata.requires-extra]
+test = [
+ "tox",
+]
+
+[tool.flit.scripts]
+foo = "foo:main"
+
+[tool.flit.external-data]
+directory = "data"
diff --git a/tests/tpb02/testdir/testfile3.txt b/tests/tpb02/testdir/testfile3.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tpb02/testdir/testfile3.txt
diff --git a/tests/tpb02/testfile1.txt b/tests/tpb02/testfile1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tpb02/testfile1.txt
diff --git a/tests/tpb03/Makefile b/tests/tpb03/Makefile
new file mode 100644
index 0000000..5337be8
--- /dev/null
+++ b/tests/tpb03/Makefile
@@ -0,0 +1,10 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ # FIXME: This used to be a 2.7 + 3.x test. It may not be useful any more, without 2.x
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py
+ grep -q 'Depends:.*python3-pkg-resources' debian/python3-foo/DEBIAN/control
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb03/debian/changelog b/tests/tpb03/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb03/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb03/debian/control b/tests/tpb03/debian/control
new file mode 100644
index 0000000..e49d924
--- /dev/null
+++ b/tests/tpb03/debian/control
@@ -0,0 +1,15 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all
+ , python3-setuptools
+# , dh-python
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
diff --git a/tests/tpb03/debian/copyright b/tests/tpb03/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb03/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb03/debian/rules b/tests/tpb03/debian/rules
new file mode 100755
index 0000000..e8953b0
--- /dev/null
+++ b/tests/tpb03/debian/rules
@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb03/debian/source/format b/tests/tpb03/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb03/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb03/foo.py b/tests/tpb03/foo.py
new file mode 100644
index 0000000..810c96e
--- /dev/null
+++ b/tests/tpb03/foo.py
@@ -0,0 +1 @@
+"foo"
diff --git a/tests/tpb03/setup.cfg b/tests/tpb03/setup.cfg
new file mode 100644
index 0000000..e60fea3
--- /dev/null
+++ b/tests/tpb03/setup.cfg
@@ -0,0 +1,7 @@
+[metadata]
+name = foo
+
+[options]
+py_modules = foo
+install_requires =
+ setuptools
diff --git a/tests/tpb03/setup.py b/tests/tpb03/setup.py
new file mode 100644
index 0000000..6068493
--- /dev/null
+++ b/tests/tpb03/setup.py
@@ -0,0 +1,3 @@
+from setuptools import setup
+
+setup()
diff --git a/tests/tpb04/Makefile b/tests/tpb04/Makefile
new file mode 100644
index 0000000..d1b6324
--- /dev/null
+++ b/tests/tpb04/Makefile
@@ -0,0 +1,10 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo.py
+ test -f debian/python3-foo-ext/usr/lib/python3/dist-packages/_foo.abi3.so
+ test -e test-executed
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb04/_foo.c b/tests/tpb04/_foo.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tpb04/_foo.c
diff --git a/tests/tpb04/debian/changelog b/tests/tpb04/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb04/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb04/debian/control b/tests/tpb04/debian/control
new file mode 100644
index 0000000..f0643cf
--- /dev/null
+++ b/tests/tpb04/debian/control
@@ -0,0 +1,23 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all-dev
+ , python3-setuptools
+ , python3-tomli
+ , tox
+# , dh-python
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
+
+Package: python3-foo-ext
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython extensions
+ example package #2
diff --git a/tests/tpb04/debian/copyright b/tests/tpb04/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb04/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb04/debian/rules b/tests/tpb04/debian/rules
new file mode 100755
index 0000000..1a4e00b
--- /dev/null
+++ b/tests/tpb04/debian/rules
@@ -0,0 +1,27 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+export PYBUILD_EXT_DESTDIR_python3=debian/python3-foo-ext
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test --test-tox --test-args=-v
+
+override_dh_auto_clean:
+ ../../pybuild --clean
+ rm -rf .pybuild .tox foo.egg-info test-executed
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb04/debian/source/format b/tests/tpb04/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb04/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb04/foo.py b/tests/tpb04/foo.py
new file mode 100644
index 0000000..810c96e
--- /dev/null
+++ b/tests/tpb04/foo.py
@@ -0,0 +1 @@
+"foo"
diff --git a/tests/tpb04/setup.cfg b/tests/tpb04/setup.cfg
new file mode 100644
index 0000000..3ff1e35
--- /dev/null
+++ b/tests/tpb04/setup.cfg
@@ -0,0 +1,5 @@
+[metadata]
+name = foo
+
+[options]
+py_modules = foo
diff --git a/tests/tpb04/setup.py b/tests/tpb04/setup.py
new file mode 100644
index 0000000..e922974
--- /dev/null
+++ b/tests/tpb04/setup.py
@@ -0,0 +1,9 @@
+from setuptools import setup, Extension
+
+setup(ext_modules=[
+ Extension(
+ '_foo',
+ ['_foo.c'],
+ py_limited_api = True,
+ )
+])
diff --git a/tests/tpb04/test_foo.py b/tests/tpb04/test_foo.py
new file mode 100644
index 0000000..bbe6954
--- /dev/null
+++ b/tests/tpb04/test_foo.py
@@ -0,0 +1,6 @@
+from unittest import TestCase
+
+
+class RequiredTest(TestCase):
+ def test_tests_are_executed(self):
+ open('test-executed', 'w').close()
diff --git a/tests/tpb04/tox.ini b/tests/tpb04/tox.ini
new file mode 100644
index 0000000..08858b5
--- /dev/null
+++ b/tests/tpb04/tox.ini
@@ -0,0 +1,6 @@
+[tox]
+envlist = py39
+
+[testenv]
+deps = tomli
+commands = python -m unittest discover
diff --git a/tests/tpb05/LICENSE b/tests/tpb05/LICENSE
new file mode 100644
index 0000000..5996299
--- /dev/null
+++ b/tests/tpb05/LICENSE
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/tests/tpb05/Makefile b/tests/tpb05/Makefile
new file mode 100644
index 0000000..b9bc2a5
--- /dev/null
+++ b/tests/tpb05/Makefile
@@ -0,0 +1,19 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py
+ grep -q ^foo/__init__.py, $(DI)/RECORD
+ test ! -f $(DI)/direct_url.json
+ grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD
+ grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control
+ grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control
+ grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control
+ find .pybuild -name test-executed | grep -q test-executed
+ grep -q usr/bin/python3$$ debian/python3-foo/usr/bin/foo
+ find debian/python3-foo/usr/lib/python3/dist-packages/ -name LICENSE | { ! grep -q LICENSE; }
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb05/debian/changelog b/tests/tpb05/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb05/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb05/debian/control b/tests/tpb05/debian/control
new file mode 100644
index 0000000..76f5dbd
--- /dev/null
+++ b/tests/tpb05/debian/control
@@ -0,0 +1,16 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all
+ , python3-poetry-core
+ , python3-pytest
+ , pybuild-plugin-pyproject
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
diff --git a/tests/tpb05/debian/copyright b/tests/tpb05/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb05/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb05/debian/rules b/tests/tpb05/debian/rules
new file mode 100755
index 0000000..4923534
--- /dev/null
+++ b/tests/tpb05/debian/rules
@@ -0,0 +1,28 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build --verbose
+ ../../pybuild --build --verbose
+
+override_dh_auto_install:
+ ../../pybuild --install
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test --test-pytest
+
+override_dh_auto_clean:
+ ../../pybuild --clean --verbose
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb05/debian/source/format b/tests/tpb05/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb05/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb05/foo/__init__.py b/tests/tpb05/foo/__init__.py
new file mode 100644
index 0000000..b3b7945
--- /dev/null
+++ b/tests/tpb05/foo/__init__.py
@@ -0,0 +1,4 @@
+"""An amazing sample package!"""
+
+def main():
+ print("Hello")
diff --git a/tests/tpb05/foo/test_foo.py b/tests/tpb05/foo/test_foo.py
new file mode 100644
index 0000000..bbe6954
--- /dev/null
+++ b/tests/tpb05/foo/test_foo.py
@@ -0,0 +1,6 @@
+from unittest import TestCase
+
+
+class RequiredTest(TestCase):
+ def test_tests_are_executed(self):
+ open('test-executed', 'w').close()
diff --git a/tests/tpb05/pyproject.toml b/tests/tpb05/pyproject.toml
new file mode 100644
index 0000000..cb6ebaa
--- /dev/null
+++ b/tests/tpb05/pyproject.toml
@@ -0,0 +1,17 @@
+[build-system]
+requires = ["poetry>=0.12"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry]
+name = "foo"
+description = "an example module"
+version = "0.1"
+authors = ["Stefano Rivera <stefanor@debian.org>"]
+license = "Expat"
+
+[tool.poetry.dependencies]
+tomli = "^1.0.0"
+importlib-metadata = { version="*", python = "<3.5" }
+
+[tool.poetry.scripts]
+foo = 'foo:main'
diff --git a/tests/tpb05/setup.py b/tests/tpb05/setup.py
new file mode 100644
index 0000000..6593127
--- /dev/null
+++ b/tests/tpb05/setup.py
@@ -0,0 +1,5 @@
+#!/usr/bin/python3
+import sys
+
+sys.stderr.write('setup.py was called. Use pep517 instead.\n')
+sys.exit(1)
diff --git a/tests/tpb06/LICENSE b/tests/tpb06/LICENSE
new file mode 100644
index 0000000..5996299
--- /dev/null
+++ b/tests/tpb06/LICENSE
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/tests/tpb06/Makefile b/tests/tpb06/Makefile
new file mode 100644
index 0000000..285fe83
--- /dev/null
+++ b/tests/tpb06/Makefile
@@ -0,0 +1,20 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+DI=debian/python3-foo/usr/lib/python3/dist-packages/foo-0.1.dist-info
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py
+ grep -q ^foo/__init__.py, $(DI)/RECORD
+ test ! -f $(DI)/direct_url.json
+ grep -L ^foo-0.1.dist-info/direct_url.json, $(DI)/RECORD | grep -q RECORD
+ grep -q 'Depends:.*python3-tomli' debian/python3-foo/DEBIAN/control
+ grep -q 'Depends:.*python3-importlib-metadata \| python3 (>> 3\.5)' debian/python3-foo/DEBIAN/control
+ grep -L 'Depends:.*tox' debian/python3-foo/DEBIAN/control | grep -q control
+ find .pybuild -name test-executed | grep -q test-executed
+ grep -q usr/bin/python3$$ debian/python3-foo/usr/bin/foo
+ find debian/python3-foo/usr/lib/python3/dist-packages/ -name LICENSE | { ! grep -q LICENSE; }
+ test -f debian/python3-foo/usr/share/man/man1/foo.1.gz
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb06/debian/changelog b/tests/tpb06/debian/changelog
new file mode 100644
index 0000000..322011c
--- /dev/null
+++ b/tests/tpb06/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb06/debian/control b/tests/tpb06/debian/control
new file mode 100644
index 0000000..dec1e1f
--- /dev/null
+++ b/tests/tpb06/debian/control
@@ -0,0 +1,15 @@
+Source: foo
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all
+ , python3-setuptools
+ , pybuild-plugin-pyproject
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: any
+Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
diff --git a/tests/tpb06/debian/copyright b/tests/tpb06/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb06/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb06/debian/rules b/tests/tpb06/debian/rules
new file mode 100755
index 0000000..db68934
--- /dev/null
+++ b/tests/tpb06/debian/rules
@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild --build --verbose
+
+override_dh_auto_install:
+ ../../pybuild --install
+
+override_dh_auto_test:
+ ../../pybuild --test
+
+override_dh_auto_clean:
+ ../../pybuild --clean --verbose
+ rm -rf .pybuild foo.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb06/debian/source/format b/tests/tpb06/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb06/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb06/foo/__init__.py b/tests/tpb06/foo/__init__.py
new file mode 100644
index 0000000..b3b7945
--- /dev/null
+++ b/tests/tpb06/foo/__init__.py
@@ -0,0 +1,4 @@
+"""An amazing sample package!"""
+
+def main():
+ print("Hello")
diff --git a/tests/tpb06/foo/ext.c b/tests/tpb06/foo/ext.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tpb06/foo/ext.c
diff --git a/tests/tpb06/foo/test_foo.py b/tests/tpb06/foo/test_foo.py
new file mode 100644
index 0000000..926af30
--- /dev/null
+++ b/tests/tpb06/foo/test_foo.py
@@ -0,0 +1,13 @@
+import os
+from unittest import TestCase
+import subprocess
+
+
+class RequiredTest(TestCase):
+ def test_tests_are_executed(self):
+ open('test-executed', 'w').close()
+
+ def test_entry_point_executed(self):
+ path, _, __ = os.environ['PATH'].partition(":")
+ assert path.endswith("/scripts")
+ subprocess.run('foo', check=True)
diff --git a/tests/tpb06/man/foo.1 b/tests/tpb06/man/foo.1
new file mode 100644
index 0000000..3bf5dce
--- /dev/null
+++ b/tests/tpb06/man/foo.1
@@ -0,0 +1,8 @@
+.TH foo 1 "December 5 2022"
+.SH NAME
+foo \- An example
+.SH SYNOPSIS
+.B foo
+.SH DESCRIPTION
+.B foo
+says hi.
diff --git a/tests/tpb06/pyproject.toml b/tests/tpb06/pyproject.toml
new file mode 100644
index 0000000..9787c3b
--- /dev/null
+++ b/tests/tpb06/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/tests/tpb06/setup.cfg b/tests/tpb06/setup.cfg
new file mode 100644
index 0000000..fbd051b
--- /dev/null
+++ b/tests/tpb06/setup.cfg
@@ -0,0 +1,21 @@
+[metadata]
+name = foo
+version = 0.1
+description = My package description
+long_description = My long description
+license = Expat
+
+[options]
+zip_safe = False
+packages = find:
+install_requires =
+ tomli
+ importlib-metadata; python_version<'3.5'
+
+[options.entry_points]
+console_scripts =
+ foo = foo:main
+
+[options.data_files]
+share/man/man1 =
+ man/foo.1
diff --git a/tests/tpb06/setup.py b/tests/tpb06/setup.py
new file mode 100644
index 0000000..de0d34b
--- /dev/null
+++ b/tests/tpb06/setup.py
@@ -0,0 +1,12 @@
+from setuptools import setup, Extension
+
+setup_args = dict(
+ ext_modules = [
+ Extension(
+ 'foo.ext',
+ ['foo/ext.c'],
+ py_limited_api = True,
+ )
+ ]
+)
+setup(**setup_args)
diff --git a/tests/tpb07/Makefile b/tests/tpb07/Makefile
new file mode 100644
index 0000000..5eb4f00
--- /dev/null
+++ b/tests/tpb07/Makefile
@@ -0,0 +1,11 @@
+#!/usr/bin/make -f
+include ../common.mk
+
+check:
+ test -f debian/python3-foo/usr/lib/python3/dist-packages/foo/__init__.py
+ test -f debian/python3-bar/usr/lib/python3/dist-packages/bar/__init__.py
+ test -f debian/python3-foo/usr/bin/foo
+ test -f debian/python3-bar/usr/bin/bar
+
+clean:
+ ./debian/rules clean
diff --git a/tests/tpb07/bar/LICENSE b/tests/tpb07/bar/LICENSE
new file mode 100644
index 0000000..5996299
--- /dev/null
+++ b/tests/tpb07/bar/LICENSE
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/tests/tpb07/bar/bar/__init__.py b/tests/tpb07/bar/bar/__init__.py
new file mode 100644
index 0000000..717b184
--- /dev/null
+++ b/tests/tpb07/bar/bar/__init__.py
@@ -0,0 +1,4 @@
+"""An amazing sample package!"""
+
+def main():
+ print("Hello I am bar")
diff --git a/tests/tpb07/bar/pyproject.toml b/tests/tpb07/bar/pyproject.toml
new file mode 100644
index 0000000..9787c3b
--- /dev/null
+++ b/tests/tpb07/bar/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/tests/tpb07/bar/setup.cfg b/tests/tpb07/bar/setup.cfg
new file mode 100644
index 0000000..296c419
--- /dev/null
+++ b/tests/tpb07/bar/setup.cfg
@@ -0,0 +1,17 @@
+[metadata]
+name = bar
+version = 0.1
+description = My package description
+long_description = My long description
+license = Expat
+
+[options]
+zip_safe = False
+packages = find:
+install_requires =
+ tomli
+ importlib-metadata; python_version<'3.5'
+
+[options.entry_points]
+console_scripts =
+ bar = bar:main
diff --git a/tests/tpb07/debian/changelog b/tests/tpb07/debian/changelog
new file mode 100644
index 0000000..fa1a4b0
--- /dev/null
+++ b/tests/tpb07/debian/changelog
@@ -0,0 +1,5 @@
+foobar (1.2.3) unstable; urgency=low
+
+ * Initial release
+
+ -- Piotr Ozarowski <piotr@debian.org> Tue, 02 Jul 2013 11:02:06 +0200
diff --git a/tests/tpb07/debian/control b/tests/tpb07/debian/control
new file mode 100644
index 0000000..6631581
--- /dev/null
+++ b/tests/tpb07/debian/control
@@ -0,0 +1,21 @@
+Source: foobar
+Section: python
+Priority: optional
+Maintainer: Piotr Ożarowski <piotr@debian.org>
+Build-Depends: debhelper-compat (= 12)
+ , python3-all
+ , python3-setuptools
+ , pybuild-plugin-pyproject
+Standards-Version: 3.9.4
+
+Package: python3-foo
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #1
+
+Package: python3-bar
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Description: package with public CPython modules
+ example package #2
diff --git a/tests/tpb07/debian/copyright b/tests/tpb07/debian/copyright
new file mode 100644
index 0000000..f96adde
--- /dev/null
+++ b/tests/tpb07/debian/copyright
@@ -0,0 +1,2 @@
+The Debian packaging is © 2013, Piotr Ożarowski <piotr@debian.org> and
+is licensed under the MIT License.
diff --git a/tests/tpb07/debian/rules b/tests/tpb07/debian/rules
new file mode 100755
index 0000000..b93abef
--- /dev/null
+++ b/tests/tpb07/debian/rules
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+
+export PYBUILD_NAME=foo
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ ../../pybuild -d foo --build --verbose --name=foo
+ ../../pybuild -d bar --build --verbose --name=bar
+
+override_dh_auto_install:
+ ../../pybuild -d foo --install --name=foo
+ ../../pybuild -d bar --install --name=bar
+
+override_dh_auto_test:
+ ../../pybuild -d foo --test --name=foo
+ ../../pybuild -d bar --test --name=bar
+
+override_dh_auto_clean:
+ ../../pybuild -d foo --clean --verbose --name=foo
+ ../../pybuild -d bar --clean --verbose --name=bar
+ rm -rf .pybuild foo/foo.egg-info bar/bar.egg-info
+
+override_dh_installinit:
+ DH_VERBOSE=1 ../../dh_python3
+ dh_installinit
+
+override_dh_python3:
+ # ignore any system dh_python3
diff --git a/tests/tpb07/debian/source/format b/tests/tpb07/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/tests/tpb07/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/tests/tpb07/foo/LICENSE b/tests/tpb07/foo/LICENSE
new file mode 100644
index 0000000..5996299
--- /dev/null
+++ b/tests/tpb07/foo/LICENSE
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/tests/tpb07/foo/foo/__init__.py b/tests/tpb07/foo/foo/__init__.py
new file mode 100644
index 0000000..1421a55
--- /dev/null
+++ b/tests/tpb07/foo/foo/__init__.py
@@ -0,0 +1,4 @@
+"""An amazing sample package!"""
+
+def main():
+ print("Hello I am foo")
diff --git a/tests/tpb07/foo/pyproject.toml b/tests/tpb07/foo/pyproject.toml
new file mode 100644
index 0000000..9787c3b
--- /dev/null
+++ b/tests/tpb07/foo/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/tests/tpb07/foo/setup.cfg b/tests/tpb07/foo/setup.cfg
new file mode 100644
index 0000000..3447fdc
--- /dev/null
+++ b/tests/tpb07/foo/setup.cfg
@@ -0,0 +1,17 @@
+[metadata]
+name = foo
+version = 0.1
+description = My package description
+long_description = My long description
+license = Expat
+
+[options]
+zip_safe = False
+packages = find:
+install_requires =
+ tomli
+ importlib-metadata; python_version<'3.5'
+
+[options.entry_points]
+console_scripts =
+ foo = foo:main