10

I am trying to make use of PEP 496 -- Environment Markers and PEP 508 -- Dependency specification for Python Software Packages by specifying dependencies that only make sense on specific OS.

My setup.py looks like this:

import setuptools
assert setuptools.__version__ >= '36.0'

setuptools.setup()

My minimal setup.cfg looks like this:

[metadata]
name = foobar
version = 1.6.5+0.1.0

[options]
packages = find:

install_requires =
    ham >= 0.1.0
    eggs >= 8.1.2
    spam >= 1.2.3; platform_system=="Darwin"
    i-love-spam >= 1.2.0; platform_system="Darwin"

However, when trying to install such a package with pip install -e foobar/, it fails with:

pip._vendor.pkg_resources.RequirementParseError: Invalid requirement, parse error at "'; platfo'"

I guess it does not expect semicolon there. But how am I supposed to use environment markers then?

toriningen
  • 7,196
  • 3
  • 46
  • 68
  • I'm rather surprised you got that far... I always thought `install_requires` was an argument to `setup()`, not a command-line flag. – Kevin Jul 03 '17 at 05:42
  • @Kevin It's not command-line flag either — it's inside of `setup.cfg`, which is another source of confusion (https://stackoverflow.com/q/44878600/472695). To be honest, I almost hate Python's packaging system. – toriningen Jul 03 '17 at 05:53
  • I've packaged and distributed a Python library with Setuptools and had no need of setup.cfg. I think the short answer here is "move everything into setup.py and delete setup.cfg." – Kevin Jul 03 '17 at 06:55
  • @Kevin, next step would be to throw out setuptools and use distutils, because setuptools is too mainstream. On the serious note, why one would go back 9 years in time to end up where python packaging started - at the archaic "setup.py"? – toriningen Jul 03 '17 at 06:59
  • http://packaging.python.org has two brief mentions of setup.cfg, and the rest is about setup.py. I don't know who told you that setup.cfg was the new hotness, but they're mistaken. – Kevin Jul 03 '17 at 15:11
  • I think Conda uses a colon rather than a semicolon. I have never used setup.cfg, but worth a try? – Oddthinking Aug 04 '17 at 15:55

1 Answers1

6

One character. That's all you were missing. You had platform_system="Darwin" instead of platform_system=="Darwin" (the very last line of your install_requires). It works fine this way:

[metadata]
name = foobar
version = 1.6.5+0.1.0

[options]
packages = find:

install_requires =
    ham >= 0.1.0
    eggs >= 8.1.2
    spam >= 1.2.3; platform_system=="Darwin"
    i-love-spam >= 1.2.0; platform_system=="Darwin"

It's not necessary but your setup.py could be simplified too.

import setuptools

setup(setup_requires=['setuptools>=36.0'])

Unlike those commenting before, I like using setup.cfg. It's clean and easy. If you want to use the information from setup.cfg at runtime, it's easy to parse:

from setuptools.config.setupcfg import read_configuration

conf_dict = read_configuration('/home/user/dev/package/setup.cfg')

More setup.cfg info

wim
  • 338,267
  • 99
  • 616
  • 750
DarkerIvy
  • 1,477
  • 14
  • 26