Merge ppa-dev-tools:packaging-drop-setup-py into ppa-dev-tools:main

Proposed by Bryce Harrington
Status: Merged
Merged at revision: dbb03eaf49059a2416cdccf5db88f1effe5db7ff
Proposed branch: ppa-dev-tools:packaging-drop-setup-py
Merge into: ppa-dev-tools:main
Diff against target: 190 lines (+31/-79)
5 files modified
INSTALL.md (+6/-6)
TESTING.md (+11/-2)
dev/null (+0/-67)
pyproject.toml (+9/-1)
tox.ini (+5/-3)
Reviewer Review Type Date Requested Status
Athos Ribeiro (community) Approve
Mitchell Dzurick (community) Approve
PpaDevTools Developers Pending
Canonical Server packageset reviewers Pending
Canonical Server Reporter Pending
Review via email: mp+464714@code.launchpad.net

Description of the change

Updates the packaging to resolve some deprecation warnings.

The bug that prompted this is LP: #2055636, and I believe this should resolve that issue by finishing the move away from setup.py, but am not sure how to 100% repro their installation approach. However, it does fix the deprecation issues I'm aware of when following the "SOURCE" section in INSTALL.md. I've not tested this exhaustively yet so there could well be a few more adjustments needed.

This also resolves the older LP: #1989617 by using the `build` packaging system with setuptools. I looked at `hatch` and `poetry` but didn't spot advantages to them that I'd need, and `build` feels like it will be more supportable on Ubuntu systems.

To post a comment you must log in.
Revision history for this message
Mitchell Dzurick (mitchdz) wrote :

comment inline

Revision history for this message
Bryce Harrington (bryce) wrote :

Thanks Mitchell, that was a good note. I did reproduce that issue on noble too, and I've been tinkering with different installation techniques, and trying to research into best practices. The latter didn't reveal anything amazing, but with the former I've found that using '--no-deps' seems to achieve the goal I was going for (installing the package with dependencies satisfied by only distro-provided packages). See if that works for you.

I'm also tempted to add a 'make install' target that hides the mechanics and have the INSTALL directions reduce to just 'make build; sudo make install'. Totally doable, but I consider that most people are not going to be installing that way but rather using the PPA package, the snap, or pip. So people who *do* install this way will by definition be wanting a more flexible and hands-on approach so knowing the options may be more interesting. Open to more ideas/opinions on this.

I've also added python3-build and python3-pip as dependencies in the INSTALL docs, since testing in a raw LXC container seemed to need them. But I'm not 100% sure they are, so would also appreciate a doublecheck on that.

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks, Bryce!

This looks good. I do have a couple comments inline below.

Revision history for this message
Bryce Harrington (bryce) wrote :

Thanks for the feedback, I've updated with the suggested changes.

Revision history for this message
Mitchell Dzurick (mitchdz) wrote (last edit ):

`python3 -m pip install --no-deps .` still produces the issue in my noble VM. The issue ultimately is because of the following doc: https://packaging.python.org/en/latest/specifications/externally-managed-environments/#externally-managed-environments .

Ultimately the "proper" fix for this is to use a venv:

python3 -m venv .venv
source .venv/bin/activate
pip install .

But that doesn't install it system-wide of course.

Anyways, I think it is fine to keep as-is due to most people will be consuming this package from the snap. Anyone doing it manually should understand the consequences and add that flag. Just add a note in INSTALL.md that you may see it.

Revision history for this message
Mitchell Dzurick (mitchdz) :
review: Approve
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

My personal workflow is also `virtualenv` oriented TBH (although I use an additional abstraction layer through mkvirtualenv). This is how I usually test, review, and use ppa-dev-tools.

The most interesting bit here is to balance between using development dependencies from the archive or from the system (we know pypi does not have all the needed dependencies).

Since this is designed to be used with the archive's dependencies, I suppose a future improvement would be to have a test matrix to test the package with the runtime dependencies of each supported Ubuntu release.

This is already a great improvement though and definitely LGTM!

review: Approve
Revision history for this message
Bryce Harrington (bryce) wrote :

Thanks for the reviews!

