5

The problem

I wanted to include requirement for pytz in setup.py script in my library, but wanted also to set the minimal version required. But the version numbers used by pytz module (eg. "2012f") seem to be incompatible with what distutils wants to be provided (eg. "1.1.3").

Is there any way to include requirement for specific version of pytz (eg. >=2012f) without altering pytz or distutils?

Details

To do that I did something like that in setup.py file:

setup(
    # ... basic data here ...
    requires=[
        'pytz (>=2012f)',
    ],
    # ... some other data here ...
)

But when I was doing sudo python setup.py install, the following error appeared:

Traceback (most recent call last):
  File "setup.py", line 25, in <module>
    long_description=long_description,
  File "/usr/lib/python2.7/distutils/core.py", line 112, in setup
    _setup_distribution = dist = klass(attrs)
  File "/usr/lib/python2.7/distutils/dist.py", line 259, in __init__
    getattr(self.metadata, "set_" + key)(val)
  File "/usr/lib/python2.7/distutils/dist.py", line 1220, in set_requires
    distutils.versionpredicate.VersionPredicate(v)
  File "/usr/lib/python2.7/distutils/versionpredicate.py", line 115, in __init__
    self.pred = [splitUp(aPred) for aPred in str.split(",")]
  File "/usr/lib/python2.7/distutils/versionpredicate.py", line 25, in splitUp
    return (comp, distutils.version.StrictVersion(verStr))
  File "/usr/lib/python2.7/distutils/version.py", line 40, in __init__
    self.parse(vstring)
  File "/usr/lib/python2.7/distutils/version.py", line 107, in parse
    raise ValueError, "invalid version number '%s'" % vstring
ValueError: invalid version number '2012f'

Seemingly the issue is caused by distutils trying to match this regular expression:

version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
                        re.VERBOSE)

and when it does not match, the above error is raised.

I have seen people altering the source code of pytz (to change the version into something more like 2012.6), but it looks like extremely bad idea to me. I hope there is another way that I missed.

Changing pytz (>=2012f) into pytz works, but it then does not limit the requirement to specific version of pytz module.

Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • 1
    you could use `install_requires='pytz >= 2012f'` from setuptools/distribute. distutils ignores this option (issues a warning, you could include the option conditionally). anyway `distutils` doesn't install dependencies. `pip install` uses setuptools/distribute so it will pull dependencies automatically. btw, don't use `sudo python setup.py install` there is no uninstall option (pip has uninstall command. also use virtualenv for the installation testing). – jfs Oct 17 '12 at 06:17
  • Yes, don’t use requires. There is an open bug to make the Python doc warn against these unused fields (requires, provides and obsoletes). Right now you have to use third-party tools like pip, setuptools or buildout to declare your dependencies, and in the future the new standard (requires-dist) will be supported by the tools. – merwok Oct 17 '12 at 17:02
  • @ÉricAraujo: I need to somehow distribute private module ("_moduleA_") to some private projects (lets say one is called "_projectB_"). Current approach is to use `requirements.txt` file within "projectB" and include something like "`git+ssh://github.com/myName/moduleA`" in it, then install every dependency in the project using `pip install -r requirements.txt`. How can I ensure that dependencies will also be installed? By changing requires into install_requires? Or by using slightly different approach? I would be grateful for advice on what to choose. – Tadeck Oct 17 '12 at 23:06
  • @J.F.Sebastian: What do you think about my [previous comment](http://stackoverflow.com/questions/12926052/providing-pytz-version-in-setup-py-requirements#comment17546368_12926052)? Will `pip install -r requirements.txt` handle dependencies in current form, if I will include path to private Git repository? If not, what could I change? – Tadeck Oct 18 '12 at 13:19
  • @Tadeck: install_requires says to pip what dependencies to install, but not where to find them. There is dependency_links setuptools option but requirements.txt might be more convient for that (to allow installing the same package from different places e.g., stable vs. dev). You need `#egg...` in the link – jfs Oct 18 '12 at 17:22
  • @J.F.Sebastian: Yes, actually the link to private repository is placed within some outer project, and has the exact location. The setup.py script is however meant to be available within this location (private git repo) and is meant to tell the installer (pip) what other modules it needs to install in order to make the whole thing work. I will change "requires" kwarg into "install_requires" then. Thanks. Would you like to post your comment as an answer? I will accept it if it works. – Tadeck Oct 18 '12 at 17:43

1 Answers1

2

Using install_requires setuptools option:

setup(
    # ... basic data here ...
    install_requires='pytz>=2012f', # distutils ignores it with a warning, pip uses it
    # ... some other data here ...
)
jfs
  • 399,953
  • 195
  • 994
  • 1,670