Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Persistent analysis, part I #1224

Merged
merged 102 commits into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
b605b76
Remove old qualified name
May 17, 2019
5471ce4
Node storage
May 17, 2019
8a8d847
Class and scope to use AST map
May 17, 2019
89ce2ca
Library analysis
May 17, 2019
7a93bf7
Fix SO
May 18, 2019
2a2bdf8
Keep small AST with imports
May 18, 2019
3edaa73
AST reduction
May 18, 2019
73371e1
Final field
May 18, 2019
7d60edc
Initial
May 20, 2019
02475f4
Reload
May 22, 2019
835eeac
Merge master
May 25, 2019
6b6e928
Ignore post-final requests
May 25, 2019
9692397
Drop AST
May 25, 2019
080beab
Remove local variables
May 25, 2019
93a6915
Test fixes
May 26, 2019
cadd7ce
Fix overload match
May 26, 2019
f61b1a7
Tests
May 26, 2019
1b20326
Add locks
May 27, 2019
d7efdac
Remove local variables
May 25, 2019
98934d4
Drop file content to save memory
May 27, 2019
417ae03
Cache PEP hints
May 28, 2019
ec5605f
Recreate AST
May 28, 2019
713d87f
Fix specialization
May 28, 2019
50e63e6
Fix locations
May 28, 2019
fcd0c06
usings
May 28, 2019
f6a992b
Test fixes
May 28, 2019
acad202
Add options to keep data in memory
May 28, 2019
f176b2f
Merge branch 'master' of https://github.com/microsoft/python-language…
May 28, 2019
4225337
Merge master
May 28, 2019
86e36a6
Fix test
May 28, 2019
ba97e9f
Fix lambda parameters
May 28, 2019
ffed87e
Fix argument set
May 29, 2019
186a9c6
Fix overload doc
May 29, 2019
4196699
Fix stub merge errors
May 29, 2019
93249d4
Fix async issues
May 29, 2019
5e61392
Undo some changes
May 29, 2019
130b95d
Fix test
May 29, 2019
a6676f1
Fix race condition
May 30, 2019
18b61ad
Merge master
Jun 1, 2019
0850544
Merge master
Jun 3, 2019
7d0bf5b
Merge branch 'proxymod' into db
Jun 4, 2019
663dc8f
Partial
Jun 4, 2019
86544a6
Models and views
Jun 4, 2019
67b06c2
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 4, 2019
9daf4a9
Merge master
Jun 4, 2019
90318e9
Restore log null checks
Jun 4, 2019
b79d918
Merge master
Jun 4, 2019
a02c6f3
Fix merge conflict
Jun 4, 2019
8a6b055
Merge master
Jun 5, 2019
57358eb
Fix merge issue
Jun 5, 2019
41ef00f
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 5, 2019
814cd64
Merge master
Jun 6, 2019
6ceb9b8
Null check
Jun 6, 2019
74bb061
Merge branch 'noast5' into db
Jun 6, 2019
478ce37
Partial
Jun 6, 2019
cb46e68
Partial
Jun 6, 2019
ef2981c
Partial
Jun 6, 2019
2164ad5
Fix test
Jun 6, 2019
1a48790
Merge branch 'noast5' into db
Jun 6, 2019
319c416
Partial
Jun 6, 2019
86b0ee6
Partial
Jun 7, 2019
1670c9d
First test
Jun 7, 2019
ab69cfd
Baseline comparison
Jun 7, 2019
e00c197
Builtins
Jun 7, 2019
4e1657c
Partial
Jun 7, 2019
ade00f4
Type fixes
Jun 10, 2019
e2fc221
Fix type names, part I
Jun 11, 2019
aaf40bb
Qualified name
Jun 11, 2019
a5b3b20
Properly write variables
Jun 11, 2019
f23a487
Partial
Jun 11, 2019
e6373a7
Construct module from model
Jun 12, 2019
6f6737d
Test
Jun 12, 2019
081f475
Variable creations
Jun 12, 2019
42fa4dc
Factories
Jun 13, 2019
2f03cb9
Factories
Jun 13, 2019
1dc3339
Split construction
Jun 13, 2019
9535bad
Restore
Jun 13, 2019
bec2a82
Save builtins
Jun 13, 2019
80c9b1c
Test passes
Jun 13, 2019
5b372f7
Qualified name
Jun 13, 2019
3066554
Better export detection
Jun 14, 2019
91491d4
Test fixes
Jun 14, 2019
bc4f587
More consistent qualified names
Jun 14, 2019
af69880
Sys test
Jun 14, 2019
5c1a0c3
Demo
Jun 14, 2019
4146690
Complete sys write/read
Jun 17, 2019
48763aa
Partial
Jun 17, 2019
93bece3
Partial
Jun 18, 2019
55b6a3f
Test staility
Jun 18, 2019
5e9bf8e
Perf bug
Jun 18, 2019
c152e67
Merge master
Jun 18, 2019
eadd622
Baseline, remove debug code, deactivate db
Jun 18, 2019
ba87581
Test fixes
Jun 18, 2019
a797593
Test fix
Jun 18, 2019
db6c7fc
Simplify a bit
Jun 19, 2019
f73fed0
Baselines and use : separator
Jun 19, 2019
4054d5a
Baselines
Jun 19, 2019
4ef96d8
PR feedback
Jun 19, 2019
c7436ed
Merge branch 'master' of https://github.com/microsoft/python-language…
Jun 19, 2019
f3860e6
Merge master
Jun 19, 2019
cab0fce
Remove registry reference
Jun 19, 2019
b9c1e14
PR feedback
Jun 19, 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,7 +17,6 @@
using System.Diagnostics;
using System.Linq;
using Microsoft.Python.Analysis.Documents;
using Microsoft.Python.Analysis.Extensions;
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Analysis.Values;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public IMember GetValueFromList(ListExpression expression) {
var value = GetValueFromExpression(item) ?? UnknownType;
contents.Add(value);
}
return PythonCollectionType.CreateList(Module.Interpreter, contents, exact: expression.Items.Count <= MaxCollectionSize);
return PythonCollectionType.CreateList(Module, contents, exact: expression.Items.Count <= MaxCollectionSize);
}

