[Python-checkins] r65497 - in doctools/trunk: EXAMPLES Makefile doc/markup/code.rst ez_setup.py sphinx/builder.py sphinx/directives/code.py sphinx/environment.py sphinx/highlighting.py sphinx/quickstart.py sphinx/util/__init__.py tests/etree13 tests/root/conf.py tests/root/contents.txt tests/root/images.txt tests/root/img.gif tests/root/img.pdf tests/root/img.png tests/root/includes.txt tests/root/literal.inc tests/root/subdir tests/root/wrongenc.inc tests/test_build.py tests/test_config.py tests/test_env.py tests/test_markup.py tests/test_quickstart.py tests/util.py

georg.brandl python-checkins at python.org
Mon Aug 4 19:01:16 CEST 2008


Author: georg.brandl
Date: Mon Aug  4 19:01:15 2008
New Revision: 65497

Log:
Merged revisions 65283,65303,65316-65317,65372-65375,65377,65380,65483-65485,65494 via svnmerge from 
svn+ssh://pythondev@svn.python.org/doctools/branches/0.4.x

........
  r65283 | georg.brandl | 2008-07-29 10:07:26 +0000 (Tue, 29 Jul 2008) | 2 lines
  
  Update ez_setup.py.
........
  r65303 | benjamin.peterson | 2008-07-30 12:35:34 +0000 (Wed, 30 Jul 2008) | 1 line
  
  add a with_testapp decorator for test functions that passes the TestApp instance in a cleans up after it
........
  r65316 | benjamin.peterson | 2008-07-30 23:12:07 +0000 (Wed, 30 Jul 2008) | 1 line
  
  make the app for test_markup global to the module
........
  r65317 | benjamin.peterson | 2008-07-30 23:31:29 +0000 (Wed, 30 Jul 2008) | 1 line
  
  make TestApp.cleanup more aggressive
........
  r65372 | georg.brandl | 2008-08-01 19:11:22 +0000 (Fri, 01 Aug 2008) | 2 lines
  
  Add more tests, fix a few bugs in image handling.
........
  r65373 | georg.brandl | 2008-08-01 19:28:33 +0000 (Fri, 01 Aug 2008) | 2 lines
  
  Fix oversight.
........
  r65374 | benjamin.peterson | 2008-08-01 19:36:32 +0000 (Fri, 01 Aug 2008) | 1 line
  
  fix one broken test
........
  r65375 | georg.brandl | 2008-08-01 19:41:11 +0000 (Fri, 01 Aug 2008) | 2 lines
  
  Fix the handling of non-ASCII input in quickstart.
........
  r65377 | georg.brandl | 2008-08-01 19:48:24 +0000 (Fri, 01 Aug 2008) | 2 lines
  
  Allow REs in markup checks.
........
  r65380 | georg.brandl | 2008-08-01 20:31:18 +0000 (Fri, 01 Aug 2008) | 2 lines
  
  Don't rely on mtimes being different for changed files.
........
  r65483 | georg.brandl | 2008-08-04 09:01:40 +0000 (Mon, 04 Aug 2008) | 4 lines
  
  Add an "encoding" option to literalinclude.
  
  Add tests for include directives.
........
  r65484 | georg.brandl | 2008-08-04 09:11:17 +0000 (Mon, 04 Aug 2008) | 2 lines
  
  Add changelog entry.
........
  r65485 | georg.brandl | 2008-08-04 09:21:58 +0000 (Mon, 04 Aug 2008) | 2 lines
  
  Fix markup.
........
  r65494 | georg.brandl | 2008-08-04 16:34:59 +0000 (Mon, 04 Aug 2008) | 2 lines
  
  Correctly use HTML file suffix in templates.
........


Added:
   doctools/trunk/tests/etree13/
      - copied from r65494, /doctools/branches/0.4.x/tests/etree13/
   doctools/trunk/tests/root/images.txt
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/images.txt
   doctools/trunk/tests/root/img.gif
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/img.gif
   doctools/trunk/tests/root/img.pdf
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/img.pdf
   doctools/trunk/tests/root/img.png
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/img.png
   doctools/trunk/tests/root/includes.txt
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/includes.txt
   doctools/trunk/tests/root/literal.inc
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/literal.inc
   doctools/trunk/tests/root/subdir/
      - copied from r65494, /doctools/branches/0.4.x/tests/root/subdir/
   doctools/trunk/tests/root/wrongenc.inc
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/root/wrongenc.inc
   doctools/trunk/tests/test_build.py
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/test_build.py
   doctools/trunk/tests/test_env.py
      - copied unchanged from r65494, /doctools/branches/0.4.x/tests/test_env.py
