After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 767988 - Allow installing with pip
Allow installing with pip
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2016-06-23 21:29 UTC by Mathieu Bridon
Modified: 2017-12-04 15:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Allow installing with pip (3.24 KB, patch)
2016-06-23 21:29 UTC, Mathieu Bridon
none Details | Review
Allow installing with pip (3.56 KB, patch)
2016-06-23 21:38 UTC, Mathieu Bridon
none Details | Review
Allow installing with pip (4.21 KB, patch)
2016-06-29 09:53 UTC, Mathieu Bridon
needs-work Details | Review
Allow installing with pip (4.21 KB, patch)
2016-06-29 09:55 UTC, Mathieu Bridon
none Details | Review
Allow installing with pip (4.29 KB, patch)
2016-06-29 10:57 UTC, Mathieu Bridon
committed Details | Review

Description Mathieu Bridon 2016-06-23 21:29:37 UTC
This commit adds a setup.py file which just calls the autotools to
configure/make/make install.
    
It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 1 Mathieu Bridon 2016-06-23 21:29:41 UTC
Created attachment 330280 [details] [review]
Allow installing with pip

This commit adds a setup.py file which just calls the autotools to
configure/make/make install.

It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 2 Mathieu Bridon 2016-06-23 21:37:52 UTC
To try this out, I've pushed it to a temporary github repo https://github.com/bochecha/pygobject in the pip-install branch.

This allows installing pygobject with pip:

  pip install git+https://github.com/bochecha/pygobject.git@pip-install#egg=pygobject

This same URL could be put in a requirements.txt file, as is usual for Python developers.

Of course, I won't keep this repository, I just made it for testing tonight. :)

If that patch was merged in pygobject, then Python developers could also install from a release tarball, for example:

  pip install pip install pygobject-3.21.1.tar.xz

This opens the door to installing pygobject in virtual environments.
Comment 3 Mathieu Bridon 2016-06-23 21:38:33 UTC
Created attachment 330281 [details] [review]
Allow installing with pip

This commit adds a setup.py file which just calls the autotools to
configure/make/make install.

It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 4 Mathieu Bridon 2016-06-23 21:40:00 UTC
In the first patch, I had forgotten to add the new setup.py file to the dist, sorry for all the mail.

One thing missing from this patch is to not hardcode the version in setup.py, but instead take it from configure.ac where it is defined.

Not sure what's the best option here, any idea?
Comment 5 Bastien Nocera 2016-06-23 23:15:37 UTC
(In reply to Mathieu Bridon from comment #4)
> In the first patch, I had forgotten to add the new setup.py file to the
> dist, sorry for all the mail.
> 
> One thing missing from this patch is to not hardcode the version in
> setup.py, but instead take it from configure.ac where it is defined.
> 
> Not sure what's the best option here, any idea?

Create a setup.py.in that you'll use to generate setup.py, and replace the hardcoded version with @VERSION@.

You might want to check in a generated version of setup.py too, if being able to install from git is planned, otherwise it's fine as-is.
Comment 6 Mathieu Bridon 2016-06-27 09:38:31 UTC
> if being able to install from git is planned,

Installing from git is very much desirable.

In fact, the only reason I created that « fork » on Github is so I could test that it works (see the command I listed in a previous command). I have no desire to actually fork pygobject, this was purely for testing purpose. :)

However, checking in git a generated setup.py file means there is a risk it could get stale, with an old version from back when it was generated.

So I'm not sure that's a good solution. :-/
Comment 7 Bastien Nocera 2016-06-27 10:02:28 UTC
(In reply to Mathieu Bridon from comment #6)
> > if being able to install from git is planned,
> 
> Installing from git is very much desirable.
> 
> In fact, the only reason I created that « fork » on Github is so I could
> test that it works (see the command I listed in a previous command). I have
> no desire to actually fork pygobject, this was purely for testing purpose. :)
> 
> However, checking in git a generated setup.py file means there is a risk it
> could get stale, with an old version from back when it was generated.

