Commits

Georg Brandl committed 99aa519 Merge

merge with 1.0

  • Participants
  • Parent commits cb12029, 16ebc97

Comments (0)

Files changed (31)

 Release 1.0.2 (in development)
 ==============================
 
+* Allow breaking long signatures, continuing with backlash-escaped
+  newlines.
+
+* Fix unwanted styling of C domain references (because of a namespace
+  clash with Pygments styles).
+
+* Allow references to PEPs and RFCs with explicit anchors.
+
+* #471: Fix LaTeX references to figures.
+
+* #482: When doing a non-exact search, match only the given type
+  of object.
+
+* #481: Apply non-exact search for Python reference targets with
+  ``.name`` for modules too.
+
+* #484: Fix crash when duplicating a parameter in an info field list.
+
+* #487: Fix setting the default role to one provided by the
+  ``oldcmarkup`` extension.
+
+* #488: Fix crash when json-py is installed, which provides a
+  ``json`` module but is incompatible to simplejson.
+
+* #480: Fix handling of target naming in intersphinx.
+
+* #486: Fix removal of ``!`` for all cross-reference roles.
+
+
 Release 1.0.1 (Jul 27, 2010)
 ============================
 
 * Satchmo: http://www.satchmoproject.com/docs/svn/
 * Sphinx: http://sphinx.pocoo.org/
 * Sqlkit: http://sqlkit.argolinux.org/
+* Tau: http://www.tango-controls.org/static/tau/latest/doc/html/index.html
 * Total Open Station: http://tops.berlios.de/
 * WebFaction: http://docs.webfaction.com/
 

File doc/builders.rst

 files.  They also copy the reST source files in the directory ``_sources``
 under the output directory.
 
-The :class:`PickleHTMLBuilder` is a builtin subclass that implements the pickle
+The :class:`.PickleHTMLBuilder` is a builtin subclass that implements the pickle
 serialization interface.
 
 The files per source file have the extensions of
-:attr:`~SerializingHTMLBuilder.out_suffix`, and are arranged in directories
+:attr:`~.SerializingHTMLBuilder.out_suffix`, and are arranged in directories
 just as the source files are.  They unserialize to a dictionary (or dictionary
 like structure) with these keys:
 
 
 The special files are located in the root output directory.  They are:
 
-:attr:`SerializingHTMLBuilder.globalcontext_filename`
+:attr:`.SerializingHTMLBuilder.globalcontext_filename`
    A pickled dict with these keys:
 
    ``project``, ``copyright``, ``release``, ``version``
    ``titles``
       A dictionary of all documents' titles, as HTML strings.
 
-:attr:`SerializingHTMLBuilder.searchindex_filename`
+:attr:`.SerializingHTMLBuilder.searchindex_filename`
    An index that can be used for searching the documentation.  It is a pickled
    list with these entries:
 
      'template generator', '', 1),
 ]
 
+# We're not using intersphinx right now, but if we did, this would be part of
+# the mapping:
+intersphinx_mapping = {'python': ('http://docs.python.org/dev', None)}
+
 
 # -- Extension interface -------------------------------------------------------
 

File doc/config.rst

 
    A boolean that decides whether module names are prepended to all
    :term:`object` names (for object types where a "module" of some kind is
-   defined), e.g. for :rst:dir:`function` directives.  Default is ``True``.
+   defined), e.g. for :rst:dir:`py:function` directives.  Default is ``True``.
 
 .. confval:: show_authors
 
-   A boolean that decides whether :rst:dir:`moduleauthor` and :rst:dir:`sectionauthor`
-   directives produce any output in the built files.
+   A boolean that decides whether :rst:dir:`codeauthor` and
+   :rst:dir:`sectionauthor` directives produce any output in the built files.
 
 .. confval:: modindex_common_prefix
 
 These options influence HTML as well as HTML Help output, and other builders
 that use Sphinx' HTMLWriter class.
 