Modified:
   doctools/trunk/   (props changed)
   doctools/trunk/EXAMPLES
   doctools/trunk/Makefile
   doctools/trunk/doc/markup/code.rst
   doctools/trunk/ez_setup.py
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/directives/code.py
   doctools/trunk/sphinx/environment.py
   doctools/trunk/sphinx/highlighting.py
   doctools/trunk/sphinx/quickstart.py
   doctools/trunk/sphinx/util/__init__.py
   doctools/trunk/tests/root/conf.py
   doctools/trunk/tests/root/contents.txt
   doctools/trunk/tests/test_config.py
   doctools/trunk/tests/test_markup.py
   doctools/trunk/tests/test_quickstart.py
   doctools/trunk/tests/util.py

Modified: doctools/trunk/EXAMPLES
==============================================================================
--- doctools/trunk/EXAMPLES	(original)
+++ doctools/trunk/EXAMPLES	Mon Aug  4 19:01:15 2008
@@ -20,6 +20,7 @@
 * Py on Windows: http://timgolden.me.uk/python-on-windows/
 * mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html
 * Zope 3: e.g. http://docs.carduner.net/z3c-tutorial/
+* Glashammer: http://glashammer.welterde.de/
 * SymPy: http://docs.sympy.org/
 * Grok (upcoming)
 * Django (upcoming)

Modified: doctools/trunk/Makefile
==============================================================================
--- doctools/trunk/Makefile	(original)
+++ doctools/trunk/Makefile	Mon Aug  4 19:01:15 2008
@@ -27,4 +27,4 @@
 	@$(PYTHON) utils/reindent.py -r -B .
 
 test:
-	@cd tests; $(PYTHON) run.py -d
+	@cd tests; $(PYTHON) run.py -d -m '^[tT]est' $(TEST)

Modified: doctools/trunk/doc/markup/code.rst
==============================================================================
--- doctools/trunk/doc/markup/code.rst	(original)
+++ doctools/trunk/doc/markup/code.rst	Mon Aug  4 19:01:15 2008
@@ -100,6 +100,15 @@
          :language: ruby
          :linenos:
 
+   Include files are assumed to be encoded in UTF-8.  If the file has a different
+   encoding, you can specify it with the ``encoding`` option::
+
+      .. literalinclude:: example.py
+         :encoding: latin-1
+
+   .. versionadded:: 0.4.3
+      The ``encoding`` option.
+
 
 .. rubric:: Footnotes
 

Modified: doctools/trunk/ez_setup.py
==============================================================================
--- doctools/trunk/ez_setup.py	(original)
+++ doctools/trunk/ez_setup.py	Mon Aug  4 19:01:15 2008
@@ -14,8 +14,8 @@
 This file can also be run as a script to install or upgrade setuptools.
 """
 import sys
-DEFAULT_VERSION = "0.6c5"
-DEFAULT_URL     = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+DEFAULT_VERSION = "0.6c8"
+DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
 
 md5_data = {
     'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
@@ -39,6 +39,15 @@
     'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
     'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
     'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
+    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
+    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
+    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
+    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
+    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
+    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
+    'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
+    'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
+    'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
 }
 
 import sys, os
@@ -71,31 +80,31 @@
     this routine will print a message to ``sys.stderr`` and raise SystemExit in
     an attempt to abort the calling script.
     """
-    try:
-        import setuptools
-        if setuptools.__version__ == '0.0.1':
-            print >>sys.stderr, (
-            "You have an obsolete version of setuptools installed.  Please\n"
-            "remove it from your system entirely before rerunning this script."
-            )
-            sys.exit(2)
-    except ImportError:
+    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
+    def do_download():
         egg = download_setuptools(version, download_base, to_dir, download_delay)
         sys.path.insert(0, egg)
         import setuptools; setuptools.bootstrap_install_from = egg
-
-    import pkg_resources
     try:
-        pkg_resources.require("setuptools>="+version)
-
+        import pkg_resources
+    except ImportError:
+        return do_download()       
+    try:
+        pkg_resources.require("setuptools>="+version); return
     except pkg_resources.VersionConflict, e:
