[Distutils] pkg_resources: inconsistency when using namespace packages
PJ Eby
pje at telecommunity.com
Sat Feb 23 18:28:58 CET 2013
On Fri, Feb 22, 2013 at 3:57 PM, Manlio Perillo
<manlio.perillo at gmail.com> wrote:
> Hi.
>
> I have find an inconstistency when using the pkg_resources module with
> namespace packages.
>
> I'm using setuptools 0.6c11-py2.5.egg
>
> Here is an interactive session:
>
>>>> import pkg_resources
>>>> dist = pkg_resources.Requirement.parse('wsgix')
>>>> dist = pkg_resources.get_provider(dist)
>>>> dist.get_resource_filename(dist, 'y')
> '/home/manlio/projects/hg/wsgix/wsgix/y'
>
>>>> dist_2 = pkg_resources.get_provider('wsgix')
>>>> dist_2.get_resource_filename(dist_2, 'y')
> '/home/manlio/projects/hg/wsgix/wsgix.forms.jqueryui/wsgix/y'
>
>
> The get_provider function returns two different distributions, when
> passing a string or Requirement object.
This is because a string passed to get_provider() is a *module* name,
not a distribution name or requirement. Thus, the first resource
obtained above is relative to the distribution root for a project
named 'wsgix', and the second is relative to
__import__('wsgix').__file__. The purpose of this difference is to
allow you to target either module-relative or distribution-relative
files.
So, you need to call it with the right type of object for the result
you want to get. In particular, note that when obtaining resources
from a namespace package, your results will be unpredictable unless
you either 1) use a distribution-relative path for a specific
distribution, by passing in a Requirement for that distribution, or 2)
use a module-relative or subpackage-relative path for a submodule or
subpackage of the namespace package that is not itself a namespace,
but is contained in the distribution that carries the resource you
need.
(IOW, you cannot pass a namespace package name to the resource API and
expect to get a consistent result. You *must* use a mdoule or
subpackage of the namespace, otherwise you will simply get something
relative to the first-imported component of that namespace.)
> My problem is with the resource API, since get_provider is called with
> the object passed (and I pass a string with the package name); instead
> the get_distribution function always convert the object passed to a
> Requirement object
The get_distribution() function is for getting a distribution, not a
module, so no matter what you pass it, it's going to get looked up as
a specifier for finding a distribution.
More information about the Distutils-SIG
mailing list