Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8bca56b
Fix #668 (partial)
Mar 1, 2019
a731c2a
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 1, 2019
069910b
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 5, 2019
7ffc9db
Tests
Mar 5, 2019
6303c45
Revert "Tests"
Mar 5, 2019
945451c
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 5, 2019
034e437
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 5, 2019
f997d68
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 6, 2019
0e4ff95
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 11, 2019
878c8c5
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 13, 2019
35e1033
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 13, 2019
1073711
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 14, 2019
86028da
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 14, 2019
4d4bca7
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 18, 2019
ac04f76
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 18, 2019
bab03da
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 20, 2019
85ec685
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 27, 2019
be7466d
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 28, 2019
01781c0
Exp
Mar 27, 2019
f544f8a
Limit concurrency
Mar 28, 2019
01bd719
Concurrency limit
Mar 28, 2019
2f8e564
Drop cache after analysis
Mar 28, 2019
9a933bd
Merge branch 'master' of https://github.com/Microsoft/python-language…
Mar 28, 2019
4ad56bb
Fix regression
Mar 28, 2019
c280c55
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 3, 2019
b21b8b8
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 7, 2019
babaee4
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 8, 2019
092efd6
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 8, 2019
b97594d
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 10, 2019
2a50eb9
Fix test
Apr 10, 2019
9c7f58d
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 10, 2019
00faa5f
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 12, 2019
4c8aa92
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 12, 2019
1a67bc8
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 12, 2019
7a13215
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 16, 2019
3d907d8
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 16, 2019
94a274f
Merge branch 'master' of https://github.com/Microsoft/python-language…
Apr 29, 2019
817b964
Limit body analysis in libraries
May 4, 2019
6253728
More skipping
May 4, 2019
da6331e
Fix test
May 6, 2019
a6a8a7b
Walk library functions once
May 7, 2019
72ecff4
Add comment
May 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System.Diagnostics;
using System.Linq;
using Microsoft.Python.Analysis.Documents;
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Analysis.Values;
using Microsoft.Python.Core.Collections;
Expand Down Expand Up @@ -158,43 +159,40 @@ public IMember GetValueFromFunctionType(IPythonFunctionType fn, IPythonInstance
// Re-declare parameters in the function scope since originally
// their types might not have been known and now argument set
// may contain concrete values.
if (fd != null) {
if (fd != null && EvaluateFunctionBody(fn)) {
using (OpenScope(fn.DeclaringModule, fn.FunctionDefinition, out _)) {
args.DeclareParametersInScope(this);
}
}

// If instance is not the same as the declaring type, then call
// most probably comes from the derived class which means that
// the original 'self' and 'cls' variables are no longer valid
// and function has to be re-evaluated with new arguments.
// If instance is not the same as the declaring type, then call most probably comes
// from the derived class which means that the original 'self' and 'cls' variables
// are no longer valid and function has to be re-evaluated with new arguments.
// Note that there is nothing to re-evaluate in stubs.
var instanceType = instance?.GetPythonType();
if (instanceType == null || fn.DeclaringType == null || fn.IsSpecialized ||
instanceType.IsSpecialized || fn.DeclaringType.IsSpecialized ||
instanceType.Equals(fn.DeclaringType) ||
fn.IsStub || !string.IsNullOrEmpty(fn.Overloads[args.OverloadIndex].GetReturnDocumentation(null))) {

if (fn.IsSpecialized && fn is PythonFunctionType ft && ft.Dependencies.Count > 0) {
var dependencies = ImmutableArray<IPythonModule>.Empty;
foreach (var moduleName in ft.Dependencies) {
var dependency = Interpreter.ModuleResolution.GetOrLoadModule(moduleName);
if (dependency != null) {
dependencies = dependencies.Add(dependency);
}
}
Services.GetService<IPythonAnalyzer>().EnqueueDocumentForAnalysis(Module, dependencies);
}
LoadFunctionDependencyModules(fn);

var t = instance?.Call(fn.Name, args) ?? fn.Call(null, fn.Name, args);
if (!t.IsUnknown()) {
return t;
}
}

// Try and evaluate with specific arguments. Note that it does not
// make sense to evaluate stubs since they already should be annotated.
if (fn.DeclaringModule is IDocument doc && fd?.Ast == doc.GetAnyAst()) {
// We could not tell the return type from the call. Here we try and evaluate with specific arguments.
// Note that it does not make sense evaluating stubs or compiled/scraped modules since they
// should be either annotated or static return type known from the analysis.
//
// Also, we do not evaluate library code with arguments for performance reasons.
// This will prevent cases like
// def func(a, b): return a + b
// from working in libraries, but this is small sacrifice for significant performance
// increase in library analysis.
if (fn.DeclaringModule is IDocument doc && fd?.Ast == doc.GetAnyAst() && EvaluateFunctionBody(fn)) {
// Stubs are coming from another module.
return TryEvaluateWithArguments(fn, args);
}
Expand Down Expand Up @@ -297,5 +295,21 @@ private static bool IsMatch(IArgumentSet args, IReadOnlyList<IParameterInfo> par
}
return true;
}

private bool EvaluateFunctionBody(IPythonFunctionType fn)
=> fn.DeclaringModule.ModuleType != ModuleType.Library;

private void LoadFunctionDependencyModules(IPythonFunctionType fn) {
if (fn.IsSpecialized && fn is PythonFunctionType ft && ft.Dependencies.Count > 0) {
var dependencies = ImmutableArray<IPythonModule>.Empty;
foreach (var moduleName in ft.Dependencies) {
var dependency = Interpreter.ModuleResolution.GetOrLoadModule(moduleName);
if (dependency != null) {
dependencies = dependencies.Add(dependency);
}
}
Services.GetService<IPythonAnalyzer>().EnqueueDocumentForAnalysis(Module, dependencies);
}
}
}
}
8 changes: 3 additions & 5 deletions src/Analysis/Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal sealed class FunctionEvaluator : MemberEvaluator {
private readonly PythonFunctionOverload _overload;
private readonly IPythonClassType _self;

public FunctionEvaluator(ExpressionEval eval, PythonFunctionOverload overload)
public FunctionEvaluator(ExpressionEval eval, PythonFunctionOverload overload)
: base(eval, overload.FunctionDefinition) {

_overload = overload;
Expand Down Expand Up @@ -76,9 +76,8 @@ public override void Evaluate() {
// variables that are later used to determine return type of other
// methods and properties.
var ctor = _function.Name.EqualsOrdinal("__init__") || _function.Name.EqualsOrdinal("__new__");
if (!stub && (ctor || annotationType.IsUnknown() || Module.ModuleType == ModuleType.User)) {
// Return type from the annotation is sufficient for libraries
// and stubs, no need to walk the body.
if (ctor || annotationType.IsUnknown() || Module.ModuleType == ModuleType.User) {
// Return type from the annotation is sufficient for libraries and stubs, no need to walk the body.
FunctionDefinition.Body?.Walk(this);
}
}
Expand All @@ -87,7 +86,6 @@ public override void Evaluate() {

public override bool Walk(AssignmentStatement node) {
var value = Eval.GetValueFromExpression(node.Right) ?? Eval.UnknownType;

foreach (var lhs in node.Left) {
switch (lhs) {
case MemberExpression memberExp when memberExp.Target is NameExpression nameExp1: {
Expand Down