Not if we automate the creation, so that running "make distcheck" will update the file automatically, or even having the release creation fail if the version change in the file isn't checked in.

> So I'm not sure that's a good solution. :-/
Comment 8 Christoph Reiter (lazka) 2016-06-27 10:36:45 UTC
Or the hacky way:

import re
with open("configure.ac", "r") as h:
    version = ".".join(re.findall("pygobject_[^\s]+_version,\s*(\d+)\)", h.read()))
Comment 9 Bastien Nocera 2016-06-27 10:44:07 UTC
(In reply to Christoph Reiter (lazka) from comment #8)
> Or the hacky way:
> 
> import re
> with open("configure.ac", "r") as h:
>     version = ".".join(re.findall("pygobject_[^\s]+_version,\s*(\d+)\)",
> h.read()))

That could work, I don't know how exactly pip downloads and unpacks things. Mathieu, want to try that out?
Comment 10 Mathieu Bridon 2016-06-27 12:17:15 UTC
(In reply to Bastien Nocera from comment #9)
> I don't know how exactly pip downloads and unpacks things.

It gets the sources (download+extract tarball, clone git, ...) then simply runs the `setup.py` script passing it the `install` argument.

(In reply to Christoph Reiter (lazka) from comment #8)
> Or the hacky way:
> 
> import re
> with open("configure.ac", "r") as h:
>     version = ".".join(re.findall("pygobject_[^\s]+_version,\s*(\d+)\)",
> h.read()))

That indeed works just fine.

The reason I didn't do anything like this in the original patch is that there are a number of ways to do it, each more hacky than the other, and with different trade-offs, so I wanted to start a discussion on what upstream would prefer. :)

This one is a bit fragile, in that if the configure.ac syntax to declare the version changes (new order, new variable names, ...) then getting the version in this way will get something entirely incorrect and silently proceed with the installation.

Not sure that's too big a problem though. What do you think?
Comment 11 Bastien Nocera 2016-06-27 12:28:15 UTC
(In reply to Mathieu Bridon from comment #10)
> (In reply to Bastien Nocera from comment #9)
> > I don't know how exactly pip downloads and unpacks things.
> 
> It gets the sources (download+extract tarball, clone git, ...) then simply
> runs the `setup.py` script passing it the `install` argument.
> 
> (In reply to Christoph Reiter (lazka) from comment #8)
> > Or the hacky way:
> > 
> > import re
> > with open("configure.ac", "r") as h:
> >     version = ".".join(re.findall("pygobject_[^\s]+_version,\s*(\d+)\)",
> > h.read()))
> 
> That indeed works just fine.
> 
> The reason I didn't do anything like this in the original patch is that
> there are a number of ways to do it, each more hacky than the other, and
> with different trade-offs, so I wanted to start a discussion on what
> upstream would prefer. :)
> 
> This one is a bit fragile, in that if the configure.ac syntax to declare the
> version changes (new order, new variable names, ...) then getting the
> version in this way will get something entirely incorrect and silently
> proceed with the installation.
> 
> Not sure that's too big a problem though. What do you think?

Add a "check:" target in the Makefile.am that would fail if the version set by configure.ac isn't the same as computed by that above code?
Comment 12 Christoph Reiter (lazka) 2016-06-29 08:39:25 UTC
Review of attachment 330281 [details] [review]:

doing setup.py build install creates "build/", "dist/", "pygobject.egg-info/". These should be added to .gitignore.

Otherwise works as advertised.

::: setup.py
@@ +1,1 @@
+import os

Making it executable and adding a shebang would be nice

@@ +10,3 @@
+
+# TODO: Get this from configure.ac
+version = '3.21.1'

See previous discussion

@@ +20,3 @@
+        srcdir = os.getcwd()
+        builddir = os.path.join(srcdir, self.build_temp)
+        os.makedirs(builddir, exist_ok=True)

This fails with python2 here
Comment 13 Mathieu Bridon 2016-06-29 09:53:15 UTC
Created attachment 330540 [details] [review]
Allow installing with pip

This commit adds a setup.py file which just calls the autotools to
configure/make/make install.

It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 14 Mathieu Bridon 2016-06-29 09:55:19 UTC
Created attachment 330541 [details] [review]
Allow installing with pip

This commit adds a setup.py file which just calls the autotools to
configure/make/make install.

It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 15 Mathieu Bridon 2016-06-29 09:56:26 UTC
Thanks for the review Christoph, the patch I just attached fixes the issues you mentioned.

For the version, I went with your regex-based solution.

As we discussed on IRC, let's not worry too much about the relative fragility of these 2 lines. (it's not very likely that configure.ac would change how the version is declared, and we can fix it if it ever does)
Comment 16 Bastien Nocera 2016-06-29 09:57:31 UTC
Review of attachment 330540 [details] [review]:

::: Makefile.am
@@ +25,3 @@
 	m4/jhflags.m4 \
+	m4/python.m4 \
+	setup.py

This is missing a "check" target, something which would look like:

check:
        $(AM_V_GEN) $(builddir)/test-version.py

Modify configure.ac to have test-version.py in the AC_OUTPUT.
And add a test-version.py.in which has something like:

#!/bin/python

import re
	with open("configure.ac", "r") as h:
	    version = ".".join(re.findall("pygobject_[^\s]+_version,\s*(\d+)\)", h.read()))

if version != @VERSION@:
      print (stderr, "Versions do not match, setup.py needs updating")
      sys.exit(1)

(I'll claim that's pseudo-code, it's just me not being used to Python)
Comment 17 Bastien Nocera 2016-06-29 09:58:44 UTC
(In reply to Bastien Nocera from comment #16)
> Review of attachment 330540 [details] [review] [review]:
<snip>
> check:

Make that:
check: test-version.py configure.ac

>         $(AM_V_GEN) $(builddir)/test-version.py

Rest still applies.
Comment 18 Christoph Reiter (lazka) 2016-06-29 09:59:59 UTC
Review of attachment 330541 [details] [review]:

::: setup.py
@@ +30,3 @@
+        raise
+os._real_makedirs = os.makedirs
+os.makedirs = makedirs

Please don't monkey patch os.makedirs that way. This would break any code passing a mode to makedirs and we don't know if distutils/setuptools might do that.
Just call your custom makedirs below.
Comment 19 Christoph Reiter (lazka) 2016-06-29 10:14:49 UTC
(In reply to Bastien Nocera from comment #16)
> Review of attachment 330540 [details] [review] [review]:
> 
> ::: Makefile.am
> @@ +25,3 @@
>  	m4/jhflags.m4 \
> +	m4/python.m4 \
> +	setup.py
> 
> This is missing a "check" target, something which would look like:

We discussed on IRC and decided to leave that for now. I hope that's OK.
Comment 20 Mathieu Bridon 2016-06-29 10:57:55 UTC
Created attachment 330554 [details] [review]
Allow installing with pip

This commit adds a setup.py file which just calls the autotools to
configure/make/make install.

It is heavily inspired by the similar work from Simon McVittie on
dbus-python.
Comment 21 Mathieu Bridon 2016-07-04 09:17:26 UTC
Anything else I can do with this patch?
Comment 22 Christoph Reiter (lazka) 2016-07-06 06:29:48 UTC
Review of attachment 330554 [details] [review]:

lgtm
Comment 23 Mathieu Bridon 2016-07-06 07:24:24 UTC
Attachment 330554 [details] pushed as f65bb1f - Allow installing with pip
Comment 24 Christoph Reiter (lazka) 2017-12-04 15:30:40 UTC
I've added a setuptools based setup.py in bug 789211. Posting here in case anyone would like to add anything there.