[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