+.. XXX document html_context
+
 .. confval:: html_theme
 
    The "theme" that the HTML output should use.  See the :doc:`section about
    This will render the template ``customdownload.html`` as the page
    ``download.html``.
 
-   .. note::
-
-      Earlier versions of Sphinx had a value called :confval:`html_index` which
-      was a clumsy way of controlling the content of the "index" document.  If
-      you used this feature, migrate it by adding an ``'index'`` key to this
-      setting, with your custom template as the value, and in your custom
-      template, use ::
-
-         {% extend "defindex.html" %}
-         {% block tables %}
-         ... old template content ...
-         {% endblock %}
-
 .. confval:: html_domain_indices
 
    If true, generate domain-specific indices in addition to the general index.

File doc/domains.rst

 
    .. py:function:: spam(eggs)
                     ham(eggs)
+
+      Spam or ham the foo.
+
+This describes the two Python functions ``spam`` and ``ham``.  (Note that when
+signatures become too long, you can break them if you add a backslash to lines
+that are continued in the next line.  Example::
+
+   .. py:function:: filterwarnings(action, message='', category=Warning, \
+                                   module='', lineno=0, append=False)
       :noindex:
 
-      Spam or ham the foo.
+(This example also shows how to use the ``:noindex:`` flag.)
 
 The domains also provide roles that link back to these object descriptions.  For
 example, to link to one of the functions described in the example above, you
 .. rst:directive:: .. py:currentmodule:: name
 
    This directive tells Sphinx that the classes, functions etc. documented from
-   here are in the given module (like :rst:dir:`py:module`), but it will not create
-   index entries, an entry in the Global Module Index, or a link target for
-   :rst:role:`mod`.  This is helpful in situations where documentation for things in
-   a module is spread over multiple files or sections -- one location has the
-   :rst:dir:`py:module` directive, the others only :rst:dir:`py:currentmodule`.
+   here are in the given module (like :rst:dir:`py:module`), but it will not
+   create index entries, an entry in the Global Module Index, or a link target
+   for :rst:role:`py:mod`.  This is helpful in situations where documentation
+   for things in a module is spread over multiple files or sections -- one
+   location has the :rst:dir:`py:module` directive, the others only
+   :rst:dir:`py:currentmodule`.
 
 
 The following directives are provided for module and class contents:
 :mod:`codecs` module, ``:py:func:`open``` always refers to the built-in
 function, while ``:py:func:`.open``` refers to :func:`codecs.open`.
 
+A similar heuristic is used to determine whether the name is an attribute of the
+currently documented class.
+
 Also, if the name is prefixed with a dot, and no exact match is found, the
 target is taken as a suffix and all object names with that suffix are
 searched.  For example, ``:py:meth:`.TarFile.close``` references the
 ``tarfile``.  Since this can get ambiguous, if there is more than one possible
 match, you will get a warning from Sphinx.
 
-A similar heuristic is used to determine whether the name is an attribute of the
-currently documented class.
+Note that you can combine the ``~`` and ``.`` prefixes:
+``:py:meth:`~.TarFile.close``` will reference the ``tarfile.TarFile.close()``
+method, but the visible link caption will only be ``close()``.
 
 
 .. _c-domain:

File doc/ext/appapi.rst

    standard Sphinx roles (see :ref:`xref-syntax`).
 
    This method is also available under the deprecated alias
-   :meth:`add_description_unit`.
+   ``add_description_unit``.
 
 .. method:: Sphinx.add_crossref_type(directivename, rolename, indextemplate='', ref_nodeclass=None, objname='')
 
    This allows to auto-document new types of objects.  See the source of the
    autodoc module for examples on how to subclass :class:`Documenter`.
 
+   .. XXX add real docs for Documenter and subclassing
+
    .. versionadded:: 0.6
 
 .. method:: Sphinx.add_autodoc_attrgetter(type, getter)

File doc/ext/autodoc.rst

 auto-generated-looking pure API documentation.
 
 :mod:`autodoc` provides several directives that are versions of the usual
-:rst:dir:`module`, :rst:dir:`class` and so forth.  On parsing time, they import the
-corresponding module and extract the docstring of the given objects, inserting
-them into the page source under a suitable :rst:dir:`module`, :rst:dir:`class` etc.
-directive.
+:rst:dir:`py:module`, :rst:dir:`py:class` and so forth.  On parsing time, they
+import the corresponding module and extract the docstring of the given objects,
+inserting them into the page source under a suitable :rst:dir:`py:module`,
+:rst:dir:`py:class` etc.  directive.
 
 .. note::
 
-   Just as :rst:dir:`class` respects the current :rst:dir:`module`, :rst:dir:`autoclass`
-   will also do so, and likewise with :rst:dir:`method` and :rst:dir:`class`.
+   Just as :rst:dir:`py:class` respects the current :rst:dir:`py:module`,
+   :rst:dir:`autoclass` will also do so.  Likewise, :rst:dir:`automethod` will
+   respect the current :rst:dir:`py:class`.
 
 
 .. rst:directive:: automodule
-               autoclass
-               autoexception
+                   autoclass
+                   autoexception
 
    Document a module, class or exception.  All three directives will by default
    only insert the docstring of the object itself::
 
      .. versionadded:: 0.4
 
-   * The :rst:dir:`automodule`, :rst:dir:`autoclass` and :rst:dir:`autoexception` directives
-     also support a flag option called ``show-inheritance``.  When given, a list
-     of base classes will be inserted just below the class signature (when used
-     with :rst:dir:`automodule`, this will be inserted for every class that is
-     documented in the module).
+   * The :rst:dir:`automodule`, :rst:dir:`autoclass` and
+     :rst:dir:`autoexception` directives also support a flag option called
+     ``show-inheritance``.  When given, a list of base classes will be inserted
+     just below the class signature (when used with :rst:dir:`automodule`, this
+     will be inserted for every class that is documented in the module).
 
      .. versionadded:: 0.4
 
    * All autodoc directives support the ``noindex`` flag option that has the
-     same effect as for standard :rst:dir:`function` etc. directives: no index
-     entries are generated for the documented object (and all autodocumented
-     members).
+     same effect as for standard :rst:dir:`py:function` etc. directives: no
+     index entries are generated for the documented object (and all
+     autodocumented members).
 
      .. versionadded:: 0.4
 
    * :rst:dir:`automodule` also recognizes the ``synopsis``, ``platform`` and
-     ``deprecated`` options that the standard :rst:dir:`module` directive supports.
+     ``deprecated`` options that the standard :rst:dir:`py:module` directive
+     supports.
 
      .. versionadded:: 0.5
 
 
    ``"class"``
       Only the class' docstring is inserted.  This is the default.  You can
-      still document ``__init__`` as a separate method using :rst:dir:`automethod`
-      or the ``members`` option to :rst:dir:`autoclass`.
+      still document ``__init__`` as a separate method using
+      :rst:dir:`automethod` or the ``members`` option to :rst:dir:`autoclass`.
    ``"both"``
       Both the class' and the ``__init__`` method's docstring are concatenated
       and inserted.

File doc/ext/inheritance.rst

 
    This directive has one or more arguments, each giving a module or class
    name.  Class names can be unqualified; in that case they are taken to exist
-   in the currently described module (see :rst:dir:`module`).
+   in the currently described module (see :rst:dir:`py:module`).
 
    For each given class, and each class in each given module, the base classes
    are determined.  Then, from all classes and their base classes, a graph is

File doc/ext/intersphinx.rst

    To add links to modules and objects in the Python standard library
    documentation, use::
 
-      intersphinx_mapping = {'python': ('http://docs.python.org/', None)}
+      intersphinx_mapping = {'python': ('http://docs.python.org/3.2', None)}
 
    This will download the corresponding :file:`objects.inv` file from the
    Internet and generate links to the pages under the given URI.  The downloaded
    A second example, showing the meaning of a non-``None`` value of the second
    tuple item::
 
-      intersphinx_mapping = {'python': ('http://docs.python.org/',
+      intersphinx_mapping = {'python': ('http://docs.python.org/3.2',
                                         'python-inv.txt')}
 
    This will read the inventory from :file:`python-inv.txt` in the source
    directory, but still generate links to the pages under
-   ``http://docs.python.org/``.  It is up to you to update the inventory file as
+   ``http://docs.python.org/3.2``.  It is up to you to update the inventory file as
    new objects are added to the Python documentation.
 
 .. confval:: intersphinx_cache_limit

File doc/ext/math.rst

 
 .. note::
 
-   :mod:`sphinx.ext.mathbase` is not meant to be added to the
-   :confval:`extensions` config value, instead, use either
-   :mod:`sphinx.ext.pngmath` or :mod:`sphinx.ext.jsmath` as described below.
+   :mod:`.mathbase` is not meant to be added to the :confval:`extensions` config
+   value, instead, use either :mod:`sphinx.ext.pngmath` or
+   :mod:`sphinx.ext.jsmath` as described below.
 
 The input language for mathematics is LaTeX markup.  This is the de-facto
 standard for plain-text math notation and has the added advantage that no
 further translation is necessary when building LaTeX output.
 
-:mod:`mathbase` defines these new markup elements:
+:mod:`.mathbase` defines these new markup elements:
 
 .. rst:role:: math
 

File doc/markup/inline.rst

 .. rst:role:: samp
 
    A piece of literal text, such as code.  Within the contents, you can use
-   curly braces to indicate a "variable" part, as in :rst:dir:`file`.  For
+   curly braces to indicate a "variable" part, as in :rst:role:`file`.  For
    example, in ``:samp:`print 1+{variable}```, the part ``variable`` would be
    emphasized.
 
 
    A reference to a Python Enhancement Proposal.  This generates appropriate
    index entries. The text "PEP *number*\ " is generated; in the HTML output,
-   this text is a hyperlink to an online copy of the specified PEP.
+   this text is a hyperlink to an online copy of the specified PEP.  You can
+   link to a specific section by saying ``:pep:`number#anchor```.
 
 .. rst:role:: rfc
 
    A reference to an Internet Request for Comments.  This generates appropriate
    index entries. The text "RFC *number*\ " is generated; in the HTML output,
