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

Commit 1a272b8

Browse files
author
Mikhail Arkhipov
authored
Adding support for egg and zip files (#1552)
* Persistent analysis, part I (#1224) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * Merge master into database branch (#1312) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * Avoid empty node in empty global scope (#1226) * Add null checks * Avoid null node in empty global scope * Remove unrelated change * Lock content since it is locked in other cases (#1227) * Fix addBrackets setting (#1241) * Fix addBrackets * Remove unrelated change * Usings * Handle library analysis better (#1246) * Trying to augment argument set with Evaluator and Expression context (#1259) * Moving anyStr to its own method to prevent FromTypeVar from being called with an ArgumentSet that has no context * Trying to augment argument set with context wherever possible * Setting expression in argument set, removing null * Renaming to WithoutContext and updating comment * Check for null args in PythonFunctionOverload * When returning in init method, report a diagnostic error (#1261) * When returning in init method, report a diagnostic error * Adding check and tests for returning None before adding error for a return statement in the init function * Cleaning up tests * Give Diagnostic messages on improper usage of Generic (#1248) * Adding diagnostic message for improper use Generic. * Adding tests to make sure no diagnostics on valid uses of Generic * Adding diagnostic error on binary operations with incompatible types (#1254) * Adding diagnostic error for binary operations with incompatible types - e.g 5 + 'str' * When NewType is called and the first argument is not a string, make a diagnostic message (#1260) * Adding diagnostic error if the user calls NewType with the first arg not of string type * Fix typo in TROUBLESHOOTING.md (#1285) * Multiple analysis fixes (#1297) Multiple analysis fixes. - Fixes #1151: Reliable way to determine final analysis of a module - Fixes #1201: NRE in SymbolCollector.AddProperty - Fixes #1228: NRE in TryFindMissingDependencies - Fixes #1294: Handle valid case for reloading AST - Fixes #1295: FindReferences doesn't work on package init members - Fixes #1296: DependencyResolver graph misses intermediate imports - Part of the fix for #1174: All references are not listed when using ms language server (fixes in analysis itself are also required for this one) * Rework search path resolution (#1289) * first working path classfier, breaks existing path code for now * inherit Comparer instead of implementing both * don't do path depth comparison, preserve user ordering as before * switch to using new path classification code in main module resolution * fix typo * clean up comment about paths in Server.cs * use String.Split instead of regex when parsing script output * test ordering of user provided paths * add new normalize and trim helper, check preconditions as debug asserts rather than commenting on them * use Split extension, don't MaybeEnumerate paths * No diagnostic message when Generic is called with no args (#1305) * No diagnostic message when Generic is called with no args * When a class inherits from something that is not a class, give a diagnostic error (#1277) * When analyzing class definitions, give diagnostic if bases are not all class types * PR feedback * Treat persistent module as regular specialized (#1334) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Fix merge issue * Remove debug code * Store location of module members in the database (#1339) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Add location converter abstraction * Store member location * Basic locations test * Navigation * Add test * Update baselines * Port changes from dbtype * Multiple fixes and additional tests for persistence (#1372) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Add location converter abstraction * Store member location * Fix merge issue * Basic locations test * Navigation * Add test * Update baselines * Type restore - initial * Remove debug code * Partial * Fix stub merge * Various model fixes * Improve module handling * Qualified name improvements * Fix unbound case * Improve stub merge * Fix qualified names of typing * Handle stub-only modules * Add tests for io, re and sys * Better handle named tuple * Handle module circular references * Handle else in platform and version clauses + handle it in symbol collector * Formatting * Fix walk of multi-level if statement * Unify package search in imports * Fix tests * Undo change * Port changes from dbtype * Partial * Named tuple support * Baseline updates * Debug code * Support types * Properly compare class member declaring type * Nested classes and functions persistence * Undo debug * Fix numpy restore * Baselines * Fix tests * Update AnyStr test reflecting changes to AnyStr behavior * Exclude baselines from git diff * Fix gitattr * Move git setting to root * Try no path * Add RDT count to the analysis_complete event (#1396) * Add RDT count to the analysis_complete event * Use property instead of method * Test fixes * Undo change * Additional stub merge fixes * Baseline updates * Fix goto def * Protect specific type creation * Track documentaton source * More reliable tests + simplification * Prevent crashes when the AST happens to be null (#1405) * Remove all references to dropped modules and force GC on reload (#1402) * First attempt at ensuring moduled dropped during reload are GC'd * Make sure AST is set after content is cleared * More tests passing * ModuleWalker updates * Also don't merge against specialized modules, do builtin _astMap reset before reanalyzing instead of after any analysis * Don't call dispose directly, it's done elsewhere and has no effect * Force GC via normal session instead of waiting for a hardcoded time * Un-refactor function since it's not being called externally anymore * Formatting/usings * PR feedback * Undo IsBuiltin, some things continued to be referenced with that changed * Move reload logic down into PythonAnalyzer, remove added public inferface items * Mode AddReference to PythonType as override * Remove dead code, make all ResetAnalyzer calls full * Typo * Cleanup * Basic classification * Fix merge error * Module unique id fixes * Stricted check to save analysis * Revert "Fix tests" This reverts commit 247a8c3. * Revert "Unify package search in imports" This reverts commit 67fed10. * Don't clear scope variables with inner classes * Fix typo * Add persistence tests for 60+ system modules (#1429) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Add location converter abstraction * Store member location * Fix merge issue * Basic locations test * Navigation * Add test * Update baselines * Type restore - initial * Remove debug code * Partial * Fix stub merge * Various model fixes * Improve module handling * Qualified name improvements * Fix unbound case * Improve stub merge * Fix qualified names of typing * Handle stub-only modules * Add tests for io, re and sys * Better handle named tuple * Handle module circular references * Handle else in platform and version clauses + handle it in symbol collector * Formatting * Fix walk of multi-level if statement * Unify package search in imports * Fix tests * Undo change * Port changes from dbtype * Partial * Named tuple support * Baseline updates * Debug code * Support types * Properly compare class member declaring type * Nested classes and functions persistence * Undo debug * Fix numpy restore * Baselines * Fix tests * Update AnyStr test reflecting changes to AnyStr behavior * Exclude baselines from git diff * Fix gitattr * Move git setting to root * Try no path * Test fixes * Undo change * Additional stub merge fixes * Baseline updates * Fix goto def * Protect specific type creation * Track documentaton source * More reliable tests + simplification * Typo * Cleanup * Basic classification * Fix merge error * Module unique id fixes * Stricted check to save analysis * Revert "Fix tests" This reverts commit 247a8c3. * Revert "Unify package search in imports" This reverts commit 67fed10. * Don't clear scope variables with inner classes * Fix typo * Many new tests * Fix collections test * Fix CTypes * Initial * Update test * Merge issues * Fix CTypes again * Fix null bases * Tell between class members with/without self better * TypeVar support * Add bound/covariant * Fix Enum reassignments * Fix Random * Fix import * over local declarations (Socket) * Move interface * Fix reference search * Enable asyncio test * More tests * Enable dataclasses * Add inspect and gzip * More tests * Add setting * Add handling of import position relative to the variable * Caching level changes * Update baselines * Test update (we no longer reassign classes) * Fix typing tests * Update baseline * Fix missing keys issue (#1451) * Typevar fix * Persistence of generics and named tuples (#1459) * Remove old qualified name * Node storage * Class and scope to use AST map * Library analysis * Fix SO * Keep small AST with imports * AST reduction * Final field * Initial * Reload * Ignore post-final requests * Drop AST * Remove local variables * Test fixes * Fix overload match * Tests * Add locks * Remove local variables * Drop file content to save memory * Cache PEP hints * Recreate AST * Fix specialization * Fix locations * usings * Test fixes * Add options to keep data in memory * Fix test * Fix lambda parameters * Fix argument set Fix global scope node * Fix overload doc * Fix stub merge errors * Fix async issues * Undo some changes * Fix test * Fix race condition * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Add location converter abstraction * Store member location * Fix merge issue * Basic locations test * Navigation * Add test * Update baselines * Type restore - initial * Remove debug code * Partial * Fix stub merge * Various model fixes * Improve module handling * Qualified name improvements * Fix unbound case * Improve stub merge * Fix qualified names of typing * Handle stub-only modules * Add tests for io, re and sys * Better handle named tuple * Handle module circular references * Handle else in platform and version clauses + handle it in symbol collector * Formatting * Fix walk of multi-level if statement * Unify package search in imports * Fix tests * Undo change * Port changes from dbtype * Partial * Named tuple support * Baseline updates * Debug code * Support types * Properly compare class member declaring type * Nested classes and functions persistence * Undo debug * Fix numpy restore * Baselines * Fix tests * Update AnyStr test reflecting changes to AnyStr behavior * Exclude baselines from git diff * Fix gitattr * Move git setting to root * Try no path * Test fixes * Undo change * Additional stub merge fixes * Baseline updates * Fix goto def * Protect specific type creation * Track documentaton source * More reliable tests + simplification * Typo * Cleanup * Basic classification * Fix merge error * Module unique id fixes * Stricted check to save analysis * Revert "Fix tests" This reverts commit 247a8c3. * Revert "Unify package search in imports" This reverts commit 67fed10. * Don't clear scope variables with inner classes * Fix typo * Many new tests * Fix collections test * Fix CTypes * Initial * Update test * Merge issues * Fix CTypes again * Fix null bases * Tell between class members with/without self better * TypeVar support * Add bound/covariant * Fix Enum reassignments * Fix Random * Fix import * over local declarations (Socket) * Move interface * Fix reference search * Enable asyncio test * More tests * Enable dataclasses * Add inspect and gzip * More tests * Add setting * Add handling of import position relative to the variable * Caching level changes * Partial * Rework * Fix null * Update baselines * Functools pass * Reverse stub merge * Partial * Partial ctypes * Update variables post merge * Fix ctypes * Merge issues * Fix typevar * Add caching on construction * Assorted fixes * Named tuples * Work around os stub oddness * Fix generic qualified names * Ignore lambdas * Support named tuples as bases * Baselines * Test updates * Named tuple tests * PR feedback * Using * Move diagnostics to GenericBase * PR feedback * - Fix #1455: AF: Library module of type Stub has been analyzed already! (#1470) - Restore task handling in unit tests - Throw exception from Debug.Fail instead of FailFast * Update baselines since __spec__ member was added * Undo some of changes to match master. * Fix null ref * Resolve conflicts * Fix null ref on bases due to new AnyStr behavior * Handling dependencies in module persistence (#1471) * Partial * Models and views * Restore log null checks * Fix merge conflict * Fix merge issue * Null check * Partial * Partial * Partial * Fix test * Partial * Partial * First test * Baseline comparison * Builtins * Partial * Type fixes * Fix type names, part I * Qualified name * Properly write variables * Partial * Construct module from model * Test * Variable creations * Factories * Factories * Split construction * Restore * Save builtins * Test passes * Qualified name * Better export detection * Test fixes * More consistent qualified names * Sys test * Demo * Complete sys write/read * Partial * Partial * Test staility * Perf bug * Baseline, remove debug code, deactivate db * Test fixes * Test fix * Simplify a bit * Baselines and use : separator * Baselines * PR feedback * Merge master * Remove registry reference * PR feedback * PR feedback * Restore persistence + update test * Better handle persistent module in dependencies * Undo * Add location converter abstraction * Store member location * Fix merge issue * Basic locations test * Navigation * Add test * Update baselines * Type restore - initial * Remove debug code * Partial * Fix stub merge * Various model fixes * Improve module handling * Qualified name improvements * Fix unbound case * Improve stub merge * Fix qualified names of typing * Handle stub-only modules * Add tests for io, re and sys * Better handle named tuple * Handle module circular references * Handle else in platform and version clauses + handle it in symbol collector * Formatting * Fix walk of multi-level if statement * Unify package search in imports * Fix tests * Undo change * Port changes from dbtype * Partial * Named tuple support * Baseline updates * Debug code * Support types * Properly compare class member declaring type * Nested classes and functions persistence * Undo debug * Fix numpy restore * Baselines * Fix tests * Update AnyStr test reflecting changes to AnyStr behavior * Exclude baselines from git diff * Fix gitattr * Move git setting to root * Try no path * Test fixes * Undo change * Additional stub merge fixes * Baseline updates * Fix goto def * Protect specific type creation * Track documentaton source * More reliable tests + simplification * Typo * Cleanup * Basic classification * Fix merge error * Module unique id fixes * Stricted check to save analysis * Revert "Fix tests" This reverts commit 247a8c3. * Revert "Unify package search in imports" This reverts commit 67fed10. * Don't clear scope variables with inner classes * Fix typo * Many new tests * Fix collections test * Fix CTypes * Initial * Update test * Merge issues * Fix CTypes again * Fix null bases * Tell between class members with/without self better * TypeVar support * Add bound/covariant * Fix Enum reassignments * Fix Random * Fix import * over local declarations (Socket) * Move interface * Fix reference search * Enable asyncio test * More tests * Enable dataclasses * Add inspect and gzip * More tests * Add setting * Add handling of import position relative to the variable * Caching level changes * Partial * Rework * Fix null * Update baselines * Functools pass * Reverse stub merge * Partial * Partial ctypes * Update variables post merge * Fix ctypes * Merge issues * Fix typevar * Add caching on construction * Assorted fixes * Named tuples * Work around os stub oddness * Fix generic qualified names * Ignore lambdas * Support named tuples as bases * Baselines * Test updates * Named tuple tests * PR feedback * Using * Separate creation and population for better handling of forward references. * Add dependency provider * Merge issues * Better class creation * Partial * Dependency providers * Add IsPersistent flag * Make special global scope * Move dependency fetch earlier * Replace AST walk by interface * Make analysis sequence closer to master * Undo some * Undo debug * Show dependencies in log * null check * Update tests * Make sure factory looks in correct scope Enable assertions in tests * Separate stub dependencies * Don't try and merge from empty stub * Match generic parameters by name * Use qualified names in generics Minor tests cleanup * Back to names * Update tests * usings * Fix dependencies for stub * Null check * PR feedback * PR feedback + fix merge issue in generics * Test fixes + PR feedback * Baseline updates * PR feedback * Restore original order * Order * Merge issues * Make cancellation closer to original * Pass cancellation to module walker * Simplify * Upgrade to 3.0 * Undo change + .NET 3 * Get back to 2.0 * Update components * Display caching level Round time to reasonble fractions. * Fix null ref due to conflicting changes * Null ref fix * Simplify * Pass AST whish is required during analysis when module does not have its own yet. * tensorflow test * Fix from import model Add tensorflow test * Undo debug * Improve goto def in import and fix class base processing (#1529) * Update signing project to 3.0 * Upgrade to .NET 3.0 (#1521) * Upgrade to 3.0 * Get back to 2.0 * Add global.json for .NET SDK * Ensure FileInfo is not relative in DirectoryInfoProxy (#1519) * Ensure FileInfo is not relative in DirectoryInfoProxy * Add tests * Hadle import * Update dependencies (#1526) * Handle from import * Add test * Fix bad find and replace in AssertionsUtilities (#1527) * Merge issues * Add test (fails) * using * Fix merge of classes * Fix regression in bases Split merging into separate class * Fix null refs * Make common CanUpdateAnalysis check * Usings * Test fix * Remove CompletionItemKind.None * Add info to asserts * PR feedback * Undo test change, enable class reassignment Fix stub merge for TypeVar * Prevent merge of unrelated types * more tests * Fix variable update * Null check * Baselines * Move analysis complete event * More stable enumeration * Improve restoring imports in tests * Make extension for tests * Add URI null check * Fix completion typo * Add assert on unresolved modules * Add more details to assert * Using * To 3.7 * Implement check for big/little endian * Sync * Synchronization Fix import model restore * Add hard assert * Fix exception * Fix typo * Add lock * Adding support for egg and zip files (#1477) * Preliminary zip file * Refactoring and adding .egg support * refactoring * More refactoring * removing irrelevant classes * Preliminary working in memory * More things to make it work * Getting rid of comment * Refactoring * More refactoring * more changes * refactoring * Removing unneeded changes * adding back * PR feedback * Test fix
1 parent 82018c6 commit 1a272b8

18 files changed

+295
-18
lines changed

src/Analysis/Ast/Impl/Modules/Resolution/ModuleResolutionBase.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public IPythonModule GetOrLoadModule(string name) {
8787
moduleRef = Modules.GetOrAdd(name, new ModuleRef());
8888
return moduleRef.GetOrCreate(name, this);
8989
}
90-
90+
9191
public ModulePath FindModule(string filePath) {
9292
var bestLibraryPath = string.Empty;
9393

@@ -102,11 +102,24 @@ public ModulePath FindModule(string filePath) {
102102
}
103103

104104
protected void ReloadModulePaths(in IEnumerable<string> rootPaths) {
105-
foreach (var moduleFile in rootPaths.Where(Directory.Exists).SelectMany(p => PathUtils.EnumerateFiles(FileSystem, p))) {
106-
PathResolver.TryAddModulePath(moduleFile.FullName, moduleFile.Length, false, out _);
105+
foreach (var root in rootPaths) {
106+
foreach (var moduleFile in PathUtils.EnumerateFiles(FileSystem, root)) {
107+
PathResolver.TryAddModulePath(moduleFile.FullName, moduleFile.Length, false, out _);
108+
}
109+
110+
if (PathUtils.TryGetZipFilePath(root, out var zipFilePath, out var _) && File.Exists(zipFilePath)) {
111+
foreach (var moduleFile in PathUtils.EnumerateZip(zipFilePath)) {
112+
if (!PathUtils.PathStartsWith(moduleFile.FullName, "EGG-INFO")) {
113+
PathResolver.TryAddModulePath(
114+
Path.Combine(zipFilePath,
115+
PathUtils.NormalizePath(moduleFile.FullName)),
116+
moduleFile.Length, false, out _
117+
);
118+
}
119+
}
120+
}
107121
}
108122
}
109-
110123
protected class ModuleRef {
111124
private readonly object _syncObj = new object();
112125
private IPythonModule _module;

src/Analysis/Ast/Impl/get_search_paths.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,18 @@ def clean(path):
6868
BEFORE_SITE.discard(None)
6969
AFTER_SITE.discard(None)
7070

71+
import zipfile
72+
7173
for p in sys.path:
7274
p = clean(p)
73-
if os.path.isdir(p):
74-
if p in BEFORE_SITE:
75-
print("%s|stdlib|" % p)
76-
elif p in AFTER_SITE:
77-
if p in SITE_PKGS:
78-
print("%s|site|" % p)
79-
else:
80-
print("%s|pth|" % p)
75+
76+
if not os.path.isdir(p) and not (os.path.isfile(p) and zipfile.is_zipfile(p)):
77+
continue
78+
79+
if p in BEFORE_SITE:
80+
print("%s|stdlib|" % p)
81+
elif p in AFTER_SITE:
82+
if p in SITE_PKGS:
83+
print("%s|site|" % p)
84+
else:
85+
print("%s|pth|" % p)

src/Analysis/Ast/Test/ImportTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// See the Apache Version 2.0 License for specific language governing
1414
// permissions and limitations under the License.
1515

16-
using System.IO;
1716
using System.Linq;
1817
using System.Threading.Tasks;
1918
using FluentAssertions;
@@ -23,7 +22,6 @@
2322
using Microsoft.Python.Analysis.Types;
2423
using Microsoft.Python.Core;
2524
using Microsoft.Python.Parsing.Tests;
26-
using Microsoft.Python.Tests.Utilities.FluentAssertions;
2725
using Microsoft.VisualStudio.TestTools.UnitTesting;
2826
using TestUtilities;
2927

src/Core/Impl/IO/FileSystem.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ public long FileSize(string path) {
2424
return fileInfo.Length;
2525
}
2626

27-
public string ReadAllText(string path) => File.ReadAllText(path);
27+
public string ReadAllText(string filePath) {
28+
if (PathUtils.TryGetZipFilePath(filePath, out var zipPath, out var relativeZipPath)) {
29+
return PathUtils.GetZipContent(zipPath, relativeZipPath);
30+
}
31+
return File.ReadAllText(filePath);
32+
}
33+
2834
public void WriteAllText(string path, string content) => File.WriteAllText(path, content);
2935
public IEnumerable<string> FileReadAllLines(string path) => File.ReadLines(path);
3036
public void FileWriteAllLines(string path, IEnumerable<string> contents) => File.WriteAllLines(path, contents);

src/Core/Impl/IO/PathUtils.cs

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.IO;
19+
using System.IO.Compression;
1920
using System.Linq;
2021
using System.Runtime.InteropServices;
2122
using System.Threading;
@@ -47,7 +48,6 @@ public static bool IsValidFileNameCharacter(char character)
4748
public static bool HasEndSeparator(string path)
4849
=> !string.IsNullOrEmpty(path) && IsDirectorySeparator(path[path.Length - 1]);
4950

50-
5151
public static bool IsDirectorySeparator(char c) => Array.IndexOf(DirectorySeparators, c) != -1;
5252

5353
public static bool PathStartsWith(string s, string prefix)
@@ -117,7 +117,7 @@ public static string FindFile(IFileSystem fileSystem,
117117
int depthLimit = 2,
118118
IEnumerable<string> firstCheck = null
119119
) {
120-
if (!Directory.Exists(root)) {
120+
if (!fileSystem.DirectoryExists(root)) {
121121
return null;
122122
}
123123

@@ -185,12 +185,17 @@ public static IEnumerable<string> EnumerateDirectories(IFileSystem fileSystem, s
185185
var path = queue.Dequeue();
186186
path = EnsureEndSeparator(path);
187187

188+
if (!fileSystem.DirectoryExists(path)) {
189+
continue;
190+
}
191+
188192
IEnumerable<string> dirs = null;
189193
try {
190194
dirs = fileSystem.GetDirectories(path);
191195
} catch (UnauthorizedAccessException) {
192196
} catch (IOException) {
193197
}
198+
194199
if (dirs == null) {
195200
continue;
196201
}
@@ -308,6 +313,87 @@ public static IEnumerable<IFileInfo> EnumerateFiles(IFileSystem fileSystem, stri
308313
}
309314
}
310315

316+
public static bool TryGetZipFilePath(string filePath, out string zipPath, out string relativeZipPath) {
317+
zipPath = string.Empty;
318+
relativeZipPath = string.Empty;
319+
if (string.IsNullOrEmpty(filePath)) {
320+
return false;
321+
}
322+
323+
var workingPath = filePath;
324+
// Filepath doesn't have zip or egg in it, bail
325+
if (!filePath.Contains(".zip") && !filePath.Contains(".egg")) {
326+
return false;
327+
}
328+
329+
while (!string.IsNullOrEmpty(workingPath)) {
330+
if (IsZipFile(workingPath, out zipPath)) {
331+
// File path is '..\\test\\test.zip\\test\\a.py'
332+
// Working path is '..\\test\\test.zip'
333+
// Relative path in zip file becomes 'test/a.py'
334+
relativeZipPath = filePath.Substring(workingPath.Length);
335+
336+
// According to https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT, zip files must have forward slashes
337+
foreach (var separator in DirectorySeparators) {
338+
relativeZipPath = relativeZipPath.Replace(separator, '/');
339+
}
340+
return true;
341+
}
342+
// \\test\\test.zip => \\test\\
343+
workingPath = GetParent(workingPath);
344+
}
345+
346+
// Filepath had .zip or .egg in it but no zip or egg files
347+
// e.g /tmp/tmp.zip.txt
348+
return false;
349+
}
350+
351+
/// <summary>
352+
/// Returns whether the given file path is a path to a zip (or egg) file
353+
/// The path can be of the form ..\\test.zip or ..\\test.zip\\
354+
/// </summary>
355+
public static bool IsZipFile(string rawZipPath, out string zipPath) {
356+
var path = NormalizePathAndTrim(rawZipPath);
357+
var extension = Path.GetExtension(path);
358+
switch (extension) {
359+
case ".zip":
360+
case ".egg":
361+
zipPath = path;
362+
return true;
363+
default:
364+
zipPath = string.Empty;
365+
return false;
366+
}
367+
}
368+
369+
/// <summary>
370+
/// Given the path to the zip file and the relative path to a file inside the zip,
371+
/// returns the contents of the zip entry
372+
/// e.g
373+
/// test.zip
374+
/// a.py
375+
/// b.py
376+
/// Can get the contents of a.py by passing in "test.zip" and "a.py"
377+
/// </summary>
378+
public static string GetZipContent(string zipPath, string relativeZipPath) {
379+
using (var zip = ZipFile.OpenRead(zipPath)) {
380+
var zipFile = zip.GetEntry(relativeZipPath);
381+
// Could not open zip, bail
382+
if (zipFile == null) {
383+
return null;
384+
}
385+
using (var reader = new StreamReader(zipFile.Open())) {
386+
return reader.ReadToEnd();
387+
}
388+
}
389+
}
390+
391+
public static IEnumerable<ZipArchiveEntry> EnumerateZip(string root) {
392+
using (var zip = ZipFile.OpenRead(root)) {
393+
return zip.Entries.ToList();
394+
}
395+
}
396+
311397
/// <summary>
312398
/// Deletes a file, making multiple attempts and suppressing any
313399
/// IO-related errors.

src/Core/Test/PathUtilsTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright(c) Microsoft Corporation
2+
// All rights reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the License); you may not use
5+
// this file except in compliance with the License. You may obtain a copy of the
6+
// License at http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
9+
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
10+
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
11+
// MERCHANTABILITY OR NON-INFRINGEMENT.
12+
//
13+
// See the Apache Version 2.0 License for specific language governing
14+
// permissions and limitations under the License.
15+
16+
using FluentAssertions;
17+
using Microsoft.Python.Core.IO;
18+
using Microsoft.VisualStudio.TestTools.UnitTesting;
19+
20+
namespace Microsoft.Python.Core.Tests {
21+
[TestClass]
22+
public class PathUtilsTests {
23+
[TestMethod, Priority(0)]
24+
public void ZipFileUNCPath() {
25+
PathUtils.TryGetZipFilePath(@"\\server\home\share\test.zip", out var zipPath, out var relativeZipPath);
26+
zipPath.Should().Be(@"\\server\home\share\test.zip");
27+
relativeZipPath.Should().BeEmpty();
28+
29+
PathUtils.TryGetZipFilePath(@"\\server\home\share\test.zip\test\a.py", out zipPath, out relativeZipPath);
30+
zipPath.Should().Be(@"\\server\home\share\test.zip");
31+
relativeZipPath.Should().Be("test/a.py");
32+
33+
PathUtils.TryGetZipFilePath("\\path\\foo\\baz\\test.zip\\test\\a.py", out zipPath, out relativeZipPath);
34+
zipPath.Should().Be("\\path\\foo\\baz\\test.zip");
35+
relativeZipPath.Should().Be("test/a.py");
36+
}
37+
38+
[TestMethod, Priority(0)]
39+
public void ZipFilePath() {
40+
PathUtils.TryGetZipFilePath("\\path\\foo\\baz\\test.zip", out var zipPath, out var relativeZipPath);
41+
zipPath.Should().Be("\\path\\foo\\baz\\test.zip");
42+
relativeZipPath.Should().BeEmpty();
43+
44+
PathUtils.TryGetZipFilePath("\\path\\foo\\baz\\test.zip\\test\\a.py", out zipPath, out relativeZipPath);
45+
zipPath.Should().Be("\\path\\foo\\baz\\test.zip");
46+
relativeZipPath.Should().Be("test/a.py");
47+
48+
PathUtils.TryGetZipFilePath("\\path\\foo\\baz\\test.zip\\test\\foo\\baz.py", out zipPath, out relativeZipPath);
49+
zipPath.Should().Be("\\path\\foo\\baz\\test.zip");
50+
relativeZipPath.Should().Be("test/foo/baz.py");
51+
}
52+
}
53+
}

src/LanguageServer/Test/ImportsTests.cs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
using System;
1717
using System.IO;
1818
using System.Threading.Tasks;
19-
using Microsoft.Python.Analysis;
2019
using Microsoft.Python.Analysis.Analyzer;
2120
using Microsoft.Python.Analysis.Documents;
21+
using Microsoft.Python.Analysis.Tests.FluentAssertions;
22+
using Microsoft.Python.Analysis.Types;
2223
using Microsoft.Python.Core.Text;
2324
using Microsoft.Python.LanguageServer.Completion;
2425
using Microsoft.Python.LanguageServer.Sources;
@@ -830,5 +831,100 @@ import module2
830831
comps = cs.GetCompletions(analysis, new SourceLocation(4, 9));
831832
comps.Should().HaveLabels("Y");
832833
}
834+
835+
[DataRow("Basic.egg")]
836+
[DataRow("Basic.zip")]
837+
[DataTestMethod, Priority(0)]
838+
public async Task BasicEggZip(string eggZipFilePath) {
839+
var root = Path.Combine(GetAnalysisTestDataFilesPath(), "EggZip");
840+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X, searchPaths: new[] { root, Path.Combine(root, eggZipFilePath) });
841+
var rdt = Services.GetService<IRunningDocumentTable>();
842+
var analyzer = Services.GetService<IPythonAnalyzer>();
843+
844+
var uriPath = Path.Combine(root, "BasicEggZip.py");
845+
var code = await File.ReadAllTextAsync(uriPath);
846+
var moduleUri = TestData.GetTestSpecificUri(uriPath);
847+
var module = rdt.OpenDocument(moduleUri, code);
848+
849+
await analyzer.WaitForCompleteAnalysisAsync();
850+
var analysis = await module.GetAnalysisAsync(-1);
851+
analysis.Should().HaveVariable("i").OfType(BuiltinTypeId.Int);
852+
}
853+
854+
[DataRow("ZipImports.zip")]
855+
[DataRow("EggImports.egg")]
856+
[DataTestMethod, Priority(0)]
857+
public async Task EggZipImports(string eggZipFilePath) {
858+
var root = Path.Combine(GetAnalysisTestDataFilesPath(), "EggZip");
859+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X, searchPaths: new[] { root, Path.Combine(root, eggZipFilePath, "test") });
860+
var rdt = Services.GetService<IRunningDocumentTable>();
861+
var analyzer = Services.GetService<IPythonAnalyzer>();
862+
863+
var uriPath = Path.Combine(root, "EggZipImports.py");
864+
var code = await File.ReadAllTextAsync(uriPath);
865+
var moduleUri = TestData.GetTestSpecificUri(uriPath);
866+
var module = rdt.OpenDocument(moduleUri, code);
867+
868+
await analyzer.WaitForCompleteAnalysisAsync();
869+
var analysis = await module.GetAnalysisAsync(-1);
870+
analysis.Should().HaveVariable("h").OfType("X");
871+
analysis.Should().HaveVariable("y").OfType(BuiltinTypeId.Int);
872+
analysis.Should().HaveVariable("b").OfType("A");
873+
analysis.Should().HaveVariable("i").OfType(BuiltinTypeId.Int);
874+
}
875+
876+
[DataRow("ZipRelativeImports.zip")]
877+
[DataRow("EggRelativeImports.egg")]
878+
[DataTestMethod, Priority(0)]
879+
public async Task EggZipRelativeImports(string eggZipFilePath) {
880+
var root = Path.Combine(GetAnalysisTestDataFilesPath(), "EggZip");
881+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X, searchPaths: new[] { root, Path.Combine(root, eggZipFilePath, "test") });
882+
var rdt = Services.GetService<IRunningDocumentTable>();
883+
var analyzer = Services.GetService<IPythonAnalyzer>();
884+
885+
var uriPath = Path.Combine(root, "EggZipRelativeImports.py");
886+
var code = await File.ReadAllTextAsync(uriPath);
887+
var moduleUri = TestData.GetTestSpecificUri(uriPath);
888+
var module = rdt.OpenDocument(moduleUri, code);
889+
890+
await analyzer.WaitForCompleteAnalysisAsync();
891+
var analysis = await module.GetAnalysisAsync(-1);
892+
analysis.Should().HaveVariable("h").OfType(BuiltinTypeId.Float);
893+
analysis.Should().HaveVariable("i").OfType(BuiltinTypeId.Int);
894+
analysis.Should().HaveVariable("s").OfType(BuiltinTypeId.Str);
895+
}
896+
897+
[DataRow("simplejson.egg")]
898+
[DataRow("simplejson.zip")]
899+
[DataTestMethod, Priority(0)]
900+
public async Task SimpleJsonEggZip(string eggZipFilePath) {
901+
var root = Path.Combine(GetAnalysisTestDataFilesPath(), "EggZip");
902+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X, searchPaths: new[] { root, Path.Combine(root, eggZipFilePath) });
903+
var rdt = Services.GetService<IRunningDocumentTable>();
904+
var analyzer = Services.GetService<IPythonAnalyzer>();
905+
906+
const string code = "import simplejson";
907+
var uriPath = Path.Combine(root, "test.py");
908+
var moduleUri = TestData.GetTestSpecificUri(uriPath);
909+
var module = rdt.OpenDocument(moduleUri, code);
910+
911+
await analyzer.WaitForCompleteAnalysisAsync();
912+
var analysis = await module.GetAnalysisAsync(-1);
913+
analysis.Should().HaveVariable("simplejson").Which.Should().HaveMembers(
914+
"Decimal",
915+
"JSONDecodeError",
916+
"JSONDecoder",
917+
"JSONEncoder",
918+
"JSONEncoderForHTML",
919+
"OrderedDict",
920+
"RawJSON",
921+
"dump",
922+
"dumps",
923+
"load",
924+
"loads",
925+
"simple_first"
926+
);
927+
}
928+
833929
}
834930
}
Binary file not shown.
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import sys
2+
import test.a
3+
4+
a = test.a.A()
5+
i = a.test()
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)