2

During development of Pylint, we encountered interesting problem related to non-dependency that may break pylint package.

Case is following:

  • python-future had a conflicting alias to configparser package. Quoting official docs:

    This release removes the configparser package as an alias for ConfigParser on Py2 to improve compatibility with Lukasz Langa’s backported configparser package. Previously python-future and the configparser backport clashed, causing various compatibility issues. (Issues #118, #181)

  • python-future itself is not a dependency of Pylint

What would be a standard way to enforce if python-future is present, force it to 0.16 or later limitation? I want to avoid defining dependency as future>=0.16 - by doing this I'd force users to install package that they don't need and won't use in a general case.

Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
  • It sounds like what you're describing is simply a bug in `python-future` that might affect any code that does `import configparser`. Is that correct? If so, it doesn't seem like it makes sense to try to "fix" it with your own dependency lists. – BrenBarn Jul 11 '17 at 07:08
  • @BrenBarn well, clients disagree. You can see quite a heated discussion under linked issue. That's why I asked this question - to figure out whether there is a smart way to handle this highly unusual case that gave a lot of people trouble. – Łukasz Rogalski Jul 11 '17 at 07:18
  • Do you have an answer to the question raised towards the end of that discussion: "what does require future or futures?" It seems like understanding that would be quite important for understanding how to approach the problem. – BrenBarn Jul 11 '17 at 07:23

3 Answers3

2
kw = {}
try:
    import future
except ImportError:
    pass
else:
    kw['install_requires'] = ['future>=0.16']

setup(
    …
    **kw
)
phd
  • 82,685
  • 13
  • 120
  • 165
  • **This.** This is *almost* there. As [pradyunsg](https://stackoverflow.com/users/1931274/pradyunsg) notes, this approach fails to scale to wheels. Assuming a local dev environment with `python-future` installed, wheel users will be forced to install `python-future` >= 0.16. That's hardly the worst thing to happen, however. A small price must be paid for a mostly-worky solution. – Cecil Curry Aug 02 '17 at 03:20
0

One workaround for this issue is to define this requirement only for the all target, so only if someone adds pylint[all]>=1.2.3 as a requirement they will have futures installed/upgraded.

At this moment I don't know another way to "ignore or upgrade" a dependency.

Also, I would avoid adding Python code to setup.py in order to make it "smart",... is a well known distribution anti-pattern ;)

sorin
  • 161,544
  • 178
  • 535
  • 806
0

There is no supported way to tell pip or setuptools that a package needs to satisfy a constraint only if installed. There might be some hacks but I imagine they'll all be fragile and likely breaking in the future versions of pip/setuptools.

Honestly, the only good way is to document it for users that future < 16.0 would break pylint, in the appropriate location in the documentation.


Making your setup.py script contain conditional dependencies is something that has been strongly discouraged for some time now. Once a wheel is built, the package is installed with the same dependency information as the wheel holds - setup.py is not run on the end-user's system, only on the packager's system, which means any setup.py hack (like @phd's) would not be useful (since pylint distributes wheels).

pradyunsg
  • 18,287
  • 11
  • 43
  • 96
  • 1
    Due to the inexpressiveness of the `install_requires` parameter, [phd](https://stackoverflow.com/users/7976758/phd)'s [approach](https://stackoverflow.com/a/44660880/2809027) is the *only* meaningful means the Python community has of specifying conditional dependencies. Admonishing developers for doing so when [circumstances dictate](https://github.com/PyCQA/pylint/issues/1318) they absolutely *must* isn't particularly helpful. What *would* have been helpful is an extension of phd's approach adding `setup.py` and application logic handling wheel-specific edge cases. – Cecil Curry Aug 02 '17 at 03:17