-        # XXX could we install in a subprocess here?
-        print >>sys.stderr, (
+        if was_imported:
+            print >>sys.stderr, (
             "The required version of setuptools (>=%s) is not available, and\n"
             "can't be installed while this script is running. Please install\n"
-            " a more recent version first.\n\n(Currently using %r)"
-        ) % (version, e.args[0])
-        sys.exit(2)
+            " a more recent version first, using 'easy_install -U setuptools'."
+            "\n\n(Currently using %r)"
+            ) % (version, e.args[0])
+            sys.exit(2)
+        else:
+            del pkg_resources, sys.modules['pkg_resources']    # reload ok
+            return do_download()
+    except pkg_resources.DistributionNotFound:
+        return do_download()
 
 def download_setuptools(
     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
@@ -144,9 +153,43 @@
             if dst: dst.close()
     return os.path.realpath(saveto)
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 def main(argv, version=DEFAULT_VERSION):
     """Install or upgrade setuptools and EasyInstall"""
-
     try:
         import setuptools
     except ImportError:
@@ -161,8 +204,11 @@
                 os.unlink(egg)
     else:
         if setuptools.__version__ == '0.0.1':
-            # tell the user to uninstall obsolete version
-            use_setuptools(version)
+            print >>sys.stderr, (
+            "You have an obsolete version of setuptools installed.  Please\n"
+            "remove it from your system entirely before rerunning this script."
+            )
+            sys.exit(2)
 
     req = "setuptools>="+version
     import pkg_resources
@@ -183,8 +229,6 @@
             print "Setuptools version",version,"or greater has been installed."
             print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
 
-
-
 def update_md5(filenames):
     """Update our built-in md5 registry"""
 
@@ -221,3 +265,8 @@
         update_md5(sys.argv[2:])
     else:
         main(sys.argv[1:])
+
+
+
+
+

Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Mon Aug  4 19:01:15 2008
@@ -145,6 +145,9 @@
                 node['uri'] = candidate
             else:
                 candidate = node['uri']
+            if candidate not in self.env.images:
+                # non-existing URI; let it alone
+                continue
             self.images[candidate] = self.env.images[candidate][1]
 
     # build methods

Modified: doctools/trunk/sphinx/directives/code.py
==============================================================================
--- doctools/trunk/sphinx/directives/code.py	(original)
+++ doctools/trunk/sphinx/directives/code.py	Mon Aug  4 19:01:15 2008
@@ -8,6 +8,7 @@
 """
 
 import sys
+import codecs
 from os import path
 
 from docutils import nodes
@@ -67,13 +68,19 @@
         lineno - state_machine.input_offset - 1)))
     fn = path.normpath(path.join(source_dir, rel_fn))
 
+    encoding = options.get('encoding', 'utf-8')
     try:
-        f = open(fn)
+        f = codecs.open(fn, 'r', encoding)
         text = f.read()
         f.close()
     except (IOError, OSError):
         retnode = state.document.reporter.warning(
             'Include file %r not found or reading it failed' % arguments[0], line=lineno)
+    except UnicodeError:
+        retnode = state.document.reporter.warning(
+            'Encoding %r used for reading included file %r seems to '
+            'be wrong, try giving an :encoding: option' %
+            (encoding, arguments[0]))
     else:
         retnode = nodes.literal_block(text, text, source=fn)
         retnode.line = 1
@@ -85,7 +92,8 @@
     return [retnode]
 
 literalinclude_directive.options = {'linenos': directives.flag,
-                                    'language': directives.unchanged}
+                                    'language': directives.unchanged,
+                                    'encoding': directives.encoding}
 literalinclude_directive.content = 0
 literalinclude_directive.arguments = (1, 0, 0)
 directives.register_directive('literalinclude', literalinclude_directive)

Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py	(original)
+++ doctools/trunk/sphinx/environment.py	Mon Aug  4 19:01:15 2008
@@ -559,12 +559,12 @@
             imgpath = path.normpath(path.join(docdir, imguri))
             node['uri'] = imgpath
             if imgpath.endswith(os.extsep + '*'):
-                for filename in glob(imgpath):
-                    basename, ext = os.path.splitext(filename)
-                    if ext == '.pdf':
-                        candidates['application/pdf'] = filename
-                    elif ext == '.svg':
-                        candidates['image/svg+xml'] = filename
+                for filename in glob(path.join(self.srcdir, imgpath)):
+                    dir, base = path.split(filename)
+                    if base.lower().endswith('.pdf'):
+                        candidates['application/pdf'] = path.join(docdir, base)
+                    elif base.lower().endswith('.svg'):
+                        candidates['image/svg+xml'] = path.join(docdir, base)
                     else:
                         f = open(filename, 'rb')
                         try:
@@ -572,23 +572,23 @@
                         finally:
                             f.close()
                         if imgtype:
-                            candidates['image/' + imgtype] = filename
+                            candidates['image/' + imgtype] = path.join(docdir, base)
             else:
                 candidates['*'] = imgpath
-            for img in candidates.itervalues():
-                self.dependencies.setdefault(docname, set()).add(img)
-                if not os.access(path.join(self.srcdir, img), os.R_OK):
-                    self.warn(docname, 'Image file not readable: %s' % img, node.line)
-                if img in self.images:
-                    self.images[img][0].add(docname)
+            for imgpath in candidates.itervalues():
+                self.dependencies.setdefault(docname, set()).add(imgpath)
+                if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
+                    self.warn(docname, 'Image file not readable: %s' % imgpath, node.line)
+                if imgpath in self.images:
+                    self.images[imgpath][0].add(docname)
                     continue
-                uniquename = path.basename(img)
+                uniquename = path.basename(imgpath)
                 base, ext = path.splitext(uniquename)
                 i = 0
                 while uniquename in existing_names:
                     i += 1
                     uniquename = '%s%s%s' % (base, i, ext)
-                self.images[img] = (set([docname]), uniquename)
+                self.images[imgpath] = (set([docname]), uniquename)
                 existing_names.add(uniquename)
 
     def process_metadata(self, docname, doctree):

Modified: doctools/trunk/sphinx/highlighting.py
==============================================================================
--- doctools/trunk/sphinx/highlighting.py	(original)
+++ doctools/trunk/sphinx/highlighting.py	Mon Aug  4 19:01:15 2008
@@ -128,6 +128,13 @@
                 if sys.version_info >= (2, 5):
                     src = 'from __future__ import with_statement\n' + src
 
+                if isinstance(src, unicode):
+                    # Non-ASCII chars will only occur in string literals
+                    # and comments.  If we wanted to give them to the parser
+                    # correctly, we'd have to find out the correct source
+                    # encoding.  Since it may not even be given in a snippet,
+                    # just replace all non-ASCII characters.
+                    src = src.encode('ascii', 'replace')
                 try:
                     parser.suite(src)
                 except parsing_exceptions:

Modified: doctools/trunk/sphinx/quickstart.py
==============================================================================
--- doctools/trunk/sphinx/quickstart.py	(original)
+++ doctools/trunk/sphinx/quickstart.py	Mon Aug  4 19:01:15 2008
@@ -12,8 +12,10 @@
 import sys, os, time
 from os import path
 
+TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
+
 from sphinx.util import make_filename
-from sphinx.util.console import purple, bold, red, nocolor
+from sphinx.util.console import purple, bold, red, turquoise, nocolor
 
 
 PROMPT_PREFIX = '> '
@@ -56,8 +58,8 @@
 master_doc = '%(master)s'
 
 # General substitutions.
-project = %(project)r
-copyright = '%(year)s, %(author)s'
+project = u'%(project)s'
+copyright = u'%(copyright)s'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
@@ -178,8 +180,8 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, document class [howto/manual]).
 latex_documents = [
-  ('%(master)s', '%(project_fn)s.tex', '%(project)s Documentation',
-   '%(author)s', 'manual'),
+  ('%(master)s', '%(project_fn)s.tex', u'%(project_doc)s',
+   u'%(author)s', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -343,8 +345,18 @@
         x = raw_input(prompt)
         if default and not x:
             x = default
+        if x.decode('ascii', 'replace').encode('ascii', 'replace') != x:
+            if TERM_ENCODING:
+                x = x.decode(TERM_ENCODING)
+            else:
+                print turquoise('* Note: non-ASCII characters entered and terminal '
+                                'encoding unknown -- assuming UTF-8 or Latin-1.')
+                try:
+                    x = x.decode('utf-8')
+                except UnicodeDecodeError:
+                    x = x.decode('latin1')
         if validator and not validator(x):
-            print red(" * " + validator.__doc__)
+            print red('* ' + validator.__doc__)
             continue
         break
     d[key] = x
@@ -414,12 +426,13 @@
               os.name == 'posix' and 'y' or 'n', boolean)
 
     d['project_fn'] = make_filename(d['project'])
-    d['year'] = time.strftime('%Y')
     d['now'] = time.asctime()
     d['underline'] = len(d['project']) * '='
     d['extensions'] = ', '.join(
         repr('sphinx.ext.' + name) for name in ('autodoc', 'doctest')
         if d['ext_' + name].upper() in ('Y', 'YES'))
+    d['copyright'] = time.strftime('%Y') + ', ' + d['author']
+    d['project_doc'] = d['project'] + ' Documentation'
 
     if not path.isdir(d['path']):
         mkdir_p(d['path'])
@@ -437,12 +450,12 @@
     mkdir_p(path.join(srcdir, d['dot'] + 'static'))
 
     f = open(path.join(srcdir, 'conf.py'), 'w')
-    f.write(QUICKSTART_CONF % d)
+    f.write((QUICKSTART_CONF % d).encode('utf-8'))
     f.close()
 
     masterfile = path.join(srcdir, d['master'] + d['suffix'])
     f = open(masterfile, 'w')
-    f.write(MASTER_FILE % d)
+    f.write((MASTER_FILE % d).encode('utf-8'))
     f.close()
 
     create_makefile = d['makefile'].upper() in ('Y', 'YES')
@@ -450,7 +463,7 @@
         d['rsrcdir'] = separate and 'source' or '.'
         d['rbuilddir'] = separate and 'build' or d['dot'] + 'build'
         f = open(path.join(d['path'], 'Makefile'), 'w')
-        f.write(MAKEFILE % d)
+        f.write((MAKEFILE % d).encode('utf-8'))
         f.close()
 
     print

Modified: doctools/trunk/sphinx/util/__init__.py
==============================================================================
--- doctools/trunk/sphinx/util/__init__.py	(original)
+++ doctools/trunk/sphinx/util/__init__.py	Mon Aug  4 19:01:15 2008
@@ -256,7 +256,7 @@
     return filter(match, names)
 
 
-no_fn_re = re.compile(r'[:/\\?*%|"\'<>. \t]')
+no_fn_re = re.compile(r'[^a-zA-Z0-9_-]')
 
 def make_filename(string):
     return no_fn_re.sub('', string)

Modified: doctools/trunk/tests/root/conf.py
==============================================================================
--- doctools/trunk/tests/root/conf.py	(original)
+++ doctools/trunk/tests/root/conf.py	Mon Aug  4 19:01:15 2008
@@ -32,7 +32,7 @@
 source_suffix = '.txt'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = 'contents'
 
 # General substitutions.
 project = 'Sphinx Tests'

Modified: doctools/trunk/tests/root/contents.txt
==============================================================================
--- doctools/trunk/tests/root/contents.txt	(original)
+++ doctools/trunk/tests/root/contents.txt	Mon Aug  4 19:01:15 2008
@@ -10,10 +10,12 @@
 .. toctree::
    :maxdepth: 2
 
+   images
+   includes
+
 Indices and tables
 ==================
 
 * :ref:`genindex`
 * :ref:`modindex`
 * :ref:`search`
-

Modified: doctools/trunk/tests/test_config.py
==============================================================================
--- doctools/trunk/tests/test_config.py	(original)
+++ doctools/trunk/tests/test_config.py	Mon Aug  4 19:01:15 2008
@@ -15,9 +15,9 @@
 from sphinx.application import ExtensionError
 
 
-def test_core_config():
-    overrides = {'master_doc': 'master', 'nonexisting_value': 'True'}
-    cfg = TestApp(confoverrides=overrides).config
+ at with_testapp(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True'})
+def test_core_config(app):
+    cfg = app.config
 
     # simple values
     assert 'project' in cfg.__dict__
@@ -61,8 +61,8 @@
     assert cfg['project'] == cfg.project == 'Sphinx Tests'
 
 
-def test_extension_values():
-    app = TestApp()
+ at with_testapp()
+def test_extension_values(app):
     cfg = app.config
 
     # default value

Modified: doctools/trunk/tests/test_markup.py
==============================================================================
--- doctools/trunk/tests/test_markup.py	(original)
+++ doctools/trunk/tests/test_markup.py	Mon Aug  4 19:01:15 2008
@@ -9,6 +9,8 @@
     :license: BSD.
 """
 
+import re
+
 from util import *
 
 from docutils import frontend, utils, nodes
@@ -18,11 +20,16 @@
 from sphinx.htmlwriter import HTMLWriter, SmartyPantsHTMLTranslator
 from sphinx.latexwriter import LaTeXWriter, LaTeXTranslator
 
-app = TestApp()
-optparser = frontend.OptionParser(components=(rst.Parser, HTMLWriter, LaTeXWriter))
-settings = optparser.get_default_values()
-settings.env = app.builder.env
-parser = rst.Parser()
+def setup_module():
+    global app, settings, parser
+    app = TestApp()
+    optparser = frontend.OptionParser(components=(rst.Parser, HTMLWriter, LaTeXWriter))
+    settings = optparser.get_default_values()
+    settings.env = app.builder.env
+    parser = rst.Parser()
+
+def teardown_module():
+    app.cleanup()
 
 # since we're not resolving the markup afterwards, these nodes may remain
 class ForgivingTranslator:
@@ -38,7 +45,7 @@
     pass
 
 
-def verify(rst, html_expected, latex_expected):
+def verify_re(rst, html_expected, latex_expected):
     document = utils.new_document('test data', settings)
     parser.parse(rst, document)
     for msg in document.traverse(nodes.system_message):
@@ -49,14 +56,17 @@
         html_translator = ForgivingHTMLTranslator(app.builder, document)
         document.walkabout(html_translator)
         html_translated = ''.join(html_translator.fragment).strip()
-        assert html_translated == html_expected, 'from ' + rst
+        assert re.match(html_expected, html_translated), 'from' + rst
 
     if latex_expected:
         latex_translator = ForgivingLaTeXTranslator(document, app.builder)
         latex_translator.first_document = -1 # don't write \begin{document}
         document.walkabout(latex_translator)
         latex_translated = ''.join(latex_translator.body).strip()
-        assert latex_translated == latex_expected, 'from ' + rst
+        assert re.match(latex_expected, latex_translated), 'from ' + rst
+
+def verify(rst, html_expected, latex_expected):
+    verify_re(rst, re.escape(html_expected) + '$', re.escape(latex_expected) + '$')
 
 
 def test_inline():
@@ -78,9 +88,9 @@
            '\\emph{a $\\rightarrow$ b}')
 
     # non-interpolation of dashes in option role
