Optimizing easy-install upgrade
Suppose I have the directory: /home/jim/tmp/dist: used 92 available 41345796 -rw-rw-r-- 1 jim jim 671 Jun 19 17:43 demoneeded-1.0-py2.4.egg -rw-rw-r-- 1 jim jim 672 Jun 19 17:46 demoneeded-1.1-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.2-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.3-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.4-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.5-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.6-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.7-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.8-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.9-py2.4.egg and then run easy install telling it to install something I already have: [jim@ds9 ~]$ /usr/local/python/2.4/bin/easy_install -d tmp/dist -mxU demoneeded==1.1 Searching for demoneeded==1.1 Reading http://www.python.org/pypi/demoneeded/ Couldn't find index page for 'demoneeded' (maybe misspelled?) Scanning index of all packages (this may take a while) Reading http://www.python.org/pypi/ Best match: demoneeded 1.1 Processing demoneeded-1.1-py2.4.egg Using /home/jim/tmp/dist/demoneeded-1.1-py2.4.egg Because this distribution was installed --multi-version, before you can import modules from this package in an application, you will need to 'import pkg_resources' and then use a 'require()' call similar to one of these examples, in order to select the desired version: pkg_resources.require("demoneeded") # latest installed version pkg_resources.require("demoneeded==1.1") # this exact version pkg_resources.require("demoneeded>=1.1") # this version or higher Note also that the installation directory must be on sys.path at runtime for this to work. (e.g. by being the application's script directory, by being on PYTHONPATH, or by being added to sys.path by your code.) Processing dependencies for demoneeded==1.1 Note that it looked at pypi even though it already had the only acceptable version. I'm not sure why it did this. Is this just a case of a missing optimization? Or is there some other reason for checking the index in a situation like this? I have some scripts that invoke easy_setup and I'd like to try to do some of this logic myself. Given a requirement, I'd like to get the specifiers and decide myself whether to invoke easy_install. I have 2 problems: - I don't want to parse the requirement myself, but, rather, use Requirement.parse. If I use Requirement.parse, I can use the specs attribute to get the specifiers, however, this attribute isn't documented. Should I assume that it is private? Or is it safe to use. - I'm still a bit foggy on how to interpret the specifiers. But we're discussing that in another thread. Jim -- Jim Fulton mailto:jim@zope.com Python Powered! CTO (540) 361-1714 http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org
At 05:37 PM 6/21/2006 -0400, Jim Fulton wrote:
Suppose I have the directory:
/home/jim/tmp/dist: used 92 available 41345796 -rw-rw-r-- 1 jim jim 671 Jun 19 17:43 demoneeded-1.0-py2.4.egg -rw-rw-r-- 1 jim jim 672 Jun 19 17:46 demoneeded-1.1-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.2-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.3-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.4-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.5-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.6-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.7-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.8-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.9-py2.4.egg
and then run easy install telling it to install something I already have:
[jim@ds9 ~]$ /usr/local/python/2.4/bin/easy_install -d tmp/dist -mxU demoneeded==1.1
The -U option means "always search PyPI".
I have some scripts that invoke easy_setup and I'd like to try to do some of this logic myself. Given a requirement, I'd like to get the specifiers and decide myself whether to invoke easy_install. I have 2 problems:
- I don't want to parse the requirement myself, but, rather, use Requirement.parse. If I use Requirement.parse, I can use the specs attribute to get the specifiers, however, this attribute isn't documented. Should I assume that it is private? Or is it safe to use.
Why do that when you can just ask the Requirement whether it matches a particular version? The __contains__ method of Requirement objects accepts a version string, distribution object, or parsed version number you can use. (For that matter, you can query an Environment or WorkingSet for the distributions whose versions you want to check.)
On Jun 21, 2006, at 6:27 PM, Phillip J. Eby wrote:
At 05:37 PM 6/21/2006 -0400, Jim Fulton wrote:
Suppose I have the directory:
/home/jim/tmp/dist: used 92 available 41345796 -rw-rw-r-- 1 jim jim 671 Jun 19 17:43 demoneeded-1.0-py2.4.egg -rw-rw-r-- 1 jim jim 672 Jun 19 17:46 demoneeded-1.1-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.2-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.3-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.4-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.5-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.6-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.7-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.8-py2.4.egg -rw-rw-r-- 1 jim jim 673 Jun 19 17:46 demoneeded-1.9-py2.4.egg
and then run easy install telling it to install something I already have:
[jim@ds9 ~]$ /usr/local/python/2.4/bin/easy_install -d tmp/dist -mxU demoneeded==1.1
The -U option means "always search PyPI".
I have some scripts that invoke easy_setup and I'd like to try to do some of this logic myself. Given a requirement, I'd like to get the specifiers and decide myself whether to invoke easy_install. I have 2 problems:
- I don't want to parse the requirement myself, but, rather, use Requirement.parse. If I use Requirement.parse, I can use the specs attribute to get the specifiers, however, this attribute isn't documented. Should I assume that it is private? Or is it safe to use.
Why do that when you can just ask the Requirement whether it matches a particular version? The __contains__ method of Requirement objects accepts a version string, distribution object, or parsed version number you can use.
(For that matter, you can query an Environment or WorkingSet for the distributions whose versions you want to check.)
Here's my use case: I want to get the most recent distribution that satisfies my requirement. If my requirement sets an upper bound, and I already have the distribution at the upper bound, then I don't want to have to search the index. For us, it will be very common to specify specific distribution versions. I don't want to have to search an index if I already have the specific version. I understand that the -U option isn't designed to meet this use case. That's fine. I want to be able to introspect a requirement to determine wether it set an upper bound. __contains__ doesn't let me do that. With the rules that you've explained for evaluating a set of specifiers, I can do that if I can get at the specifiers. What I want is either a public API for getting the specifiers, or an API that lets me retrieve the upper bound, if there is one. (Obviously, it could return None if no upper bound exists.) Jim -- Jim Fulton mailto:jim@zope.com Python Powered! CTO (540) 361-1714 http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org
At 07:25 AM 6/22/2006 -0400, Jim Fulton wrote:
I can get at the specifiers. What I want is either a public API for getting the specifiers, or an API that lets me retrieve the upper bound, if there is one. (Obviously, it could return None if no upper bound exists.)
Use the specs attribute, which is a list of (op,ver) pairs in ascending version order (and an undefined order among pairs that have equivalent versions). The 'ver' is an *unparsed* version number, so you should parse it in order to do comparisons. The specs attribute is currently undocumented, but I'll document it. It has to be the way it is, because it's needed in order to produce a consistent string representation of a particular requirement.
On Jun 22, 2006, at 11:48 AM, Phillip J. Eby wrote:
At 07:25 AM 6/22/2006 -0400, Jim Fulton wrote:
I can get at the specifiers. What I want is either a public API for getting the specifiers, or an API that lets me retrieve the upper bound, if there is one. (Obviously, it could return None if no upper bound exists.)
Use the specs attribute, which is a list of (op,ver) pairs in ascending version order (and an undefined order among pairs that have equivalent versions). The 'ver' is an *unparsed* version number, so you should parse it in order to do comparisons.
The specs attribute is currently undocumented, but I'll document it. It has to be the way it is, because it's needed in order to produce a consistent string representation of a particular requirement.
Cool. Thanks. Jim -- Jim Fulton mailto:jim@zope.com Python Powered! CTO (540) 361-1714 http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org
participants (2)
-
Jim Fulton
-
Phillip J. Eby