-   this text is a hyperlink to an online copy of the specified RFC.
+   this text is a hyperlink to an online copy of the specified RFC.  You can
+   link to a specific section by saying ``:rfc:`number#anchor```.
 
 
 Note that there are no special roles for including hyperlinks as you can use

File doc/markup/para.rst

    Example::
 
       .. versionadded:: 2.5
-         The `spam` parameter.
+         The *spam* parameter.
 
    Note that there must be no blank line between the directive head and the
    explanation; this is to make these blocks visually continuous in the markup.
 
 .. rst:directive:: .. versionchanged:: version
 
-   Similar to :rst:dir:`versionadded`, but describes when and what changed in the named
-   feature in some way (new parameters, changed side effects, etc.).
+   Similar to :rst:dir:`versionadded`, but describes when and what changed in
+   the named feature in some way (new parameters, changed side effects, etc.).
+
+.. rst:directive:: .. deprecated:: vesion
+
+   Similar to :rst:dir:`versionchanged`, but describes when the feature was
+   deprecated.  An explanation can also be given, for example to inform the
+   reader what should be used instead.  Example::
+
+      .. deprecated:: 3.1
+         Use :func:`spam` instead.
+
 
 --------------
 

File doc/markup/toctree.rst

   :ref:`object descriptions <basic-domain-markup>`, and from :rst:dir:`index`
   directives.
 
