[Distutils] setup.py install using pip
Ronny Pfannschmidt
opensource at ronnypfannschmidt.de
Fri Dec 4 02:55:14 EST 2015
But it still needs a change in command
A direct switch to a real pip command comes with a free implementation and zero additional features to maintain in setuptools
Am 3. Dezember 2015 23:01:21 MEZ, schrieb Erik Bray <erik.m.bray at gmail.com>:
>On Thu, Dec 3, 2015 at 3:37 PM, Ronny Pfannschmidt
><opensource at ronnypfannschmidt.de> wrote:
>> Lets avoid getting setuptools even more complex in that way
>
>It's not deeply complex--it's just bypassing the normal behavior of
>using easy_install. In my example code I subclassed
>the existing command, but an easier approach would be to build it into
>setuptools.
>
>The way the 'install' command works in setuptools is to hand
>installation off to the easy_install command unless
>--single-version-externally-managed is specified (as well as
>--record). Otherwise it hands installation off to the default
>base 'install' command of distutils.
>
>This proposal just adds a third option for what actual installer the
>'install' command should
>use. But it's opt-in instead of forced on any package by default (as
>easy_install is forced on us by setuptools).
>
>> Putting pip-ish-ness on top of easy install is a maintenance horror
>and I don't think setuptools does has enough consistent developer
>resources to handle something like that
>
>It doesn't put anything "on top of" easy_install; it ignores
>easy_install.
>
>> Instead let's just give options to destroy the normal install command
>from setup.py so projects can phase out easy install forcefully making
>downstream require patches or pip usage
>
>That's the goal, yes. This is just offering a transitional tool.
>
>
>Erik
>
>>
>> Am 3. Dezember 2015 21:06:06 MEZ, schrieb Erik Bray
><erik.m.bray at gmail.com>:
>>>Hi all,
>>>
>>>I've been on vacation for a bit in general, and on vacation from this
>>>mailing list even longer. I'm not entirely caught up yet on the
>>>latest developments so apologies if something like this is entirely
>>>moot by now.
>>>
>>>But I have seen some discussions here and in other lists related to
>>>using pip for all installations, and phasing out the old distutils
>>>`./setup.py install` (eg. [1]). This is not a new discussion, and
>>>there are many related discussions, for example, about changing
>>>setuptools not to default to egg installs anymore (see [2]).
>>>
>>>I'm definitely all for this in general. Nowadays whenever I install
>a
>>>package from source I run `pip install .` But of course there are a
>>>lot of existing tools, not to mention folk wisdom, assuming
>>>`./setup.py install`. We also don't want to change the long-existing
>>>behavior in setuptools.
>>>
>>>I have a modest proposal for a small addition to setuptools that
>might
>>>be helpful in a transition away from using setuptools+distutils for
>>>installation. This would be to add a `--pip` flag to setuptools'
>>>install command (or possibly straight in distutils too, but might as
>>>well start with setuptools).
>>>
>>>Therefore, running
>>>
>>>$ ./setup.py install --pip
>>>
>>>would be equivalent to running
>>>
>>>$ pip install .
>>>
>>>By extension, running
>>>
>>>$ ./setup.py install --pip --arg1 --arg2=foo
>>>
>>>would be equivalent to
>>>
>>>$ pip install --install-option="--arg1" --install-option="--arg2=foo"
>.
>>>
>>>and so on.
>>>
>>>By making `--pip` opt-in, it does not automatically break backward
>>>compatibility for users expecting `./setup.py install` to use
>>>easy_install. However, individual users may opt into it globally by
>>>adding
>>>
>>>[install]
>>>pip = True
>>>
>>>to their .pydistutils.cfg. Similarly, package authors who are
>>>confident that none of their users are ever going to care about egg
>>>installs (e.g. me) can add the same to their project's setup.cfg.
>>>
>>>Does something like this have any merit? I hacked together a
>>>prototype which follows the sig line. It's just a proof of concept,
>>>but seems to work in the most basic cases. I'd like to add it to my
>>>own projects too, but would appreciate some peer review.
>>>
>>>Thanks,
>>>Erik
>>>
>>>
>>>
>>>[1]
>>>https://mail.scipy.org/pipermail/numpy-discussion/2015-November/074142.html
>>>[2]
>>>https://bitbucket.org/pypa/setuptools/issues/371/setuptools-and-state-of-pep-376
>>>
>>>
>>>$ cat pipinstall.py
>>>from distutils.errors import DistutilsArgError
>>>from setuptools.command.install import install as SetuptoolsInstall
>>>
>>>
>>>class PipInstall(SetuptoolsInstall):
>>> command_name = 'install'
>>> user_options = SetuptoolsInstall.user_options + [
>>> ('pip', None, 'install using pip; ignored when also using '
>>> '--single-version-externally-managed')
>>> ]
>>> boolean_options = SetuptoolsInstall.boolean_options + ['pip']
>>>
>>> def initialize_options(self):
>>> SetuptoolsInstall.initialize_options(self)
>>> self.pip = False
>>>
>>> def finalize_options(self):
>>> SetuptoolsInstall.finalize_options(self)
>>>
>>> if self.single_version_externally_managed:
>>> self.pip = False
>>>
>>> if self.pip:
>>> try:
>>> import pip
>>> except ImportError:
>>> raise DistutilsArgError(
>>> 'pip must be installed in order to install with the
>'
>>> '--pip option')
>>>
>>> def run(self):
>>> if self.pip:
>>> import pip
>>> opts = (['install', '--ignore-installed'] +
>>> ['--install-option="{0}"'.format(opt)
>>> for opt in self._get_command_line_opts()])
>>> pip.main(opts + ['.'])
>>> else:
>>> SetuptoolsInstall.run(self)
>>>
>>> def _get_command_line_opts(self):
>>> # Generate a mapping from the attribute name associated with
>a
>>># command-line option to the name of the command-line option
>(including
>>> # an = if the option takes an argument)
>>> attr_to_opt = dict((opt[0].rstrip('=').replace('-', '_'),
>opt[0])
>>> for opt in self.user_options)
>>>
>>> opt_dict =
>self.distribution.get_option_dict(self.get_command_name())
>>> opts = []
>>>
>>> for attr, value in opt_dict.items():
>>> if value[0] != 'command line' or attr == 'pip':
>>> # Only look at options passed in on the command line
>(ignoring
>>> # the pip option itself)
>>> continue
>>>
>>> opt = attr_to_opt[attr]
>>>
>>> if opt in self.boolean_options:
>>> opts.append('--' + opt)
>>> else:
>>> opts.append('--{0}{1}'.format(opt, value[1]))
>>>
>>> return opts
>>>
>>> @staticmethod
>>> def _called_from_setup(run_frame):
>>> # A hack to work around a setuptools hack
>>> return SetuptoolsInstall._called_from_setup(run_frame.f_back)
>>>_______________________________________________
>>>Distutils-SIG maillist - Distutils-SIG at python.org
>>>https://mail.python.org/mailman/listinfo/distutils-sig
>>
>> MFG Ronny
MFG Ronny
More information about the Distutils-SIG
mailing list