tests.java.org.python.indexer.IndexerTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer;
import org.python.indexer.Indexer;
import org.python.indexer.NBinding;
import org.python.indexer.Scope;
import org.python.indexer.ast.NAlias;
import org.python.indexer.ast.NAssert;
import org.python.indexer.ast.NAssign;
import org.python.indexer.ast.NAttribute;
import org.python.indexer.ast.NAugAssign;
import org.python.indexer.ast.NBinOp;
import org.python.indexer.ast.NBlock;
import org.python.indexer.ast.NBody;
import org.python.indexer.ast.NBoolOp;
import org.python.indexer.ast.NBreak;
import org.python.indexer.ast.NCall;
import org.python.indexer.ast.NClassDef;
import org.python.indexer.ast.NCompare;
import org.python.indexer.ast.NComprehension;
import org.python.indexer.ast.NContinue;
import org.python.indexer.ast.NDelete;
import org.python.indexer.ast.NDict;
import org.python.indexer.ast.NEllipsis;
import org.python.indexer.ast.NExceptHandler;
import org.python.indexer.ast.NExec;
import org.python.indexer.ast.NExprStmt;
import org.python.indexer.ast.NFor;
import org.python.indexer.ast.NFunctionDef;
import org.python.indexer.ast.NGeneratorExp;
import org.python.indexer.ast.NGlobal;
import org.python.indexer.ast.NIf;
import org.python.indexer.ast.NIfExp;
import org.python.indexer.ast.NImport;
import org.python.indexer.ast.NImportFrom;
import org.python.indexer.ast.NIndex;
import org.python.indexer.ast.NKeyword;
import org.python.indexer.ast.NLambda;
import org.python.indexer.ast.NList;
import org.python.indexer.ast.NListComp;
import org.python.indexer.ast.NModule;
import org.python.indexer.ast.NName;
import org.python.indexer.ast.NNode;
import org.python.indexer.ast.NNodeVisitor;
import org.python.indexer.ast.NNum;
import org.python.indexer.ast.NPass;
import org.python.indexer.ast.NPlaceHolder;
import org.python.indexer.ast.NPrint;
import org.python.indexer.ast.NQname;
import org.python.indexer.ast.NRaise;
import org.python.indexer.ast.NRepr;
import org.python.indexer.ast.NReturn;
import org.python.indexer.ast.NSlice;
import org.python.indexer.ast.NStr;
import org.python.indexer.ast.NSubscript;
import org.python.indexer.ast.NTryExcept;
import org.python.indexer.ast.NTryFinally;
import org.python.indexer.ast.NTuple;
import org.python.indexer.ast.NUnaryOp;
import org.python.indexer.ast.NUrl;
import org.python.indexer.ast.NWhile;
import org.python.indexer.ast.NWith;
import org.python.indexer.ast.NYield;
import org.python.indexer.types.NDictType;
import org.python.indexer.types.NFuncType;
import org.python.indexer.types.NListType;
import org.python.indexer.types.NModuleType;
import org.python.indexer.types.NTupleType;
import org.python.indexer.types.NType;
import org.python.indexer.types.NUnionType;
import org.python.indexer.types.NUnknownType;
import java.io.File;
import java.util.List;
import java.util.Set;
public class IndexerTest extends TestBase {
public void testBuiltinModulePresent() throws Exception {
NType mod = idx.moduleTable.lookupType("__builtin__");
assertNotNull("missing __builtin__ module", mod);
assertTrue("wrong type: " + mod.getClass(), mod instanceof NModuleType);
}
public void testLazyModuleLoad() throws Exception {
assertNull("'array' module should not yet be loaded",
idx.moduleTable.lookupType("array"));
assertNoBinding("array");
assertNotNull(idx.loadModule("array")); // lazy loads it
assertNotNull("'array' module should have been loaded",
idx.moduleTable.lookupType("array"));
assertModuleBinding("array");
}
public void testNativeModulesAvailable() throws Exception {
for (String name : new String[] {
"array", "ctypes", "errno",
"math", "operator", "os",
"signal", "sys", "thread", "time",}) {
assertNoBinding(name);
assertNotNull(name, idx.loadModule(name));
assertModuleBinding(name);
}
}
public void testBuiltinObject() throws Exception {
assertClassBinding("__builtin__.object");
assertClassBinding("__builtin__.object.__class__");
}
public void testBuiltinTuple() throws Exception {
assertClassBinding("__builtin__.tuple");
assertMethodBinding("__builtin__.tuple.__rmul__");
assertMethodBinding("__builtin__.tuple.__iter__");
}
public void testBuiltinList() throws Exception {
assertClassBinding("__builtin__.list");
assertMethodBinding("__builtin__.list.append");
assertMethodBinding("__builtin__.list.count");
}
public void testBuiltinNum() throws Exception {
assertClassBinding("__builtin__.float");
NBinding b = assertMethodBinding("__builtin__.float.fromhex");
assertTrue(b.isBuiltin());
}
public void testBuiltinStr() throws Exception {
assertClassBinding("__builtin__.str");
assertMethodBinding("__builtin__.str.encode");
assertMethodBinding("__builtin__.str.startswith");
assertMethodBinding("__builtin__.str.split");
assertMethodBinding("__builtin__.str.partition");
}
public void testBuiltinDict() throws Exception {
assertClassBinding("__builtin__.dict");
assertMethodBinding("__builtin__.dict.__getitem__");
assertMethodBinding("__builtin__.dict.keys");
assertMethodBinding("__builtin__.dict.clear");
}
public void testBuiltinFile() throws Exception {
assertClassBinding("__builtin__.file");
assertMethodBinding("__builtin__.file.__enter__");
assertMethodBinding("__builtin__.file.readline");
assertMethodBinding("__builtin__.file.readlines");
assertMethodBinding("__builtin__.file.isatty");
}
public void testBuiltinFuncs() throws Exception {
assertFunctionBinding("__builtin__.apply");
assertFunctionBinding("__builtin__.abs");
assertFunctionBinding("__builtin__.hex");
assertFunctionBinding("__builtin__.range");
assertFunctionBinding("__builtin__.globals");
assertFunctionBinding("__builtin__.open");
}
public void testBuiltinTypes() throws Exception {
assertClassBinding("__builtin__.ArithmeticError");
assertClassBinding("__builtin__.ZeroDivisionError");
assertAttributeBinding("__builtin__.True");
assertAttributeBinding("__builtin__.False");
assertAttributeBinding("__builtin__.None");
assertAttributeBinding("__builtin__.Ellipsis");
}
public void testStrConstructor() throws Exception {
String src = index(
"newstr.py",
"x = str([])");
assertStringType("newstr.x");
}
public void testListSubscript() throws Exception {
String src = index(
"test.py",
"x = [1, 2, 3]",
"y = x[2]");
assertNumType("test.y");
}
public void testBuiltinSys() throws Exception {
idx.loadModule("sys");
assertModuleBinding("sys");
assertAttributeBinding("sys.__stderr__");
NBinding b = assertFunctionBinding("sys.exit");
assertTrue(b.isBuiltin());
assertFunctionBinding("sys.getprofile");
assertFunctionBinding("sys.getdefaultencoding");
assertAttributeBinding("sys.api_version");
assertNumType("sys.api_version");
assertAttributeBinding("sys.argv");
assertBindingType("sys.argv", NListType.class);
assertAttributeBinding("sys.byteorder");
assertStringType("sys.byteorder");
assertAttributeBinding("sys.flags");
assertBindingType("sys.flags", NDictType.class);
}
public void testFetchAst() throws Exception {
NModule ast = idx.getAstForFile(abspath("hello.py"));
assertNotNull("failed to load file", ast);
assertEquals("module has wrong name", "hello", ast.name);
assertNotNull("AST has no body", ast.body);
assertNotNull("AST body has no children", ast.body.seq);
assertEquals("wrong number of children", 1, ast.body.seq.size());
NNode e = ast.body.seq.get(0);
assertTrue("Incorrect AST: " + e.getClass(), e instanceof NExprStmt);
e = ((NExprStmt)e).value;
assertTrue("Incorrect AST: " + e.getClass(), e instanceof NStr);
assertEquals("Wrong string content", "Hello", ((NStr)e).n.toString());
}
public void testFileLoad() throws Exception {
idx.loadFile(abspath("testfileload.py"), /*skipParentChain=*/true);
idx.ready();
assertEquals("loaded more than 1 file", 1, idx.numFilesLoaded());
}
public void testAstCacheTmpDir() throws Exception {
AstCache cache = AstCache.get();
File f = new File(AstCache.CACHE_DIR);
assertTrue(f.exists());
assertTrue(f.canRead());
assertTrue(f.canWrite());
assertTrue(f.isDirectory());
}
public void testAstCacheNames() throws Exception {
AstCache cache = AstCache.get();
String sourcePath = abspath("hello.py");
String cachePath = cache.getCachePath(new File(sourcePath));
String cachedName = new File(cachePath).getName();
assertTrue("Invalid cache name: " + cachedName,
cachedName.matches("^hello.py[A-Za-z0-9]{32}.ast$"));
}
public void testAstCache() throws Exception {
AstCache cache = AstCache.get();
String sourcePath = abspath("hello.py");
// ensure not cached on disk
NModule ast = cache.getSerializedModule(sourcePath);
assertNull(ast);
cache.getAST(sourcePath);
// ensure cached on disk
ast = cache.getSerializedModule(sourcePath);
assertNotNull(ast);
assertEquals(sourcePath, ast.getFile());
}
public void testAstCacheEmptyFile() throws Exception {
AstCache cache = AstCache.get();
NModule mod = cache.getAST(abspath("empty_file.py"));
assertNotNull(mod);
NBlock seq = mod.body;
assertNotNull(seq);
assertTrue(seq.seq.isEmpty());
}
// Make sure node types all have NType None when constructed,
// to ensure that no nodes are relying on a particular type when being
// resolved (since deserialization won't call the constructor).
public void testConstructedTypes() throws Exception {
assertNoneType(new NAlias(null, null, null));
assertNoneType(new NAssert(null, null));
assertNoneType(new NAssign(null, null));
assertNoneType(new NAttribute(new NStr(), new NName("")));
assertNoneType(new NAugAssign(null, null, null));
assertNoneType(new NBinOp(null, null, null));
assertNoneType(new NBlock(null));
assertNoneType(new NBody((List)null));
assertNoneType(new NBoolOp(null, null));
assertNoneType(new NBreak());
assertNoneType(new NCall(null, null, null, null, null));
assertNoneType(new NClassDef(null, null, null));
assertNoneType(new NCompare(null, null, null));
assertNoneType(new NComprehension(null, null, null));
assertNoneType(new NContinue());
assertNoneType(new NDelete(null));
assertNoneType(new NDict(null, null));
assertNoneType(new NEllipsis());
assertNoneType(new NExceptHandler(null, null, null));
assertNoneType(new NExec(null, null, null));
assertNoneType(new NExprStmt(null));
assertNoneType(new NFor(null, null, null, null));
assertNoneType(new NFunctionDef(null, null, null, null, null, null));
assertNoneType(new NGeneratorExp(null, null));
assertNoneType(new NGlobal(null));
assertNoneType(new NIf(null, null, null));
assertNoneType(new NIfExp(null, null, null));
assertNoneType(new NImport(null));
assertNoneType(new NImportFrom(null, null, null));
assertNoneType(new NIndex(null));
assertNoneType(new NKeyword(null, null));
assertNoneType(new NLambda(null, null, null, null, null));
assertNoneType(new NList(null));
assertNoneType(new NListComp(null, null));
assertNoneType(new NModule(null, 0, 1));
assertNoneType(new NName(""));
assertNoneType(new NNum(-1));
assertNoneType(new NPass());
assertNoneType(new NPlaceHolder());
assertNoneType(new NPrint(null, null));
assertNoneType(new NQname(null, new NName("")));
assertNoneType(new NRaise(null, null, null));
assertNoneType(new NRepr(null));
assertNoneType(new NReturn(null));
assertNoneType(new NSlice(null, null, null));
assertNoneType(new NStr());
assertNoneType(new NSubscript(null, null));
assertNoneType(new NTryExcept(null, null, null));
assertNoneType(new NTryFinally(null, null));
assertNoneType(new NTuple(null));
assertNoneType(new NUnaryOp(null, null));
assertNoneType(new NUrl(""));
assertNoneType(new NWhile(null, null, null));
assertNoneType(new NWith(null, null, null));
assertNoneType(new NYield(null));
}
private void assertNoneType(NNode n) {
assertEquals(n.getType(), Indexer.idx.builtins.None);
}
public void testClassTypeBuiltinAttrs() throws Exception {
String file = "classtype_builtins.py";
buildIndex(file);
NModuleType module = (NModuleType)idx.moduleTable.lookupType(abspath(file));
Scope mtable = module.getTable();
assertTrue(mtable.lookupType("MyClass").isClassType());
assertTrue(mtable.lookupType("MyClassNoDoc").isClassType());
assertTrue(mtable.lookupType("MyClass").getTable().getParent() == mtable);
assertEquals(NBinding.Kind.CLASS, mtable.lookup("MyClass").getKind());
Scope t = mtable.lookupType("MyClass").getTable();
assertTrue(t.lookupType("__bases__").isTupleType());
assertTrue(t.lookupType("__dict__").isDictType());
assertEquals(idx.builtins.BaseStr, t.lookupType("__name__"));
assertEquals(idx.builtins.BaseStr, t.lookupType("__module__"));
assertEquals(idx.builtins.BaseStr, t.lookupType("__doc__"));
t = mtable.lookupType("MyClassNoDoc").getTable();
assertEquals(idx.builtins.BaseStr, t.lookupType("__doc__"));
}
public void testMethodBuiltinAttrs() throws Exception {
String file = "classtype_builtins.py";
buildIndex(file);
Scope mtable = idx.moduleTable.lookupType(abspath(file)).getTable();
NBinding method = mtable.lookupType("MyClass").getTable().lookup("__init__");
assertNotNull(method);
assertEquals(NBinding.Kind.CONSTRUCTOR, method.getKind());
assertEquals("classtype_builtins.MyClass.__init__", method.getQname());
NType ftype = mtable.lookupType("MyClass").getTable().lookupType("__init__");
assertTrue(ftype.isFuncType());
NBinding c = mtable.lookup("MyClass");
for (String special : new String[]{"im_class", "__class__", "im_self", "__self__"}) {
NBinding attr = ftype.getTable().lookup(special);
assertNotNull("missing binding for " + special, attr);
assertEquals(c.getType(), attr.getType());
}
}
public void testModulePaths() throws Exception {
idx.loadModule("pkg");
idx.loadModule("pkg.animal");
idx.loadModule("pkg.mineral.stone.lapis");
idx.ready();
assertModuleBinding("pkg");
assertModuleBinding("pkg.animal");
assertModuleBinding("pkg.mineral.stone.lapis");
}
public void testCircularImport() throws Exception {
idx.loadModule("pkg.animal.mammal.cat");
idx.ready();
// XXX: finish me
}
public void testBasicDefsAndRefs() throws Exception {
idx.loadModule("refs");
idx.ready();
assertScopeBinding("refs.foo");
String src = getSource("refs.py");
assertDefinition("refs.foo", "foo", nthIndexOf(src, "foo", 1));
assertNoReference("Definition site should not produce a reference",
"refs.foo", nthIndexOf(src, "foo", 1), "foo".length());
assertReference("refs.foo", nthIndexOf(src, "foo", 2));
assertReference("refs.foo", nthIndexOf(src, "foo", 3));
assertReference("refs.foo", nthIndexOf(src, "foo", 4));
assertReference("refs.foo", nthIndexOf(src, "foo", 5));
assertNoReference("Should not have been a reference inside a string",
"refs.foo", nthIndexOf(src, "foo", 6), "foo".length());
assertReference("refs.foo", nthIndexOf(src, "foo", 7));
assertReference("refs.foo", nthIndexOf(src, "foo", 8));
assertReference("refs.foo", nthIndexOf(src, "foo", 9));
assertReference("refs.foo", nthIndexOf(src, "foo", 10));
assertReference("refs.foo", nthIndexOf(src, "foo", 11));
assertReference("refs.foo", nthIndexOf(src, "foo", 12));
assertNoReference("Function param cannot refer to outer scope",
"refs.foo", nthIndexOf(src, "foo", 13), "foo".length());
assertNoReference("Function param 'foo' should hide outer foo",
"refs.foo", nthIndexOf(src, "foo", 14), "foo".length());
assertReference("refs.foo", nthIndexOf(src, "foo", 15));
assertReference("refs.foo", nthIndexOf(src, "foo", 16));
}
public void testAutoClassBindings() throws Exception {
idx.loadModule("class1");
idx.ready();
assertModuleBinding("class1");
assertClassBinding("class1.A");
NBinding b = assertAttributeBinding("class1.A.__bases__");
assertStaticSynthetic(b);
assertTrue(b.getType().isTupleType());
assertTrue(((NTupleType)b.getType()).getElementTypes().isEmpty());
b = assertAttributeBinding("class1.A.__name__");
assertStaticSynthetic(b);
assertEquals(b.getType(), idx.builtins.BaseStr);
b = assertAttributeBinding("class1.A.__module__");
assertStaticSynthetic(b);
assertEquals(b.getType(), idx.builtins.BaseStr);
b = assertAttributeBinding("class1.A.__doc__");
assertStaticSynthetic(b);
assertEquals(b.getType(), idx.builtins.BaseStr);
b = assertAttributeBinding("class1.A.__dict__");
assertStaticSynthetic(b);
assertTrue(b.getType().isDictType());
assertEquals(((NDictType)b.getType()).getKeyType(), idx.builtins.BaseStr);
assertTrue(((NDictType)b.getType()).getValueType().isUnknownType());
}
public void testLocalVarRef() throws Exception {
idx.loadModule("class2");
idx.ready();
assertFunctionBinding("class2.hi");
assertParamBinding("class2.hi@msg");
String src = getSource("class2.py");
assertReference("class2.hi@msg", nthIndexOf(src, "msg", 2));
}
public void testClassMemberBindings() throws Exception {
idx.loadModule("class1");
idx.ready();
assertScopeBinding("class1.A.a");
assertConstructorBinding("class1.A.__init__");
assertMethodBinding("class1.A.hi");
assertParamBinding("class1.A.__init__@self");
assertParamBinding("class1.A.hi@self");
assertParamBinding("class1.A.hi@msg");
String src = getSource("class1.py");
assertReference("class1.A.hi@msg", nthIndexOf(src, "msg", 2));
assertReference("class1.A", src.indexOf("A.a"), 1);
assertReference("class1.A.a", src.indexOf("A.a") + 2, 1);
assertScopeBinding("class1.x");
assertScopeBinding("class1.y");
assertScopeBinding("class1.z");
assertReference("class1.A", src.indexOf("= A") + 2, 1);
assertConstructed("class1.A", src.indexOf("A()"), 1);
assertReference("class1.y", src.indexOf("y.b"), 1);
assertInstanceType("class1.y", "class1.A");
assertReference("class1.A.b", src.indexOf("y.b") + 2, 1);
assertScopeBinding("class1.z");
assertNumType("class1.z");
}
public void testCallNewRef() throws Exception {
idx.loadModule("callnewref");
idx.ready();
String src = getSource("callnewref.py");
String fsig = "callnewref.myfunc";
assertFunctionBinding(fsig);
assertDefinition(fsig, "myfunc", src.indexOf("myfunc"));
assertReference(fsig, nthIndexOf(src, "myfunc", 2));
assertCall(fsig, nthIndexOf(src, "myfunc", 3));
String csig = "callnewref.MyClass";
assertClassBinding(csig);
assertDefinition(csig, "MyClass", src.indexOf("MyClass"));
assertReference(csig, nthIndexOf(src, "MyClass", 2));
assertConstructed(csig, nthIndexOf(src, "MyClass", 3));
String msig = "callnewref.MyClass.mymethod";
assertMethodBinding(msig);
assertDefinition(msig, "mymethod", src.indexOf("mymethod"));
assertReference(msig, nthIndexOf(src, "mymethod", 2));
assertCall(msig, nthIndexOf(src, "mymethod", 3));
}
public void testPackageLoad() throws Exception {
idx.loadModule("pkgload");
idx.ready();
assertModuleBinding("pkgload");
assertModuleBinding("pkg");
assertScopeBinding("pkg.myvalue");
}
public void testUnqualifiedSamePkgImport() throws Exception {
idx.loadModule("pkg.animal.reptile.snake");
idx.ready();
assertModuleBinding("pkg.animal.reptile.snake");
assertModuleBinding("pkg.animal.reptile.croc");
assertClassBinding("pkg.animal.reptile.snake.Snake");
assertClassBinding("pkg.animal.reptile.snake.Python");
assertClassBinding("pkg.animal.reptile.croc.Crocodilian");
assertClassBinding("pkg.animal.reptile.croc.Gavial");
String snakeSrc = getSource("pkg/animal/reptile/snake.py");
assertReference("pkg.animal.reptile.croc", snakeSrc.indexOf("croc"));
assertReference("pkg.animal.reptile.croc", nthIndexOf(snakeSrc, "croc", 2));
assertReference("pkg.animal.reptile.croc.Gavial", snakeSrc.indexOf("Gavial"));
}
public void testAbsoluteImport() throws Exception {
idx.loadModule("pkg.mineral.metal.lead");
idx.ready();
assertModuleBinding("pkg");
assertModuleBinding("pkg.plant");
assertModuleBinding("pkg.plant.poison");
assertModuleBinding("pkg.plant.poison.eggplant");
String src = getSource("pkg/mineral/metal/lead.py");
assertReference("pkg", nthIndexOf(src, "pkg", 1));
assertReference("pkg", nthIndexOf(src, "pkg", 2));
assertReference("pkg.plant", nthIndexOf(src, "plant", 1));
assertReference("pkg.plant", nthIndexOf(src, ".plant", 2) + 1);
assertReference("pkg.plant.poison", nthIndexOf(src, "poison", 1));
assertReference("pkg.plant.poison", nthIndexOf(src, ".poison", 2) + 1);
assertReference("pkg.plant.poison.eggplant", nthIndexOf(src, "eggplant", 1));
assertReference("pkg.plant.poison.eggplant", nthIndexOf(src, ".eggplant", 2) + 1);
}
public void testAbsoluteImportAs() throws Exception {
idx.loadModule("pkg.mineral.metal.iron");
idx.ready();
assertModuleBinding("pkg");
assertModuleBinding("pkg.mineral");
assertModuleBinding("pkg.mineral.metal");
assertModuleBinding("pkg.mineral.metal.iron");
assertModuleBinding("pkg.plant");
assertModuleBinding("pkg.plant.poison");
assertModuleBinding("pkg.plant.poison.eggplant");
String adjectives = "pkg.plant.poison.eggplant.adjectives";
assertScopeBinding(adjectives);
String aubergine = "pkg.mineral.metal.iron.aubergine";
assertScopeBinding(aubergine);
assertBindingType(aubergine, "pkg.plant.poison.eggplant");
String src = getSource("pkg/mineral/metal/iron.py");
assertReference("pkg", src.indexOf("pkg"));
assertReference("pkg.plant", src.indexOf("plant"));
assertReference("pkg.plant.poison", src.indexOf("poison"));
assertReference("pkg.plant.poison.eggplant", src.indexOf("eggplant"));
assertReference(aubergine, nthIndexOf(src, "aubergine", 2));
assertReference(adjectives, src.indexOf("adjectives"));
}
public void testImportFrom() throws Exception {
idx.loadModule("pkg.other.color.white");
idx.ready();
String src = getSource("pkg/other/color/white.py");
assertReference("pkg.other.color.red", src.indexOf("red"));
assertReference("pkg.other.color.green", src.indexOf("green"));
assertReference("pkg.other.color.blue", src.indexOf("blue"));
assertReference("pkg.other.color.red.r", src.indexOf("r as"), 1);
assertReference("pkg.other.color.blue.b", src.indexOf("b as"), 1);
assertReference("pkg.other.color.red.r", src.indexOf("= R") + 2, 1);
assertReference("pkg.other.color.green.g", src.indexOf("g #"), 1);
assertReference("pkg.other.color.blue.b", src.indexOf("= B") + 2, 1);
}
public void testImportStar() throws Exception {
idx.loadModule("pkg.other.color.crimson");
idx.ready();
String src = getSource("pkg/other/color/crimson.py");
assertReference("pkg.other.color.red.r", src.indexOf("r,"), 1);
assertReference("pkg.other.color.red.g", src.indexOf("g,"), 1);
assertReference("pkg.other.color.red.b", src.indexOf("b"), 1);
}
public void testImportStarAll() throws Exception {
idx.loadModule("pkg.misc.moduleB");
idx.ready();
String src = getSource("pkg/misc/moduleB.py");
assertReference("pkg.misc.moduleA.a", src.indexOf("a #"), 1);
assertReference("pkg.misc.moduleA.b", src.indexOf("b #"), 1);
assertReference("pkg.misc.moduleA.c", src.indexOf("c #"), 1);
assertNoReference("Should not have imported 'd'",
"pkg.misc.moduleA.d", src.indexOf("d #"), 1);
}
public void testImportFromInitPy() throws Exception {
idx.loadModule("pkg.animal");
idx.ready();
assertModuleBinding("pkg");
assertModuleBinding("pkg.animal");
assertModuleBinding("pkg.animal.animaltest");
assertScopeBinding("pkg.animal.success");
assertScopeBinding("pkg.animal.animaltest.living");
}
// // Tests to add:
// // - import inside a function; check that names are VARIABLE (not SCOPE)
// public void finishme_testModuleDictMerging() throws Exception {
// // goal is to test this case:
// // mod1.py:
// // a = 1
// // mod2.py:
// // import mod1
// // def test():
// // print mod1.b # at this point mod1.b is an unknown attr of mod1
// // mod3.py:
// // import mod1
// // mod1.b = 2 # at this later point it gets defined
// // test:
// // load mod1, mod2, mod3
// // => assert that in mod2.py, mod1.b refers to the definition in mod3.py
// }
// test creating temp definition and then re-resolving it
public void testTempName() throws Exception {
String src = index(
"tmpname.py",
"def purge():",
" cache.clear()",
"cache = {}");
assertScopeBinding("tmpname.cache");
assertBindingType("tmpname.cache", NDictType.class);
assertDefinition("tmpname.cache", "cache", src.lastIndexOf("cache"));
assertReference("tmpname.cache", src.indexOf("cache"));
assertNoDefinition("Temp-def should have been replaced",
"tmpname.cache", src.indexOf("cache"), "cache".length());
assertCall("__builtin__.dict.clear", src.lastIndexOf("clear"));
}
public void testTempAttr() throws Exception {
String src = index(
"tmpattr.py",
"x = app.usage",
"app.usage = 'hi'");
assertScopeBinding("tmpattr.x");
assertScopeBinding("tmpattr.app");
assertAttributeBinding("tmpattr.app.usage");
assertStringType("tmpattr.app.usage");
assertStringType("tmpattr.x");
assertDefinition("tmpattr.app.usage", src.lastIndexOf("usage"));
assertReference("tmpattr.app.usage", src.indexOf("usage"));
}
public void testTempAttrOnParam() throws Exception {
String src = index(
"tmpattr_param.py",
"def foo(x):",
" x.hello = 'hi'",
"def bar(y=None):",
" y.hello = 'hola'");
assertFunctionBinding("tmpattr_param.foo");
assertParamBinding("tmpattr_param.foo@x");
assertAttributeBinding("[email protected]");
assertStringType("[email protected]");
assertReference("tmpattr_param.foo@x", src.indexOf("x.hello"), 1);
assertFunctionBinding("tmpattr_param.bar");
assertParamBinding("tmpattr_param.bar@y");
assertAttributeBinding("[email protected]");
assertStringType("[email protected]");
assertReference("tmpattr_param.bar@y", src.indexOf("y.hello"), 1);
}
public void testParamDefaultLambdaBinding() throws Exception {
String src = index(
"test.py",
"def foo(arg=lambda name: name + '!'):",
" x = arg('hi')");
assertFunctionBinding("test.foo");
assertParamBinding("test.foo@arg");
assertFunctionBinding("test.lambda%1");
assertParamBinding("test.lambda%1@name");
assertReference("test.lambda%1@name", src.lastIndexOf("name"));
assertCall("test.foo@arg", src.lastIndexOf("arg"));
assertStringType("test.foo&x");
}
public void testNestedLambdaParam() throws Exception {
String src = index(
"test.py",
"def util(create):",
" return create()",
"z = lambda:util(create=lambda: str())",
"y = z()()");
assertScopeBinding("test.z");
assertFunctionBinding("test.lambda%1&lambda%1");
// XXX: will require inferring across calls
// assertStringType("test.y");
}
public void testReassignAttrOfUnknown() throws Exception {
// This test has broken surprisingly often, so don't change it.
String src = index(
"reassign.py",
"app.foo = 'hello'",
"app.foo = 2");
assertScopeBinding("reassign.app");
NBinding nb = assertAttributeBinding("reassign.app.foo");
NType type = nb.getType();
assertTrue(type.isUnionType());
Set types = ((NUnionType)type).getTypes();
assertEquals(2, types.size());
assertTrue(types.contains(idx.builtins.BaseStr));
assertTrue(types.contains(idx.builtins.BaseNum));
}
public void testRefToProvisionalBinding() throws Exception {
String src = index(
"provisional.py",
"for a in []:",
" a.dump()",
"for a in []:",
" a.dump()");
assertModuleBinding("provisional");
assertScopeBinding("provisional.a");
assertNoBinding("provisional.a.dump");
}
public void testRefToProvisionalBindingNewType() throws Exception {
String src = index(
"provisional.py",
"for b in []:",
" b.dump()",
"for b in ():",
" b.dump()");
assertModuleBinding("provisional");
assertScopeBinding("provisional.b");
assertNoBinding("provisional.b.dump");
}
// http://www.python.org/dev/peps/pep-0227
public void testSkipClassScope() throws Exception {
String src = index(
"skipclass.py",
"def aa():",
" xx = 'foo'",
" class bb:",
" xx = 10",
" def cc(self):",
" print bb.xx",
" print xx");
assertReference("skipclass.aa&bb.xx", nthIndexOf(src, "xx", 3));
assertReference("skipclass.aa&xx", nthIndexOf(src, "xx", 4));
}
public void testLambdaArgs() throws Exception {
String src = index(
"lambda_args.py",
"y = lambda x='hi': x.upper()",
"y = lambda x='there': x.lower()");
assertScopeBinding("lambda_args.y");
assertFunctionBinding("lambda_args.lambda%1");
assertParamBinding("lambda_args.lambda%1@x");
assertStringType("lambda_args.lambda%1@x");
assertReference("lambda_args.lambda%1@x", nthIndexOf(src, "x", 2));
assertCall("__builtin__.str.upper", src.indexOf("upper"));
assertFunctionBinding("lambda_args.lambda%2");
assertParamBinding("lambda_args.lambda%1@x");
assertReference("lambda_args.lambda%2@x", nthIndexOf(src, "x", 4));
assertCall("__builtin__.str.lower", src.indexOf("lower"));
}
public void testFunArgs() throws Exception {
String src = index(
"funargs.py",
"def foo(x, y='hi'):",
" z = 9",
" return x + y.upper() + z");
assertFunctionBinding("funargs.foo");
assertParamBinding("funargs.foo@x");
assertReference("funargs.foo@x", nthIndexOf(src, "x", 2));
assertParamBinding("funargs.foo@y");
assertStringType("funargs.foo@y");
assertReference("funargs.foo@y", nthIndexOf(src, "y", 2));
assertCall("__builtin__.str.upper", src.indexOf("upper"));
assertVariableBinding("funargs.foo&z");
assertReference("funargs.foo&z", nthIndexOf(src, "z", 2));
}
public void testDatetime() throws Exception {
String src = index(
"date_time.py",
"from datetime import datetime as dt",
"import datetime",
"now = dt.now()",
"d = now.date()",
"tz = now.tzinfo");
assertModuleBinding("datetime");
assertClassBinding("datetime.datetime");
assertMethodBinding("datetime.datetime.date");
assertReference("datetime", nthIndexOf(src, "datetime", 1));
assertReference("datetime.datetime", nthIndexOf(src, "datetime", 2));
assertReference("datetime.datetime", nthIndexOf(src, "dt", 1), 2);
assertReference("datetime.datetime", nthIndexOf(src, "dt", 2), 2);
assertReference("datetime", nthIndexOf(src, "datetime", 3));
assertCall("datetime.datetime.now", nthIndexOf(src, "now", 2));
assertCall("datetime.datetime.date", nthIndexOf(src, "date()", 1));
assertReference("datetime.time.tzinfo", nthIndexOf(src, "tzinfo", 1));
assertBindingType("date_time.tz", "datetime.tzinfo");
}
public void testUnpackList() throws Exception {
index("unpacklist.py",
"a = [1, 2]",
"(b, c) = [3, 4]",
"[d, e] = ['hi', 'there']");
assertScopeBinding("unpacklist.a");
assertScopeBinding("unpacklist.b");
assertScopeBinding("unpacklist.c");
assertScopeBinding("unpacklist.d");
assertScopeBinding("unpacklist.e");
assertListType("unpacklist.a", "__builtin__.float");
assertNumType("unpacklist.b");
assertNumType("unpacklist.c");
assertStringType("unpacklist.d");
assertStringType("unpacklist.e");
}
public void testStringSlice() throws Exception {
String src = index(
"slicestring.py",
"a = 'hello'[2]",
"b = 'hello'[2:4]",
"test = 'testing'",
"test[-3:].lower()");
assertScopeBinding("slicestring.a");
assertScopeBinding("slicestring.b");
assertStringType("slicestring.a");
assertStringType("slicestring.b");
assertCall("__builtin__.str.lower", src.lastIndexOf("lower"));
}
public void testUnionStringSliceTempAttr() throws Exception {
String src = index(
"tmpattr_slice.py",
"def foo(filename):",
" module = filename or ''",
" module[-3:].lower()");
assertCall("__builtin__.str.lower", src.lastIndexOf("lower"));
}
public void testSelfBinding() throws Exception {
String src = index(
"selfish.py",
"class Foo():",
" def hello(self):",
" print self");
assertClassBinding("selfish.Foo");
assertMethodBinding("selfish.Foo.hello");
assertParamBinding("selfish.Foo.hello@self");
assertDefinition("selfish.Foo.hello@self", nthIndexOf(src, "self", 1));
assertReference("selfish.Foo.hello@self", nthIndexOf(src, "self", 2));
assertBindingType("selfish.Foo.hello@self", "selfish.Foo");
}
public void testInstanceAttrs() throws Exception {
String src = index(
"attr.py",
"class Foo():",
" def __init__(self):",
" self.elts = []",
" def add(self, item):",
" self.elts.append(item)");
assertClassBinding("attr.Foo");
assertConstructorBinding("attr.Foo.__init__");
assertParamBinding("attr.Foo.__init__@self");
assertDefinition("attr.Foo.__init__@self", nthIndexOf(src, "self", 1));
assertReference("attr.Foo.__init__@self", nthIndexOf(src, "self", 2));
assertBindingType("attr.Foo.__init__@self", "attr.Foo");
assertAttributeBinding("attr.Foo.elts");
assertListType("attr.Foo.elts");
assertMethodBinding("attr.Foo.add");
assertParamBinding("attr.Foo.add@self");
assertBindingType("attr.Foo.add@self", "attr.Foo");
assertParamBinding("attr.Foo.add@item");
assertReference("attr.Foo.add@self", nthIndexOf(src, "self", 4));
assertReference("attr.Foo.elts", nthIndexOf(src, "elts", 2));
assertCall("__builtin__.list.append", src.indexOf("append"));
assertReference("attr.Foo.add@item", src.lastIndexOf("item"));
}
public void testInstanceAttrsWithStdLib() throws Exception {
includeStandardLibrary();
String src = index(
"dice.py",
"import random",
"class Dice(object):",
" def __init__(self):",
" self.__random = random.Random()",
" def set_seed(self, seed):",
" self.__random.seed(seed)");
assertModuleBinding("random");
NBinding r = assertClassBinding("random.Random");
assertFalse(r.isBuiltin());
assertReference("random", nthIndexOf(src, "random", 3));
assertConstructed("random.Random", src.indexOf("Random"));
assertClassBinding("dice.Dice");
assertReference("__builtin__.object", src.indexOf("object"));
assertConstructorBinding("dice.Dice.__init__");
assertParamBinding("dice.Dice.__init__@self");
assertDefinition("dice.Dice.__init__@self", nthIndexOf(src, "self", 1));
assertReference("dice.Dice.__init__@self", nthIndexOf(src, "self", 2));
assertBindingType("dice.Dice.__init__@self", "dice.Dice");
assertAttributeBinding("dice.Dice.__random");
assertInstanceType("dice.Dice.__random", "random.Random");
assertMethodBinding("dice.Dice.set_seed");
assertParamBinding("dice.Dice.set_seed@self");
assertBindingType("dice.Dice.set_seed@self", "dice.Dice");
assertParamBinding("dice.Dice.set_seed@seed");
assertReference("dice.Dice.set_seed@self", nthIndexOf(src, "self", 4));
assertReference("dice.Dice.__random", nthIndexOf(src, "__random", 2));
assertCall("random.Random.seed", nthIndexOf(src, "seed", 3));
assertReference("dice.Dice.set_seed@seed", src.lastIndexOf("seed"));
}
public void testOsPath() throws Exception {
String src = index(
"test.py",
"from os import path",
"print path.devnull",
"base, ext = path.split('/foo/bar/baz.py')",
"print ext.endswith('py')");
assertReference("os.path.devnull", src.indexOf("devnull"));
assertStringType("os.path.devnull");
assertStringType("test.base");
assertStringType("test.ext");
assertCall("os.path.split", src.indexOf("split"));
assertCall("__builtin__.str.endswith", src.indexOf("endswith"));
}
public void testImportOsPath() throws Exception {
String src = index(
"test.py",
"import os.path",
"print os.path.devnull");
assertReference("os", nthIndexOf(src, "os", 1));
assertReference("os", nthIndexOf(src, "os", 2));
assertReference("os.path", nthIndexOf(src, "path", 1));
assertReference("os.path", nthIndexOf(src, "path", 2));
assertReference("os.path.devnull", src.indexOf("devnull"));
}
public void testExceptionsModule() throws Exception {
String src = index(
"test.py",
"import exceptions",
"raise exceptions.NotImplementedError");
assertModuleBinding("exceptions");
assertClassBinding("exceptions.NotImplementedError");
assertReference("exceptions.NotImplementedError", src.indexOf("Not"));
}
public void testDupFunctionDecl() throws Exception {
String src = index(
"test.py",
"if x:",
" def a(args):",
" print args",
"elif y:",
" def a(args):",
" print args");
assertFunctionBinding("test.a");
assertParamBinding("test.a@args");
}
public void testResolveExportedNames() throws Exception {
String src = index(
"test.py",
"__all__ = ['foo', 'bar' + 'baz', 'one', 'two']",
"def foo(x):",
" return x",
"bar = 6",
"baz = 7",
"barbaz = 8",
"one = 'hi'",
"two = 'there'");
assertReference("test.foo", src.indexOf("'foo"), 5);
assertReference("test.one", src.indexOf("'one"), 5);
assertReference("test.two", src.indexOf("'two"), 5);
assertNoReference("Should not have referenced 'bar'",
"test.bar", src.indexOf("bar"), 3);
}
public void testImportFromPlusAssign() throws Exception {
String src = index(
"test.py",
"from os import sep",
"os = 10",
"print os");
assertModuleBinding("os");
assertReference("os", src.indexOf("os"));
assertNoDefinition("Import-from should not introduce a definition",
"test.os", src.indexOf("os"), "os".length());
assertDefinition("test.os", nthIndexOf(src, "os", 2));
assertNumType("test.os");
assertReference("test.os", src.lastIndexOf("os"));
}
public void testCircularTypeFunAndTuple() throws Exception {
String src = index(
"test.py",
"def foo():",
" return (foo,)");
assertFunctionBinding("test.foo");
NType ftype = idx.lookupQnameType("test.foo");
assertTrue(ftype instanceof NFuncType);
NType rtype = ftype.asFuncType().getReturnType();
assertTrue(rtype instanceof NTupleType);
assertEquals(1, rtype.asTupleType().getElementTypes().size());
assertEquals(ftype, rtype.asTupleType().getElementTypes().get(0));
assertEquals("]>>", ftype.toString());
}
public void testCircularTypeXInOwnList() throws Exception {
String src = index(
"test.py",
"x = (2,)",
"y = [x]",
"x = y");
NType xtype = idx.lookupQnameType("test.x");
assertTrue(xtype instanceof NUnionType);
// Jump through some hoops to allow for either order in the union.
Set types = xtype.asUnionType().getTypes();
assertEquals(2, types.size());
NType[] array = types.toArray(new NType[2]);
boolean array0List = array[0] instanceof NListType;
boolean array1List = array[1] instanceof NListType;
assertTrue(array0List || array1List);
int other = array0List ? 1 : 0;
assertTrue("Expected tuple: " + array[other], array[other].isTupleType());
assertEquals(1, array[other].asTupleType().getElementTypes().size());
assertEquals(idx.builtins.BaseNum, array[other].asTupleType().getElementTypes().get(0));
String s = xtype.toString();
int index = s.indexOf("]>";
String ref = "<#" + num + ">";
if (array0List) {
// union(list(unknown(tuple)), ref)
assertEquals("," + ref + "]>", s);
} else {
// union(tuple, list(unknown(ref)))
assertEquals("]>", s);
}
}
public void testFunReturn() throws Exception {
// This use case used to extend the function return type by one
// wrapped NUnknownType for each static invocation of the function.
String src = index(
"fret.py",
"def foo(x): return x",
"a = foo('a')",
"b = foo('b')",
"c = foo('c')");
NType ftype = idx.lookupQnameType("fret.foo");
assertEquals(">", ftype.toString());
NType ctype = idx.lookupQnameType("fret.c");
assertEquals(ctype.follow(), ftype.asFuncType().getReturnType());
}
public void testListCompForIn() throws Exception {
String src = index(
"listforin.py",
"[line for line in ['foo']]");
assertStringType("listforin.line");
}
public void testNoAddToBuiltin() throws Exception {
String src = index(
"nob.py",
"x = [line.rstrip() + '\\n' for line in ['a ']]");
assertStringType("nob.line");
assertCall("__builtin__.str.rstrip", src.indexOf("rstrip"));
assertNoBinding("__builtin__.list.rstrip");
assertListType("nob.x", "__builtin__.str");
}
public void testDecoratorSyntax() throws Exception {
String deco1 = "@deco1";
String deco2 = "@deco2 ('yargh')";
String src = index(
"deco.py",
deco1,
deco2,
"def foo(): pass");
assertFunctionBinding("deco.foo");
NModule m = idx.getAstForFile("deco.py");
assertNotNull(m);
NNode obj = m.body.seq.get(0);
assertTrue(obj instanceof NFunctionDef);
NFunctionDef f = (NFunctionDef)obj;
List decos = f.getDecoratorList();
assertNotNull(decos);
assertEquals(2, decos.size());
assertTrue(decos.get(0) instanceof NName);
NName d1 = (NName)decos.get(0);
assertEquals(nthIndexOf(src, "deco1", 1), d1.start());
assertEquals("deco1".length(), d1.length());
assertEquals("deco1", d1.id);
assertTrue(decos.get(1) instanceof NCall);
NCall d2 = (NCall)decos.get(1);
assertTrue(d2.func instanceof NName);
assertEquals("deco2", ((NName)d2.func).id);
}
public void testBasicDecoratorSyntax() throws Exception {
String src = index(
"deco.py",
"def deco1(func): print 'hello'; return func",
"@deco1()",
"def foo(): pass");
assertFunctionBinding("deco.deco1");
assertFunctionBinding("deco.foo");
assertCall("deco.deco1", nthIndexOf(src, "deco1", 2));
}
}