from moduleA import a, b as c, d
and from foo.bar.moduleB import *. The indexer's implementation of import * uses different semantics from all the other forms of import. It's basically a bug, although the jury is still out as to which implementation is better.
For the others we define name bindings anywhere an actual name is introduced into the scope containing the import statement, and references to the imported module or name everywhere else. This mimics the behavior of Python at runtime, but it may be confusing to anyone with only a casual understanding of Python's data model, who might think it works more like Java.
For import * we just enter the imported names into the symbol table, which lets other code reference them, but the references "pass through" automatically to the module from which the names were imported.
To illustate the difference, consider the following four modules:
moduleA.py:
a = 1
b = 2
moduleB.py:
c = 3
d = 4
moduleC.py:
from moduleA import a, b
from moduleB import *
print a # indexer finds definition of 'a' 2 lines up
print b # indexer finds definition of 'b' 3 lines up
print c # indexer finds definition of 'c' in moduleB
print d # indexer finds definition of 'd' in moduleB
moduleD.py:
import moduleC
print moduleC.a # indexer finds definition of 'a' in moduleC
print moduleC.b # indexer finds definition of 'b' in moduleC
print moduleC.c # indexer finds definition of 'c' in moduleB
print moduleC.c # indexer finds definition of 'd' in moduleB
To make import * work like the others, we need only create bindings
for the imported names. But where would the bindings be located?
Assuming that we were to co-locate them all at the "*" name node,
clicking on a reference to any of the names would jump to the "*".
It's not clear that this is a better user experience.
We could make the other import statement forms work like import *,
but that path is even more fraught with confusing inconsistencies.
| Modifier and Type | Field and Description |
|---|---|
| public List | |
| public String | |
| public NQname | |
| pack-priv static final long |
| Access | Constructor and Description |
|---|---|
| public | |
| public |
| Modifier and Type | Method and Description |
|---|---|
| protected void | bindNames(Scope s)
Overrides org. Called by resolver to bind names into the passed scope. |
| public boolean | bindsName()
Overrides org. Returns |
| private void | |
| public boolean | |
| public NType | resolve(Scope s)
Overrides org. Node should set the resolved type in its |
| private void | resolveAlias(Scope
the scope into which names should be imported scope, NModuleType the non- mt, NAlias null module "x[.y]". Could refer to
either x/y.py or x/y/__init__.py.the "foo [as bar]" component of the import statement a)Resolve "foo [as bar]" in "from x[.y] import foo [as bar]". |
| public String | |
| public void | visit(NNodeVisitor
the object to call with this node.
If the visitor returns v)true, the node also
passes its children to the visitor.Implements abstract org. Visits this node and optionally its children. |
| aliases | back to summary |
|---|---|
| public List<NAlias> aliases | |
| module | back to summary |
|---|---|
| public String module | |
| qname | back to summary |
|---|---|
| public NQname qname | |
| serialVersionUID | back to summary |
|---|---|
| pack-priv static final long serialVersionUID | |
| NImportFrom | back to summary |
|---|---|
| public NImportFrom(String module, NQname qname, List<NAlias> aliases) | |
| NImportFrom | back to summary |
|---|---|
| public NImportFrom(String module, NQname qname, List<NAlias> aliases, int start, int end) | |
| bindNames | back to summary |
|---|---|
| protected void bindNames(Scope s) throws Exception Overrides org. Doc from org. Called by resolver to bind names into the passed scope.
| |
| bindsName | back to summary |
|---|---|
| public boolean bindsName() Overrides org. Doc from org. Returns
| |
| importStar | back to summary |
|---|---|
| private void importStar(Scope s, NModuleType mt) throws Exception | |
| isImportStar | back to summary |
|---|---|
| public boolean isImportStar() | |
| resolve | back to summary |
|---|---|
| public NType resolve(Scope s) throws Exception Overrides org. Doc from org. Node should set the resolved type in its
| |
| resolveAlias | back to summary |
|---|---|
| private void resolveAlias(Scope scope, NModuleType mt, NAlias a) throws Exception Resolve "foo [as bar]" in "from x[.y] import foo [as bar]". There are several possibilities for "foo": it could be a file in the directory "x[.y]", or it could be a name exported by the module "x[.y]" (from its __init__.py), or it could be a public name in the file "x/y.py".
| |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object.
Satisfying this method's contract implies a non- | |
| visit | back to summary |
|---|---|
| public void visit(NNodeVisitor v) Implements abstract org. Doc from org. Visits this node and optionally its children.
| |