public IMember GetValueFromDictionary(DictionaryExpression expression) {
Expand All @@ -72,7 +72,7 @@ public IMember GetValueFromDictionary(DictionaryExpression expression) {
var value = GetValueFromExpression(item.SliceStop) ?? UnknownType;
contents[key] = value;
}
return new PythonDictionary(Interpreter, contents, exact: expression.Items.Count <= MaxCollectionSize);
return new PythonDictionary(Module, contents, exact: expression.Items.Count <= MaxCollectionSize);
}

private IMember GetValueFromTuple(TupleExpression expression) {
Expand All @@ -81,7 +81,7 @@ private IMember GetValueFromTuple(TupleExpression expression) {
var value = GetValueFromExpression(item) ?? UnknownType;
contents.Add(value);
}
return PythonCollectionType.CreateTuple(Module.Interpreter, contents, exact: expression.Items.Count <= MaxCollectionSize);
return PythonCollectionType.CreateTuple(Module, contents, exact: expression.Items.Count <= MaxCollectionSize);
}

public IMember GetValueFromSet(SetExpression expression) {
Expand All @@ -90,7 +90,7 @@ public IMember GetValueFromSet(SetExpression expression) {
var value = GetValueFromExpression(item) ?? UnknownType;
contents.Add(value);
}
return PythonCollectionType.CreateSet(Interpreter, contents, exact: expression.Items.Count <= MaxCollectionSize);
return PythonCollectionType.CreateSet(Module, contents, exact: expression.Items.Count <= MaxCollectionSize);
}

