<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On 18 March 2015 at 14:37, Daniel Holth <span dir="ltr"><<a href="mailto:dholth@gmail.com" target="_blank">dholth@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>[...]<br>
<br>
</span>The behavior we're aiming for would be:<br>
<br>
"installer run setup.py" - installs things<br>
"python setup.py" - does not install things</blockquote><div><br></div><div>Besides that, I'd add that we're also looking for: "python setup.py" (by itself) should not raise ImportError, even if setup.py needs extra things installed for certain operations (egg_info, build, sdist, develop, install).</div><div><br></div><div>IMO, the biggest pain point is not people putting crazy stuff in setup.py to get version numbers. For me, the biggest pain point is when setup.py needs to import other packages in order to even know how to build:</div><div><br></div><div>So I'd like to suggest the following series of small improvements to both pip and setuptools:</div><div><br></div><div> * setuptools: `python setup.py setup_requires` dumps its setup_requires keyword in 'requirements.txt' format</div><div><br></div><div>It's is already in this format, so should be trivial, but allows one to do something like:</div><div><br></div><div>    $ python setup.py setup_requires > setup_requires.txt</div><div>    $ pip install -r setup_requires.txt</div><div><br></div><div>Or in one bash line:</div><div><br></div><div>    $ pip install -r <( python setup.py setup_requires )</div><div><br></div><div> * setuptools: setup.py gains the ability to accept callables in most (all?) of its parameters.</div><div><br></div><div>This will allow people to move all top level setup.py imports into functions, so that we can turn code like this:</div><div><br></div><div><div>    from setuptools import setup, Extension</div><div>    import numpy</div><div><br></div><div>    setup(ext_modules=[</div><div>        Extension("_cos_doubles",</div><div>            sources=["cos_doubles.c", "cos_doubles.i"],</div><div>            include_dirs=[numpy.get_include()])])</div></div><div><br></div><div>Into this:</div><div><br></div><div><div>    from setuptools import setup, Extension</div><div><br></div><div>    def ext_modules():</div><div>        import numpy</div><div><div>        return [</div><div>            Extension("_cos_doubles",</div><div>                sources=["cos_doubles.c", "cos_doubles.i"],</div><div>                include_dirs=[numpy.get_include()])</div><div>        ]</div></div><div><br></div><div>    setup(ext_modules=ext_modules</div><div>              setup_requires=['setuptools'])</div></div><div><br></div><div> * pip: When working with an sdist, before running "setup.py egg_info" in a sandbox, pip would run "setup.py setup_requires", install those packages in the sandbox (not in the main environment), then run "egg_info", "wheel", etc.</div><div><br></div><div>Notice that the changes proposed above are all backward compatible, create no additional pain, and allow developers to move all top level setup.py craziness inside functions.</div><div><br></div><div>After that, we can consider making setup.py not call the easy_install functionality when it finds a setup_requires keyword while running other commands, but just report if those packages are not available.</div><div><br></div><div><br></div><div>PS: Yes, I've already proposed something similar recently: <a href="https://mail.python.org/pipermail/distutils-sig/2015-January/025682.html">https://mail.python.org/pipermail/distutils-sig/2015-January/025682.html</a></div></div></div></div>