[Zconfig] SVN: ZConfig/trunk/ZConfig/ add support for importing
schema components from ZIP archives (including eggs)
Fred L. Drake, Jr.
fdrake at gmail.com
Tue Nov 8 11:33:54 EST 2005
Log message for revision 39982:
add support for importing schema components from ZIP archives (including eggs)
Changed:
U ZConfig/trunk/ZConfig/loader.py
A ZConfig/trunk/ZConfig/tests/foosample.zip
U ZConfig/trunk/ZConfig/tests/test_loader.py
A ZConfig/trunk/ZConfig/tests/zipsource/
A ZConfig/trunk/ZConfig/tests/zipsource/README.txt
A ZConfig/trunk/ZConfig/tests/zipsource/foo/
A ZConfig/trunk/ZConfig/tests/zipsource/foo/__init__.py
A ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/
A ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/__init__.py
A ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/component.xml
A ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/datatypes.py
-=-
Modified: ZConfig/trunk/ZConfig/loader.py
===================================================================
--- ZConfig/trunk/ZConfig/loader.py 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/loader.py 2005-11-08 16:33:53 UTC (rev 39982)
@@ -13,6 +13,7 @@
##############################################################################
"""Schema loader utility."""
+import cStringIO
import os.path
import sys
import urllib
@@ -90,16 +91,20 @@
# change and provide the cached resource when the remote
# resource is not accessible.
url = str(url)
- try:
- file = urllib2.urlopen(url)
- except urllib2.URLError, e:
- # urllib2.URLError has a particularly hostile str(), so we
- # generally don't want to pass it along to the user.
- self._raise_open_error(url, e.reason)
- except (IOError, OSError), e:
- # Python 2.1 raises a different error from Python 2.2+,
- # so we catch both to make sure we detect the situation.
- self._raise_open_error(url, str(e))
+ if url.startswith("package:"):
+ _, package, filename = url.split(":", 2)
+ file = openPackageResource(package, filename)
+ else:
+ try:
+ file = urllib2.urlopen(url)
+ except urllib2.URLError, e:
+ # urllib2.URLError has a particularly hostile str(), so we
+ # generally don't want to pass it along to the user.
+ self._raise_open_error(url, e.reason)
+ except (IOError, OSError), e:
+ # Python 2.1 raises a different error from Python 2.2+,
+ # so we catch both to make sure we detect the situation.
+ self._raise_open_error(url, str(e))
return self.createResource(file, url)
def _raise_open_error(self, url, message):
@@ -135,7 +140,30 @@
return True
+def openPackageResource(package, path):
+ __import__(package)
+ pkg = sys.modules[package]
+ try:
+ loader = pkg.__loader__
+ except AttributeError:
+ relpath = os.path.join(*path.split("/"))
+ for dir in pkg.__path__:
+ filename = os.path.join(dir, relpath)
+ if os.path.exists(filename):
+ break
+ else:
+ raise ZConfig.SchemaResourceError("schema component not found",
+ filename=path,
+ package=package,
+ path=pkg.__path__)
+ url = "file:" + urllib.pathname2url(filename)
+ url = ZConfig.url.urlnormalize(url)
+ return urllib2.urlopen(url)
+ else:
+ loadpath = os.path.join(os.path.dirname(pkg.__file__), path)
+ return cStringIO.StringIO(loader.get_data(loadpath))
+
def _url_from_file(file):
name = getattr(file, "name", None)
if name and name[0] != "<" and name[-1] != ">":
@@ -184,16 +212,7 @@
raise ZConfig.SchemaResourceError(
"import name does not refer to a package",
filename=file, package=package)
- for dir in pkg.__path__:
- dirname = os.path.abspath(dir)
- fn = os.path.join(dirname, file)
- if os.path.exists(fn):
- return "file://" + urllib.pathname2url(fn)
- else:
- raise ZConfig.SchemaResourceError("schema component not found",
- filename=file,
- package=package,
- path=pkg.__path__)
+ return "package:%s:%s" % (package, file)
class ConfigLoader(BaseLoader):
Added: ZConfig/trunk/ZConfig/tests/foosample.zip
===================================================================
(Binary files differ)
Property changes on: ZConfig/trunk/ZConfig/tests/foosample.zip
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: ZConfig/trunk/ZConfig/tests/test_loader.py
===================================================================
--- ZConfig/trunk/ZConfig/tests/test_loader.py 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/test_loader.py 2005-11-08 16:33:53 UTC (rev 39982)
@@ -284,9 +284,57 @@
"http://www.zope.org/no-such-document/")
+class TestResourcesInZip(unittest.TestCase):
+
+ def setUp(self):
+ self.old_path = sys.path[:]
+ # now add our sample EGG to sys.path:
+ zipfile = os.path.join(os.path.dirname(myfile), "foosample.zip")
+ sys.path.append(zipfile)
+
+ def tearDown(self):
+ sys.path[:] = self.old_path
+
+ def test_zip_import_component_from_schema(self):
+ sio = StringIO('''
+ <schema>
+ <abstracttype name="something"/>
+ <import package="foo.sample"/>
+ <section name="*"
+ attribute="something"
+ type="something"
+ />
+ </schema>
+ ''')
+ schema = ZConfig.loadSchemaFile(sio)
+ t = schema.gettype("sample")
+ self.failIf(t.isabstract())
+
+ def test_zip_import_component_from_config(self):
+ sio = StringIO('''
+ <schema>
+ <abstracttype name="something"/>
+ <section name="*"
+ attribute="something"
+ type="something"
+ />
+ </schema>
+ ''')
+ schema = ZConfig.loadSchemaFile(sio)
+ sio = StringIO('''
+ %import foo.sample
+ <sample>
+ data value
+ </sample>
+ ''')
+ config, _ = ZConfig.loadConfigFile(schema, sio)
+ self.assertEqual(config.something.data, "| value |")
+
+
def test_suite():
suite = unittest.makeSuite(LoaderTestCase)
suite.addTest(unittest.makeSuite(TestNonExistentResources))
+ suite.addTest(unittest.makeSuite(TestResourcesInZip))
return suite
if __name__ == '__main__':
Added: ZConfig/trunk/ZConfig/tests/zipsource/README.txt
===================================================================
--- ZConfig/trunk/ZConfig/tests/zipsource/README.txt 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/zipsource/README.txt 2005-11-08 16:33:53 UTC (rev 39982)
@@ -0,0 +1,2 @@
+This directory contains a sample package that is used to create the
+'foosample.zip' file used in the tests.
Property changes on: ZConfig/trunk/ZConfig/tests/zipsource/README.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added: ZConfig/trunk/ZConfig/tests/zipsource/foo/__init__.py
===================================================================
--- ZConfig/trunk/ZConfig/tests/zipsource/foo/__init__.py 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/zipsource/foo/__init__.py 2005-11-08 16:33:53 UTC (rev 39982)
@@ -0,0 +1 @@
+# This directory is a Python package.
Property changes on: ZConfig/trunk/ZConfig/tests/zipsource/foo/__init__.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
Added: ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/__init__.py
===================================================================
--- ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/__init__.py 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/__init__.py 2005-11-08 16:33:53 UTC (rev 39982)
@@ -0,0 +1 @@
+# This directory is a Python package.
Property changes on: ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/__init__.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
Added: ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/component.xml
===================================================================
--- ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/component.xml 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/component.xml 2005-11-08 16:33:53 UTC (rev 39982)
@@ -0,0 +1,9 @@
+<component prefix="foo.sample">
+
+ <!-- `something` is an abstract type that's already defined -->
+
+ <sectiontype name="sample" implements="something">
+ <key name="data" datatype=".datatypes.data"/>
+ </sectiontype>
+
+</component>
Added: ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/datatypes.py
===================================================================
--- ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/datatypes.py 2005-11-08 16:31:24 UTC (rev 39981)
+++ ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/datatypes.py 2005-11-08 16:33:53 UTC (rev 39982)
@@ -0,0 +1,7 @@
+"""Sample datatypes used for testing.
+"""
+__docformat__ = "reStructuredText"
+
+
+def data(value):
+ return "| %s |" % value
Property changes on: ZConfig/trunk/ZConfig/tests/zipsource/foo/sample/datatypes.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
More information about the ZConfig
mailing list