public IMember GetValueFromGenerator(GeneratorExpression expression) {
Expand All @@ -110,14 +110,14 @@ public IMember GetValueFromComprehension(Comprehension node) {
switch (node) {
case ListComprehension lc:
var v1 = GetValueFromExpression(lc.Item) ?? UnknownType;
return PythonCollectionType.CreateList(Interpreter, new[] { v1 });
return PythonCollectionType.CreateList(Module, new[] { v1 });
case SetComprehension sc:
var v2 = GetValueFromExpression(sc.Item) ?? UnknownType;
return PythonCollectionType.CreateSet(Interpreter, new[] { v2 });
return PythonCollectionType.CreateSet(Module, new[] { v2 });
case DictionaryComprehension dc:
var k = GetValueFromExpression(dc.Key) ?? UnknownType;
var v = GetValueFromExpression(dc.Value) ?? UnknownType;
return new PythonDictionary(new PythonDictionaryType(Interpreter), new Dictionary<IMember, IMember> { { k, v } });
return new PythonDictionary(new PythonDictionaryType(Interpreter.ModuleResolution.BuiltinsModule), new Dictionary<IMember, IMember> { { k, v } });
}

return UnknownType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ private IMember GetValueFromBinaryOp(Expression expr) {

switch (leftTypeId) {
case BuiltinTypeId.List:
return PythonCollectionType.CreateConcatenatedList(Module.Interpreter, lc, rc);
return PythonCollectionType.CreateConcatenatedList(Module, lc, rc);
case BuiltinTypeId.Tuple:
return PythonCollectionType.CreateConcatenatedTuple(Module.Interpreter, lc, rc);
return PythonCollectionType.CreateConcatenatedTuple(Module, lc, rc);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public ExpressionEval(IServiceContainer services, IPythonModule module, GlobalSc
public ModuleSymbolTable SymbolTable { get; } = new ModuleSymbolTable();
public IPythonType UnknownType => Interpreter.UnknownType;
public Location DefaultLocation { get; }
public IPythonModule BuiltinsModule => Interpreter.ModuleResolution.BuiltinsModule;

public LocationInfo GetLocationInfo(Node node) => node?.GetLocation(Module) ?? LocationInfo.Empty;

Expand Down
2 changes: 1 addition & 1 deletion src/Analysis/Ast/Impl/Analyzer/Handlers/ImportHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private PythonVariableModule GetOrCreateVariableModule(in string fullName, in Py
return variableModule;
}

variableModule = new PythonVariableModule(fullName, Interpreter);
variableModule = new PythonVariableModule(fullName, Eval.Interpreter);
_variableModules[fullName] = variableModule;
parentModule?.AddChildModule(memberName, variableModule);
return variableModule;
Expand Down
12 changes: 9 additions & 3 deletions src/Analysis/Ast/Impl/Analyzer/ModuleWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private void HandleAllAppendExtend(CallExpression node) {
IPythonCollection values = null;
switch (me.Name) {
case "append":
values = PythonCollectionType.CreateList(Module.Interpreter, new List<IMember> { v }, exact: true);
values = PythonCollectionType.CreateList(Module, new List<IMember> { v }, exact: true);
break;
case "extend":
values = v as IPythonCollection;
Expand All @@ -129,7 +129,7 @@ private void ExtendAll(Node location, IPythonCollection values) {
}

var all = scope.Variables[AllVariableName]?.Value as IPythonCollection;
var list = PythonCollectionType.CreateConcatenatedList(Module.Interpreter, all, values);
var list = PythonCollectionType.CreateConcatenatedList(Module, all, values);
var source = list.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;

Eval.DeclareVariable(AllVariableName, list, source, location);
Expand Down Expand Up @@ -228,6 +228,8 @@ private void MergeStub() {
return;
}

var builtins = Module.Interpreter.ModuleResolution.BuiltinsModule;

// Note that scrape can pick up more functions than the stub contains
// Or the stub can have definitions that scraping had missed. Therefore
// merge is the combination of the two with the documentation coming
Expand Down Expand Up @@ -258,6 +260,10 @@ private void MergeStub() {

var memberType = member?.GetPythonType();
var stubMemberType = stubMember.GetPythonType();

if (builtins.Equals(memberType?.DeclaringModule) || builtins.Equals(stubMemberType.DeclaringModule)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not the stubMemberType.IsBuiltin?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

Copy link
Author

@MikhailArkhipov MikhailArkhipov Jun 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no. We have a bit of a mess with what is IsBuiltin on the type. Ex PythonModule has IsBuiltin => true always. So does PythonVariableModule. Or Union when it has all types as builtin types... Modules assume they are builtin if IsBuiltin => IsCompiled && ModulePath == null.

This specific check is if member actually belongs to the builtins module. We should go clean this up, but it may be some other time. Or maybe make IsBuiltinType() and remove IsBuiltin property from IPythonType. It is not actually used that much.

continue; // Leave builtins alone.
}
if (!IsStubBetterType(memberType, stubMemberType)) {
continue;
}
Expand All @@ -271,7 +277,7 @@ private void MergeStub() {
// Re-declare variable with the data from the stub unless member is a module.
// Modules members that are modules should remain as they are, i.e. os.path
// should remain library with its own stub attached.
if (!(stubType is IPythonModule)) {
if (!(stubType is IPythonModule) && !builtins.Equals(stubType.DeclaringModule)) {
sourceType.TransferDocumentationAndLocation(stubType);
// TODO: choose best type between the scrape and the stub. Stub probably should always win.
var source = Eval.CurrentScope.Variables[v.Name]?.Source ?? VariableSource.Declaration;
Expand Down
4 changes: 3 additions & 1 deletion src/Analysis/Ast/Impl/Analyzer/PythonAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public PythonAnalyzer(IServiceManager services, string cacheFolderPath = null) {
_startNextSession = StartNextSession;

_progress = new ProgressReporter(services.GetService<IProgressService>());
_services.AddService(new StubCache(_services, cacheFolderPath));

_services.AddService(new CacheFolderService(_services, cacheFolderPath));
_services.AddService(new StubCache(_services));
}

public void Dispose() {
Expand Down
1 change: 1 addition & 0 deletions src/Analysis/Ast/Impl/Analyzer/PythonAnalyzerSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Runtime;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Python.Analysis.Caching;
using Microsoft.Python.Analysis.Dependencies;
using Microsoft.Python.Analysis.Diagnostics;
using Microsoft.Python.Analysis.Modules;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
using System.Diagnostics;
using System.Linq;
using Microsoft.Python.Analysis.Analyzer.Evaluation;
using Microsoft.Python.Analysis.Extensions;
using Microsoft.Python.Analysis.Modules;
using Microsoft.Python.Analysis.Types;
using Microsoft.Python.Analysis.Values;
Expand Down
38 changes: 14 additions & 24 deletions src/Analysis/Ast/Impl/Caching/CacheFolders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,27 @@
using System.Security.Cryptography;
using System.Text;
using Microsoft.Python.Core;
using Microsoft.Python.Core.IO;
using Microsoft.Python.Core.Logging;
using Microsoft.Python.Core.OS;

namespace Microsoft.Python.Analysis.Caching {
internal static class CacheFolders {
public static string GetCacheFilePath(string root, string moduleName, string content, IFileSystem fs) {
// Folder for all module versions and variants
// {root}/module_name/content_hash.pyi
var folder = Path.Combine(root, moduleName);

var filePath = Path.Combine(root, folder, $"{FileNameFromContent(content)}.pyi");
if (fs.StringComparison == StringComparison.Ordinal) {
filePath = filePath.ToLowerInvariant();
}
internal sealed class CacheFolderService: ICacheFolderService {
public CacheFolderService(IServiceContainer services, string cacheRootFolder) {
CacheFolder = cacheRootFolder ?? GetCacheFolder(services);
}

public string CacheFolder { get; }

return filePath;
public string GetFileNameFromContent(string content) {
// File name depends on the content so we can distinguish between different versions.
using (var hash = SHA256.Create()) {
return Convert
.ToBase64String(hash.ComputeHash(new UTF8Encoding(false).GetBytes(content)))
.Replace('/', '_').Replace('+', '-');
}
}

public static string GetCacheFolder(IServiceContainer services) {
private static string GetCacheFolder(IServiceContainer services) {
var platform = services.GetService<IOSPlatform>();
var logger = services.GetService<ILogger>();

Expand Down Expand Up @@ -95,17 +96,6 @@ public static string GetCacheFolder(IServiceContainer services) {
return cachePath;
}

public static string FileNameFromContent(string content) {
// File name depends on the content so we can distinguish between different versions.
var hash = SHA256.Create();
return Convert
.ToBase64String(hash.ComputeHash(new UTF8Encoding(false).GetBytes(content)))
.Replace('/', '_').Replace('+', '-');
}

public static string GetAnalysisCacheFilePath(string analysisRootFolder, string moduleName, string content, IFileSystem fs)
=> GetCacheFilePath(analysisRootFolder, moduleName, content, fs);

private static bool CheckPathRooted(string varName, string path, ILogger logger) {
if (!string.IsNullOrWhiteSpace(path) && Path.IsPathRooted(path)) {
return true;
Expand Down
21 changes: 21 additions & 0 deletions src/Analysis/Ast/Impl/Caching/Definitions/ICacheFolderService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright(c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the License); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

namespace Microsoft.Python.Analysis.Caching {
public interface ICacheFolderService {
string CacheFolder { get; }
string GetFileNameFromContent(string content);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright(c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the License); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Python.Analysis.Types;

namespace Microsoft.Python.Analysis.Caching {
internal interface IModuleDatabaseService {
/// <summary>
/// Creates module representation from module persistent state.
/// </summary>
/// <param name="moduleName">Module name. If the name is not qualified
/// the module will ge resolved against active Python version.</param>
/// <param name="filePath">Module file path.</param>
/// <param name="module">Python module.</param>
/// <returns>Module storage state</returns>
ModuleStorageState TryCreateModule(string moduleName, string filePath, out IPythonModule module);

/// <summary>
/// Writes module data to the database.
/// </summary>
Task StoreModuleAnalysisAsync(IDocumentAnalysis analysis, CancellationToken cancellationToken = default);
}
}
42 changes: 42 additions & 0 deletions src/Analysis/Ast/Impl/Caching/Definitions/ModuleStorageState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright(c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the License); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

namespace Microsoft.Python.Analysis.Caching {
/// <summary>
/// Describes module data stored in a database.
/// </summary>
public enum ModuleStorageState {
/// <summary>
/// Module does not exist in the database.
/// </summary>
DoesNotExist,

/// <summary>
/// Partial data. This means module is still being analyzed
/// and the data on the module members is incomplete.
/// </summary>
Partial,

/// <summary>
/// Modules exist and the analysis is complete.
/// </summary>
Complete,

/// <summary>
/// Storage is corrupted or incompatible.
/// </summary>
Corrupted
}
}
9 changes: 5 additions & 4 deletions src/Analysis/Ast/Impl/Caching/StubCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ internal sealed class StubCache : IStubCache {

private readonly IFileSystem _fs;
private readonly ILogger _log;
private readonly ICacheFolderService _cfs;

public StubCache(IServiceContainer services, string cacheRootFolder = null) {
public StubCache(IServiceContainer services) {
_fs = services.GetService<IFileSystem>();
_log = services.GetService<ILogger>();

cacheRootFolder = cacheRootFolder ?? CacheFolders.GetCacheFolder(services);
StubCacheFolder = Path.Combine(cacheRootFolder, $"stubs.v{_stubCacheFormatVersion}");
_cfs = services.GetService<ICacheFolderService>();
StubCacheFolder = Path.Combine(_cfs.CacheFolder, $"stubs.v{_stubCacheFormatVersion}");
}

public string StubCacheFolder { get; }
Expand All @@ -58,7 +59,7 @@ public string GetCacheFilePath(string filePath) {
dir = dir.ToLowerInvariant();
}

var dirHash = CacheFolders.FileNameFromContent(dir);
var dirHash = _cfs.GetFileNameFromContent(dir);
var stubFile = Path.Combine(StubCacheFolder, Path.Combine(dirHash, name));
return Path.ChangeExtension(stubFile, ".pyi");
}
Expand Down
3 changes: 2 additions & 1 deletion src/Analysis/Ast/Impl/Extensions/ArgumentSetExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Microsoft.Python.Analysis.Analyzer.Evaluation;
using Microsoft.Python.Analysis.Types;
Expand Down Expand Up @@ -57,7 +58,7 @@ internal static void DeclareParametersInScope(this IArgumentSet args, Expression
}

if (args.ListArgument != null && !string.IsNullOrEmpty(args.ListArgument.Name)) {
var type = new PythonCollectionType(null, BuiltinTypeId.List, eval.Interpreter, false);
var type = new PythonCollectionType(null, BuiltinTypeId.List, eval.BuiltinsModule, false);
var list = new PythonCollection(type, args.ListArgument.Values);
eval.DeclareVariable(args.ListArgument.Name, list, VariableSource.Declaration, args.ListArgument.Location);
}
Expand Down
Loading