summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--EXAMPLES1
-rw-r--r--doc/ext/autodoc.rst2
-rw-r--r--sphinx/cmd/quickstart.py14
-rw-r--r--sphinx/domains/c.py3
-rw-r--r--sphinx/domains/cpp.py3
-rw-r--r--sphinx/pycode/parser.py7
-rw-r--r--sphinx/util/console.py18
-rw-r--r--sphinx/util/inspect.py4
-rw-r--r--tests/test_pycode_parser.py9
-rw-r--r--tests/test_util_inspect.py23
11 files changed, 79 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index c2c0bd45c..2c4374abe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -179,6 +179,13 @@ Bugs fixed
* #5022: latex: crashed with docutils package provided by Debian/Ubuntu
* #5009: latex: a label for table is vanished if table does not have a caption
* #5048: crashed with numbered toctree
+* #2410: C, render empty argument lists for macros.
+* C++, fix lookup of full template specializations with no template arguments.
+* #4667: C++, fix assertion on missing references in global scope when using
+ intersphinx. Thanks to Alan M. Carroll.
+* #5019: autodoc: crashed by Form Feed Character
+* #5032: autodoc: loses the first staticmethod parameter for old styled classes
+* #5036: quickstart: Typing Ctrl-U clears the whole of line
Testing
--------
diff --git a/EXAMPLES b/EXAMPLES
index 4310eff75..ee9d4a128 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -218,6 +218,7 @@ Documentation using sphinx_rtd_theme
* peewee: http://docs.peewee-orm.com/
* Phinx: http://docs.phinx.org/
* phpMyAdmin: https://docs.phpmyadmin.net/
+* PROS: https://pros.cs.purdue.edu/v5/ (customized)
* Pweave: http://mpastell.com/pweave/
* PyPy: http://doc.pypy.org/
* python-sqlparse: https://sqlparse.readthedocs.io/
diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst
index bf20f7ac4..9064fe1b3 100644
--- a/doc/ext/autodoc.rst
+++ b/doc/ext/autodoc.rst
@@ -374,7 +374,7 @@ There are also new config values that you can set:
This value contains a list of modules to be mocked up. This is useful when
some external dependencies are not met at build time and break the building
process. You may only specify the root package of the dependencies
- themselves and ommit the sub-modules:
+ themselves and omit the sub-modules:
.. code-block:: python
diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py
index d6c7fa22a..14217d1a7 100644
--- a/sphinx/cmd/quickstart.py
+++ b/sphinx/cmd/quickstart.py
@@ -41,7 +41,7 @@ from sphinx import __display_version__, package_dir
from sphinx.locale import __
from sphinx.util import texescape
from sphinx.util.console import ( # type: ignore
- purple, bold, red, turquoise, nocolor, color_terminal
+ colorize, bold, red, turquoise, nocolor, color_terminal
)
from sphinx.util.osutil import ensuredir, make_filename
from sphinx.util.template import SphinxRenderer
@@ -85,8 +85,14 @@ PROMPT_PREFIX = '> '
# function to get input from terminal -- overridden by the test suite
def term_input(prompt):
# type: (unicode) -> unicode
- print(prompt, end='')
- return input('')
+ if sys.platform == 'win32':
+ # Important: On windows, readline is not enabled by default. In these
+ # environment, escape sequences have been broken. To avoid the
+ # problem, quickstart uses ``print()`` to show prompt.
+ print(prompt, end='')
+ return input('')
+ else:
+ return input(prompt)
class ValidationError(Exception):
@@ -186,7 +192,7 @@ def do_prompt(text, default=None, validator=nonempty):
prompt = prompt.encode('utf-8')
except UnicodeEncodeError:
prompt = prompt.encode('latin1')
- prompt = purple(prompt)
+ prompt = colorize('purple', prompt, input_mode=True)
x = term_input(prompt).strip()
if default and not x:
x = default
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index 50e9b2e5e..e6b370d62 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -147,7 +147,8 @@ class CObject(ObjectDescription):
fullname = name
if not arglist:
- if self.objtype == 'function':
+ if self.objtype == 'function' or \
+ self.objtype == 'macro' and sig.rstrip().endswith('()'):
# for functions, add an empty parameter list
signode += addnodes.desc_parameterlist()
if const:
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index f2ff3aa0b..aebc5d245 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -3566,6 +3566,9 @@ class Symbol(object):
# and params that are packs must in the args be the name expanded
if len(templateParams.params) != len(templateArgs.args):
return True
+ # having no template params and no arguments is also a specialization
+ if len(templateParams.params) == 0:
+ return True
for i in range(len(templateParams.params)):
param = templateParams.params[i]
arg = templateArgs.args[i]
diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py
index 31d2c465a..9d464a253 100644
--- a/sphinx/pycode/parser.py
+++ b/sphinx/pycode/parser.py
@@ -34,6 +34,11 @@ else:
ASSIGN_NODES = (ast.Assign)
+def filter_whitespace(code):
+ # type: (unicode) -> unicode
+ return code.replace('\f', ' ') # replace FF (form feed) with whitespace
+
+
def get_assign_targets(node):
# type: (ast.AST) -> List[ast.expr]
"""Get list of targets from Assign and AnnAssign node."""
@@ -467,7 +472,7 @@ class Parser(object):
def __init__(self, code, encoding='utf-8'):
# type: (unicode, unicode) -> None
- self.code = code
+ self.code = filter_whitespace(code)
self.encoding = encoding
self.comments = {} # type: Dict[Tuple[unicode, unicode], unicode]
self.deforders = {} # type: Dict[unicode, int]
diff --git a/sphinx/util/console.py b/sphinx/util/console.py
index 7663feb1e..d62169adf 100644
--- a/sphinx/util/console.py
+++ b/sphinx/util/console.py
@@ -87,9 +87,21 @@ def coloron():
codes.update(_orig_codes)
-def colorize(name, text):
- # type: (str, unicode) -> unicode
- return codes.get(name, '') + text + codes.get('reset', '')
+def colorize(name, text, input_mode=False):
+ # type: (str, unicode, bool) -> unicode
+ def escseq(name):
+ # Wrap escape sequence with ``\1`` and ``\2`` to let readline know
+ # it is non-printable characters
+ # ref: https://tiswww.case.edu/php/chet/readline/readline.html
+ #
+ # Note: This hack does not work well in Windows (see #5059)
+ escape = codes.get(name, '')
+ if input_mode and escape and sys.platform != 'win32':
+ return '\1' + escape + '\2'
+ else:
+ return escape
+
+ return escseq(name) + text + escseq('reset')
def strip_colors(s):
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 7bda11503..5727d69b1 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -176,8 +176,8 @@ def isstaticmethod(obj, cls=None, name=None):
elif cls and name:
# trace __mro__ if the method is defined in parent class
#
- # .. note:: This only works with new style classes.
- for basecls in getattr(cls, '__mro__', []):
+ # .. note:: This only works well with new style classes.
+ for basecls in getattr(cls, '__mro__', [cls]):
meth = basecls.__dict__.get(name)
if meth:
if isinstance(meth, staticmethod):
diff --git a/tests/test_pycode_parser.py b/tests/test_pycode_parser.py
index 29363e17e..0875329a4 100644
--- a/tests/test_pycode_parser.py
+++ b/tests/test_pycode_parser.py
@@ -315,3 +315,12 @@ def test_decorators():
'func3': ('def', 7, 9),
'Foo': ('class', 11, 15),
'Foo.method': ('def', 13, 15)}
+
+
+def test_formfeed_char():
+ source = ('class Foo:\n'
+ '\f\n'
+ ' attr = 1234 #: comment\n')
+ parser = Parser(source)
+ parser.parse()
+ assert parser.comments == {('Foo', 'attr'): 'comment'}
diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py
index 09aff512f..e82d42eab 100644
--- a/tests/test_util_inspect.py
+++ b/tests/test_util_inspect.py
@@ -380,3 +380,26 @@ def test_dict_customtype():
description = inspect.object_description(dictionary)
# Type is unsortable, just check that it does not crash
assert "<CustomType(2)>: 2" in description
+
+
+def test_isstaticmethod():
+ class Foo():
+ @staticmethod
+ def method1():
+ pass
+
+ def method2(self):
+ pass
+
+ class Bar(Foo):
+ pass
+
+ assert inspect.isstaticmethod(Foo.method1, Foo, 'method1') is True
+ assert inspect.isstaticmethod(Foo.method2, Foo, 'method2') is False
+
+ if sys.version_info < (3, 0):
+ assert inspect.isstaticmethod(Bar.method1, Bar, 'method1') is False
+ assert inspect.isstaticmethod(Bar.method2, Bar, 'method2') is False
+ else:
+ assert inspect.isstaticmethod(Bar.method1, Bar, 'method1') is True
+ assert inspect.isstaticmethod(Bar.method2, Bar, 'method2') is False