-  The module index contains one entry per :rst:dir:`module` directive.
+  The Python module index contains one entry per :rst:dir:`py:module` directive.
 
   The search page contains a form that uses the generated JSON search index and
   JavaScript to full-text search the generated documents for search words; it

File doc/templating.rst

   configuration value accordingly.
 
 * You can :ref:`write a custom builder <writing-builders>` that derives from
-  :class:`~sphinx.builders.StandaloneHTMLBuilder` and calls your template engine
-  of choice.
+  :class:`~sphinx.builders.html.StandaloneHTMLBuilder` and calls your template
+  engine of choice.
 
-* You can use the :class:`~sphinx.builders.PickleHTMLBuilder` that produces
+* You can use the :class:`~sphinx.builders.html.PickleHTMLBuilder` that produces
   pickle files with the page contents, and postprocess them using a custom tool,
   or use them in your Web application.
 
 
 .. data:: file_suffix
 
-   The value of the builder's :attr:`out_suffix` attribute, i.e. the file name
-   extension that the output files will get.  For a standard HTML builder, this
-   is usually ``.html``.
+   The value of the builder's :attr:`~.SerializingHTMLBuilder.out_suffix`
+   attribute, i.e. the file name extension that the output files will get.  For
+   a standard HTML builder, this is usually ``.html``.
 
 .. data:: has_source
 

File sphinx/directives/__init__.py

 
 
 # RE to strip backslash escapes
+nl_escape_re = re.compile(r'\\\n')
 strip_backslash_re = re.compile(r'\\(?=[^\\])')
 
 
         """
         Retrieve the signatures to document from the directive arguments.  By
         default, signatures are given as arguments, one per line.
+
+        Backslash-escaping of newlines is supported.
         """
+        lines = nl_escape_re.sub('', self.arguments[0]).split('\n')
         # remove backslashes to support (dummy) escapes; helps Vim highlighting
-        return [strip_backslash_re.sub('', sig.strip())
-                for sig in self.arguments[0].split('\n')]
+        return [strip_backslash_re.sub('', line.strip()) for line in lines]
 
     def handle_signature(self, sig, signode):
         """

File sphinx/domains/python.py

         env.domaindata['py']['modules'][modname] = \
             (env.docname, self.options.get('synopsis', ''),
              self.options.get('platform', ''), 'deprecated' in self.options)
+        # make a duplicate entry in 'objects' to facilitate searching for the
+        # module in PythonDomain.find_obj()
+        env.domaindata['py']['objects'][modname] = (env.docname, 'module')
         targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
         self.state.document.note_explicit_target(targetnode)
         ret = [targetnode]
             if fn == docname:
                 del self.data['modules'][modname]
 
-    def find_obj(self, env, modname, classname, name, type, searchorder=0):
+    def find_obj(self, env, modname, classname, name, type, searchmode=0):
         """
         Find a Python object for "name", perhaps using the given module and/or
         classname.  Returns a list of (name, object entry) tuples.
         matches = []
 
         newname = None
