diff --git a/CHANGES b/CHANGES index 4a02f8692..9eceac076 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,9 @@ Features added Bugs fixed ---------- +* #4415: autodoc classifies inherited classmethods as regular methods +* #4415: autodoc classifies inherited staticmethods as regular methods + Testing -------- @@ -45,7 +48,7 @@ Incompatible changes * shebang line is removed from generated conf.py * #2557: autodoc: :confval:`autodoc_mock_imports` only mocks specified modules with their descendants. It does not mock their ancestors. If you want to - mock them, please specify the name of ancestors implicitly. + mock them, please specify the name of ancestors explicitly. * #3620: html theme: move DOCUMENTATION_OPTIONS to independent JavaScript file (refs: #4295) * #4246: Limit width of text body for all themes. Conifigurable via theme @@ -190,7 +193,8 @@ Bugs fixed ---------- * #1922: html search: Upper characters problem in French - +* #4412: Updated jQuery version from 3.1.0 to 3.2.1 +* #4438: math: math with labels with whitespace cause html error Testing -------- diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index d9e82813d..1597d0c1b 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -32,7 +32,7 @@ from sphinx.application import ExtensionError from sphinx.util import logging from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \ safe_getattr, object_description, is_builtin_class_method, \ - isenumattribute, getdoc + isenumattribute, isclassmethod, isstaticmethod, getdoc from sphinx.util.docstrings import prepare_docstring if False: @@ -1261,12 +1261,14 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: # to distinguish classmethod/staticmethod obj = self.parent.__dict__.get(self.object_name) + if obj is None: + obj = self.object - if isinstance(obj, classmethod): + if isclassmethod(obj): self.directivetype = 'classmethod' # document class and static members before ordinary ones self.member_order = self.member_order - 1 - elif isinstance(obj, staticmethod): + elif isstaticmethod(obj, cls=self.parent, name=self.object_name): self.directivetype = 'staticmethod' # document class and static members before ordinary ones self.member_order = self.member_order - 1 diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index f2e15b485..d9bc3726b 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -10,6 +10,7 @@ """ from docutils import nodes, utils +from docutils.nodes import make_id from docutils.parsers.rst import Directive, directives from sphinx.config import string_classes @@ -55,7 +56,8 @@ class MathDomain(Domain): label = 'mathematics' initial_data = { - 'objects': {}, # labelid -> (docname, eqno) + 'nameids': {}, # label -> equation ID + 'objects': {}, # equation ID -> (docname, eqno) } # type: Dict[unicode, Dict[unicode, Tuple[unicode, int]]] dangling_warnings = { 'eq': 'equation not found: %(target)s', @@ -63,9 +65,9 @@ class MathDomain(Domain): def clear_doc(self, docname): # type: (unicode) -> None - for labelid, (doc, eqno) in list(self.data['objects'].items()): + for equation_id, (doc, eqno) in list(self.data['objects'].items()): if doc == docname: - del self.data['objects'][labelid] + del self.data['objects'][equation_id] def merge_domaindata(self, docnames, otherdata): # type: (Iterable[unicode], Dict) -> None @@ -84,10 +86,10 @@ class MathDomain(Domain): newnode['target'] = target return newnode else: + node_id = make_id('equation-%s' % target) if env.config.math_numfig and env.config.numfig: if docname in env.toc_fignumbers: - id = 'equation-' + target - number = env.toc_fignumbers[docname]['displaymath'].get(id, ()) + number = env.toc_fignumbers[docname]['displaymath'].get(node_id, ()) number = '.'.join(map(str, number)) else: number = '' @@ -98,8 +100,8 @@ class MathDomain(Domain): logger.warning('Invalid math_eqref_format: %r', exc, location=node) title = nodes.Text("(%d)" % number) - return make_refnode(builder, fromdocname, docname, - "equation-" + target, title) + title = nodes.Text("(%d)" % number) + return make_refnode(builder, fromdocname, docname, node_id, title) else: return None @@ -260,7 +262,8 @@ class MathDirective(Directive): node['number'] = eqno # add target node - target = nodes.target('', '', ids=['equation-' + node['label']]) + node_id = make_id('equation-%s' % node['label']) + target = nodes.target('', '', ids=[node_id]) self.state.document.note_explicit_target(target) ret.insert(0, target) except UserWarning as exc: diff --git a/sphinx/themes/basic/static/jquery-3.1.0.js b/sphinx/themes/basic/static/jquery-3.2.1.js similarity index 94% rename from sphinx/themes/basic/static/jquery-3.1.0.js rename to sphinx/themes/basic/static/jquery-3.2.1.js index f2fc27478..d2d8ca479 100644 --- a/sphinx/themes/basic/static/jquery-3.1.0.js +++ b/sphinx/themes/basic/static/jquery-3.2.1.js @@ -1,16 +1,15 @@ -/*eslint-disable no-unused-vars*/ /*! - * jQuery JavaScript Library v3.1.0 + * jQuery JavaScript Library v3.2.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * - * Copyright jQuery Foundation and other contributors + * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * - * Date: 2016-07-07T21:44Z + * Date: 2017-03-20T18:59Z */ ( function( global, factory ) { @@ -83,13 +82,13 @@ var support = {}; doc.head.appendChild( script ).parentNode.removeChild( script ); } /* global Symbol */ -// Defining this global in .eslintrc would create a danger of using the global +// Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var - version = "3.1.0", + version = "3.2.1", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -129,13 +128,14 @@ jQuery.fn = jQuery.prototype = { // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { - return num != null ? - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } - // Return all the elements in a clean array - slice.call( this ); + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack @@ -236,11 +236,11 @@ jQuery.extend = jQuery.fn.extend = function() { // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + ( copyIsArray = Array.isArray( copy ) ) ) ) { if ( copyIsArray ) { copyIsArray = false; - clone = src && jQuery.isArray( src ) ? src : []; + clone = src && Array.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; @@ -279,8 +279,6 @@ jQuery.extend( { return jQuery.type( obj ) === "function"; }, - isArray: Array.isArray, - isWindow: function( obj ) { return obj != null && obj === obj.window; }, @@ -355,10 +353,6 @@ jQuery.extend( { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); }, - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - each: function( obj, callback ) { var length, i = 0; @@ -543,14 +537,14 @@ function isArrayLike( obj ) { } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.3.0 + * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2016-01-04 + * Date: 2016-08-08 */ (function( window ) { @@ -696,7 +690,7 @@ var i, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { @@ -723,7 +717,7 @@ var i, disabledAncestor = addCombinator( function( elem ) { - return elem.disabled === true; + return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" } ); @@ -1009,26 +1003,54 @@ function createButtonPseudo( type ) { * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { - // Known :disabled false positives: - // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) - // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { - // Check form elements and option elements for explicit disabling - return "label" in elem && elem.disabled === disabled || - "form" in elem && elem.disabled === disabled || + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { - // Check non-disabled form elements for fieldset[disabled] ancestors - "form" in elem && elem.disabled === false && ( - // Support: IE6-11+ - // Ancestry is covered for us - elem.isDisabled === disabled || + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { - // Otherwise, assume any non-