[Distutils] Disabling --single-version-externally-managed
Phillip J. Eby
pje at telecommunity.com
Mon Sep 3 00:50:10 CEST 2007
At 01:12 PM 9/2/2007 -0700, Toshio Kuratomi wrote:
>What is the real way to allow people to do quick and dirty scripting and
>experimentation from the interpreter shell in this environment?
1. Select the desired default version using "easy_install package==version", or
2. Have *no* default version, and always use require() (or
automatically-managed dependencies declared via a setup.py script).
>And once again, we are *not* creating and packaging scripts that use
>__require__. We are packaging multiple versions of modules with a
And once again, this won't work. Either you must not have a default
version, or you must deal with the potential conflict in your scripts.
The supported way of doing that is to generate the scripts using
easy_install. If you are packaging something that doesn't use
setuptools explicitly, you'll just have to patch it to declare its
dependencies. You're already patching the .spec file; heck, if it
would make it more palatable, perhaps we could add a way to specify
the requirements via the command line. (Alternately, you could just
create a requires.txt in the .egg-info directory.)
> We need to have instructions for end-users who want to do
>quick and dirty scripting or experiment in the interpreter shell how to
>select the version that they wish.
easy_install package==version will change the default version, and
require() will work if there is no default version. Those are the
supported ways of doing this.
>Once again, *we are not creating any system level python scripts that
>make use of a specific, non-default version*.
I'm saying that even your programs that use the default version,
should explicitly specify what version they use. If you're going to
support multiple versions, then declare *all* the dependencies, or at
least the ones that would otherwise have conflicts.
>B) For projects
>that have not been ported to a new version of the module. We have no
>control over how those upstream scripts are written -- whether they use
>easy_install, hand code __requires__, or munge sys.path themselves.
The correct instructions are for them to use setuptools and declare
their dependencies, or live with whatever the status quo is.
>This is true. But it's not going to change until all upstreams have
>moved to using setuptools. We provide a set of packages that work
>together. And we provide a means for the user to shoot themselves in
>the foot. But this is nothing new, they've had access to PYTHONPATH,
>su, rm -rf, etc in the past.
>What we can do is make as much of what they expect to work work as it
>used to. And where it differs, we offer a standard, logical, and simple
>method to get the behaviour they want.
Right - and the single simplest solution for all of this is to simply
use setuptools as it was designed: select a default version using
easy_install, and declare dependencies for everything
else. Alternatively, don't install *anything* as the default
version, and declare *all* dependencies.
If your goal is to have simple and consistent behavior, the second is
the best choice. If you want the greatest backward-compatibility,
the first is the best choice.
Note that it isn't really possible for users *now* to choose a
different package version at runtime, so requiring the use of
easy_install to switch default versions doesn't seem like a big
deal. They already have to make this choice by what RPMs they
install, and it's just as global a choice -- except that this way,
they can do it without breaking anything.
>If you feel that __requires__ is a private method that shouldn't be used
>then we'd respect that. But between that and your teelling us that
>pkg_resources.require() isn't meant to work like that, it means that
>there's simply no method for making setuptools do what we need it to and
>we'll have to find some other method to accomplish this.
There are *two* ways to accomplish it: have a default (and use
easy_install to change it when desired), or don't have a default.
Either way, you are going to ultimately end up at a place where
everything needs to declare its dependencies, preferably in a
setup.py. Having a default version may be useful for the transition
period, but the best way to encourage people to actually transition
is to have some *benefit* for declaring their dependencies -- like
being able to use the non-default versions.
This is why I even discourage direct use of require(), as it says in the docs:
"""In general, it should not be necessary for you to call this method
directly. It's intended more for use in quick-and-dirty scripting and
interactive interpreter hacking than for production use. If you're
creating an actual library or application, it's strongly recommended
that you create a "setup.py" script using setuptools, and declare all
your requirements there. That way, tools like EasyInstall can
automatically detect what requirements your package has, and deal
with them accordingly."""
More information about the Distutils-SIG