-        if searchorder == 1:
-            if modname and classname and \
-                   modname + '.' + classname + '.' + name in objects:
-                newname = modname + '.' + classname + '.' + name
-            elif modname and modname + '.' + name in objects:
-                newname = modname + '.' + name
-            elif name in objects:
-                newname = name
-            else:
-                # "fuzzy" searching mode
-                searchname = '.' + name
-                matches = [(name, objects[name]) for name in objects
-                           if name.endswith(searchname)]
+        if searchmode == 1:
+            objtypes = self.objtypes_for_role(type)
+            if modname and classname:
+                fullname = modname + '.' + classname + '.' + name
+                if fullname in objects and objects[fullname][1] in objtypes:
+                    newname = fullname
+            if not newname:
+                if modname and modname + '.' + name in objects and \
+                   objects[modname + '.' + name][1] in objtypes:
+                    newname = modname + '.' + name
+                elif name in objects and objects[name][1] in objtypes:
+                    newname = name
+                else:
+                    # "fuzzy" searching mode
+                    searchname = '.' + name
+                    matches = [(name, objects[name]) for name in objects
+                               if name.endswith(searchname)
+                               and objects[name][1] in objtypes]
         else:
+            # NOTE: searching for exact match, object type is not considered
             if name in objects:
                 newname = name
+            elif type == 'mod':
+                # only exact matches allowed for modules
+                return []
             elif classname and classname + '.' + name in objects:
                 newname = classname + '.' + name
             elif modname and modname + '.' + name in objects:
 
     def resolve_xref(self, env, fromdocname, builder,
                      type, target, node, contnode):
-        if (type == 'mod' or
-            type == 'obj' and target in self.data['modules']):
-            docname, synopsis, platform, deprecated = \
-                self.data['modules'].get(target, ('','','', ''))
-            if not docname:
-                return None
-            else:
-                title = '%s%s%s' % ((platform and '(%s) ' % platform),
-                                    synopsis,
-                                    (deprecated and ' (deprecated)' or ''))
-                return make_refnode(builder, fromdocname, docname,
-                                    'module-' + target, contnode, title)
+        modname = node.get('py:module')
+        clsname = node.get('py:class')
+        searchmode = node.hasattr('refspecific') and 1 or 0
+        matches = self.find_obj(env, modname, clsname, target,
+                                type, searchmode)
+        if not matches:
+            return None
+        elif len(matches) > 1:
+            env.warn(fromdocname,
+                     'more than one target found for cross-reference '
+                     '%r: %s' % (target,
+                                 ', '.join(match[0] for match in matches)),
+                     node.line)
+        name, obj = matches[0]
+
+        if obj[1] == 'module':
+            # get additional info for modules
+            docname, synopsis, platform, deprecated = self.data['modules'][name]
+            assert docname == obj[0]
+            title = name
+            if synopsis:
+                title += ': ' + synopsis
+            if deprecated:
+                title += _(' (deprecated)')
+            if platform:
+                title += ' (' + platform + ')'
+            return make_refnode(builder, fromdocname, docname,
+                                'module-' + name, contnode, title)
         else:
-            modname = node.get('py:module')
-            clsname = node.get('py:class')
-            searchorder = node.hasattr('refspecific') and 1 or 0
-            matches = self.find_obj(env, modname, clsname, target,
-                                    type, searchorder)
-            if not matches:
-                return None
-            elif len(matches) > 1:
-                env.warn(fromdocname,
-                         'more than one target found for cross-reference '
-                         '%r: %s' % (target,
-                                     ', '.join(match[0] for match in matches)),
-                         node.line)
-            name, obj = matches[0]
             return make_refnode(builder, fromdocname, obj[0], name,
                                 contnode, name)
 

