[Checkins] SVN: z3c.etree/trunk/ Move away from using proxy objects
and directly register the elementtree module
Michael Kerrin
michael.kerrin at openapp.ie
Tue Jul 3 14:31:14 EDT 2007
Log message for revision 77374:
Move away from using proxy objects and directly register the elementtree module
with the Zope CA.
Updated the documentation and bumped the version.
Changed:
_U z3c.etree/trunk/
A z3c.etree/trunk/README.txt
U z3c.etree/trunk/setup.py
U z3c.etree/trunk/src/z3c/etree/README.txt
U z3c.etree/trunk/src/z3c/etree/etree.py
U z3c.etree/trunk/src/z3c/etree/testing.py
U z3c.etree/trunk/src/z3c/etree/tests.py
U z3c.etree/trunk/src/z3c/etree/z3c.etree-configure.zcml
-=-
Property changes on: z3c.etree/trunk
___________________________________________________________________
Name: svn:ignore
+ bin
parts
Added: z3c.etree/trunk/README.txt
===================================================================
--- z3c.etree/trunk/README.txt (rev 0)
+++ z3c.etree/trunk/README.txt 2007-07-03 18:31:14 UTC (rev 77374)
@@ -0,0 +1,5 @@
+*z3c.etree* provides some mechanisms (a common interface) for integrating any
+ElementTree engine with the Zope component architecture. This allows
+applications to look up a engine against the interface. *z3c.etree* also
+provides a set of utilities that can be used to make testing XML output in
+doctests easier.
Property changes on: z3c.etree/trunk/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.etree/trunk/setup.py
===================================================================
--- z3c.etree/trunk/setup.py 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/setup.py 2007-07-03 18:31:14 UTC (rev 77374)
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages
setup(name = "z3c.etree",
- version = "0.8",
+ version = "0.9",
author = "Michael Kerrin",
author_email = "michael.kerrin at openapp.ie",
url = "http://svn.zope.org/z3c.etree",
Modified: z3c.etree/trunk/src/z3c/etree/README.txt
===================================================================
--- z3c.etree/trunk/src/z3c/etree/README.txt 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/src/z3c/etree/README.txt 2007-07-03 18:31:14 UTC (rev 77374)
@@ -1,107 +1,43 @@
-=========================
-Zope Element Tree Support
-=========================
+=========
+z3c.etree
+=========
-This package does not implement the ElementTree API but instead provides
-proxy objects that wrap some of the more common ElementTree implementations.
-Then one of these proxy objects is registered as a utility, providing the
-*z3c.etree.interfaces.IEtree* interface, which can be looked up through
-the Zope component architecture. Thus removing the hard dependency a Python
-import statement introduces on any one ElementTree implementation.
+*z3c.etree* provides some mechanisms (a common interface) for integrating any
+ElementTree engine with the Zope component architecture. This allows
+applications to look up a engine against this interface. As such this package
+does not implement the ElementTree API.
-This will allow anyone interested in just trying out a module developed using
-*z3c.etree* to use a pure Python implementation of ElementTree (which is really
-easy to install, but slow). While a developer who is in the final stages of
-going live with a new site might want to configure the same module to use lxml
-(which is *not* easy to install as it depends on libxml2 and libxslt but is
-really, really, really fast).
+*z3c.etree* also provides a set of utilities that can be used to make
+testing XML output in doctests easier. This functionality can also be called
+from a python based unit test via the *assertXMLEqual* method.
-If there is any ElementTree implementation that I have missed, or any bugs,
-improvements, then please contact me at
-michael.kerrin at openapp.ie and I will do my best to fix the situation.
-
-Installation and Configuration
-==============================
-
-*z3c.etree* is installed like any other Zope3 module. That is it should be
-copied verbatim into your Python path and the z3c.etree-configure.zcml file
-should be copied to the package-includes directory for each instance of Zope
-that requires this package. (Once I figure out how to, I will use Python eggs
-for the installation process.)
-
-Now each of the z3c.etree-configure.zcml files that exist in a instances
-package-includes directory can be edited to configure which ElementTree
-implementation to use within that instance.
-
-To configure a particular ElementTree implementation for an instance the
-z3c.etree-configure.zcml file should contain only one ZCML utility
-declaration. For example to configure an instance use lxml
-z3c.etree-configure.zcml should contain the the following::
-
- <utility
- factory="z3c.etree.etree.LxmlEtree"
- />
-
-Where *z3c.etree.etree.LxmlEtree* is the proxy object that wraps the lxml
-implementation. Currently the other implementations include:
-
-+ *z3c.etree.etree.EtreeEtree* - proxy for the pure python *elementtree*
- module.
-
-+ *z3c.etree.etree.EtreePy25* - proxy for the ElementTree implementation
- included in Python 2.5's standard library.
-
-Tests setup
-===========
-
-Some setup for the developers tests.
-
- >>> from zope import component
- >>> import z3c.etree.interfaces
-
-This happens automatically during Zope startup.
-
- >>> from z3c.etree.testing import etreeSetup, etreeTearDown
- >>> from z3c.etree.testing import assertXMLEqual
- >>> dummy = etreeSetup()
-
Developers
==========
+ >>> import z3c.etree
+ >>> import z3c.etree.testing
+ >>> engine = z3c.etree.testing.etreeSetup()
+
Here are some examples for how to use *z3c.etree* with your own code.
To generate a Element object with the tag *DAV:getcontenttype* all we have
to do is:
- >>> etree = component.getUtility(z3c.etree.interfaces.IEtree)
+ >>> etree = z3c.etree.getEngine()
>>> elem = etree.Element("{DAV:}getcontenttype")
- >>> assertXMLEqual(etree.tostring(elem), """
- ... <ns0:getcontenttype xmlns:ns0="DAV:"/>""")
+ >>> elem #doctest:+ELLIPSIS
+ <Element ...>
+ >>> z3c.etree.testing.assertXMLEqual(etree.tostring(elem), """
+ ... <getcontenttype xmlns="DAV:"/>""")
Now to add a value this element use just use the *elem* variable has the API
suggests.
>>> elem.text = "text/plain"
- >>> assertXMLEqual(etree.tostring(elem), """
- ... <ns0:getcontenttype xmlns:ns0="DAV:">text/plain</ns0:getcontenttype>""")
+ >>> z3c.etree.testing.assertXMLEqual(etree.tostring(elem), """
+ ... <getcontenttype xmlns="DAV:">text/plain</getcontenttype>""")
-Testing
-=======
+Tear-down
+=========
-For developers who are writing unit tests for their code that uses
-*z3c.etree*. They should call the method *z3c.etree.testing.etreeSetup* in
-there tests setup code, in order to correctly register a ElementTree utility
-for use within their tests. And similar, call the method
-*z3c.etree.testing.etreeTearDown* in their teardown code. See the Setup
-and Teardown sections of this file.
-
-The *etreeSetup* method will load and parse the *z3c.etree-configure.zcml*
-file from within the *z3c.etree* module (NOT the file from the instance). So
-if the default utility defined in this file, which is
-*z3c.etree.etree.EtreeEtree*, doesn't apply to your system due to a missing
-module for example, then this file should be edited to reflect this.
-
-Teardown
-========
-
- >>> etreeTearDown()
+ >>> z3c.etree.testing.etreeTearDown()
Modified: z3c.etree/trunk/src/z3c/etree/etree.py
===================================================================
--- z3c.etree/trunk/src/z3c/etree/etree.py 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/src/z3c/etree/etree.py 2007-07-03 18:31:14 UTC (rev 77374)
@@ -118,9 +118,3 @@
def __init__(self):
from lxml import etree
self.etree = etree
-
- def tostring(self, element, encoding = None):
- """LXML loses the namespace information whenever we print out an
- element who namespace was defined in
- """
- return self.etree.tostring(copy.copy(element), encoding)
Modified: z3c.etree/trunk/src/z3c/etree/testing.py
===================================================================
--- z3c.etree/trunk/src/z3c/etree/testing.py 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/src/z3c/etree/testing.py 2007-07-03 18:31:14 UTC (rev 77374)
@@ -22,6 +22,7 @@
from zope.testing import doctest
import z3c.etree
+import z3c.etree.interfaces
import z3c.etree.etree
#
@@ -31,32 +32,39 @@
engine_env_key = "ELEMENTTREE_ENGINE"
known_engines = {
- "cElementTree": ("cElementTree", z3c.etree.etree.CEtree),
- "elementtree": ("elementtree.ElemenTree", z3c.etree.etree.EtreeEtree),
- "lxml": ("lxml.etree", z3c.etree.etree.LxmlEtree),
- "py25": ("xml.etree", z3c.etree.etree.EtreePy25),
+ "cElementTree": "cElementTree",
+ "elementtree": "elementtree.ElementTree",
+ "lxml": "lxml.etree",
+ "py25": "xml.etree",
}
+
+def importEngine(modname):
+ components = modname.split(".")
+ engine = __import__(components[0])
+ for comp in components[1:]:
+ engine = getattr(engine, comp)
+ return engine
+
+
def etreeSetup(test = None):
engine = None
if engine_env_key in os.environ:
- engine = known_engines[os.environ[engine_env_key]][1]()
+ engine = importEngine(known_engines[os.environ[engine_env_key]])
else:
- for key, info in known_engines.items():
- modname, factory = info
+ for key, modname in known_engines.items():
try:
- __import__(modname)
+ engine = __import__(modname)
+ break
except ImportError:
pass
- else:
- engine = factory()
- break
if engine is None:
raise ValueError("Failed to import a known element tree implementation")
- zope.component.getGlobalSiteManager().registerUtility(engine)
+ zope.component.getGlobalSiteManager().registerUtility(
+ engine, provided = z3c.etree.interfaces.IEtree)
if test is not None:
test.globs["etree"] = engine
@@ -80,7 +88,8 @@
del test.globs["assertXMLEqual"]
if etreeEngine is None:
etreeEngine = z3c.etree.getEngine()
- zope.component.getGlobalSiteManager().unregisterUtility(etreeEngine)
+ zope.component.getGlobalSiteManager().unregisterUtility(
+ etreeEngine, provided = z3c.etree.interfaces.IEtree)
z3c.etree._utility = None # clear the cache
#
@@ -149,7 +158,8 @@
etree = z3c.etree.getEngine()
if want.tag != got.tag:
- return False, "%r != %r different tag name." %(want.tag, got.tag)
+ return False, "%r != %r different tag name." %(str(want.tag),
+ str(got.tag))
if len(want) != len(got):
return False, "%d != %d different number of subchildren on %r." %(
len(want), len(got), want.tag)
Modified: z3c.etree/trunk/src/z3c/etree/tests.py
===================================================================
--- z3c.etree/trunk/src/z3c/etree/tests.py 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/src/z3c/etree/tests.py 2007-07-03 18:31:14 UTC (rev 77374)
@@ -134,16 +134,16 @@
def test_xmltreebulider(self):
self.assertRaises(NotImplementedError, self.etree.XMLTreeBuilder)
- def test_namespaces(self):
+ def test_mightbebroken_namespaces(self):
# When we have a element whoes namespace declaration is declared
- # in a parent element lxml doesn't print out the namespace
- # declaration by default.
+ # in a parent element lxml doesn't print out this namespace.
+ # This is a feature or bug of lxml but I don't think making work
+ # arounds is a good idea.
multinselemstr = """<D:prop xmlns:D="DAV:"><D:owner><H:href xmlns:H="examplens">http://example.org</H:href></D:owner></D:prop>"""
multinselem = self.etree.fromstring(multinselemstr)
self.assertEqual(self.etree.tostring(multinselem[0]),
- """<D:owner xmlns:D="DAV:"><H:href xmlns:H="examplens">http://example.org</H:href></D:owner>""")
+ """<D:owner><H:href xmlns:H="examplens">http://example.org</H:href></D:owner>""")
-
class Python25ElementTreeTestCase(BaseEtreeTestCase):
def setUp(self):
@@ -170,12 +170,14 @@
self.etree = etree
def __call__(self, test):
- component.getGlobalSiteManager().registerUtility(self.etree)
+ component.getGlobalSiteManager().registerUtility(
+ self.etree, provided = IEtree)
test.globs["etree"] = self.etree
def tearDown(test):
- component.getGlobalSiteManager().unregisterUtility(test.globs["etree"])
+ component.getGlobalSiteManager().unregisterUtility(
+ test.globs["etree"], provided = IEtree)
del test.globs["etree"]
@@ -289,6 +291,21 @@
optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
setUp = setUp(z3c.etree.etree.EtreeEtree()),
tearDown = tearDown))
+ suite.addTest(doctest.DocTestSuite(
+ "z3c.etree.testing",
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(elementtree.ElementTree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "doctestssuccess.txt", package = z3c.etree,
+ checker = z3c.etree.testing.xmlOutputChecker,
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(elementtree.ElementTree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "README.txt", package = z3c.etree,
+ setUp = doctestsSetup("elementtree"),
+ tearDown = doctestsTearDown))
foundetree = True
except ImportError:
pass
@@ -313,6 +330,21 @@
optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
setUp = setUp(z3c.etree.etree.CEtree()),
tearDown = tearDown))
+ suite.addTest(doctest.DocTestSuite(
+ "z3c.etree.testing",
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(cElementTree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "doctestssuccess.txt", package = z3c.etree,
+ checker = z3c.etree.testing.xmlOutputChecker,
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(cElementTree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "README.txt", package = z3c.etree,
+ setUp = doctestsSetup("cElementTree"),
+ tearDown = doctestsTearDown))
foundetree = True
except ImportError:
pass
@@ -337,6 +369,21 @@
optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
setUp = setUp(z3c.etree.etree.LxmlEtree()),
tearDown = tearDown))
+ suite.addTest(doctest.DocTestSuite(
+ "z3c.etree.testing",
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(lxml.etree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "doctestssuccess.txt", package = z3c.etree,
+ checker = z3c.etree.testing.xmlOutputChecker,
+ optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
+ setUp = setUp(lxml.etree),
+ tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "README.txt", package = z3c.etree,
+ setUp = doctestsSetup("lxml"),
+ tearDown = doctestsTearDown))
foundetree = True
except ImportError:
pass
@@ -361,6 +408,10 @@
optionflags = doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE,
setUp = setUp(z3c.etree.etree.EtreePy25()),
tearDown = tearDown))
+ suite.addTest(doctest.DocFileSuite(
+ "README.txt", package = z3c.etree,
+ setUp = doctestsSetup("py25"),
+ tearDown = doctestsTearDown))
foundetree = True
except ImportError:
pass
Modified: z3c.etree/trunk/src/z3c/etree/z3c.etree-configure.zcml
===================================================================
--- z3c.etree/trunk/src/z3c/etree/z3c.etree-configure.zcml 2007-07-03 17:58:06 UTC (rev 77373)
+++ z3c.etree/trunk/src/z3c/etree/z3c.etree-configure.zcml 2007-07-03 18:31:14 UTC (rev 77374)
@@ -11,7 +11,8 @@
uses the *elementtree* module.
-->
<utility
- factory="z3c.etree.etree.EtreeEtree"
+ factory="elementtree.ElementTree"
+ provided="z3c.etree.interfaces.IEtree"
/>
<!--
@@ -19,7 +20,8 @@
-->
<!--
<utility
- factory="z3c.etree.etree.CEtree"
+ factory="cElementTree"
+ provided="z3c.etree.interfaces.IEtree"
/>
-->
@@ -28,7 +30,8 @@
-->
<!--
<utility
- factory="z3c.etree.etree.LxmlEtree"
+ factory="lxml.etree"
+ provided="z3c.etree.interfaces.IEtree"
/>
-->
@@ -37,7 +40,8 @@
-->
<!--
<utility
- factory="z3c.etree.etree.EtreePy25"
+ factory="xml.etree.ElementTree"
+ provided="z3c.etree.interfaces.IEtree"
/>
-->
More information about the Checkins
mailing list