-    verify(':option:`--with-option`',
-           '<p><em>--with-option</em></p>',
-           r'\emph{\texttt{--with-option}}')
+    verify_re(':option:`--with-option`',
+              '<p><em( class="xref")?>--with-option</em></p>$',
+              r'\\emph{\\texttt{--with-option}}$')
 
     # verify smarty-pants quotes
     verify('"John"', '<p>&#8220;John&#8221;</p>', "``John''")

Modified: doctools/trunk/tests/test_quickstart.py
==============================================================================
--- doctools/trunk/tests/test_quickstart.py	(original)
+++ doctools/trunk/tests/test_quickstart.py	Mon Aug  4 19:01:15 2008
@@ -38,6 +38,7 @@
 
 def teardown_module():
     qs.raw_input = __builtin__.raw_input
+    qs.TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
     coloron()
 
 
@@ -108,10 +109,10 @@
         'Root path': tempdir,
         'Separate source and build': 'y',
         'Name prefix for templates': '_',
-        'Project name': 'Sphinx Test',
-        'Author name': 'Georg Brandl',
-        'Project version': '0.1',
-        'Project release': '0.1.1',
+        'Project name': 'STASI\xe2\x84\xa2',
+        'Author name': 'Wolfgang Sch\xc3\xa4uble',
+        'Project version': '2.0',
+        'Project release': '2.0.1',
         'Source file suffix': '.txt',
         'Name of your master document': 'contents',
         'autodoc': 'y',
