Hello community,

here is the log from the commit of package python-sphinxcontrib-httpdomain for 
openSUSE:Factory checked in at 2016-11-24 21:23:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sphinxcontrib-httpdomain (Old)
 and      /work/SRC/openSUSE:Factory/.python-sphinxcontrib-httpdomain.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sphinxcontrib-httpdomain"

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-sphinxcontrib-httpdomain/python-sphinxcontrib-httpdomain.changes
  2016-08-09 22:14:41.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-sphinxcontrib-httpdomain.new/python-sphinxcontrib-httpdomain.changes
     2016-11-24 21:23:09.000000000 +0100
@@ -1,0 +2,5 @@
+Mon Nov 14 14:20:01 UTC 2016 - [email protected]
+
+- update to 1.5.0
+
+-------------------------------------------------------------------

Old:
----
  sphinxcontrib-httpdomain-1.4.0.tar.gz

New:
----
  sphinxcontrib-httpdomain-1.5.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sphinxcontrib-httpdomain.spec ++++++
--- /var/tmp/diff_new_pack.lh2SRE/_old  2016-11-24 21:23:10.000000000 +0100
+++ /var/tmp/diff_new_pack.lh2SRE/_new  2016-11-24 21:23:10.000000000 +0100
@@ -17,13 +17,13 @@
 
 
 Name:           python-sphinxcontrib-httpdomain
-Version:        1.4.0
+Version:        1.5.0
 Release:        0
 Summary:        Sphinx domain for HTTP APIs
 License:        BSD-2-Clause
 Group:          Development/Languages/Python
 Url:            http://bitbucket.org/birkenfeld/sphinx-contrib
-Source:         
http://pypi.python.org/packages/source/s/sphinxcontrib-httpdomain/sphinxcontrib-httpdomain-%{version}.tar.gz
+Source:         
https://pypi.io/packages/source/s/sphinxcontrib-httpdomain/sphinxcontrib-httpdomain-%{version}.tar.gz
 BuildRequires:  python-devel
 BuildRequires:  python-setuptools
 Requires:       python-Sphinx

++++++ sphinxcontrib-httpdomain-1.4.0.tar.gz -> 
sphinxcontrib-httpdomain-1.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinxcontrib-httpdomain-1.4.0/PKG-INFO 
new/sphinxcontrib-httpdomain-1.5.0/PKG-INFO
--- old/sphinxcontrib-httpdomain-1.4.0/PKG-INFO 2015-08-13 16:15:20.000000000 
+0200
+++ new/sphinxcontrib-httpdomain-1.5.0/PKG-INFO 2016-05-29 20:16:06.000000000 
+0200
@@ -1,22 +1,24 @@
 Metadata-Version: 1.1
 Name: sphinxcontrib-httpdomain
-Version: 1.4.0
+Version: 1.5.0
 Summary: Sphinx domain for HTTP APIs
-Home-page: http://bitbucket.org/birkenfeld/sphinx-contrib
+Home-page: 
https://bitbucket.org/birkenfeld/sphinx-contrib/src/default/httpdomain/
 Author: Hong Minhee
-Author-email: [email protected]
+Author-email: [email protected]
 License: BSD
-Download-URL: http://pypi.python.org/pypi/sphinxcontrib-httpdomain
-Description: 
-        This contrib extension, sphinxcontrib.httpdomain provides a Sphinx
-        domain for describing RESTful HTTP APIs.
+Download-URL: https://pypi.python.org/pypi/sphinxcontrib-httpdomain
+Description: sphinxcontrib.httpdomain --- Documenting RESTful HTTP APIs
+        ==========================================================
+        
+        This contrib extension, sphinxcontrib.httpdomain, provides a Sphinx 
domain
+        for describing RESTful HTTP APIs.
         
         You can find the documentation from the following URL:
         
-        http://pythonhosted.org/sphinxcontrib-httpdomain/
+        https://pythonhosted.org/sphinxcontrib-httpdomain/
         
 Platform: any
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Console
 Classifier: Environment :: Web Environment
 Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinxcontrib-httpdomain-1.4.0/README.rst 
new/sphinxcontrib-httpdomain-1.5.0/README.rst
--- old/sphinxcontrib-httpdomain-1.4.0/README.rst       2015-08-13 
15:44:55.000000000 +0200
+++ new/sphinxcontrib-httpdomain-1.5.0/README.rst       2016-05-29 
19:36:33.000000000 +0200
@@ -6,4 +6,4 @@
 
 You can find the documentation from the following URL:
 
