[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