diff --git a/python/testData/inspections/PyArgumentListInspection/badDecorator.py b/python/testData/inspections/PyArgumentListInspection/badDecorator.py
new file mode 100644
index 000000000000..1f9b0bbf1ab7
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/badDecorator.py
@@ -0,0 +1,4 @@
+def baddeco(): pass
+
+@baddeco
+def f21(): pass
diff --git a/python/testData/inspections/PyArgumentListInspection/badarglist.py b/python/testData/inspections/PyArgumentListInspection/badarglist.py
new file mode 100644
index 000000000000..ee17bcadcdef
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/badarglist.py
@@ -0,0 +1,55 @@
+# bad argument list samples
+class A:
+ def foo(self, x, y):
+ pass
+
+ # no self, but so what
+ def bar(one, two):
+ pass
+
+a = A()
+
+a.foo(1,2)
+
+a.bar();
+
+
+def f1():
+ pass
+
+f1()
+f1(1)
+f1(a = 1)
+
+
+def f2(a):
+ pass
+
+
+f2() # ok, fail
+f2(1) # ok, pass
+f2(1, 2) # ok, fail
+f2(a = 1) # ok, pass
+f2(b = 1) # ok, fail
+f2(a = 1, b = 2) # ok, fail
+
+
+def f3(a, b):
+ pass
+
+f3(1, 2)
+f3(1, 2, 3)
+f3(b=2, a=1)
+f3(b=1, b=2, a=1)
+f3(1, b=2)
+f3(a=1, 2)
+
+def f4(a, *b):
+ pass
+
+f4(1)
+f4(1, 2)
+f4(1, 2, 3)
+f4(1, *(2, 3))
+f4(*(1,2,3))
+f4(a=1, 2, 3)
diff --git a/python/testData/inspections/PyArgumentListInspection/callingClassDefinition.py b/python/testData/inspections/PyArgumentListInspection/callingClassDefinition.py
new file mode 100644
index 000000000000..c029bc8d569c
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/callingClassDefinition.py
@@ -0,0 +1,9 @@
+class Payout:
+ @classmethod
+ def create(cls, teacher_id, entries):
+ payout = cls()
+ # payout.teacher = Teacher(teacher_id)
+ payout.save() # ok
+
+ def save(self):
+ pass
diff --git a/python/testData/inspections/PyArgumentListInspection/decorators.py b/python/testData/inspections/PyArgumentListInspection/decorators.py
new file mode 100644
index 000000000000..83b09550f065
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/decorators.py
@@ -0,0 +1,70 @@
+def deco(param):
+ pass
+
+@deco # ok
+def f6():
+ pass
+
+@deco(1) # ok
+def f7():
+ pass
+
+@deco() # fail: missing param
+def f8():
+ pass
+
+@deco(1, 2) # fail: extra param
+def f9():
+ pass
+
+def deco2(p1, p2): pass
+
+@deco2 # fail: missing p2
+def f10():
+ pass
+
+@deco2(1) # fail: missing p2
+def f11():
+ pass
+
+@deco2(1, 2) # ok
+def f12():
+ pass
+
+@deco2(p2=2, p1=1) # ok
+def f13():
+ pass
+
+
+class Dec:
+ def __init__(self, param):
+ pass
+
+@Dec # ok
+def f14():
+ pass
+
+@Dec(param=1) # ok
+def f15():
+ pass
+
+@Dec() # fail: missing param
+def f16():
+ pass
+
+
+class Dec2:
+ def __init__(self, p1, p2):
+ pass
+
+@Dec2() # fail: no p1, p2
+def f17():
+ pass
+
+@Dec2 # fail: no p2
+def f18():
+ pass
+
+@Dec2(1, 2) # ok
+def f19():
+ pass
diff --git a/python/testData/inspections/PyArgumentListInspection/expected.xml b/python/testData/inspections/PyArgumentListInspection/expected.xml
deleted file mode 100644
index e69e4a5c42ba..000000000000
--- a/python/testData/inspections/PyArgumentListInspection/expected.xml
+++ /dev/null
@@ -1,195 +0,0 @@
-
-
-
- badarglist.py
- 14
- Parameter 'two' unfilled
-
-
- badarglist.py
- 21
- Unexpected argument
-
-
- badarglist.py
- 22
- Unexpected argument
-
-
- badarglist.py
- 29
- Parameter 'a' unfilled
-
-
- badarglist.py
- 31
- Unexpected argument
-
-
- badarglist.py
- 33
- Unexpected argument
-
-
- badarglist.py
- 33
- Parameter 'a' unfilled
-
-
- badarglist.py
- 34
- Unexpected argument
-
-
- badarglist.py
- 41
- Unexpected argument
-
-
- badarglist.py
- 43
- Duplicate argument
-
-
- badarglist.py
- 45
- Cannot appear past keyword arguments or *arg or **kwarg
-
-
- badarglist.py
- 45
- Parameter 'b' unfilled
-
-
- badarglist.py
- 55
- Cannot appear past keyword arguments or *arg or **kwarg
-
-
- badarglist.py
- 55
- Cannot appear past keyword arguments or *arg or **kwarg
-
-
- badarglist.py
- 65
- Unexpected argument
-
-
- badarglist.py
- 66
- Unexpected argument
-
-
- badarglist.py
- 80
- Parameter 'param' unfilled
-
-
- badarglist.py
- 84
- Unexpected argument
-
-
- badarglist.py
- 90
- Parameter 'p2' unfilled
-
-
- badarglist.py
- 94
- Parameter 'p2' unfilled
-
-
- badarglist.py
- 119
- Parameter 'param' unfilled
-
-
- badarglist.py
- 128
- Parameter 'p1' unfilled
-
-
- badarglist.py
- 128
- Parameter 'p2' unfilled
-
-
- badarglist.py
- 132
- Parameter 'p2' unfilled
-
-
- badarglist.py
- 145
- Unexpected argument
-
-
- badarglist.py
- 158
- Function 'baddeco' lacks a positional argument
-
-
-
- badarglist.py
- 211
- Duplicate argument
-
-
- badarglist.py
- 212
- More arguments than positional parameters left
-
-
- badarglist.py
- 213
- Expected a sequence, got int
-
-
- badarglist.py
- 214
- Parameter 'c' unfilled
-
-
- badarglist.py
- 227
- Cannot appear past keyword arguments or *arg or **kwarg
-
-
- badarglist.py
- 232
- Duplicate argument
-
-
- badarglist.py
- 233
- Duplicate argument
-
-
- badarglist.py
- 236
- Duplicate argument
-
-
- badarglist.py
- 237
- Duplicate argument
-
-
- badarglist.py
- 238
- Unexpected argument
-
-
- badarglist.py
- 243
- Duplicate argument
-
-
diff --git a/python/testData/inspections/PyArgumentListInspection/implicitResolveResult.py b/python/testData/inspections/PyArgumentListInspection/implicitResolveResult.py
new file mode 100644
index 000000000000..ec985d1ec8cf
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/implicitResolveResult.py
@@ -0,0 +1,6 @@
+class Baz:
+ def long_unique_identifier(self): pass
+
+
+def xyzzy(baz):
+ baz.long_unique_identifier(1, 2, 3) # don't perform validation for implicit resolve results
diff --git a/python/testData/inspections/PyArgumentListInspection/inheritedInit.py b/python/testData/inspections/PyArgumentListInspection/inheritedInit.py
new file mode 100644
index 000000000000..13a32ef6405c
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/inheritedInit.py
@@ -0,0 +1,7 @@
+class Foo:
+ def __init__(self, name):
+ print name
+
+class Bar(Foo):
+ def __init__(self, name):
+ Foo.__init__(self, name) #ok
diff --git a/python/testData/inspections/PyArgumentListInspection/kwargsMapToNothing.py b/python/testData/inspections/PyArgumentListInspection/kwargsMapToNothing.py
new file mode 100644
index 000000000000..5029c3b56bd8
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/kwargsMapToNothing.py
@@ -0,0 +1,9 @@
+def f5(a, b, c):
+ pass
+
+arg = [1, 2, 3]
+kwarg = {'c':3}
+f5(*arg, **kwarg) # ok
+f5(1,2, **kwarg) # ok
+f5(1, 2, 3, **kwarg) # fail
+f5(1, 2, 3, *arg) # fail
diff --git a/python/testData/inspections/PyArgumentListInspection/py1133.py b/python/testData/inspections/PyArgumentListInspection/py1133.py
new file mode 100644
index 000000000000..1f3c4f630928
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/py1133.py
@@ -0,0 +1,6 @@
+class Py845:
+ def xyzzy(self): pass
+
+def x(p):
+ if isinstance(p, Py845):
+ p.xyzzy()
diff --git a/python/testData/inspections/PyArgumentListInspection/py1268.py b/python/testData/inspections/PyArgumentListInspection/py1268.py
new file mode 100644
index 000000000000..df80a57ac58b
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/py1268.py
@@ -0,0 +1,38 @@
+def f(a, b, c):
+ pass
+
+f(c=1, *(10, 20))
+f(*(10, 20), c=1)
+f(*(10, 20, 30), c=1) # fail: duplicate c
+f(1, *(10, 20, 30)) # fail: tuple too long
+f(1, *(10)) # fail: wrong type
+f(1, *(10,)) # fail: tuple too short, c not mapped
+
+def f1(a, b, c=1):
+ return a,b,c
+
+f1(c=3, *(1, 2))
+
+def f2(a, b, c=1, *d):
+ return a,b,c,d
+
+f2(c=3, *(1,2))
+f2(1,2,3, *(1,2))
+f2(*(1,2), c=20)
+f2(*(1,2), 20) # fail: positional past *
+
+def f3(a=1, b=2, c=3, *d):
+ return a,b,c,d
+
+f3(c=3, a=1, b=2, *(1,2)) # fail: a twice
+f3(1, 2, *(3,), c=4) # fail: c twice
+f3(1,2,3, *(1,2))
+f3(c=3, *(1,2)) #
+f3(1, c=3, *(1,2)) # fail: c twice
+f3(c=3, a=1, b=2, *(1,2)) # fail: a twice, no positinals
+f3(c=3, a=1, b=2, d=(1,2)) # fail: unexpected d
+f3(1, c=3, *(10,)) # ZZZ
+f3(1, *(10,))
+f3(1, *(10,), c=20)
+f3(*(1,2), c=20)
+f3(*(1,2), a=20) # fail: a twice
diff --git a/python/testData/inspections/PyArgumentListInspection/py2005.py b/python/testData/inspections/PyArgumentListInspection/py2005.py
new file mode 100644
index 000000000000..7035a2ac0c90
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/py2005.py
@@ -0,0 +1,17 @@
+class Foo(object):
+ def __init__(self, color):
+ self.color = color
+
+class Bar(object):
+ fooFactory = Foo
+
+ def quux(self):
+ foo = self.fooFactory("orange") # ok
+
+class Foo:
+ def __init__(self, name):
+ print name
+class Bar(Foo):
+ def __init__(self, name):
+ Foo.__init__(self, name)
+Foo("Foo") # pass
diff --git a/python/testData/inspections/PyArgumentListInspection/py3k.py b/python/testData/inspections/PyArgumentListInspection/py3k.py
new file mode 100644
index 000000000000..5fe8f202e90d
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/py3k.py
@@ -0,0 +1,27 @@
+def keywordonly_sum(*, k1=0, k2):
+ return k1 + k2
+
+keywordonly_sum(k2=1)
+keywordonly_sum(k1=1, k2=2)
+keywordonly_sum()
+keywordonly_sum(1, 2)
+
+def namedpast(*args, foo=None):
+ pass
+
+namedpast(1,2,3, foo='a') # pass
+namedpast(*args, foo='b') # pass
+namedpast(foo='c') # pass
+namedpast() # pass
+namedpast(foo='1', 2) # fail
+
+def a23(a, *b, c=1):
+ pass
+
+a23(1,2,3, c=10) # pass
+a23(1,2,3, c=10, a=1) # fail
+a23(c=10, a=1) # pass
+a23(c=10, 1) # fail
+a23(*args, a=1) # fail
+a23(*args, c=1) # pass
+
diff --git a/python/testData/inspections/PyArgumentListInspection/tupleVsLiteralList.py b/python/testData/inspections/PyArgumentListInspection/tupleVsLiteralList.py
new file mode 100644
index 000000000000..41302aae7fe8
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/tupleVsLiteralList.py
@@ -0,0 +1,5 @@
+def f20(a, (b, c)):
+ pass
+
+f20(1, [2, 3]) # ok
+f20(1, (2, 3, 4)) # fail: 4 is unexpected
diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java
index 2608b3fdbd7c..3a5fab86a1c9 100644
--- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java
@@ -47,11 +47,6 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
doTest(getTestName(false), inspection);
}
- public void testPyArgumentListInspection() {
- LocalInspectionTool inspection = new PyArgumentListInspection();
- doTest(getTestName(false), inspection);
- }
-
public void testPyMethodParametersInspection() {
LocalInspectionTool inspection = new PyMethodParametersInspection();
doTest(getTestName(false), inspection);
@@ -62,11 +57,6 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
doTest(getTestName(false), inspection);
}
- public void testPyArgumentListInspection3K() {
- LocalInspectionTool inspection = new PyArgumentListInspection();
- doTestWithPy3k(getTestName(false), inspection);
- }
-
public void testPyRedeclarationInspection() {
LocalInspectionTool inspection = new PyRedeclarationInspection();
doTest(getTestName(false), inspection);
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
index 2fe88a4af23a..a1adceead27c 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
@@ -1,11 +1,57 @@
package com.jetbrains.python.inspections;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
+import com.jetbrains.python.psi.LanguageLevel;
+import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
/**
* @author yole
*/
public class PyArgumentListInspectionTest extends PyLightFixtureTestCase {
+ public void testBadarglist() {
+ doTest();
+ }
+
+ public void testKwargsMapToNothing() {
+ doTest();
+ }
+
+ public void testDecorators() {
+ doTest();
+ }
+
+ public void testTupleVsLiteralList() {
+ doTest();
+ }
+
+ public void testInheritedInit() { // PY-312
+ doTest();
+ }
+
+ public void testBadDecorator() { // PY-428
+ doTest();
+ }
+
+ public void testImplicitResolveResult() {
+ doTest();
+ }
+
+ public void testCallingClassDefinition() {
+ doTest();
+ }
+
+ public void testPy1133() {
+ doTest();
+ }
+
+ public void testPy2005() {
+ doTest();
+ }
+
+ public void testPy1268() {
+ doTest();
+ }
+
public void testInstanceMethodAsLambda() {
doTest();
}
@@ -33,6 +79,16 @@ public class PyArgumentListInspectionTest extends PyLightFixtureTestCase {
public void testFunctionStoredInInstance() { // PY-3623
doTest();
}
+
+ public void testPy3k() {
+ PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON30);
+ try {
+ doTest();
+ }
+ finally {
+ PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null);
+ }
+ }
private void doTest() {
myFixture.configureByFile("inspections/PyArgumentListInspection/" + getTestName(true) + ".py");