Merge branch 'master' into python-objectapi-to-valueapi-wrongnumberargumentsincall

This commit is contained in:
Rebecca Valentine
2020-04-22 09:52:33 -07:00
363 changed files with 12828 additions and 14506 deletions

View File

@@ -22,9 +22,9 @@ predicate does_not_define_special_method(Class cls) {
}
predicate no_inheritance(Class c) {
not exists(ClassObject cls, ClassObject other |
cls.getPyClass() = c and
other != theObjectType()
not exists(ClassValue cls, ClassValue other |
cls.getScope() = c and
other != ClassValue::object()
|
other.getABaseType() = cls or
cls.getABaseType() = other

View File

@@ -16,9 +16,9 @@
import python
import Expressions.CallArgs
from Call call, ClassObject cls, string name, FunctionObject init
from Call call, ClassValue cls, string name, FunctionValue init
where
illegally_named_parameter_objectapi(call, cls, name) and
init = get_function_or_initializer_objectapi(cls)
illegally_named_parameter(call, cls, name) and
init = get_function_or_initializer(cls)
select call, "Keyword argument '" + name + "' is not a supported parameter name of $@.", init,
init.getQualifiedName()

View File

@@ -15,17 +15,17 @@
import python
import Expressions.CallArgs
from Call call, ClassObject cls, string too, string should, int limit, FunctionObject init
from Call call, ClassValue cls, string too, string should, int limit, FunctionValue init
where
(
too_many_args_objectapi(call, cls, limit) and
too_many_args(call, cls, limit) and
too = "too many arguments" and
should = "no more than "
or
too_few_args_objectapi(call, cls, limit) and
too_few_args(call, cls, limit) and
too = "too few arguments" and
should = "no fewer than "
) and
init = get_function_or_initializer_objectapi(cls)
init = get_function_or_initializer(cls)
select call, "Call to $@ with " + too + "; should be " + should + limit.toString() + ".", init,
init.getQualifiedName()

View File

@@ -13,21 +13,21 @@
import python
import Expressions.CallArgs
from Call call, FunctionObject func, FunctionObject overriding, string problem
from Call call, FunctionValue func, FunctionValue overriding, string problem
where
not func.getName() = "__init__" and
overriding.overrides(func) and
call = overriding.getAMethodCall().getNode() and
correct_args_if_called_as_method_objectapi(call, overriding) and
correct_args_if_called_as_method(call, overriding) and
(
arg_count_objectapi(call) + 1 < func.minParameters() and problem = "too few arguments"
arg_count(call) + 1 < func.minParameters() and problem = "too few arguments"
or
arg_count_objectapi(call) >= func.maxParameters() and problem = "too many arguments"
arg_count(call) >= func.maxParameters() and problem = "too many arguments"
or
exists(string name |
call.getAKeyword().getArg() = name and
overriding.getFunction().getAnArg().(Name).getId() = name and
not func.getFunction().getAnArg().(Name).getId() = name and
overriding.getScope().getAnArg().(Name).getId() = name and
not func.getScope().getAnArg().(Name).getId() = name and
problem = "an argument named '" + name + "'"
)
)

View File

@@ -12,18 +12,10 @@
import python
ClassObject return_type(FunctionObject f) {
exists(ControlFlowNode n, Return ret |
ret.getScope() = f.getFunction() and
ret.getValue() = n.getNode() and
n.refersTo(_, result, _)
)
}
from ClassObject iterable, FunctionObject iter, ClassObject iterator
from ClassValue iterable, FunctionValue iter, ClassValue iterator
where
iter = iterable.lookupAttribute("__iter__") and
iterator = return_type(iter) and
iter = iterable.lookup("__iter__") and
iterator = iter.getAnInferredReturnType() and
not iterator.isIterator()
select iterator,
"Class " + iterator.getName() +

View File

@@ -15,10 +15,10 @@
import python
from FunctionObject method
from FunctionValue method
where
exists(ClassObject c |
exists(ClassValue c |
c.declaredAttribute("__del__") = method and
method.getFunction().getMetrics().getCyclomaticComplexity() > 3
method.getScope().getMetrics().getCyclomaticComplexity() > 3
)
select method, "Overly complex '__del__' method."

View File

@@ -62,7 +62,7 @@ private string doctest_in_scope(Scope scope) {
}
pragma[noinline]
private string typehint_annotation_in_file(File file) {
private string typehint_annotation_in_module(Module module_scope) {
exists(StrConst annotation |
annotation = any(Arguments a).getAnAnnotation().getASubExpression*()
or
@@ -71,7 +71,7 @@ private string typehint_annotation_in_file(File file) {
annotation = any(FunctionExpr f).getReturns().getASubExpression*()
|
annotation.pointsTo(Value::forString(result)) and
file = annotation.getLocation().getFile()
annotation.getEnclosingModule() = module_scope
)
}
@@ -84,17 +84,19 @@ private string typehint_comment_in_file(File file) {
)
}
predicate imported_module_used_in_typehint(Import imp) {
exists(string modname, File file |
imp.getAName().getAsname().(Name).getId() = modname and
file = imp.getScope().(Module).getFile()
/** Holds if the imported alias `name` from `imp` is used in a typehint (in the same file as `imp`) */
predicate imported_alias_used_in_typehint(Import imp, Variable name) {
imp.getAName().getAsname().(Name).getVariable() = name and
exists(File file, Module module_scope |
module_scope = imp.getEnclosingModule() and
file = module_scope.getFile()
|
// Look for type hints containing the patterns:
// # type: …name…
typehint_comment_in_file(file).regexpMatch("# type:.*" + modname + ".*")
typehint_comment_in_file(file).regexpMatch("# type:.*" + name.getId() + ".*")
or
// Type hint is inside a string annotation, as needed for forward references
typehint_annotation_in_file(file).regexpMatch(".*\\b" + modname + "\\b.*")
typehint_annotation_in_module(module_scope).regexpMatch(".*\\b" + name.getId() + "\\b.*")
)
}
@@ -114,7 +116,7 @@ predicate unused_import(Import imp, Variable name) {
// Assume that opaque `__all__` includes imported module
not all_not_understood(imp.getEnclosingModule()) and
not imported_module_used_in_doctest(imp) and
not imported_module_used_in_typehint(imp) and
not imported_alias_used_in_typehint(imp, name) and
// Only consider import statements that actually point-to something (possibly an unknown module).
// If this is not the case, it's likely that the import statement never gets executed.
imp.getAName().getValue().pointsTo(_)

View File

@@ -66,7 +66,7 @@ class Copy extends @duplication_or_similarity {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
sourceFile().getName() = filepath and
sourceFile().getAbsolutePath() = filepath and
startline = sourceStartLine() and
startcolumn = sourceStartColumn() and
endline = sourceEndLine() and

View File

@@ -26,7 +26,7 @@ class DefectResult extends int {
/** Gets the file in which this query result was reported. */
File getFile() {
exists(string path | defectResults(this, _, path, _, _, _, _, _) and result.getName() = path)
exists(string path | defectResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path)
}
/** Gets the file path in which this query result was reported. */
@@ -54,7 +54,7 @@ class DefectResult extends int {
/** Gets the URL corresponding to the location of this query result. */
string getURL() {
result =
"file://" + getFile().getName() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
getEndLine() + ":" + getEndColumn()
}
}

View File

@@ -23,7 +23,7 @@ class Commit extends @svnentry {
string getMessage() { svnentrymsg(this, result) }
string getAnAffectedFilePath(string action) {
exists(File rawFile | svnaffectedfiles(this, rawFile, action) | result = rawFile.getName())
exists(File rawFile | svnaffectedfiles(this, rawFile, action) | result = rawFile.getAbsolutePath())
}
string getAnAffectedFilePath() { result = getAnAffectedFilePath(_) }

View File

@@ -2,3 +2,4 @@ name: codeql-python
version: 0.0.0
dbscheme: semmlecode.python.dbscheme
suites: codeql-suites
extractor: python

View File

@@ -11,7 +11,7 @@ class OpenFileConfiguration extends TaintTracking::Configuration {
OpenFileConfiguration() { this = "Open file configuration" }
override predicate isSource(DataFlow::Node src, TaintKind kind) {
theOpenFunction().(FunctionObject).getACall() = src.asCfgNode() and
src.asCfgNode() = Value::named("open").getACall() and
kind instanceof OpenFile
}

View File

@@ -659,7 +659,7 @@ module DataFlow {
}
}
private class ConfigurationAdapter extends TaintTracking::Configuration {
deprecated private class ConfigurationAdapter extends TaintTracking::Configuration {
ConfigurationAdapter() { this instanceof Configuration }
override predicate isSource(DataFlow::Node node, TaintKind kind) {
@@ -727,7 +727,7 @@ module DataFlow {
}
}
private class DataFlowType extends TaintKind {
deprecated private class DataFlowType extends TaintKind {
DataFlowType() {
this = "Data flow" and
exists(DataFlow::Configuration c)

View File

@@ -170,7 +170,7 @@ string from_mako_import(Module m) {
/** File generated by Google's protobuf tool. */
class ProtobufGeneratedFile extends SpecificGeneratedFile {
ProtobufGeneratedFile() {
this.getName().regexpMatch(".*_pb2?.py") and
this.getAbsolutePath().regexpMatch(".*_pb2?.py") and
exists(Module m | m.getFile() = this |
exists(ImportExpr imp | imp.getEnclosingModule() = m |
imp.getImportedModuleName() = "google.net.proto2.python.public"

View File

@@ -540,10 +540,10 @@ class ClassValue extends Value {
Value declaredAttribute(string name) { Types::declaredAttribute(this, name, result, _) }
/**
* Holds if this class has the attribute `name`, including
* attributes declared by super classes.
* Holds if this class has the attribute `name`, including attributes
* declared by super classes.
*/
predicate hasAttribute(string name) { this.getMro().declares(name) }
override predicate hasAttribute(string name) { this.getMro().declares(name) }
/**
* Holds if this class declares the attribute `name`,
@@ -630,6 +630,10 @@ abstract class FunctionValue extends CallableValue {
class PythonFunctionValue extends FunctionValue {
PythonFunctionValue() { this instanceof PythonFunctionObjectInternal }
override string getQualifiedName() {
result = this.(PythonFunctionObjectInternal).getScope().getQualifiedName()
}
override string descriptiveString() {
if this.getScope().isMethod()
then
@@ -639,10 +643,6 @@ class PythonFunctionValue extends FunctionValue {
else result = "function " + this.getQualifiedName()
}
override string getQualifiedName() {
result = this.(PythonFunctionObjectInternal).getScope().getQualifiedName()
}
override int minParameters() {
exists(Function f |
f = this.getScope() and

View File

@@ -114,7 +114,7 @@ module PointsTo {
/* Backwards compatibility */
cached
deprecated predicate points_to(
predicate points_to(
ControlFlowNode f, PointsToContext context, Object obj, ClassObject cls, ControlFlowNode origin
) {
exists(ObjectInternal value |

View File

@@ -37,8 +37,8 @@ abstract deprecated class CustomPointsToFact extends @py_flow_node {
abstract predicate pointsTo(Context context, Object value, ClassObject cls, ControlFlowNode origin);
}
/* For backwards compatibility */
class FinalCustomPointsToFact = CustomPointsToFact;
/** DEPRECATED -- Use PointsToExtension instead */
deprecated class FinalCustomPointsToFact = CustomPointsToFact;
abstract deprecated class CustomPointsToOriginFact extends CustomPointsToFact {
abstract predicate pointsTo(Object value, ClassObject cls);
@@ -151,7 +151,7 @@ class ReModulePointToExtension extends PointsToExtension {
private predicate pointsTo_helper(Context context) { context.appliesTo(this) }
}
private class BackwardCompatiblePointToExtension extends PointsToExtension {
deprecated private class BackwardCompatiblePointToExtension extends PointsToExtension {
BackwardCompatiblePointToExtension() { this instanceof CustomPointsToFact }
override predicate pointsTo(Context context, ObjectInternal value, ControlFlowNode origin) {
@@ -174,7 +174,7 @@ private class BackwardCompatiblePointToExtension extends PointsToExtension {
}
}
private predicate additionalAttribute(
deprecated private predicate additionalAttribute(
ObjectInternal owner, string name, ObjectInternal value, ControlFlowNode origin
) {
exists(Object obj, ClassObject cls |

View File

@@ -1,5 +1,3 @@
WARNING: Predicate points_to has been deprecated and may be removed in future (BooleanConstants.ql:6,25-44)
WARNING: Predicate points_to has been deprecated and may be removed in future (BooleanConstants.ql:7,29-48)
| module.py | 2 | ControlFlowNode for ImportExpr | import | true |
| module.py | 2 | ControlFlowNode for sys | import | true |
| module.py | 3 | ControlFlowNode for Compare | import | false |

View File

@@ -1,4 +1,3 @@
WARNING: Predicate points_to has been deprecated and may be removed in future (Extend.ql:50,32-51)
WARNING: Type CustomPointsToAttribute has been deprecated and may be removed in future (Extend.ql:22,34-57)
WARNING: Type CustomPointsToObjectFact has been deprecated and may be removed in future (Extend.ql:38,32-56)
WARNING: Type CustomPointsToOriginFact has been deprecated and may be removed in future (Extend.ql:5,28-52)

View File

@@ -1,4 +1,3 @@
WARNING: Predicate points_to has been deprecated and may be removed in future (PointsToWithContext.ql:7,7-26)
| a_simple.py:2 | ControlFlowNode for FloatLiteral | float 1.0 | builtin-class float | 2 | import |
| a_simple.py:2 | ControlFlowNode for f1 | float 1.0 | builtin-class float | 2 | import |
| a_simple.py:3 | ControlFlowNode for dict | builtin-class dict | builtin-class type | 3 | import |

View File

@@ -1,4 +1,3 @@
WARNING: Predicate points_to has been deprecated and may be removed in future (PointsToWithType.ql:6,7-26)
| a_simple.py:2 | ControlFlowNode for FloatLiteral | float 1.0 | builtin-class float | 2 |
| a_simple.py:2 | ControlFlowNode for f1 | float 1.0 | builtin-class float | 2 |
| a_simple.py:3 | ControlFlowNode for dict | builtin-class dict | builtin-class type | 3 |

View File

@@ -1,3 +1,4 @@
name: codeql-python-tests
version: 0.0.0
libraryPathDependencies: codeql-python
extractor: python

View File

@@ -1,4 +1,4 @@
| wrong_arguments.py:65:1:65:7 | F0() | Keyword argument 'y' is not a supported parameter name of $@. | wrong_arguments.py:4:5:4:26 | Function __init__ | F0.__init__ |
| wrong_arguments.py:66:1:66:7 | F1() | Keyword argument 'z' is not a supported parameter name of $@. | wrong_arguments.py:8:5:8:36 | Function __init__ | F1.__init__ |
| wrong_arguments.py:67:1:67:12 | F2() | Keyword argument 'y' is not a supported parameter name of $@. | wrong_arguments.py:12:5:12:30 | Function __init__ | F2.__init__ |
| wrong_arguments.py:92:1:92:27 | F6() | Keyword argument 'z' is not a supported parameter name of $@. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:65:1:65:7 | F0() | Keyword argument 'y' is not a supported parameter name of $@. | wrong_arguments.py:4:5:4:26 | Function F0.__init__ | F0.__init__ |
| wrong_arguments.py:66:1:66:7 | F1() | Keyword argument 'z' is not a supported parameter name of $@. | wrong_arguments.py:8:5:8:36 | Function F1.__init__ | F1.__init__ |
| wrong_arguments.py:67:1:67:12 | F2() | Keyword argument 'y' is not a supported parameter name of $@. | wrong_arguments.py:12:5:12:30 | Function F2.__init__ | F2.__init__ |
| wrong_arguments.py:92:1:92:27 | F6() | Keyword argument 'z' is not a supported parameter name of $@. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |

View File

@@ -1,15 +1,15 @@
| wrong_arguments.py:37:1:37:4 | F0() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:4:5:4:26 | Function __init__ | F0.__init__ |
| wrong_arguments.py:38:1:38:4 | F1() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:8:5:8:36 | Function __init__ | F1.__init__ |
| wrong_arguments.py:39:1:39:4 | F2() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:12:5:12:30 | Function __init__ | F2.__init__ |
| wrong_arguments.py:40:1:40:4 | F3() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:16:5:16:40 | Function __init__ | F3.__init__ |
| wrong_arguments.py:41:1:41:4 | F4() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:20:5:20:31 | Function __init__ | F4.__init__ |
| wrong_arguments.py:42:1:42:4 | F5() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:24:5:24:42 | Function __init__ | F5.__init__ |
| wrong_arguments.py:43:1:43:5 | F6() | Call to $@ with too few arguments; should be no fewer than 2. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:44:1:44:7 | F7() | Call to $@ with too few arguments; should be no fewer than 3. | wrong_arguments.py:32:5:32:33 | Function __init__ | F7.__init__ |
| wrong_arguments.py:48:1:48:7 | F0() | Call to $@ with too many arguments; should be no more than 1. | wrong_arguments.py:4:5:4:26 | Function __init__ | F0.__init__ |
| wrong_arguments.py:49:1:49:9 | F1() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:8:5:8:36 | Function __init__ | F1.__init__ |
| wrong_arguments.py:50:1:50:9 | F5() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:24:5:24:42 | Function __init__ | F5.__init__ |
| wrong_arguments.py:51:1:51:9 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:52:1:52:11 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:85:1:85:12 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:86:1:86:7 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function __init__ | F6.__init__ |
| wrong_arguments.py:37:1:37:4 | F0() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:4:5:4:26 | Function F0.__init__ | F0.__init__ |
| wrong_arguments.py:38:1:38:4 | F1() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:8:5:8:36 | Function F1.__init__ | F1.__init__ |
| wrong_arguments.py:39:1:39:4 | F2() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:12:5:12:30 | Function F2.__init__ | F2.__init__ |
| wrong_arguments.py:40:1:40:4 | F3() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:16:5:16:40 | Function F3.__init__ | F3.__init__ |
| wrong_arguments.py:41:1:41:4 | F4() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:20:5:20:31 | Function F4.__init__ | F4.__init__ |
| wrong_arguments.py:42:1:42:4 | F5() | Call to $@ with too few arguments; should be no fewer than 1. | wrong_arguments.py:24:5:24:42 | Function F5.__init__ | F5.__init__ |
| wrong_arguments.py:43:1:43:5 | F6() | Call to $@ with too few arguments; should be no fewer than 2. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |
| wrong_arguments.py:44:1:44:7 | F7() | Call to $@ with too few arguments; should be no fewer than 3. | wrong_arguments.py:32:5:32:33 | Function F7.__init__ | F7.__init__ |
| wrong_arguments.py:48:1:48:7 | F0() | Call to $@ with too many arguments; should be no more than 1. | wrong_arguments.py:4:5:4:26 | Function F0.__init__ | F0.__init__ |
| wrong_arguments.py:49:1:49:9 | F1() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:8:5:8:36 | Function F1.__init__ | F1.__init__ |
| wrong_arguments.py:50:1:50:9 | F5() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:24:5:24:42 | Function F5.__init__ | F5.__init__ |
| wrong_arguments.py:51:1:51:9 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |
| wrong_arguments.py:52:1:52:11 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |
| wrong_arguments.py:85:1:85:12 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |
| wrong_arguments.py:86:1:86:7 | F6() | Call to $@ with too many arguments; should be no more than 2. | wrong_arguments.py:28:5:28:30 | Function F6.__init__ | F6.__init__ |

View File

@@ -1,4 +1,4 @@
| file://:Compiled Code:0:0:0:0 | builtin-class object | Class object is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:16:5:16:23 | Function __iter__ | __iter__ |
| protocols.py:20:1:20:26 | class IteratorMissingNext | Class IteratorMissingNext is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:22:5:22:23 | Function __iter__ | __iter__ |
| protocols.py:20:1:20:26 | class IteratorMissingNext | Class IteratorMissingNext is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:27:5:27:23 | Function __iter__ | __iter__ |
| protocols.py:30:1:30:26 | class IteratorMissingIter | Class IteratorMissingIter is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:40:5:40:23 | Function __iter__ | __iter__ |
| file://:0:0:0:0 | builtin-class object | Class object is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:16:5:16:23 | Function X.__iter__ | __iter__ |
| protocols.py:20:1:20:26 | class IteratorMissingNext | Class IteratorMissingNext is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:22:5:22:23 | Function IteratorMissingNext.__iter__ | __iter__ |
| protocols.py:20:1:20:26 | class IteratorMissingNext | Class IteratorMissingNext is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:27:5:27:23 | Function IterableMissingNext.__iter__ | __iter__ |
| protocols.py:30:1:30:26 | class IteratorMissingIter | Class IteratorMissingIter is returned as an iterator (by $@) but does not fully implement the iterator interface. | protocols.py:40:5:40:23 | Function IterableMissingIter.__iter__ | __iter__ |

View File

@@ -1 +1 @@
| protocols.py:74:5:74:22 | Function __del__ | Overly complex '__del__' method. |
| protocols.py:74:5:74:22 | Function MegaDel.__del__ | Overly complex '__del__' method. |

View File

@@ -1,9 +1,9 @@
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed an argument named 'spam'. Overriding method $@ matches the call. | test.py:19:9:19:31 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed an argument named 'spam'. Overriding method $@ matches the call. | test.py:38:9:38:31 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:16:9:16:21 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:19:9:19:31 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:35:9:35:21 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:38:9:38:31 | Attribute() | call | test.py:24:5:24:26 | Function meth1 | method Derived.meth1 |
| test.py:8:5:8:26 | Function meth2 | Overridden method signature does not match $@, where it is passed too few arguments. Overriding method $@ matches the call. | test.py:17:9:17:20 | Attribute() | call | test.py:27:5:27:20 | Function meth2 | method Derived.meth2 |
| test.py:8:5:8:26 | Function meth2 | Overridden method signature does not match $@, where it is passed too few arguments. Overriding method $@ matches the call. | test.py:36:9:36:20 | Attribute() | call | test.py:27:5:27:20 | Function meth2 | method Derived.meth2 |
| test.py:64:5:64:19 | Function meth | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:78:1:78:12 | Attribute() | call | test.py:74:5:74:24 | Function meth | method Correct2.meth |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed an argument named 'spam'. Overriding method $@ matches the call. | test.py:19:9:19:31 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed an argument named 'spam'. Overriding method $@ matches the call. | test.py:38:9:38:31 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:16:9:16:21 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:19:9:19:31 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:35:9:35:21 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:5:5:5:20 | Function Base.meth1 | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:38:9:38:31 | Attribute() | call | test.py:24:5:24:26 | Function Derived.meth1 | method Derived.meth1 |
| test.py:8:5:8:26 | Function Base.meth2 | Overridden method signature does not match $@, where it is passed too few arguments. Overriding method $@ matches the call. | test.py:17:9:17:20 | Attribute() | call | test.py:27:5:27:20 | Function Derived.meth2 | method Derived.meth2 |
| test.py:8:5:8:26 | Function Base.meth2 | Overridden method signature does not match $@, where it is passed too few arguments. Overriding method $@ matches the call. | test.py:36:9:36:20 | Attribute() | call | test.py:27:5:27:20 | Function Derived.meth2 | method Derived.meth2 |
| test.py:64:5:64:19 | Function BlameBase.meth | Overridden method signature does not match $@, where it is passed too many arguments. Overriding method $@ matches the call. | test.py:78:1:78:12 | Attribute() | call | test.py:74:5:74:24 | Function Correct2.meth | method Correct2.meth |

View File

@@ -1,3 +1,5 @@
| import_structure_1.py:5:1:5:28 | Import | Import of 'bar' is not used. |
| import_structure_2.py:6:1:6:23 | Import | Import of 'bar' is not used. |
| imports_test.py:2:1:2:23 | Import | Import of 'module2' is not used. |
| imports_test.py:6:1:6:12 | Import | Import of 'cycle' is not used. |
| imports_test.py:10:1:10:22 | Import | Import of 'top_level_cycle' is not used. |

View File

@@ -0,0 +1,8 @@
# there should be no difference whether you import 2 things on 1 line, or use 2
# lines
from typing import Optional
from unknown import foo, bar
var: Optional['foo'] = None

View File

@@ -0,0 +1,8 @@
# there should be no difference whether you import 2 things on 1 line, or use 2
# lines
from typing import Optional
from unknown import foo
from unknown import bar
var: Optional['foo'] = None