-http://pythonhosted.org/sphinxcontrib-httpdomain/
+https://pythonhosted.org/sphinxcontrib-httpdomain/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinxcontrib-httpdomain-1.4.0/setup.cfg 
new/sphinxcontrib-httpdomain-1.5.0/setup.cfg
--- old/sphinxcontrib-httpdomain-1.4.0/setup.cfg        2015-08-13 
16:15:20.000000000 +0200
+++ new/sphinxcontrib-httpdomain-1.5.0/setup.cfg        2016-05-29 
20:16:06.000000000 +0200
@@ -9,7 +9,7 @@
 upload_dir = build/sphinx/html
 
 [egg_info]
-tag_build = 
 tag_date = 0
 tag_svn_revision = 0
+tag_build = 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinxcontrib-httpdomain-1.4.0/setup.py 
new/sphinxcontrib-httpdomain-1.5.0/setup.py
--- old/sphinxcontrib-httpdomain-1.4.0/setup.py 2015-08-13 16:10:47.000000000 
+0200
+++ new/sphinxcontrib-httpdomain-1.5.0/setup.py 2016-05-29 19:41:49.000000000 
+0200
@@ -1,34 +1,36 @@
 # -*- coding: utf-8 -*-
+from __future__ import with_statement
 
 from setuptools import setup, find_packages
 
-long_desc = '''
-This contrib extension, sphinxcontrib.httpdomain provides a Sphinx
-domain for describing RESTful HTTP APIs.
-
-You can find the documentation from the following URL:
-
-http://pythonhosted.org/sphinxcontrib-httpdomain/
-'''
 
 requires = [
     'Sphinx >= 1.0',
     'six'
 ]
 