File sphinx/domains/rst.py

     """
 
     def add_target_and_index(self, name, sig, signode):
-        targetname = name + '-' + self.objtype
+        targetname = self.objtype + '-' + name
         if targetname not in self.state.document.ids:
             signode['names'].append(targetname)
             signode['ids'].append(targetname)
             if (objtype, target) in objects:
                 return make_refnode(builder, fromdocname,
                                     objects[objtype, target],
-                                    target, contnode, target)
+                                    objtype + '-' + target,
+                                    contnode, target + ' ' + objtype)
 
     def get_objects(self):
         for (typ, name), docname in self.data['objects'].iteritems():
-            yield name, name, typ, docname, name, 1
+            yield name, name, typ, docname, typ + '-' + name, 1

File sphinx/environment.py

 
 # This is increased every time an environment attribute is added
 # or changed to properly invalidate pickle files.
-ENV_VERSION = 37
+ENV_VERSION = 38
 
 
 default_substitutions = set([

File sphinx/ext/inheritance_diagram.py

 # -*- coding: utf-8 -*-
-"""
+r"""
     sphinx.ext.inheritance_diagram
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

File sphinx/ext/intersphinx.py

             proj, version, uri, dispname = inventory[objtype][target]
             newnode = nodes.reference('', '', internal=False, refuri=uri,
                                       reftitle='(in %s v%s)' % (proj, version))
-            if dispname == '-':
-                dispname = target
-            newnode.append(contnode.__class__(dispname, dispname))
+            if node.get('refexplicit'):
+                # use whatever title was given
+                newnode.append(contnode)
+            elif dispname == '-':
+                # use whatever title was given, but strip prefix
+                title = contnode.astext()
+                if in_set and title.startswith(in_set+':'):
+                    newnode.append(contnode.__class__(title[len(in_set)+1:],
+                                                      title[len(in_set)+1:]))
+                else:
+                    newnode.append(contnode)
+            else:
+                # else use the given display name (used for :ref:)
+                newnode.append(contnode.__class__(dispname, dispname))
             return newnode
     # at least get rid of the ':' in the target if no explicit title given
     if in_set is not None and not node.get('refexplicit', True):

File sphinx/ext/oldcmarkup.py

 
 def old_crole(typ, rawtext, text, lineno, inliner, options={}, content=[]):
     env = inliner.document.settings.env
+    if not typ:
+        typ = env.config.default_role
     if not env.app._oldcmarkup_warned:
         env.warn(env.docname, WARNING_MSG)
         env.app._oldcmarkup_warned = True

File sphinx/highlighting.py

             # no HTML styles needed
             return ''
         if self.dest == 'html':
-            return self.fmter[0].get_style_defs()
+            return self.fmter[0].get_style_defs('.highlight')
         else:
             styledefs = self.fmter[0].get_style_defs()
             # workaround for Pygments < 0.12

File sphinx/roles.py

             classes = ['xref', domain, '%s-%s' % (domain, role)]
         # if the first character is a bang, don't cross-reference at all
         if text[0:1] == '!':
-            text = utils.unescape(text)
+            text = utils.unescape(text)[1:]
             if self.fix_parens:
-                text, tgt = self._fix_parens(env, False, text[1:], "")
+                text, tgt = self._fix_parens(env, False, text, "")
             innernode = self.innernodeclass(rawtext, text, classes=classes)
             return self.result_nodes(inliner.document, env, innernode,
                                      is_ref=False)
         indexnode['entries'] = [
             ('single', _('Python Enhancement Proposals!PEP %s') % text,
              targetid, 'PEP %s' % text)]
+        anchor = ''
+        anchorindex = text.find('#')
+        if anchorindex > 0:
+            text, anchor = text[:anchorindex], text[anchorindex:]
         try:
             pepnum = int(text)
         except ValueError:
             return [prb], [msg]
         ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum
         sn = nodes.strong('PEP '+text, 'PEP '+text)
-        rn = nodes.reference('', '', internal=False, refuri=ref, classes=[typ])
+        rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
+                             classes=[typ])
         rn += sn
         return [indexnode, targetnode, rn], []
     elif typ == 'rfc':
         indexnode['entries'] = [('single', 'RFC; RFC %s' % text,
                                  targetid, 'RFC %s' % text)]
+        anchor = ''
+        anchorindex = text.find('#')
+        if anchorindex > 0:
+            text, anchor = text[:anchorindex], text[anchorindex:]
         try:
             rfcnum = int(text)
         except ValueError:
             return [prb], [msg]
         ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
         sn = nodes.strong('RFC '+text, 'RFC '+text)
-        rn = nodes.reference('', '', internal=False, refuri=ref, classes=[typ])
+        rn = nodes.reference('', '', internal=False, refuri=ref+anchor,
+                             classes=[typ])
         rn += sn
         return [indexnode, targetnode, rn], []
 

File sphinx/texinputs/sphinx.sty

                 linkcolor=InnerLinkColor,filecolor=OuterLinkColor,
                 menucolor=OuterLinkColor,urlcolor=OuterLinkColor,
                 citecolor=InnerLinkColor]{hyperref}
+\RequirePackage[figure,table]{hypcap}
 
 % From docutils.writers.latex2e
 \providecommand{\DUspan}[2]{%

File sphinx/util/docfields.py

             par += self.make_xref(self.rolename, domain, fieldarg, nodes.strong)
             if fieldarg in types:
                 par += nodes.Text(' (')
-                fieldtype = types[fieldarg]
+                # NOTE: using .pop() here to prevent a single type node to be
+                # inserted twice into the doctree, which leads to
+                # inconsistencies later when references are resolved
+                fieldtype = types.pop(fieldarg)
                 if len(fieldtype) == 1 and isinstance(fieldtype[0], nodes.Text):
-                    typename = u''.join(n.astext() for n in types[fieldarg])
+                    typename = u''.join(n.astext() for n in fieldtype)
                     par += self.make_xref(self.typerolename, domain, typename)
                 else:
                     par += fieldtype

File sphinx/util/jsonimpl.py

 
 try:
     import json
+    # json-py's json module has not JSONEncoder; this will raise AttributeError
+    # if json-py is imported instead of the built-in json module
     JSONEncoder = json.JSONEncoder
-except ImportError:
+except (ImportError, AttributeError):
     try:
         import simplejson as json
         JSONEncoder = json.JSONEncoder

File sphinx/writers/latex.py

             else:
                 self.top_sectionlevel = 1
         self.next_section_ids = set()
+        self.next_figure_ids = set()
+        self.next_table_ids = set()
         # flags
         self.verbatim = None
         self.in_title = 0
                 self.body.append('{|' + ('L|' * self.table.colcount) + '}\n')
         if self.table.longtable and self.table.caption is not None:
             self.body.append(u'\\caption{%s} \\\\\n' % self.table.caption)
-
+        if self.table.caption is not None:
+            for id in self.next_table_ids:
+                self.body.append(self.hypertarget(id, anchor=False))
+            self.next_table_ids.clear()
         if self.table.longtable:
             self.body.append('\\hline\n')
             self.body.append('\\endfirsthead\n\n')
         pass
 
     def visit_figure(self, node):
+        ids = ''
+        for id in self.next_figure_ids:
+            ids += self.hypertarget(id, anchor=False)
+        self.next_figure_ids.clear()
         if 'width' in node and node.get('align', '') in ('left', 'right'):
             self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
                              (node['align'] == 'right' and 'r' or 'l',
                               node['width']))
-            self.context.append('\\end{wrapfigure}\n')
+            self.context.append(ids + '\\end{wrapfigure}\n')
         else:
             if (not 'align' in node.attributes or
                 node.attributes['align'] == 'center'):
                 align = '\\begin{flush%s}' % node.attributes['align']
                 align_end = '\\end{flush%s}' % node.attributes['align']
             self.body.append('\\begin{figure}[htbp]%s\n' % align)
-            self.context.append('%s\\end{figure}\n' % align_end)
+            self.context.append(ids + align_end + '\\end{figure}\n')
     def depart_figure(self, node):
         self.body.append(self.context.pop())
 
                     self.next_section_ids.add(node['refid'])
                 self.next_section_ids.update(node['ids'])
                 return
+            elif isinstance(next, nodes.figure):
+                # labels for figures go in the figure body, not before
+                if node.get('refid'):
+                    self.next_figure_ids.add(node['refid'])
+                self.next_figure_ids.update(node['ids'])
+                return
+            elif isinstance(next, nodes.table):
+                # same for tables, but only if they have a caption
+                for n in node:
+                    if isinstance(n, nodes.title):
+                        if node.get('refid'):
+                            self.next_table_ids.add(node['refid'])
+                        self.next_table_ids.update(node['ids'])
+                        return
         except IndexError:
             pass
         if 'refuri' in node:

File tests/root/objects.txt

 
 .. function:: func_without_module2() -> annotation
 
+.. object:: long(parameter, \
+              list)
+	    another one
+
 .. class:: TimeInt
 
    :param moo: |test|
    :ivar int hour: like *hour*
    :ivar minute: like *minute*
    :vartype minute: int
+   :param hour: Duplicate param.  Should not lead to crashes.
+   :type hour: Duplicate type.
 
 
 C items

File tests/test_build_html.py

 reading included file u'wrongenc.inc' seems to be wrong, try giving an \
 :encoding: option\\n?
 %(root)s/includes.txt:4: WARNING: download file not readable: nonexisting.png
-%(root)s/objects.txt:84: WARNING: using old C markup; please migrate to \
+%(root)s/objects.txt:\\d*: WARNING: using old C markup; please migrate to \
 new-style markup \(e.g. c:function instead of cfunction\), see \
 http://sphinx.pocoo.org/domains.html
 """
     'objects.html': [
         (".//dt[@id='mod.Cls.meth1']", ''),
         (".//dt[@id='errmod.Error']", ''),
+        (".//dt/tt", r'long\(parameter,\s* list\)'),
+        (".//dt/tt", 'another one'),
         (".//a[@href='#mod.Cls'][@class='reference internal']", ''),
         (".//dl[@class='userdesc']", ''),
         (".//dt[@id='userdesc-myobj']", ''),

File tests/test_intersphinx.py

            ('foo', '2.0', 'http://docs.python.org/foo.html#module-module2', '-')
 
     # create fake nodes and check referencing
-    contnode = nodes.emphasis('foo', 'foo')
-    refnode = addnodes.pending_xref('')
-    refnode['reftarget'] = 'module1.func'
-    refnode['reftype'] = 'func'
-    refnode['refdomain'] = 'py'
 
-    rn = missing_reference(app, app.env, refnode, contnode)
+    def fake_node(domain, type, target, content, **attrs):
+        contnode = nodes.emphasis(content, content)
+        node = addnodes.pending_xref('')
+        node['reftarget'] = target
+        node['reftype'] = type
+        node['refdomain'] = domain
+        node.attributes.update(attrs)
+        node += contnode
+        return node, contnode
+
+    def reference_check(*args, **kwds):
+        node, contnode = fake_node(*args, **kwds)
+        return missing_reference(app, app.env, node, contnode)
+
+    # check resolution when a target is found
+    rn = reference_check('py', 'func', 'module1.func', 'foo')
     assert isinstance(rn, nodes.reference)
     assert rn['refuri'] == 'http://docs.python.org/sub/foo.html#module1.func'
     assert rn['reftitle'] == '(in foo v2.0)'
-    assert rn[0].astext() == 'module1.func'
+    assert rn[0].astext() == 'foo'
 
     # create unresolvable nodes and check None return value
-    refnode['reftype'] = 'foo'
-    assert missing_reference(app, app.env, refnode, contnode) is None
-
-    refnode['reftype'] = 'function'
-    refnode['reftarget'] = 'foo.func'
-    assert missing_reference(app, app.env, refnode, contnode) is None
+    assert reference_check('py', 'foo', 'module1.func', 'foo') is None
+    assert reference_check('py', 'func', 'foo', 'foo') is None
+    assert reference_check('py', 'func', 'foo', 'foo') is None
 
     # check handling of prefixes
 
     # prefix given, target found: prefix is stripped
-    refnode['reftype'] = 'mod'
-    refnode['reftarget'] = 'py3k:module2'
-    rn = missing_reference(app, app.env, refnode, contnode)
+    rn = reference_check('py', 'mod', 'py3k:module2', 'py3k:module2')
     assert rn[0].astext() == 'module2'
 
+    # prefix given, but not in title: nothing stripped
+    rn = reference_check('py', 'mod', 'py3k:module2', 'module2')
+    assert rn[0].astext() == 'module2'
+
+    # prefix given, but explicit: nothing stripped
+    rn = reference_check('py', 'mod', 'py3k:module2', 'py3k:module2',
+                         refexplicit=True)
+    assert rn[0].astext() == 'py3k:module2'
+
     # prefix given, target not found and nonexplicit title: prefix is stripped
-    refnode['reftarget'] = 'py3k:unknown'
-    refnode['refexplicit'] = False
-    contnode[0] = nodes.Text('py3k:unknown')
-    rn = missing_reference(app, app.env, refnode, contnode)
+    node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown',
+                               refexplicit=False)
+    rn = missing_reference(app, app.env, node, contnode)
     assert rn is None
     assert contnode[0].astext() == 'unknown'
 
     # prefix given, target not found and explicit title: nothing is changed
-    refnode['reftarget'] = 'py3k:unknown'
-    refnode['refexplicit'] = True
-    contnode[0] = nodes.Text('py3k:unknown')
-    rn = missing_reference(app, app.env, refnode, contnode)
+    node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown',
+                               refexplicit=True)
+    rn = missing_reference(app, app.env, node, contnode)
     assert rn is None
     assert contnode[0].astext() == 'py3k:unknown'