[Distutils] PATCH: setuptools-0.4a3 resource loading from egg problem
Ryan Tomayko
rtomayko at gmail.com
Tue Jun 14 14:17:55 CEST 2005
I've been getting the following when trying to use resource_filename
when my package is in a zipped egg (since somewhere around 0.3a2 or so):
Traceback (most recent call last):
File "/usr/local/bin/somescript.py", line 4, in ?
pkg_resources.run_main('somepackage==1.0', 'somescript.py')
File "setuptools/pkg_resources.py", line 110, in run_main
require(dist_spec)[0].metadata.run_script(script_name,
__main__.__dict__)
File "setuptools/pkg_resources.py", line 599, in run_script
exec script_code in namespace, namespace
File "/usr/local/bin/somescript.py", line 7, in ?
File "egg/somepackage/somemodule.py", line 3, in ?
File "setuptools/pkg_resources.py", line 388, in resource_filename
return get_provider(package_name).get_resource_filename(
File "setuptools/pkg_resources.py", line 728, in
get_resource_filename
return self._extract_resource(manager, resource_name)
File "setuptools/pkg_resources.py", line 745, in _extract_resource
zip_stat = self.zipinfo[os.path.join(*self.prefix+parts)]
KeyError: 'somepackage/someresource.txt'
Here's a test egg that illustrates the problem:
<http://lesscode.org/eggs/somepackage-1.0-py2.4.egg>
Install that and then run the included "somescript.py". You should
see the traceback above.
The problem seems to be with loading resources relative to a module
in a package. The egg contains a package "somepackage" and a module
within that package "somemodule". somemodule calls ``resource_filename
(__name__, 'someresource.txt')``. The ZipProvider seems to handle
this case badly.
Attached is a patch against 0.4a3 that fixes this particular case but
I'm not confident it won't cause problems elsewhere. I'll comment
each hunk here with an explanation of what I think may be happening.
@@ -573,7 +573,7 @@
def resource_listdir(self,resource_name):
- return self._listdir(self._fn(self.egg_info,resource_name))
+ return self._listdir(self._fn(self.module_path, resource_name))
def metadata_listdir(self,name):
if self.egg_info:
Here we see NullProvider.resource_listdir using [path]/EGG_INFO
instead of [path]. This seems like a simple typo to me as there are
resource_XXX and metadata_XXX methods, the first based on the module
path and the second set based on the EGG_INFO dir.
@@ -703,7 +703,7 @@
def __init__(self, module):
DefaultProvider.__init__(self,module)
self.zipinfo = zipimport._zip_directory_cache
[self.loader.archive]
- self.zip_pre = self.loader.archive+os.sep
+ self.zip_pre = self.module_path + os.sep
def _short_name(self, path):
if path.startswith(self.zip_pre):
This is where I was a bit shaky:
loader_archive = /path/to/the-egg.egg
module_path = /path/to/the-egg.egg/package
Shouldn't resource loading be relative to the package directory and
not the root of the egg?
@@ -738,7 +738,7 @@
def _extract_resource(self, manager, resource_name):
if self.resource_isdir(resource_name):
- return self._extract_dir(resource_name)
+ return self._extract_directory(manager, resource_name)
parts = resource_name.split('/')
zip_path = os.path.join(self.module_path, *parts)
I believe this was a simple typo / refactoring-miss. This isn't
breaking the test case but is causing problems in another package
that is using resource_filename to get a directory.
Thanks,
Ryan Tomayko
rtomayko at gmail.com
http://naeblis.cx/rtomayko/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: zip-resource-loading.patch
Type: application/octet-stream
Size: 1107 bytes
Desc: not available
Url : http://mail.python.org/pipermail/distutils-sig/attachments/20050614/23661a54/zip-resource-loading.obj
-------------- next part --------------
More information about the Distutils-SIG
mailing list