+
+def readme():
+    try:
+        with open('README.rst') as f:
+            return f.read()
+    except IOError:
+        pass
+
+
 setup(
     name='sphinxcontrib-httpdomain',
-    version='1.4.0',
-    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
-    download_url='http://pypi.python.org/pypi/sphinxcontrib-httpdomain',
+    version='1.5.0',
+    
url='https://bitbucket.org/birkenfeld/sphinx-contrib/src/default/httpdomain/',  
# noqa
+    download_url='https://pypi.python.org/pypi/sphinxcontrib-httpdomain',
     license='BSD',
     author='Hong Minhee',
-    author_email='[email protected]',
+    author_email='[email protected]',
     description='Sphinx domain for HTTP APIs',
-    long_description=long_desc,
+    long_description=readme(),
     zip_safe=False,
     classifiers=[
-        'Development Status :: 4 - Beta',
+        'Development Status :: 5 - Production/Stable',
         'Environment :: Console',
         'Environment :: Web Environment',
         'Intended Audience :: Developers',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flask.py 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flask.py
--- old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flask.py  
2015-08-13 16:06:35.000000000 +0200
+++ new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flask.py  
2015-11-19 18:35:47.000000000 +0100
@@ -9,6 +9,7 @@
     :license: BSD, see LICENSE for details.
 
 """
+from __future__ import absolute_import
 
 import re
 import itertools
@@ -27,122 +28,9 @@
 from sphinxcontrib import httpdomain
 from sphinxcontrib.autohttp.common import http_directive, import_object
 
+from .flask_base import AutoflaskBase
 
-def translate_werkzeug_rule(rule):
-    from werkzeug.routing import parse_rule
-    buf = six.StringIO()
-    for conv, arg, var in parse_rule(rule):
-        if conv:
-            buf.write('(')
-            if conv != 'default':
-                buf.write(conv)
-                buf.write(':')
-            buf.write(var)
-            buf.write(')')
-        else:
-            buf.write(var)
-    return buf.getvalue()
-
-
-def get_routes(app, endpoint=None):
-    endpoints = []
-    for rule in app.url_map.iter_rules(endpoint):
-        if rule.endpoint not in endpoints:
-            endpoints.append(rule.endpoint)
-    for endpoint in endpoints:
-        methodrules = {}
-        for rule in app.url_map.iter_rules(endpoint):
-            methods = rule.methods.difference(['OPTIONS', 'HEAD'])
-            path = translate_werkzeug_rule(rule.rule)
-            for method in methods:
-                if method in methodrules:
-                    methodrules[method].append(path)
-                else:
-                    methodrules[method] = [path]
-        for method, paths in methodrules.items():
-            yield method, paths, endpoint
-
-
-class AutoflaskDirective(Directive):
-
-    has_content = True
-    required_arguments = 1
-    option_spec = {'endpoints': directives.unchanged,
-                   'blueprints': directives.unchanged,
-                   'undoc-endpoints': directives.unchanged,
-                   'undoc-blueprints': directives.unchanged,
-                   'undoc-static': directives.unchanged,
-                   'include-empty-docstring': directives.unchanged}
-
-    @property
-    def endpoints(self):
-        endpoints = self.options.get('endpoints', None)
-        if not endpoints:
-            return None
-        return re.split(r'\s*,\s*', endpoints)
-
-    @property
-    def undoc_endpoints(self):
-        undoc_endpoints = self.options.get('undoc-endpoints', None)
-        if not undoc_endpoints:
-            return frozenset()
-        return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
-
-    @property
-    def blueprints(self):
-        blueprints = self.options.get('blueprints', None)
-        if not blueprints:
-            return None
-        return frozenset(re.split(r'\s*,\s*', blueprints))
-
-    @property
-    def undoc_blueprints(self):
-        undoc_blueprints = self.options.get('undoc-blueprints', None)
-        if not undoc_blueprints:
-            return frozenset()
-        return frozenset(re.split(r'\s*,\s*', undoc_blueprints))
-
-    def make_rst(self):
-        app = import_object(self.arguments[0])
-        if self.endpoints:
-            routes = itertools.chain(*[get_routes(app, endpoint)
-                    for endpoint in self.endpoints])
-        else:
-            routes = get_routes(app)
-        for method, paths, endpoint in routes:
-            try:
-                blueprint, _, endpoint_internal = endpoint.rpartition('.')
-                if self.blueprints and blueprint not in self.blueprints:
-                    continue
-                if blueprint in self.undoc_blueprints:
-                    continue
-            except ValueError:
-                pass  # endpoint is not within a blueprint
-
-            if endpoint in self.undoc_endpoints:
-                continue
-            try:
-                static_url_path = app.static_url_path # Flask 0.7 or higher
-            except AttributeError:
-                static_url_path = app.static_path # Flask 0.6 or under
-            if ('undoc-static' in self.options and endpoint == 'static' and
-                static_url_path + '/(path:filename)' in paths):
-                continue
-            view = app.view_functions[endpoint]
-            docstring = view.__doc__ or ''
-            if hasattr(view, 'view_class'):
-                meth_func = getattr(view.view_class, method.lower(), None)
-                if meth_func and meth_func.__doc__:
-                    docstring = meth_func.__doc__
-            if not isinstance(docstring, six.text_type):
-                analyzer = ModuleAnalyzer.for_module(view.__module__)
-                docstring = force_decode(docstring, analyzer.encoding)
-    
-            if not docstring and 'include-empty-docstring' not in self.options:
-                continue
-            docstring = prepare_docstring(docstring)
-            for line in http_directive(method, paths, docstring):
-                yield line
+class AutoflaskDirective(AutoflaskBase):
 
     def run(self):
         node = nodes.section()
@@ -158,4 +46,3 @@
     if 'http' not in app.domains:
         httpdomain.setup(app)
     app.add_directive('autoflask', AutoflaskDirective)
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flask_base.py 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flask_base.py
--- old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flask_base.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flask_base.py     
2015-11-19 18:36:45.000000000 +0100
@@ -0,0 +1,215 @@
+"""
+    sphinxcontrib.autohttp.flask
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder (from Flask)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+
+import re
+import itertools
+import six
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
+
+from sphinx.util import force_decode
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.docstrings import prepare_docstring
+from sphinx.pycode import ModuleAnalyzer
+
+from sphinxcontrib import httpdomain
+from sphinxcontrib.autohttp.common import http_directive, import_object
+
+
+def translate_werkzeug_rule(rule):
+    from werkzeug.routing import parse_rule
+    buf = six.StringIO()
+    for conv, arg, var in parse_rule(rule):
+        if conv:
+            buf.write('(')
+            if conv != 'default':
+                buf.write(conv)
+                buf.write(':')
+            buf.write(var)
+            buf.write(')')
+        else:
+            buf.write(var)
+    return buf.getvalue()
+
+
+def get_routes(app, endpoint=None, order=None):
+    endpoints = []
+    for rule in app.url_map.iter_rules(endpoint):
+        url_with_endpoint = (
+            six.text_type(next(app.url_map.iter_rules(rule.endpoint))),
+            rule.endpoint
+        )
+        if url_with_endpoint not in endpoints:
+            endpoints.append(url_with_endpoint)
+    if order == 'path':
+        endpoints.sort()
+    endpoints = [e for _, e in endpoints]
+    for endpoint in endpoints:
+        methodrules = {}
+        for rule in app.url_map.iter_rules(endpoint):
+            methods = rule.methods.difference(['OPTIONS', 'HEAD'])
+            path = translate_werkzeug_rule(rule.rule)
+            for method in methods:
+                if method in methodrules:
+                    methodrules[method].append(path)
+                else:
+                    methodrules[method] = [path]
+        for method, paths in methodrules.items():
+            yield method, paths, endpoint
+
+
+def quickref_directive(method, path, content):
+    rcomp = re.compile("^\s*.. :quickref:\s*(?P<quick>.*)$")
+    method = method.lower().strip()
+    if isinstance(content, six.string_types):
+         content = content.splitlines()
+    description=""
+    name=""
+    ref = 
path.replace("<","(").replace(">",")").replace("/","-").replace(":","-")
+    for line in content:
+         qref = rcomp.match(line)
+         if qref:
+            quickref = qref.group("quick")
+            parts = quickref.split(";",1)
+            if len(parts)>1:
+                name = parts[0]
+                description= parts[1]
+            else:
+                description= quickref
+            break
+
+    row ={}
+    row['name'] = name
+    row['operation'] = '      - `%s %s <#%s-%s>`_' % (method.upper(), path, 
method.lower(), ref)
+    row['description'] = description
+
+    return row
+
+class AutoflaskBase(Directive):
+
+    has_content = True
+    required_arguments = 1
+    option_spec = {'endpoints': directives.unchanged,
+                   'blueprints': directives.unchanged,
+                   'modules': directives.unchanged,
+                   'order': directives.unchanged,
+                   'undoc-endpoints': directives.unchanged,
+                   'undoc-blueprints': directives.unchanged,
+                   'undoc-modules': directives.unchanged,
+                   'undoc-static': directives.unchanged,
+                   'include-empty-docstring': directives.unchanged}
+
+    @property
+    def endpoints(self):
+        endpoints = self.options.get('endpoints', None)
+        if not endpoints:
+            return None
+        return re.split(r'\s*,\s*', endpoints)
+
+    @property
+    def undoc_endpoints(self):
+        undoc_endpoints = self.options.get('undoc-endpoints', None)
+        if not undoc_endpoints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
+
+    @property
+    def blueprints(self):
+        blueprints = self.options.get('blueprints', None)
+        if not blueprints:
+            return None
+        return frozenset(re.split(r'\s*,\s*', blueprints))
+
+    @property
+    def undoc_blueprints(self):
+        undoc_blueprints = self.options.get('undoc-blueprints', None)
+        if not undoc_blueprints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_blueprints))
+
+    @property
+    def modules(self):
+        modules = self.options.get('modules', None)
+        if not modules:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', modules))
+
+    @property
+    def undoc_modules(self):
+        undoc_modules = self.options.get('undoc-modules', None)
+        if not undoc_modules:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_modules))
+
+    @property
+    def order(self):
+        order = self.options.get('order', None)
+        if order not in (None, 'path'):
+            raise ValueError('Invalid value for :order:')
+        return order
+
+    def make_rst(self, qref=False):
+        app = import_object(self.arguments[0])
+        if self.endpoints:
+            routes = itertools.chain(*[get_routes(app, endpoint, self.order)
+                    for endpoint in self.endpoints])
+        else:
+            routes = get_routes(app, order=self.order)
+        for method, paths, endpoint in routes:
+            try:
+                blueprint, _, endpoint_internal = endpoint.rpartition('.')
+                if self.blueprints and blueprint not in self.blueprints:
+                    continue
+                if blueprint in self.undoc_blueprints:
+                    continue
+            except ValueError:
+                pass  # endpoint is not within a blueprint
+
+            if endpoint in self.undoc_endpoints:
+                continue
+            try:
+                static_url_path = app.static_url_path # Flask 0.7 or higher
+            except AttributeError:
+                static_url_path = app.static_path # Flask 0.6 or under
+            if ('undoc-static' in self.options and endpoint == 'static' and
+                static_url_path + '/(path:filename)' in paths):
+                continue
+            view = app.view_functions[endpoint]
+
+            if self.modules and view.__module__ not in self.modules:
+                continue
+
+            if self.undoc_modules and view.__module__ in self.modules:
+                continue
+
+            docstring = view.__doc__ or ''
+            if hasattr(view, 'view_class'):
+                meth_func = getattr(view.view_class, method.lower(), None)
+                if meth_func and meth_func.__doc__:
+                    docstring = meth_func.__doc__
+            if not isinstance(docstring, six.text_type):
+                analyzer = ModuleAnalyzer.for_module(view.__module__)
+                docstring = force_decode(docstring, analyzer.encoding)
+
+            if not docstring and 'include-empty-docstring' not in self.options:
+                continue
+            docstring = prepare_docstring(docstring)
+            if qref == True:
+                for path in paths:
+                    row = quickref_directive(method, path, docstring)
+                    yield row
+            else:
+                for line in http_directive(method, paths, docstring):
+                    yield line
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flaskqref.py 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flaskqref.py
--- old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/autohttp/flaskqref.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/autohttp/flaskqref.py      
2015-11-19 18:24:33.000000000 +0100
@@ -0,0 +1,80 @@
+"""
+    sphinxcontrib.autohttp.flaskqref
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API quick reference 
+    builder (from Flask)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+
+from docutils import nodes
+from docutils.statemachine import ViewList
+
+from sphinxcontrib import httpdomain
+from sphinx.util.nodes import nested_parse_with_titles
+
+from .flask import AutoflaskBase
+
+
+class QuickReferenceFlaskDirective(AutoflaskBase):
+
+
+    header = [ '',
+              '.. list-table::',
+              '    :widths: 20 45 35',
+              '    :header-rows: 1',
+              '',
+              '    * - Resource',
+              '      - Operation',
+              '      - Description'
+            ]
+
+    def run(self):
+        node = nodes.section()
+        node.document = self.state.document
+        result = ViewList()
+        for line in QuickReferenceFlaskDirective.header:
+            result.append(line, '<qrefflask>') 
+        table={}
+        table_sorted_names=[]
+        
+        for table_row in self.make_rst(qref=True):
+            name = table_row['name']
+            if table.get(name) is None:
+                table[name]=[]
+            table[name].append(table_row) 
+            if name not in table_sorted_names:
+                table_sorted_names.append(name)
+
+        table_sorted_names.sort()
+
+        for name in table_sorted_names:
+            # Keep table display clean by not repeating duplicate
+            # resource names and descriptions
+            display_name = name
+            previous_description=None
+            for row in table[name]:
+                result.append('    * - %s' % display_name, '<qrefflask>')
+                display_name =""
+                result.append(row['operation'], '<qrefflask>')
+                description = row['description']
+                if previous_description is not None and previous_description 
== description:
+                    description =""
+                else:
+                    previous_description = description
+
+                result.append('      - %s' % description,  '<qrefflask>')
+
+        result.append('', '<qrefflask>')
+        nested_parse_with_titles(self.state, result, node)
+        return node.children
+        
+def setup(app):
+    if 'http' not in app.domains:
+        httpdomain.setup(app)
+    app.add_directive('qrefflask', QuickReferenceFlaskDirective)
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/httpdomain.py 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/httpdomain.py
--- old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib/httpdomain.py      
2015-08-13 15:44:55.000000000 +0200
+++ new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib/httpdomain.py      
2016-05-29 19:32:00.000000000 +0200
@@ -25,6 +25,16 @@
 from sphinx.util.nodes import make_refnode
 from sphinx.util.docfields import GroupedField, TypedField
 
+# The env.get_doctree() lookup results in a pickle.load() call which is
+# expensive enough to dominate the runtime entirely when the number of 
endpoints
+# and references is large enough. The doctrees are generated during the read-
+# phase and we can cache their lookup during the write-phase significantly
+# improving performance.
+# Currently sphinxcontrib-httpdomain does not declare to support parallel read
+# support (parallel_read_safe is the default False) so we can simply use a
+# module global to hold the cache.
+_doctree_cache = {}
+
 
 class DocRef(object):
     """Represents a reference to an abstract specification."""
@@ -41,7 +51,8 @@
 
 
 class RFC2616Ref(DocRef):
-    """Represents a reference to RFC2616."""
+    """Represents a reference to RFC2616.
+    In 2014, RFC2616 was replaced by multiple RFCs (7230-7237)."""
 
     def __init__(self, section):
         url = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec{0:d}.html'
@@ -77,14 +88,14 @@
 #: HTTP method.
 METHOD_REFS = {
     'patch': IETFRef(5789, 2),
-    'options': RFC2616Ref(9.2),
-    'get': RFC2616Ref(9.3),
-    'head': RFC2616Ref(9.4),
-    'post': RFC2616Ref(9.5),
-    'put': RFC2616Ref(9.6),
-    'delete': RFC2616Ref(9.7),
-    'trace': RFC2616Ref(9.8),
-    'connect': RFC2616Ref(9.9),
+    'options': IETFRef(7231, '4.3.7'),
+    'get': IETFRef(7231, '4.3.1'),
+    'head': IETFRef(7231, '4.3.2'),
+    'post': IETFRef(7231, '4.3.3'),
+    'put': IETFRef(7231, '4.3.4'),
+    'delete': IETFRef(7231, '4.3.5'),
+    'trace': IETFRef(7231, '4.3.8'),
+    'connect': IETFRef(7231, '4.3.6'),
     'copy': IETFRef(2518, 8.8),
     'any': ''
 }
@@ -93,58 +104,58 @@
 #: Mapping from HTTP header name to :class:`DocRef` object which
 #: maintains the URL which points to the related section of the RFC.
 HEADER_REFS = {
-    'Accept': RFC2616Ref(14.1),
-    'Accept-Charset': RFC2616Ref(14.2),
-    'Accept-Encoding': RFC2616Ref(14.3),
-    'Accept-Language': RFC2616Ref(14.4),
-    'Accept-Ranges': RFC2616Ref(14.5),
-    'Age': RFC2616Ref(14.6),
-    'Allow': RFC2616Ref(14.7),
-    'Authorization': RFC2616Ref(14.8),
-    'Cache-Control': RFC2616Ref(14.9),
-    'Connection': RFC2616Ref(14.10),
-    'Content-Encoding': RFC2616Ref(14.11),
-    'Content-Language': RFC2616Ref(14.12),
-    'Content-Length': RFC2616Ref(14.13),
-    'Content-Location': RFC2616Ref(14.14),
-    'Content-MD5': RFC2616Ref(14.15),
-    'Content-Range': RFC2616Ref(14.16),
-    'Content-Type': RFC2616Ref(14.17),
-    'Cookie': IETFRef(2109, '4.3.4'),
-    'Date': RFC2616Ref(14.18),
+    'Accept': IETFRef(7231, '5.3.2'),
+    'Accept-Charset': IETFRef(7231, '5.3.3'),
+    'Accept-Encoding': IETFRef(7231, '5.3.4'),
+    'Accept-Language': IETFRef(7231, '5.3.5'),
+    'Accept-Ranges': IETFRef(7233, 2.3),
+    'Age': IETFRef(7234, 5.1),
+    'Allow': IETFRef(7231, '7.4.1'),
+    'Authorization': IETFRef(7235, 4.2),
+    'Cache-Control': IETFRef(7234, 5.2),
+    'Connection': IETFRef(7230, 6.1),
+    'Content-Encoding': IETFRef(7231, '3.1.2.2'),
+    'Content-Language': IETFRef(7231, '3.1.3.2'),
+    'Content-Length': IETFRef(7230, '3.3.2'),
+    'Content-Location': IETFRef(7231, '3.1.4.2'),
+    'Content-MD5': RFC2616Ref(14.15), # removed
+    'Content-Range': IETFRef(7233, 4.2),
+    'Content-Type': IETFRef(7231, '3.1.1.5'),
+    'Cookie': IETFRef(2109, '4.3.4'), # also RFC6265 section 5.4
+    'Date': IETFRef(7231, '7.1.1.2'),
     'Destination': IETFRef(2518, 9.3),
-    'ETag': RFC2616Ref(14.19),
-    'Expect': RFC2616Ref(14.20),
-    'Expires': RFC2616Ref(14.21),
-    'From': RFC2616Ref(14.22),
-    'Host': RFC2616Ref(14.23),
-    'If-Match': RFC2616Ref(14.24),
-    'If-Modified-Since': RFC2616Ref(14.25),
-    'If-None-Match': RFC2616Ref(14.26),
-    'If-Range': RFC2616Ref(14.27),
-    'If-Unmodified-Since': RFC2616Ref(14.28),
+    'ETag': IETFRef(7231, 2.3),
+    'Expect': IETFRef(7231, '5.1.1'),
+    'Expires': IETFRef(7234, 5.3),
+    'From': IETFRef(7231, '5.5.2'),
+    'Host': IETFRef(7230, 5.4),
+    'If-Match': IETFRef(7232, 3.1),
+    'If-Modified-Since': IETFRef(7232, 3.3),
+    'If-None-Match': IETFRef(7232, 3.2),
+    'If-Range': IETFRef(7233, 3.2),
+    'If-Unmodified-Since': IETFRef(7232, 3.4),
     'Last-Event-ID': EventSourceRef('last-event-id'),
-    'Last-Modified': RFC2616Ref(14.29),
+    'Last-Modified': IETFRef(7232, 2.2),
     'Link': IETFRef(5988, '5'),
-    'Location': RFC2616Ref(14.30),
-    'Max-Forwards': RFC2616Ref(14.31),
-    'Pragma': RFC2616Ref(14.32),
-    'Proxy-Authenticate': RFC2616Ref(14.33),
-    'Proxy-Authorization': RFC2616Ref(14.34),
-    'Range': RFC2616Ref(14.35),
-    'Referer': RFC2616Ref(14.36),
-    'Retry-After': RFC2616Ref(14.37),
-    'Server': RFC2616Ref(14.38),
+    'Location': IETFRef(7231, '7.1.2'),
+    'Max-Forwards': IETFRef(7231, '5.1.2'),
+    'Pragma': IETFRef(7234, 5.4),
+    'Proxy-Authenticate': IETFRef(7235, 4.3),
+    'Proxy-Authorization': IETFRef(7235, 4.4),
+    'Range': IETFRef(7233, 3.1),
+    'Referer': IETFRef(7231, '5.5.2'),
+    'Retry-After': IETFRef(7231, '7.1.3'),
+    'Server': IETFRef(7231, '7.4.2'),
     'Set-Cookie': IETFRef(2109, '4.2.2'),
-    'TE': RFC2616Ref(14.39),
-    'Trailer': RFC2616Ref(14.40),
-    'Transfer-Encoding': RFC2616Ref(14.41),
-    'Upgrade': RFC2616Ref(14.42),
-    'User-Agent': RFC2616Ref(14.43),
-    'Vary': RFC2616Ref(14.44),
-    'Via': RFC2616Ref(14.45),
-    'Warning': RFC2616Ref(14.46),
-    'WWW-Authenticate': RFC2616Ref(14.47),
+    'TE': IETFRef(7230, 4.3),
+    'Trailer': IETFRef(7230, 4.4),
+    'Transfer-Encoding': IETFRef(7230, '3.3.1'),
+    'Upgrade': IETFRef(7230, 6.7),
+    'User-Agent': IETFRef(7231, '5.5.3'),
+    'Vary': IETFRef(7231, '7.1.4'),
+    'Via': IETFRef(7230, '5.7.1'),
+    'Warning': IETFRef(7234, 5.5),
+    'WWW-Authenticate': IETFRef(7235, 4.1),
     'Access-Control-Allow-Origin': CORSRef('access-control-allow-origin',
                                            'response-header'),
     'Access-Control-Allow-Credentials': 
CORSRef('access-control-allow-credentials',
@@ -210,6 +221,7 @@
     426: 'Upgrade Required',
     429: 'Too Many Requests',
     449: 'Retry With',           # proprietary MS extension
+    451: 'Unavailable For Legal Reasons',
     500: 'Internal Server Error',
     501: 'Not Implemented',
     502: 'Bad Gateway',
@@ -496,21 +508,10 @@
     def result_nodes(self, document, env, node, is_ref):
         header = node[0][0]
         rawsource = node[0].rawsource
-        config = env.domains['http'].env.config
         if header not in HEADER_REFS:
             _header = '-'.join(map(lambda i: i.title(), header.split('-')))
             if _header not in HEADER_REFS:
-                if not config['http_strict_mode']:
-                    return [nodes.emphasis(header, header)], []
-                _header = _header.lower()
-                if any([_header.startswith(prefix.lower())
-                        for prefix in config['http_headers_ignore_prefixes']]):
-                    return [nodes.emphasis(header, header)], []
-                reporter = document.reporter
-                msg = reporter.error('%s is not unknown HTTP header' % header,
-                                     line=node.line)
-                prb = nodes.problematic(header, header)
-                return [prb], [msg]
+                return [nodes.emphasis(header, header)], []
         url = str(HEADER_REFS[header])
         node = nodes.reference(rawsource, header, refuri=url)
         return [node], []
@@ -649,11 +650,15 @@
             role = self.roles.get(typ)
             if role is None:
                 return None
-            resnode = role.result_nodes(env.get_doctree(fromdocname),
-                                        env, node, None)[0][0]
+
+            if fromdocname not in _doctree_cache:
+                _doctree_cache[fromdocname] = env.get_doctree(fromdocname)
+            doctree = _doctree_cache[fromdocname]
+
+            resnode = role.result_nodes(doctree, env, node, None)[0][0]
             if isinstance(resnode, addnodes.pending_xref):
                 text = node[0][0]
-                reporter = env.get_doctree(fromdocname).reporter
+                reporter = doctree.reporter
                 reporter.warning('Cannot resolve reference to %r' % text,
                                  line=node.line)
                 return None
@@ -664,6 +669,20 @@
             return make_refnode(builder, fromdocname, info[0], anchor,
                                 contnode, title)
 
+    def resolve_any_xref(self, env, fromdocname, builder, target, node, 
contnode):
+        """Resolve the pending_xref *node* with the given *target*.
+
+        The reference comes from an "any" or similar role, which means that 
Sphinx
+        don't know the type.
+
+        For now sphinxcontrib-httpdomain doesn't resolve any xref nodes.
+
+        :return:
+           list of tuples ``('domain:role', newnode)``, where ``'domain:role'``
+           is the name of a role that could have created the same reference,
+        """
+        return []
+
     def get_objects(self):
         for method, routes in self.routes.items():
             for path, info in routes.items():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib_httpdomain.egg-info/PKG-INFO 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib_httpdomain.egg-info/PKG-INFO
--- 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib_httpdomain.egg-info/PKG-INFO   
    2015-08-13 16:15:19.000000000 +0200
+++ 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib_httpdomain.egg-info/PKG-INFO   
    2016-05-29 20:16:04.000000000 +0200
@@ -1,22 +1,24 @@
 Metadata-Version: 1.1
 Name: sphinxcontrib-httpdomain
-Version: 1.4.0
+Version: 1.5.0
 Summary: Sphinx domain for HTTP APIs
-Home-page: http://bitbucket.org/birkenfeld/sphinx-contrib
+Home-page: 
https://bitbucket.org/birkenfeld/sphinx-contrib/src/default/httpdomain/
 Author: Hong Minhee
-Author-email: [email protected]
+Author-email: [email protected]
 License: BSD
-Download-URL: http://pypi.python.org/pypi/sphinxcontrib-httpdomain
-Description: 
-        This contrib extension, sphinxcontrib.httpdomain provides a Sphinx
-        domain for describing RESTful HTTP APIs.
+Download-URL: https://pypi.python.org/pypi/sphinxcontrib-httpdomain
+Description: sphinxcontrib.httpdomain --- Documenting RESTful HTTP APIs
+        ==========================================================
+        
+        This contrib extension, sphinxcontrib.httpdomain, provides a Sphinx 
domain
+        for describing RESTful HTTP APIs.
         
         You can find the documentation from the following URL:
         
-        http://pythonhosted.org/sphinxcontrib-httpdomain/
+        https://pythonhosted.org/sphinxcontrib-httpdomain/
         
 Platform: any
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Console
 Classifier: Environment :: Web Environment
 Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib_httpdomain.egg-info/SOURCES.txt
 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib_httpdomain.egg-info/SOURCES.txt
--- 
old/sphinxcontrib-httpdomain-1.4.0/sphinxcontrib_httpdomain.egg-info/SOURCES.txt
    2015-08-13 16:15:20.000000000 +0200
+++ 
new/sphinxcontrib-httpdomain-1.5.0/sphinxcontrib_httpdomain.egg-info/SOURCES.txt
    2016-05-29 20:16:05.000000000 +0200
@@ -9,6 +9,8 @@
 sphinxcontrib/autohttp/bottle.py
 sphinxcontrib/autohttp/common.py
 sphinxcontrib/autohttp/flask.py
+sphinxcontrib/autohttp/flask_base.py
+sphinxcontrib/autohttp/flaskqref.py
 sphinxcontrib/autohttp/tornado.py
 sphinxcontrib_httpdomain.egg-info/PKG-INFO
 sphinxcontrib_httpdomain.egg-info/SOURCES.txt


Reply via email to