pkg_resources: inconsistency when using namespace packages
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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. 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 Thanks Manlio -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlEn258ACgkQscQJ24LbaURXCwCcDeuCWFUANQwsH0Q9CBATghha ttMAn1GmzdWmefLyP/7rz0/yBKjfcOyU =85ks -----END PGP SIGNATURE-----
On Fri, Feb 22, 2013 at 3:57 PM, Manlio Perillo
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.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Il 23/02/2013 18:28, PJ Eby ha scritto:
[...]
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.
Yes, thanks. I have read the HTML documentation, and it was a bit more clear.
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,
I'm rewriting my projects, using a wrapper around pkg resource API that will make sure to cast a distribution name string to a Requirement, in order to get "distribution resources, aka non-package data files". The main problem is that I can no longer use `package_data` setup argument, but I have to use the `data_file` argument. Since `data_file` is not very convenient, I have written this (draft) function: http://pastebin.com/w5Ejz3Jt As an example: data_files=find_data_files({ '': ['locale/*/LC_MESSAGES/*.mo'], '/tmp/bin': ['tools/*'] }),
[...]
Regards Manlio Perillo -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlEpM+IACgkQscQJ24LbaURG8gCfVDL2XEYohx2bUmVOq7r0VNMU 7DcAnio7QpH85b0tKTmKH8MpeqocaNjm =CcqL -----END PGP SIGNATURE-----
participants (2)
-
Manlio Perillo
-
PJ Eby