Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2013-09-15 21:19:48 +02:00
35 changed files with 967 additions and 1069 deletions
-208
View File
@@ -89,214 +89,6 @@ cStringIO.OutputType.__iter__ = \
:rtype: cStringIO.OutputType of T \n\
## 8.1. datetime
datetime.date.today = \
:rtype: date \n\
datetime.date.fromtimestamp = \
:rtype: date \n\
datetime.date.fromordinal = \
:rtype: date \n\
datetime.date.replace = \
:rtype: date \n\
datetime.date.toordinal = \
:rtype: int \n\
datetime.date.weekday = \
:rtype: int \n\
datetime.date.isoweekday = \
:rtype: int \n\
datetime.date.isocalendar = \
:rtype: (int, int, int) \n\
datetime.date.isoformat = \
:rtype: bytes \n\
datetime.date.ctime = \
:rtype: bytes \n\
datetime.date.strftime = \
:type format: string \n\
:rtype: string \n\
datetime.date.__add__ = \
:type y: timedelta \n\
:type other: timedelta \n\
:rtype: date \n\
datetime.date.__radd__ = \
:type y: timedelta \n\
:type other: timedelta \n\
:rtype: date \n\
datetime.date.__sub__ = \
:type y: date or timedelta \n\
:type other: date or timedelta \n\
:rtype: date or timedelta \n\
datetime.date.__rsub__ = \
:type y: date \n\
:type other: date \n\
:rtype: timedelta \n\
datetime.time.isoformat = \
:rtype: bytes \n\
datetime.time.strftime = \
:type format: string \n\
:rtype: string \n\
datetime.time.utcoffset = \
:rtype: timedelta or None \n\
datetime.time.dst = \
:rtype: timedelta or None \n\
datetime.ime.tzname = \
:rtype: string \n\
datetime.timedelta.__add__ = \
:type y: T <= timedelta or date or datetime \n\
:type other: T <= timedelta or date or datetime \n\
:rtype: T \n\
datetime.timedelta.__radd__ = \
:type y: timedelta or date or datetime \n\
:type other: timedelta or date or datetime \n\
:rtype: timedelta or date or datetime \n\
datetime.timedelta.__sub__ = \
:type y: timedelta or date or datetime \n\
:type other: timedelta or date or datetime \n\
:rtype: timedelta or date or datetime \n\
datetime.timedelta.__rsub__ = \
:type y: timedelta or date or datetime \n\
:type other: timedelta or date or datetime \n\
:rtype: timedelta or date or datetime \n\
datetime.timedelta.__mul__ = \
:type y: int or long \n\
:type other: int or long \n\
:rtype: timedelta \n\
datetime.timedelta.__rmul__ = \
:type y: int or long \n\
:type other: int or long \n\
:rtype: timedelta \n\
datetime.timedelta.__div__ = \
:type y: int or long \n\
:type other: int or long \n\
:rtype: timedelta \n\
datetime.timedelta.__truediv__ = \
:type y: int or long \n\
:type other: int or long \n\
:rtype: timedelta \n\
datetime.datetime.today = \
:rtype: datetime \n\
datetime.datetime.now = \
:type tz: tzinfo or None \n\
:rtype: datetime \n\
datetime.datetime.utcnow = \
:rtype: datetime \n\
datetime.datetime.fromtimestamp = \
:type timestamp: int or long or float \n\
:type tz: tzinfo or None \n\
:rtype: datetime \n\
datetime.datetime.utcfromtimestamp = \
:type timestamp: int or long or float \n\
:rtype: datetime \n\
datetime.datetime.fromordinal = \
:type ordinal: int \n\
:rtype: datetime \n\
datetime.datetime.combine = \
:type date: date \n\
:type time: time \n\
:rtype: datetime \n\
datetime.datetime.strptime = \
:type date_string: string \n\
:type format: string \n\
:rtype: datetime \n\
datetime.datetime.date = \
:rtype: date \n\
datetime.datetime.time = \
:rtype: time \n\
datetime.datetime.timetz = \
:rtype: time \n\
datetime.datetime.replace = \
:rtype: datetime \n\
datetime.datetime.astimezone = \
:type tz: tzinfo \n\
:rtype: datetime \n\
datetime.datetime.utcoffset = \
:rtype: timedelta or None \n\
datetime.datetime.dst = \
:rtype: timedelta or None \n\
datetime.datetime.tzname = \
:rtype: string \n\
datetime.datetime.toordinal = \
:rtype: int \n\
datetime.datetime.weekday = \
:rtype: int \n\
datetime.datetime.isoweekday = \
:rtype: int \n\
datetime.datetime.isocalendar = \
:rtype: (int, int, int) \n\
datetime.datetime.isoformat = \
:rtype: bytes \n\
datetime.datetime.ctime = \
:rtype: bytes \n\
datetime.datetime.strftime = \
:type format: string \n\
:rtype: string \n\
datetime.datetime.__add__ = \
:type y: timedelta \n\
:type other: timedelta \n\
:rtype: datetime \n\
datetime.datetime.__radd__ = \
:type y: timedelta \n\
:type other: timedelta \n\
:rtype: datetime \n\
datetime.datetime.__sub__ = \
:type y: datetime or timedelta \n\
:type other: datetime or timedelta \n\
:rtype: datetime or timedelta \n\
## 8.3. collections
collections.Iterator.__init__ = \
Binary file not shown.
+2 -2
View File
@@ -5,7 +5,7 @@ import os
ERROR_WRONG_USAGE = 1
ERROR_NO_PIP = 2
ERROR_NO_DISTRIBUTE = 3
ERROR_NO_SETUPTOOLS = 3
ERROR_EXCEPTION = 4
def exit(retcode):
@@ -42,7 +42,7 @@ def do_list():
try:
import pkg_resources
except ImportError:
error("Python package management tool 'setuptools' or 'distribute' not found", ERROR_NO_DISTRIBUTE)
error("Python package management tool 'setuptools' or 'distribute' not found", ERROR_NO_SETUPTOOLS)
for pkg in pkg_resources.working_set:
requires = ':'.join([str(x) for x in pkg.requires()])
sys.stdout.write('\t'.join([pkg.project_name, pkg.version, pkg.location, requires])+chr(10))
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -39,14 +39,6 @@ public interface PyParameterList extends PyElement, StubBasedPsiElement<PyParame
*/
boolean hasKeywordContainer();
/**
* Checks is this parameter list is the same or is a superset of another parameter list.
* (The reverse is only true is the lists are the same.)
* @param another what to compare to
* @return true if this list is a superset of another.
*/
boolean isCompatibleTo(@NotNull PyParameterList another);
String getPresentableText(boolean includeDefaultValue);
@Nullable
@@ -558,6 +558,7 @@
<!-- User skeletons -->
<pyModuleMembersProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsModuleMembersProvider"/>
<pyClassMembersProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsClassMembersProvider"/>
<typeProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsTypeProvider"/>
<typeProvider implementation="com.jetbrains.python.debugger.PyCallSignatureTypeProvider"/>
@@ -6,12 +6,13 @@ import com.intellij.codeInsight.generation.PsiElementMemberChooserObject;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.util.Function;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.TypeEvalContext;
import javax.swing.*;
import java.util.List;
/**
* @author Alexey.Ivanov
@@ -20,7 +21,14 @@ public class PyMethodMember extends PsiElementMemberChooserObject implements Cla
private final String myFullName;
private static String buildNameFor(final PyElement element) {
if (element instanceof PyFunction) {
return element.getName() + ((PyFunction)element).getParameterList().getText();
final TypeEvalContext context = TypeEvalContext.userInitiated(element.getContainingFile());
final List<PyParameter> parameters = PyUtil.getParameters((PyFunction)element, context);
return element.getName() + "(" + StringUtil.join(parameters, new Function<PyParameter, String>() {
@Override
public String fun(PyParameter parameter) {
return PyUtil.getReadableRepr(parameter, false);
}
}, ", ") + ")";
}
if (element instanceof PyClass && PyNames.FAKE_OLD_BASE.equals(element.getName())) {
return "<old-style class>";
@@ -179,7 +179,8 @@ public class PyOverrideImplementUtil {
if (anno != null) {
pyFunctionBuilder.annotation(anno.getText());
}
final PyParameter[] baseParams = baseFunction.getParameterList().getParameters();
final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getContainingFile());
final List<PyParameter> baseParams = PyUtil.getParameters(baseFunction, context);
for (PyParameter parameter : baseParams) {
pyFunctionBuilder.parameter(parameter.getText());
}
@@ -211,7 +212,6 @@ public class PyOverrideImplementUtil {
statementBody.append(PyNames.PASS);
}
else {
final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getContainingFile());
if (!PyNames.INIT.equals(baseFunction.getName()) && baseFunction.getReturnType(context, null) != PyNoneType.INSTANCE) {
statementBody.append("return ");
}
@@ -220,7 +220,9 @@ public class PyOverrideImplementUtil {
statementBody.append("(");
final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel();
if (!langLevel.isPy3K()) {
statementBody.append(pyClass.getName()).append(", ").append(PyUtil.getFirstParameterName(baseFunction));
final String baseFirstName = !baseParams.isEmpty() ? baseParams.get(0).getName() : null;
final String firstName = baseFirstName != null ? baseFirstName : PyNames.CANONICAL_SELF;
statementBody.append(pyClass.getName()).append(", ").append(firstName);
}
statementBody.append(").").append(baseFunction.getName()).append("(");
if (parameters.size() > 0) {
@@ -0,0 +1,82 @@
package com.jetbrains.python.codeInsight.userSkeletons;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyTargetExpression;
import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
import com.jetbrains.python.psi.types.PyClassType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author vlan
*/
public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase {
@NotNull
@Override
public Collection<PyDynamicMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
final PyClass cls = classType.getPyClass();
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
if (skeleton != null) {
return getClassMembers(skeleton);
}
return Collections.emptyList();
}
@Nullable
@Override
public PsiElement resolveMember(@NotNull PyClassType classType, @NotNull String name, PsiElement location) {
final PyClass cls = classType.getPyClass();
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
if (skeleton != null) {
return findClassMember(skeleton, name);
}
return null;
}
private static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name) {
final PyFunction function = cls.findMethodByName(name, false);
if (function != null) {
return function;
}
final PyTargetExpression instanceAttribute = cls.findInstanceAttribute(name, false);
if (instanceAttribute != null) {
return instanceAttribute;
}
final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
if (classAttribute != null) {
return classAttribute;
}
return null;
}
private static Collection<PyDynamicMember> getClassMembers(@NotNull PyClass cls) {
final List<PyDynamicMember> result = new ArrayList<PyDynamicMember>();
for (PyFunction function : cls.getMethods()) {
final String name = function.getName();
if (name != null) {
result.add(new PyDynamicMember(name, function));
}
}
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
final String name = attribute.getName();
if (name != null) {
result.add(new PyDynamicMember(name, attribute));
}
}
for (PyTargetExpression attribute : cls.getClassAttributes()) {
final String name = attribute.getName();
if (name != null) {
result.add(new PyDynamicMember(name, attribute));
}
}
return result;
}
}
@@ -7,7 +7,7 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyParameterList;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -46,13 +46,11 @@ public class PyInitNewSignatureInspection extends PyInspection {
String the_other_name = PyNames.NEW.equals(init_or_new.getName()) ? PyNames.INIT : PyNames.NEW;
PyFunction the_other = cls.findMethodByName(the_other_name, true);
if (the_other == null || builtins.getClass("object") == the_other.getContainingClass()) return;
final PyParameterList closer_list = init_or_new.getParameterList();
final PyParameterList farther_list = the_other.getParameterList();
if (! farther_list.isCompatibleTo(closer_list) &&
! closer_list.isCompatibleTo(farther_list) &&
closer_list.getContainingFile() == cls.getContainingFile()
if (!PyUtil.isSignatureCompatibleTo(the_other, init_or_new, myTypeEvalContext) &&
!PyUtil.isSignatureCompatibleTo(init_or_new, the_other, myTypeEvalContext) &&
init_or_new.getContainingFile() == cls.getContainingFile()
) {
registerProblem(closer_list, PyNames.NEW.equals(init_or_new.getName()) ?
registerProblem(init_or_new.getParameterList(), PyNames.NEW.equals(init_or_new.getName()) ?
PyBundle.message("INSP.new.incompatible.to.init") :
PyBundle.message("INSP.init.incompatible.to.new")
);
@@ -8,6 +8,7 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -48,7 +49,7 @@ public class PyMethodOverridingInspection extends PyInspection {
if (psiElement instanceof PyFunction) {
final PyFunction baseMethod = (PyFunction)psiElement;
final PyClass baseClass = baseMethod.getContainingClass();
if (!function.getParameterList().isCompatibleTo(baseMethod.getParameterList())) {
if (!PyUtil.isSignatureCompatibleTo(function, baseMethod, myTypeEvalContext)) {
final String msg = PyBundle.message("INSP.signature.mismatch",
cls.getName() + "." + name + "()",
baseClass != null ? baseClass.getName() : "");
@@ -57,8 +57,8 @@ public class PyPropertyDefinitionInspection extends PyInspection {
private LanguageLevel myLevel;
private List<PyClass> myStringClasses;
private PyParameterList myOneParamList;
private PyParameterList myTwoParamList; // arglist with two args, 'self' and 'value'
private PyFunction myOneParamFunction;
private PyFunction myTwoParamFunction; // arglist with two args, 'self' and 'value'
public Visitor(final ProblemsHolder holder, LocalInspectionToolSession session) {
super(holder, session);
@@ -83,9 +83,9 @@ public class PyPropertyDefinitionInspection extends PyInspection {
PyClass object_class = builtins.getClass("object");
if (object_class != null) {
final PyFunction method_repr = object_class.findMethodByName("__repr__", false);
if (method_repr != null) myOneParamList = method_repr.getParameterList();
if (method_repr != null) myOneParamFunction = method_repr;
final PyFunction method_delattr = object_class.findMethodByName("__delattr__", false);
if (method_delattr != null) myTwoParamList = method_delattr.getParameterList();
if (method_delattr != null) myTwoParamFunction = method_delattr;
}
}
@@ -235,8 +235,7 @@ public class PyPropertyDefinitionInspection extends PyInspection {
if (callable != null) {
// signature: at least two params, more optionals ok; first arg 'self'
final PyParameterList param_list = callable.getParameterList();
final PyParameterList two_parameters_list = myTwoParamList;
if (two_parameters_list != null && !param_list.isCompatibleTo(two_parameters_list)) {
if (myTwoParamFunction != null && !PyUtil.isSignatureCompatibleTo(callable, myTwoParamFunction, myTypeEvalContext)) {
registerProblem(being_checked, PyBundle.message("INSP.setter.signature.advice"));
}
checkForSelf(param_list);
@@ -254,8 +253,7 @@ public class PyPropertyDefinitionInspection extends PyInspection {
private void checkOneParameter(Callable callable, PsiElement being_checked, boolean is_getter) {
final PyParameterList param_list = callable.getParameterList();
final PyParameterList one_parameter_list = myOneParamList;
if (one_parameter_list != null && ! param_list.isCompatibleTo(one_parameter_list)) {
if (myOneParamFunction != null && !PyUtil.isSignatureCompatibleTo(callable, myOneParamFunction, myTypeEvalContext)) {
if (is_getter) registerProblem(being_checked, PyBundle.message("INSP.getter.signature.advice"));
else registerProblem(being_checked, PyBundle.message("INSP.deleter.signature.advice"));
}
@@ -71,7 +71,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
public static final int OK = 0;
public static final int ERROR_WRONG_USAGE = 1;
public static final int ERROR_NO_PIP = 2;
public static final int ERROR_NO_DISTRIBUTE = 3;
public static final int ERROR_NO_SETUPTOOLS = 3;
public static final int ERROR_INVALID_SDK = -1;
public static final int ERROR_TOOL_NOT_FOUND = -2;
public static final int ERROR_TIMEOUT = -3;
@@ -97,9 +97,12 @@ public class PyPackageManagerImpl extends PyPackageManager {
public static final String UNINSTALL = "uninstall";
public static final String UNTAR = "untar";
// Bundled package management tools
public static final String DISTRIBUTE = "distribute-0.6.27";
public static final String PIP = "pip-1.1";
// Bundled versions of package management tools
public static final String SETUPTOOLS_VERSION = "1.1.5";
public static final String PIP_VERSION = "1.4.1";
public static final String SETUPTOOLS = PACKAGE_SETUPTOOLS + "-" + SETUPTOOLS_VERSION;
public static final String PIP = PACKAGE_PIP + "-" + PIP_VERSION;
private List<PyPackage> myPackagesCache = null;
private Map<String, Set<PyPackage>> myDependenciesCache = null;
@@ -604,7 +607,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
if (useGlobalSite) {
args.add("--system-site-packages");
}
args.addAll(list("--never-download", "--distribute", destinationDir));
args.add(destinationDir);
runPythonHelper(VIRTUALENV, args);
}
@@ -619,7 +622,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
final ProjectJdkImpl tmpSdk = new ProjectJdkImpl("", PythonSdkType.getInstance());
tmpSdk.setHomePath(path);
final PyPackageManagerImpl manager = new PyPackageManagerImpl(tmpSdk);
manager.installManagement(DISTRIBUTE);
manager.installManagement(SETUPTOOLS);
manager.installManagement(PIP);
}
}
@@ -26,22 +26,22 @@ import java.util.Set;
* @author yole
*/
public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
public static final String INSTALL_DISTRIBUTE = "installDistribute";
public static final String INSTALL_SETUPTOOLS = "installSetuptools";
public static final String INSTALL_PIP = "installPip";
public static final String CREATE_VENV = "createVEnv";
private boolean myHasDistribute;
private boolean myHasSetuptools;
private boolean myHasPip = true;
public PyInstalledPackagesPanel(Project project, PackagesNotificationPanel area) {
super(project, area);
myNotificationArea.addLinkHandler(INSTALL_DISTRIBUTE, new Runnable() {
myNotificationArea.addLinkHandler(INSTALL_SETUPTOOLS, new Runnable() {
@Override
public void run() {
final Sdk sdk = getSelectedSdk();
if (sdk != null) {
installManagementTool(sdk, PyPackageManagerImpl.DISTRIBUTE);
installManagementTool(sdk, PyPackageManagerImpl.SETUPTOOLS);
}
}
});
@@ -69,9 +69,9 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
PyExternalProcessException exc = null;
try {
PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(selectedSdk);
myHasDistribute = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_DISTRIBUTE) != null;
if (!myHasDistribute) {
myHasDistribute = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_SETUPTOOLS) != null;
myHasSetuptools = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_SETUPTOOLS) != null;
if (!myHasSetuptools) {
myHasSetuptools = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_DISTRIBUTE) != null;
}
myHasPip = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_PIP) != null;
}
@@ -98,18 +98,18 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
if (retCode == PyPackageManagerImpl.ERROR_NO_PIP) {
myHasPip = false;
}
else if (retCode == PyPackageManagerImpl.ERROR_NO_DISTRIBUTE) {
myHasDistribute = false;
else if (retCode == PyPackageManagerImpl.ERROR_NO_SETUPTOOLS) {
myHasSetuptools = false;
}
else {
text = externalProcessException.getMessage();
}
final boolean hasPackagingTools = myHasPip && myHasDistribute;
final boolean hasPackagingTools = myHasPip && myHasSetuptools;
allowCreateVirtualEnv &= !hasPackagingTools;
}
if (text == null) {
if (!myHasDistribute) {
text = "Python package management tools not found. <a href=\"" + INSTALL_DISTRIBUTE + "\">Install 'distribute'</a>";
if (!myHasSetuptools) {
text = "Python package management tools not found. <a href=\"" + INSTALL_SETUPTOOLS + "\">Install 'setuptools'</a>";
}
else if (!myHasPip) {
text = "Python packaging tool 'pip' not found. <a href=\"" + INSTALL_PIP + "\">Install 'pip'</a>";
@@ -172,7 +172,10 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
return false;
}
}
if ("pip".equals(pkg.getName()) || "distribute".equals(pkg.getName())) {
final String name = pkg.getName();
if (PyPackageManagerImpl.PACKAGE_PIP.equals(name) ||
PyPackageManagerImpl.PACKAGE_SETUPTOOLS.equals(name) ||
PyPackageManagerImpl.PACKAGE_DISTRIBUTE.equals(name)) {
return false;
}
return true;
@@ -12,7 +12,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.MessageType;
@@ -125,6 +125,7 @@ public class PyUtil {
List<T> result = new SmartList<T>();
for (PsiElement child : element.getChildren()) {
if (instanceOf(child, aClass)) {
//noinspection unchecked
result.add((T)child);
}
else {
@@ -865,7 +866,7 @@ public class PyUtil {
@NotNull
public static Collection<VirtualFile> getSourceRoots(@NotNull PsiElement foothold) {
final Module module = ModuleUtil.findModuleForPsiElement(foothold);
final Module module = ModuleUtilCore.findModuleForPsiElement(foothold);
if (module != null) {
return getSourceRoots(module);
}
@@ -1298,4 +1299,77 @@ public class PyUtil {
}
return Arrays.asList(callable.getParameterList().getParameters());
}
public static boolean isSignatureCompatibleTo(@NotNull Callable callable, @NotNull Callable otherCallable,
@NotNull TypeEvalContext context) {
final List<PyParameter> parameters = getParameters(callable, context);
final List<PyParameter> otherParameters = getParameters(otherCallable, context);
final int optionalCount = optionalParametersCount(parameters);
final int otherOptionalCount = optionalParametersCount(otherParameters);
final int requiredCount = requiredParametersCount(callable, parameters);
final int otherRequiredCount = requiredParametersCount(otherCallable, otherParameters);
if (hasPositionalContainer(otherParameters) || hasKeywordContainer(otherParameters)) {
if (otherParameters.size() == specialParametersCount(otherCallable, otherParameters)) {
return true;
}
}
if (hasPositionalContainer(parameters) || hasKeywordContainer(parameters)) {
return requiredCount <= otherRequiredCount;
}
return requiredCount <= otherRequiredCount && parameters.size() >= otherParameters.size() && optionalCount >= otherOptionalCount;
}
private static int optionalParametersCount(@NotNull List<PyParameter> parameters) {
int n = 0;
for (PyParameter parameter : parameters) {
if (parameter.getDefaultValue() != null) {
n++;
}
}
return n;
}
private static int requiredParametersCount(@NotNull Callable callable, @NotNull List<PyParameter> parameters) {
return parameters.size() - optionalParametersCount(parameters) - specialParametersCount(callable, parameters);
}
private static int specialParametersCount(@NotNull Callable callable, @NotNull List<PyParameter> parameters) {
int n = 0;
if (hasPositionalContainer(parameters)) {
n++;
}
if (hasKeywordContainer(parameters)) {
n++;
}
if (callable.asMethod() != null) {
n++;
}
else {
if (parameters.size() > 0) {
final PyParameter first = parameters.get(0);
if (PyNames.CANONICAL_SELF.equals(first.getName())) {
n++;
}
}
}
return n;
}
private static boolean hasPositionalContainer(@NotNull List<PyParameter> parameters) {
for (PyParameter parameter : parameters) {
if (parameter instanceof PyNamedParameter && ((PyNamedParameter)parameter).isPositionalContainer()) {
return true;
}
}
return false;
}
private static boolean hasKeywordContainer(@NotNull List<PyParameter> parameters) {
for (PyParameter parameter : parameters) {
if (parameter instanceof PyNamedParameter && ((PyNamedParameter)parameter).isKeywordContainer()) {
return true;
}
}
return false;
}
}
@@ -5,7 +5,6 @@ import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.IStubElementType;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.PythonDialectsTokenSetProvider;
import com.jetbrains.python.psi.*;
@@ -85,65 +84,6 @@ public class PyParameterListImpl extends PyBaseElementImpl<PyParameterListStub>
return false;
}
public boolean isCompatibleTo(@NotNull PyParameterList other) {
PyParameter[] params = getParameters();
final PyParameter[] otherParams = other.getParameters();
final int optionalCount = optionalParametersCount(params);
final int otherOptionalCount = optionalParametersCount(otherParams);
final int requiredCount = requiredParametersCount(this);
final int otherRequiredCount = requiredParametersCount(other);
if (other.hasPositionalContainer() || other.hasKeywordContainer()) {
if (otherParams.length == specialParametersCount(other)) {
return true;
}
}
if (hasPositionalContainer() || hasKeywordContainer()) {
return requiredCount <= otherRequiredCount;
}
return requiredCount <= otherRequiredCount && params.length >= otherParams.length && optionalCount >= otherOptionalCount;
}
private static int optionalParametersCount(@NotNull PyParameter[] parameters) {
int n = 0;
for (PyParameter parameter : parameters) {
if (parameter.getDefaultValue() != null) {
n++;
}
}
return n;
}
private static int specialParametersCount(@NotNull PyParameterList parameterList) {
int n = 0;
if (parameterList.hasPositionalContainer()) {
n++;
}
if (parameterList.hasKeywordContainer()) {
n++;
}
final PyFunction function = parameterList.getContainingFunction();
if (function != null) {
if (function.asMethod() != null) {
n++;
}
}
else {
final PyParameter[] parameters = parameterList.getParameters();
if (parameters.length > 0) {
final PyParameter first = parameters[0];
if (PyNames.CANONICAL_SELF.equals(first.getName())) {
n++;
}
}
}
return n;
}
private static int requiredParametersCount(@NotNull PyParameterList parameterList) {
final PyParameter[] parameters = parameterList.getParameters();
return parameters.length - optionalParametersCount(parameters) - specialParametersCount(parameterList);
}
@Override
@Nullable
public PyNamedParameter findParameterByName(@NotNull final String name) {
@@ -16,6 +16,7 @@ import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -50,8 +51,9 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
hasNoCustomDecorators((PyFunction)object) &&
!isSingleArgDecoratorCall(myContext, (PyFunction)object)) {
item = item.withInsertHandler(PyFunctionInsertHandler.INSTANCE);
final PyParameterList parameterList = ((PyFunction)object).getParameterList();
final String params = StringUtil.join(parameterList.getParameters(), new Function<PyParameter, String>() {
final TypeEvalContext context = TypeEvalContext.userInitiated(myContext != null ? myContext.getContainingFile() : null);
final List<PyParameter> parameters = PyUtil.getParameters((PyFunction)object, context);
final String params = StringUtil.join(parameters, new Function<PyParameter, String>() {
@Override
public String fun(PyParameter pyParameter) {
return pyParameter.getName();
@@ -75,7 +75,7 @@ public class PyTypeChecker {
}
if (expected instanceof PyClassType) {
final PyClass c = ((PyClassType)expected).getPyClass();
if (c != null && "object".equals(c.getName())) {
if ("object".equals(c.getName())) {
return true;
}
}
@@ -136,7 +136,7 @@ public class PyTypeChecker {
}
if (actual instanceof PyFunctionType && expected instanceof PyClassType) {
final PyClass superClass = ((PyClassType)expected).getPyClass();
if (superClass != null && PyNames.CALLABLE.equals(superClass.getName())) {
if (PyNames.CALLABLE.equals(superClass.getName())) {
return true;
}
}
@@ -164,9 +164,12 @@ public class PyTypeChecker {
return true;
}
}
return matchNumericTypes(expected, actual);
}
private static boolean matchNumericTypes(PyType expected, PyType actual) {
final String superName = expected.getName();
final String subName = actual.getName();
// TODO: No inheritance check for builtin numerics at this moment
final boolean subIsBool = "bool".equals(subName);
final boolean subIsInt = "int".equals(subName);
final boolean subIsLong = "long".equals(subName);
@@ -383,7 +386,17 @@ public class PyTypeChecker {
if (markedCallee != null) {
final Callable callable = markedCallee.getCallable();
if (callable instanceof PyFunction) {
final PyExpression receiver = callee instanceof PyQualifiedExpression ? ((PyQualifiedExpression)callee).getQualifier() : null;
final PyFunction function = (PyFunction)callable;
final PyExpression receiver;
if (function.getModifier() == PyFunction.Modifier.STATICMETHOD) {
receiver = null;
}
else if (callee instanceof PyQualifiedExpression) {
receiver = ((PyQualifiedExpression)callee).getQualifier();
}
else {
receiver = null;
}
return new AnalyzeCallResults(callable, receiver, arguments);
}
}
@@ -394,39 +407,42 @@ public class PyTypeChecker {
@Nullable
public static AnalyzeCallResults analyzeCall(@NotNull PyBinaryExpression expr, @NotNull TypeEvalContext context) {
final PsiPolyVariantReference ref = expr.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
final ResolveResult[] resolveResult = ref.multiResolve(false);
AnalyzeCallResults firstResults = null;
for (ResolveResult result : resolveResult) {
final PsiElement resolved = result.getElement();
if (resolved instanceof PyTypedElement) {
final PyTypedElement typedElement = (PyTypedElement)resolved;
final PyType type = context.getType(typedElement);
if (!(type instanceof PyFunctionType)) {
return null;
}
final Callable callable = ((PyFunctionType)type).getCallable();
final boolean isRight = PyNames.isRightOperatorName(typedElement.getName());
final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression();
final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length >= 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (arg != null && param != null) {
final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
arguments.put(arg, param);
final AnalyzeCallResults results = new AnalyzeCallResults(callable, receiver, arguments);
if (firstResults == null) {
firstResults = results;
}
if (match(context.getType(param), context.getType(arg), context)) {
return results;
final ResolveResult[] resolveResult;
if (ref != null) {
resolveResult = ref.multiResolve(false);
AnalyzeCallResults firstResults = null;
for (ResolveResult result : resolveResult) {
final PsiElement resolved = result.getElement();
if (resolved instanceof PyTypedElement) {
final PyTypedElement typedElement = (PyTypedElement)resolved;
final PyType type = context.getType(typedElement);
if (!(type instanceof PyFunctionType)) {
return null;
}
final Callable callable = ((PyFunctionType)type).getCallable();
final boolean isRight = PyNames.isRightOperatorName(typedElement.getName());
final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression();
final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length >= 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (arg != null && param != null) {
final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
arguments.put(arg, param);
final AnalyzeCallResults results = new AnalyzeCallResults(callable, receiver, arguments);
if (firstResults == null) {
firstResults = results;
}
if (match(context.getType(param), context.getType(arg), context)) {
return results;
}
}
}
}
}
}
if (firstResults != null) {
return firstResults;
if (firstResults != null) {
return firstResults;
}
}
return null;
}
@@ -434,20 +450,23 @@ public class PyTypeChecker {
@Nullable
public static AnalyzeCallResults analyzeCall(@NotNull PySubscriptionExpression expr, @NotNull TypeEvalContext context) {
final PsiReference ref = expr.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
final PsiElement resolved = ref.resolve();
if (resolved instanceof PyTypedElement) {
final PyType type = context.getType((PyTypedElement)resolved);
if (type instanceof PyFunctionType) {
final Callable callable = ((PyFunctionType)type).getCallable();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length == 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (param != null) {
final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
final PyExpression arg = expr.getIndexExpression();
if (arg != null) {
arguments.put(arg, param);
return new AnalyzeCallResults(callable, expr.getOperand(), arguments);
final PsiElement resolved;
if (ref != null) {
resolved = ref.resolve();
if (resolved instanceof PyTypedElement) {
final PyType type = context.getType((PyTypedElement)resolved);
if (type instanceof PyFunctionType) {
final Callable callable = ((PyFunctionType)type).getCallable();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length == 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (param != null) {
final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
final PyExpression arg = expr.getIndexExpression();
if (arg != null) {
arguments.put(arg, param);
return new AnalyzeCallResults(callable, expr.getOperand(), arguments);
}
}
}
}
@@ -347,6 +347,10 @@ public class PyTypeParser {
final PsiElement resolved = results.get(0).getElement();
if (resolved instanceof PyTypedElement) {
type = context.getType((PyTypedElement)resolved);
if (type != null && !allowResolveToType(type)) {
type = null;
break;
}
if (type instanceof PyClassLikeType) {
type = ((PyClassLikeType)type).toInstance();
}
@@ -395,6 +399,9 @@ public class PyTypeParser {
type = context.getType((PyTypedElement)resolved);
if (type != null) {
tokens.remove(0);
if (!allowResolveToType(type)) {
return null;
}
if (type instanceof PyClassLikeType) {
type = ((PyClassLikeType)type).toInstance();
}
@@ -443,6 +450,10 @@ public class PyTypeParser {
return type;
}
private static boolean allowResolveToType(@NotNull PyType type) {
return type instanceof PyClassLikeType || type instanceof PyModuleType || type instanceof PyImportedModuleType;
}
@Nullable
private ParseResult parseBuiltinType(@NotNull Token<PyElementType> token) {
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(myAnchor);
@@ -12,6 +12,7 @@ import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBLabel;
import com.jetbrains.python.debugger.PyDebuggerOptionsProvider;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -36,6 +37,7 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
myProject = configuration.getProject();
FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
return file.isDirectory() || file.getExtension() == null || Comparing.equal(file.getExtension(), "py");
}
@@ -46,7 +48,8 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>("Select Script", "", myScriptTextField, myProject,
chooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
protected void onFileChoosen(VirtualFile chosenFile) {
@Override
protected void onFileChoosen(@NotNull VirtualFile chosenFile) {
super.onFileChoosen(chosenFile);
myCommonOptionsForm.setWorkingDirectory(chosenFile.getParent().getPath());
}
@@ -61,22 +64,27 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
return myRootPanel;
}
@Override
public AbstractPythonRunConfigurationParams getBaseParams() {
return myCommonOptionsForm;
}
@Override
public String getScriptName() {
return FileUtil.toSystemIndependentName(myScriptTextField.getText().trim());
}
@Override
public void setScriptName(String scriptName) {
myScriptTextField.setText(scriptName == null ? "" : FileUtil.toSystemDependentName(scriptName));
}
@Override
public String getScriptParameters() {
return myScriptParametersTextField.getText().trim();
}
@Override
public void setScriptParameters(String scriptParameters) {
myScriptParametersTextField.setText(scriptParameters);
}
@@ -0,0 +1,13 @@
class MyType1(type):
def __instancecheck__(cls, instance):
return True
class MyType2(type):
def __instancecheck__<warning descr="Signature of method 'MyType2.__instancecheck__()' does not match signature of base method in class 'type'">(cls)</warning>:
return True
class MyType3(type):
def __instancecheck__<warning descr="Signature of method 'MyType3.__instancecheck__()' does not match signature of base method in class 'type'">(cls, foo, bar)</warning>:
return True
@@ -0,0 +1,9 @@
class C(object):
def __new__(cls):
self = object.__new__(cls)
self.foo = 1
return self
x = C()
print(x.foo)
print(x.<warning descr="Unresolved attribute reference 'bar' for class 'C'">bar</warning>)
@@ -0,0 +1,5 @@
from datetime import date
print(date.today)
print(date.max)
print(date.<warning descr="Unresolved attribute reference 'foo' for class 'date'">foo</warning>)
@@ -0,0 +1,4 @@
class date(object):
@classmethod
def today(cls):
return date(0, 0, 0)
@@ -0,0 +1,9 @@
class C(object):
def __new__(cls):
self = object.__new__(cls)
self.foo = 1
return self
x = C()
print(x.foo)
print(x.<warning descr="Unresolved attribute reference 'bar' for class 'C'">bar</warning>)
@@ -0,0 +1,2 @@
class MyType(type):
<caret>pass
@@ -0,0 +1,3 @@
class MyType(type):
def __instancecheck__(cls, instance):
<selection>return super(MyType, cls).__instancecheck__(instance)</selection>
@@ -64,6 +64,11 @@ public class PyMethodOverridingInspectionTest extends PyTestCase {
doTest();
}
// PY-10229
public void testInstanceCheck() {
doTest();
}
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
myFixture.enableInspections(PyMethodOverridingInspection.class);
@@ -97,4 +97,13 @@ public class PyOverrideTest extends PyTestCase {
public void testKwargs() { // PY-7401
doTest3k();
}
// PY-10229
public void testInstanceCheck() {
myFixture.configureByFile("override/" + getTestName(true) + ".py");
final PyClass cls = getTopLevelClass(0);
final PyFunction method = cls.findMethodByName("__instancecheck__", true);
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), cls, Collections.singletonList(new PyMethodMember(method)));
myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true);
}
}
@@ -724,6 +724,19 @@ public class PyTypeTest extends PyTestCase {
"expr = io.open('foo', 'rb')\n");
}
public void testNoResolveToFunctionsInTypes() {
doTest("C | unknown",
"class C(object):\n" +
" def bar(self):\n" +
" pass\n" +
"\n" +
"def foo(x):\n" +
" '''\n" +
" :type x: C | C.bar | foo\n" +
" '''\n" +
" expr = x\n");
}
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
}
@@ -57,4 +57,13 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
public void testMetaclassMethods() {
doTest();
}
// PY-9011
public void testDatetimeDateAttributesOutsideClass() {
doMultiFileTest("a.py");
}
public void testObjectNewAttributes() {
doTest();
}
}
@@ -285,6 +285,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doMultiFileTest("a.py");
}
public void testObjectNewAttributes() {
doTest();
}
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);