In thinking about this a bit more, the reason I'm partial to documenting how to install without PIP is less about ease use but to facilitate packaging this into a deb for the PPA, to catch any dependencies (or versions) that wouldn't be available from the archive.

However, that doesn't mean that additional directions couldn't be included, after all the INSTALL doc is already a catalog of different approaches, why not include one more if users are actually using it?

So, I'd like to include the venv+pip-based approach, perhaps either in the PIP section or right after it. However, I'm curious how you two are doing your test installations, since for me it appears to be not pulling in the dependencies properly. So far I've got this for documentation:

"""
Or to install from the source checkout locally with PIP-provided
dependencies in a virtual environment:

  $ python3 -m venv .venv
  $ source .venv/bin/activate
  (.venv)$ pip install addict distro_info lazr lazr.restfulclient ruamel.yaml yapf
  (.venv)$ pip install .
  (.venv)$ ppa --version
  ppa 0.5.0
"""

However, this still complains about missing the apt_pkg dependency. More importantly though, why is this not automatically detecting the dependencies? Have I broken it by removing setup.py, or is there an extra step missing?

I'll go ahead and land this branch as-is without this, and then add this once it's working for me.

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Hi Bryce, I usually go for virtual environments for most python projects I work with, this included. Since some of the dependencies are not available through PyPI, as you already pointed out, I install a virtual environment with access to my system's installed python packages.

The following should be enough to get it up to a functional states and with tests passing:

$ mkvirtualenv --system-site-packages ppa-dev-tools
$ pip install -r requirements-dev.txt
$ pip install -e .
$ pip install mock
$ python -m pytest tests
$ ppa --help

Note that I had to install mock manually (probably missing from the dev requirements).

Also, note that the current Makefile is not fully compatible with virtual environments given how the binaries are being called.

To Stop using the virtual environment:
$ deactivate

