diff --git a/python/helpers/rest_formatter.py b/python/helpers/rest_formatter.py index b7f1736e8e87..266c794216de 100644 --- a/python/helpers/rest_formatter.py +++ b/python/helpers/rest_formatter.py @@ -1,6 +1,43 @@ import sys +from docutils.core import publish_string from epydoc.markup import DocstringLinker -from epydoc.markup.restructuredtext import parse_docstring +from epydoc.markup.restructuredtext import ParsedRstDocstring, _EpydocHTMLTranslator, _DocumentPseudoWriter, _EpydocReader + +class RestHTMLTranslator(_EpydocHTMLTranslator): + def visit_field_name(self, node): + atts = {} + if self.in_docinfo: + atts['class'] = 'docinfo-name' + else: + atts['class'] = 'field-name' + if ( self.settings.field_name_limit + and len(node.astext()) > self.settings.field_name_limit): + atts['colspan'] = 2 + self.context.append('\n ') + else: + self.context.append('') + atts['align'] = "right" + self.body.append(self.starttag(node, 'th', '', **atts)) + +class MyParsedRstDocstring(ParsedRstDocstring): + def __init__(self, document): + ParsedRstDocstring.__init__(self, document) + + def to_html(self, docstring_linker, directory=None, + docindex=None, context=None, **options): + visitor = RestHTMLTranslator(self._document, docstring_linker, + directory, docindex, context) + self._document.walkabout(visitor) + return ''.join(visitor.body) + +def parse_docstring(docstring, errors, **options): + writer = _DocumentPseudoWriter() + reader = _EpydocReader(errors) # Outputs errors to the list. + publish_string(docstring, writer=writer, reader=reader, + settings_overrides={'report_level':10000, + 'halt_level':10000, + 'warning_stream':None}) + return MyParsedRstDocstring(writer.document) try: src = "".join(sys.argv[1:]) diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index fcfe8862615d..30c45d109c9a 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -472,7 +472,10 @@ - + + + diff --git a/python/src/com/jetbrains/python/documentation/ReSTRunner.java b/python/src/com/jetbrains/python/documentation/ReSTRunner.java index 68b5f5a3b21a..44c32332acbf 100644 --- a/python/src/com/jetbrains/python/documentation/ReSTRunner.java +++ b/python/src/com/jetbrains/python/documentation/ReSTRunner.java @@ -4,15 +4,12 @@ import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.jetbrains.python.PythonHelpersLocator; import com.jetbrains.python.sdk.PythonSdkType; import com.jetbrains.python.sdk.SdkUtil; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; /** * User : catherine diff --git a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java index bc3d7826af17..dc59ce06f194 100644 --- a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java @@ -1,7 +1,9 @@ package com.jetbrains.python.inspections; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; import com.jetbrains.python.PyBundle; import com.jetbrains.python.actions.RemoveArgumentEqualDefaultQuickFix; import com.jetbrains.python.psi.*; @@ -55,11 +57,10 @@ public class PyArgumentEqualDefaultInspection extends PyInspection { PyExpression defaultValue = e.getValue().getDefaultValue(); if (defaultValue != null) { PyExpression key = e.getKey(); - String text = e.getKey().getText(); if (key instanceof PyKeywordArgument && ((PyKeywordArgument)key).getValueExpression() != null) { - text = ((PyKeywordArgument)key).getValueExpression().getText(); + key = ((PyKeywordArgument)key).getValueExpression(); } - if (text.equals(defaultValue.getText())) { + if (isEqual(key, defaultValue)) { problemElements.add(e.getKey()); } } @@ -77,5 +78,27 @@ public class PyArgumentEqualDefaultInspection extends PyInspection { if (!(arguments[i] instanceof PyKeywordArgument)) canDelete = false; } } + + private boolean isEqual(PyExpression key, PyExpression defaultValue) { + if (key instanceof PyNumericLiteralExpression && defaultValue instanceof PyNumericLiteralExpression) { + if (key.getText().equals(defaultValue.getText())) + return true; + } + else if (key instanceof PyStringLiteralExpression && defaultValue instanceof PyStringLiteralExpression) { + if (((PyStringLiteralExpression)key).getStringValue().equals(((PyStringLiteralExpression)defaultValue).getStringValue())) + return true; + } + else { + PsiReference keyRef = key.getReference(); + PsiReference defRef = defaultValue.getReference(); + if (keyRef != null && defRef != null) { + PsiElement keyResolve = keyRef.resolve(); + PsiElement defResolve = defRef.resolve(); + if (keyResolve != null && keyResolve.equals(defResolve)) + return true; + } + } + return false; + } } } diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java index eb7ebae0f28f..529cb8f88d5b 100644 --- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java @@ -237,7 +237,7 @@ public class PyStringFormatInspection extends PyInspection { if (myExpectedArguments > 0) { if (myExpectedArguments == (expressions.length + additionalExpressions.size())) { // probably "%s %s" % {'a':1, 'b':2}, with names forgotten in template - registerProblem(pyElement, PyBundle.message("INSP.format.requires.no.mapping")); + registerProblem(rightExpression, PyBundle.message("INSP.format.requires.no.mapping")); } else { // "braces: %s" % {'foo':1} gives "braces: {'foo':1}", implicit str() kicks in diff --git a/python/testData/inspections/PyArgumentEqualDefaultInspection/test.py b/python/testData/inspections/PyArgumentEqualDefaultInspection/test.py index be7fd9fa43e0..6e6cfea07e67 100644 --- a/python/testData/inspections/PyArgumentEqualDefaultInspection/test.py +++ b/python/testData/inspections/PyArgumentEqualDefaultInspection/test.py @@ -38,3 +38,21 @@ class C(object): del self._x x = property(getx, None, fdel = delx, doc = "I'm the 'x' property.") + + +# PY-3455 +import optparse + +class Option(optparse.Option): + pass + +class OptionParser(optparse.OptionParser): + def __init__(self): + optparse.OptionParser.__init__(self, option_class=Option) + +## + +def bar(a = "qwer"): + pass + +bar(a = 'qwer')