@@ -119,6 +120,7 @@
         'Create Makefile': 'no',
     }
     qs.raw_input = mock_raw_input(answers, needanswer=True)
+    qs.TERM_ENCODING = 'utf-8'
     qs.inner_main([])
 
     conffile = tempdir / 'source' / 'conf.py'
@@ -129,14 +131,14 @@
     assert ns['templates_path'] == ['_templates']
     assert ns['source_suffix'] == '.txt'
     assert ns['master_doc'] == 'contents'
-    assert ns['project'] == 'Sphinx Test'
-    assert ns['copyright'] == '%s, Georg Brandl' % time.strftime('%Y')
-    assert ns['version'] == '0.1'
-    assert ns['release'] == '0.1.1'
+    assert ns['project'] == u'STASI™'
+    assert ns['copyright'] == u'%s, Wolfgang Schäuble' % time.strftime('%Y')
+    assert ns['version'] == '2.0'
+    assert ns['release'] == '2.0.1'
     assert ns['html_static_path'] == ['_static']
     assert ns['latex_documents'] == [
-        ('contents', 'SphinxTest.tex', 'Sphinx Test Documentation',
-         'Georg Brandl', 'manual')]
+        ('contents', 'STASI.tex', u'STASI™ Documentation',
+         u'Wolfgang Schäuble', 'manual')]
 
     assert (tempdir / 'build').isdir()
     assert (tempdir / 'source' / '_static').isdir()