To enable (and then disable it again:
$ workon ppa-dev-tools
$ deactivate

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/INSTALL.md b/INSTALL.md
2index e1fd232..03d61cd 100644
3--- a/INSTALL.md
4+++ b/INSTALL.md
5@@ -48,19 +48,19 @@ On Ubuntu 20.04 and similar systems, prerequisites can be satisfied from
6 the apt repository:
7
8 $ sudo apt-get install \
9+ python3-build \
10 python3-appdirs \
11 python3-debian \
12 python3-distro-info \
13 python3-launchpadlib \
14 python3-lazr.restfulclient \
15- python3-setuptools \
16 python3-software-properties \
17- python3-yaml
18+ python3-yaml \
19+ python3-pip
20
21-Installation follows the usual python conventions:
22+Installation is performed as follows:
23
24- $ python3 ./setup.py check
25- $ python3 ./setup.py build
26- $ sudo python3 ./setup.py install
27+ $ python3 -m build --no-isolation
28+ $ sudo python3 -m pip install --no-deps .
29 $ ppa --version
30 ppa 0.5.0
31diff --git a/TESTING.md b/TESTING.md
32index a81966e..6e1e80e 100644
33--- a/TESTING.md
34+++ b/TESTING.md
35@@ -2,9 +2,18 @@
36
37 For running the testsuite:
38
39-$ sudo apt install -y python3-pytest python3-mock
40+$ sudo apt install -y \
41+ python3-pytest \
42+ python3-mock \
43+ python3-flake8 \
44+ python3-coverage
45
46
47 ## Testing
48
49-$ python3 setup.py check
50+$ make check
51+
52+or
53+
54+$ pytest-3
55+
56diff --git a/pyproject.toml b/pyproject.toml
57index 3b1ce9a..d4efadb 100644
58--- a/pyproject.toml
59+++ b/pyproject.toml
60@@ -2,6 +2,14 @@
61 requires = ["setuptools >= 40.6.0", "wheel"]
62 build-backend = "setuptools.build_meta"
63
64+[tool.setuptools]
65+script-files = ["scripts/ppa"]
66+
67+[tool.setuptools.packages.find]
68+where = ["."]
69+include = ["ppa"]
70+exclude = ["snap", "debian"]
71+
72 [tool.towncrier]
73 filename = "CHANGELOG.md"
74 package = "ppa-dev-tools"
75@@ -31,4 +39,4 @@ classifiers = [
76
77 [project.urls]
78 "Homepage" = "https://launchpad.net/ppa-dev-tools"
79-"Bug Tracker" = "https://bugs.launchpad.net/ppa-dev-tools"
80\ No newline at end of file
81+"Bug Tracker" = "https://bugs.launchpad.net/ppa-dev-tools"
82diff --git a/setup.py b/setup.py
83deleted file mode 100755
84index 2f1dee0..0000000
85--- a/setup.py
86+++ /dev/null
87@@ -1,67 +0,0 @@
88-#!/usr/bin/env python3
89-# -*- coding: utf-8 -*-
90-#
91-# ppa - Tools for creating, installing, modifying, and testing PPAs.
92-#
93-# Copyright (c) 2012,2019-2022 - Bryce W. Harrington
94-
95-from setuptools import setup, find_packages
96-
97-import sys
98-import re
99-
100-if sys.version_info < (3,0):
101- sys.exit('Please run setup.py with python3')
102-
103-def get_version(package):
104- """Directly retrieve version, avoiding an import.
105-
106- Since setup.py runs before the package is set up, we can't expect
107- that simply doing an import ._version will work reliably in all
108- cases. Instead, manually import the version from the file here,
109- and then the module can be imported elsewhere in the project easily.
110- """
111- version_file = "%s/%s" %(package, '_version.py')
112- version_string = open(version_file, "rt").read()
113- re_version = r"^__version__ = ['\"]([^'\"]*)['\"]"
114- m = re.search(re_version, version_string, re.M)
115- if not m:
116- raise RuntimeError("Unable to find version string for %s in %s." %(
117- package, version_file))
118- return m.group(1)
119-
120-def get_description():
121- return open('README.md', 'rt').read()
122-
123-setup(
124- name = 'ppa-dev-tools',
125- version = get_version('ppa'),
126- url = 'https://launchpad.net/ppa-dev-tools',
127- author = 'Bryce W. Harrington',
128- author_email = 'bryce@canonical.com',
129- description = 'Utility for interacting with PPAs on Launchpad',
130- long_description = get_description(),
131- classifiers = [
132- # See https://pypi.org/pypi?%3Aaction=list_classifiers
133- 'Development Status :: 3 - Alpha',
134- 'Intended Audience :: Information Technology',
135- 'Topic :: Software Development :: Build Tools',
136- 'Topic :: System :: Archiving :: Packaging',
137- 'Topic :: System :: Software Distribution',
138- 'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
139- 'Programming Language :: Python :: 3',
140- ],
141- platforms = ['any'],
142- python_requires = '>=3',
143- setup_requires = [
144- 'pytest-runner'
145- ],
146- tests_require = [
147- 'pytest'
148- ],
149- install_requires = [], # See INSTALL.md
150- scripts = ['scripts/ppa'],
151- packages = find_packages(),
152- package_data = { },
153- data_files = [ ],
154-)
155diff --git a/tox.ini b/tox.ini
156index 5e56ea0..58fa3a8 100644
157--- a/tox.ini
158+++ b/tox.ini
159@@ -2,26 +2,28 @@
160 envlist = flake8, pylint, pytest
161 recreate = true
162 skipsdist = true
163+sitepackages = True
164
165 [testenv:flake8]
166 deps =
167 flake8
168 flake8-docstrings
169-commands = flake8 ppa tests setup.py
170+commands = flake8 ppa tests
171
172 [testenv:pylint]
173 deps =
174 pylint
175 pytest
176 commands =
177- pylint --max-line-length=100 ppa tests setup.py
178+ pylint --max-line-length=100 ppa tests
179
180 [testenv:pytest]
181 deps =
182 pytest
183 pytest-cov
184+ mock
185 commands =
186- py.test --cov ppa tests
187+ python3 -m pytest --cov ppa tests
188
189 [flake8]
190 max-line-length = 100

Subscribers

People subscribed via source and target branches

to all changes: