Skip to content


Cleaner minimum version comparison #1028

merged 3 commits into from

5 participants


Cleaner minimum version comparison using setuptools to reduce chance of breakage (0.11 broke with pyzmq 2.1.10)


I don't think we want to depend on setuptools at runtime. It looks like distutils (which is in the standard library) has tools for doing this - have a look at distutils.version.


That is reasonable, but just as a note: I did need to install setuptools on windows for IPython to start up.


To actually start it, or to install it? I know we require setuptools to install from source on Windows (although I don't know why). I think if we need it to start, that's a bug, but there might be some windows specific thing I don't know about.


setuptools and its spawn have the feature to create .exe files on Windows for the scripts so they can be executed from the command line. This is too useful to avoid the setuptools install-time dependency. The auxiliary scripts it creates uses its pkg_resources module to locate the actual script. Avoiding that runtime dependency is tricky. But nothing else in IPython should depend on setuptools.


Yes, to start it. I installed using the binary installer for Windows. On startup complained that "ImportError: No module named pkg_resources".


Fair enough. So setuptools is a dependency on Windows, but needn't be elsewhere. For similar reasons, distribute (the successor to setuptools) is required on Python 3 for the time being.


Only one line needs to be changed to do what you suggested: from pkg_resources import parse_version as V to from distutils.version import LooseVersion as V. I am not sure how to change this. This is my first time on GitHub, or any other similar site. I am sorry if my pull-request reaction to IPython 0.11 not working with the latest stable ZMQ (2.1.10) was too hasty (as it probably was). Please close this request if it is inappropriate.


Don't worry, it's OK. We've actually already fixed the issue with 2.1.10, but I think it's better to use standard functionality for this rather than splitting version numbers up ourselves.

If you're using git on your own computer, just make another commit and push it back to github - the pull request automatically updates. If you are editing directly on Github, go to your copy of the file here and click the "Edit this File" button.


Yes, this is definitely better than mine, I just didn't know about this function. Thanks for fixing it.

I should note that unfortunately this will not work on Python 3 for users of pyzmq-dev:

from distutils.version import LooseVersion as V
V('2.1dev') > V('2.1.4') # ultimately [2,1,'dev'] > [2,1,4]
TypeError: unorderable types: str() < int()

So the check should be if 'dev' not in pyzmq_version and V(pyzmq_version) < V(minimum_version):, to prevent evaluating the invalid comparison.

re: setuptools

setuptools is considered a temporary install and runtime dependency on Windows (installing with setuptools makes scripts that depend on itself), because during the major reorganization of 0.11 our Windows install voodoo broke, and we didn't have the time or interest to fix it, and just punted to setuptools. We do intend to remove this dependency (see #539), but it is probably going to take an actual Windows user/developer (of which there are zero on the IPython team) to do it.


I'm surprised that's not accounted for - LooseVersion seems pretty useless without it.


All LooseVersion does is turn a version string into a list of the contiguous number or letter blobs ('2.10.4b5-dev' -> (2,10,4,'b',5,'dev')). It doesn't do anything clever in the comparison, it just compares the lists.

The decision to remove str/int comparison in Python 3 seems a very bad one, to me.

pyzmq 2.1.10 skirts this issue itself by adding a pyzmq_version_info() function for returning a tuple of numbers, turning 'dev' into inf, so it can always be used in comparisons.


Just to confirm/clarify re. setuptools: we accepted it as a dependency on windows for the reasons Robert pointed out, but that's it. Setuptools will never be a runtime dependency for ipython, and it will never be a dependency, period, on linux.


BTW, @minrk and @takluyver, I'll leave the merge of this one to you guys, since you've already looked at it more than I did. I just wanted to clarify the setuptools question for the OP (thanks, BTW, @szhorvat! :)


Looks perfect, thanks @szhorvat!


OK, since this has @minrk's and @takluyver's review, I'm merging it so we keep our queue moving along... Thanks everyone!

@fperez fperez merged commit f19b131 into ipython:master
@fperez fperez referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 22, 2011
  1. @szhorvat

    Cleaner minimum version comparison using setuptools to reduce chance …

    szhorvat committed
    …of breakage (0.11 broke with pyzmq 2.1.10)
  2. @szhorvat
Commits on Nov 23, 2011
  1. @szhorvat
This page is out of date. Refresh to see the latest.
Showing with 4 additions and 7 deletions.
  1. +4 −7 IPython/zmq/
11 IPython/zmq/
@@ -9,21 +9,18 @@
# Verify zmq version dependency >= 2.1.4
-import re
import warnings
+from distutils.version import LooseVersion as V
def check_for_zmq(minimum_version, module='IPython.zmq'):
- min_vlist = [int(n) for n in minimum_version.split('.')]
import zmq
except ImportError:
raise ImportError("%s requires pyzmq >= %s"%(module, minimum_version))
pyzmq_version = zmq.__version__
- vlist = [int(n) for n in re.findall(r'\d+', pyzmq_version)]
- if 'dev' not in pyzmq_version and vlist < min_vlist:
+ if 'dev' not in pyzmq_version and V(pyzmq_version) < V(minimum_version):
raise ImportError("%s requires pyzmq >= %s, but you have %s"%(
module, minimum_version, pyzmq_version))
@@ -33,7 +30,7 @@ def check_for_zmq(minimum_version, module='IPython.zmq'):
if not hasattr(zmq, 'ROUTER'):
zmq.ROUTER = zmq.XREP
- if zmq.zmq_version() >= '4.0.0':
+ if V(zmq.zmq_version()) >= V('4.0.0'):
warnings.warn("""libzmq 4 detected.
It is unlikely that IPython's zmq code will work properly.
Please install libzmq stable, which is 2.1.x or 2.2.x""",
Something went wrong with that request. Please try again.