Modified: doctools/trunk/tests/util.py
==============================================================================
--- doctools/trunk/tests/util.py	(original)
+++ doctools/trunk/tests/util.py	Mon Aug  4 19:01:15 2008
@@ -8,19 +8,26 @@
 """
 
 import sys
+import os
 import StringIO
 import tempfile
+import shutil
+
+from functools import wraps
 
 from sphinx import application, builder
 
 from path import path
 
+from nose import tools
+
 
 __all__ = [
     'test_root',
     'raises', 'raises_msg',
-    'ErrorOutput', 'TestApp',
+    'ListOutput', 'TestApp', 'with_testapp',
     'path', 'with_tempdir', 'write_file',
+    'sprint',
 ]
 
 
@@ -59,15 +66,19 @@
                              (func.__name__, _excstr(exc)))
 
 
-class ErrorOutput(object):
+class ListOutput(object):
     """
-    File-like object that raises :exc:`AssertionError` on ``write()``.
+    File-like object that collects written text in a list.
     """
     def __init__(self, name):
         self.name = name
+        self.content = []
+
+    def reset(self):
+        del self.content[:]
 
     def write(self, text):
-        assert False, 'tried to write %r to %s' % (text, self.name)
+        self.content.append(text)
 
 
 class TestApp(application.Sphinx):
@@ -84,20 +95,32 @@
 
         if srcdir is None:
             srcdir = test_root
+        if srcdir == '(temp)':
+            tempdir = path(tempfile.mkdtemp()) / 'root'
+            test_root.copytree(tempdir)
+            srcdir = tempdir
         else:
             srcdir = path(srcdir)
+        self.builddir = srcdir.joinpath('_build')
+        if not self.builddir.isdir():
+            self.builddir.makedirs()
+            self.made_builddir = True
+        else:
+            self.made_builddir = False
         if confdir is None:
             confdir = srcdir
         if outdir is None:
-            outdir = srcdir.joinpath('_build', buildername)
+            outdir = srcdir.joinpath(self.builddir, buildername)
+            if not outdir.isdir():
+                outdir.makedirs()
         if doctreedir is None:
-            doctreedir = srcdir.joinpath(srcdir, '_build', 'doctrees')
+            doctreedir = srcdir.joinpath(srcdir, self.builddir, 'doctrees')
         if confoverrides is None:
             confoverrides = {}
         if status is None:
             status = StringIO.StringIO()
         if warning is None:
-            warning = ErrorOutput('stderr')
+            warning = ListOutput('stderr')
         if freshenv is None:
             freshenv = True
 
@@ -105,6 +128,30 @@
                                     buildername, confoverrides, status, warning,
                                     freshenv)
 
+    def cleanup(self):
+        trees = [self.outdir, self.doctreedir]
+        #f self.made_builddir:
+        #    trees.append(self.builddir)
+        #for tree in trees:
+        #    shutil.rmtree(tree, True)
+
+
+def with_testapp(*args, **kwargs):
+    """
+    Make a TestApp with args and kwargs, pass it to the test and clean up
+    properly.
+    """
+    def generator(func):
+        @wraps(func)
+        def deco(*args2, **kwargs2):
+            app = TestApp(*args, **kwargs)
+            try:
+                func(app, *args2, **kwargs2)
+            finally:
+                app.cleanup()
+        return deco
+    return generator
+
 
 def with_tempdir(func):
     def new_func():
@@ -119,3 +166,7 @@
     f = open(str(name), 'wb')
     f.write(contents)
     f.close()
+
+
+def sprint(*args):
+    sys.stderr.write(' '.join(map(str, args)) + '\n')


More information about the Python-checkins mailing list