Top Description Fields Constructors Methods
org.python.indexer.ast

public Class NImportFrom

extends NNode
Class Inheritance
Imports
org.python.indexer.Def, .Indexer, .NBinding, .Scope, org.python.indexer.types.NModuleType, .NType, .NUnknownType, java.util.ArrayList, .List, .Map.Entry, .Set

Handles import from statements such as 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.

Field Summary

Modifier and TypeField and Description
public List<NAlias>
public String
public NQname
pack-priv static final long
Inherited from org.python.indexer.ast.NNode:
parent

Constructor Summary

AccessConstructor and Description
public
NImportFrom(String module, NQname qname, List<NAlias> aliases)

public
NImportFrom(String module, NQname qname, List<NAlias> aliases, int start, int end)

Method Summary

Modifier and TypeMethod and Description
protected void
bindNames(Scope s)

Overrides org.python.indexer.ast.NNode.bindNames.

Called by resolver to bind names into the passed scope.

public boolean
bindsName()

Overrides org.python.indexer.ast.NNode.bindsName.

Returns true if this is a name-binding node.

private void
public boolean
public NType
resolve(Scope s)

Overrides org.python.indexer.ast.NNode.resolve.

Node should set the resolved type in its type field and also return it.

private void
resolveAlias(Scope
the scope into which names should be imported
scope
,
NModuleType
the non-null module "x[.y]". Could refer to either x/y.py or x/y/__init__.py.
mt
,
NAlias
the "foo [as bar]" component of the import statement
a
)

Resolve "foo [as bar]" in "from x[.y] import foo [as bar]".

public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

public void
visit(NNodeVisitor
the object to call with this node. If the visitor returns true, the node also passes its children to the visitor.
v
)

Implements abstract org.python.indexer.ast.NNode.visit.

Visits this node and optionally its children.

Inherited from org.python.indexer.ast.NNode:
addChildrenaddChildrenaddErroraddErroraddTypeaddWarningaddWarningendgetAstRootgetDeepestNodeAtOffsetgetEnclosingNamespacegetFilegetParentgetTablegetTypeisCallisClassDefisFunctionDefisLambdaisModuleisNamelengthresolveExprresolveListresolveListAsUnionsetEndsetParentsetStartsetTypestartvisitNodevisitNodeList

Field Detail

aliasesback to summary
public List<NAlias> aliases
moduleback to summary
public String module
qnameback to summary
public NQname qname
serialVersionUIDback to summary
pack-priv static final long serialVersionUID

Hides org.python.indexer.ast.NNode.serialVersionUID.

Constructor Detail

NImportFromback to summary
public NImportFrom(String module, NQname qname, List<NAlias> aliases)
NImportFromback to summary
public NImportFrom(String module, NQname qname, List<NAlias> aliases, int start, int end)

Method Detail

bindNamesback to summary
protected void bindNames(Scope s) throws Exception

Overrides org.python.indexer.ast.NNode.bindNames.

Doc from org.python.indexer.ast.NNode.bindNames.

Called by resolver to bind names into the passed scope.

Annotations
@Override
bindsNameback to summary
public boolean bindsName()

Overrides org.python.indexer.ast.NNode.bindsName.

Doc from org.python.indexer.ast.NNode.bindsName.

Returns true if this is a name-binding node. Includes functions/lambdas, function/lambda params, classes, assignments, imports, and implicit assignment via for statements and except clauses.

Annotations
@Override
importStarback to summary
private void importStar(Scope s, NModuleType mt) throws Exception
isImportStarback to summary
public boolean isImportStar()
resolveback to summary
public NType resolve(Scope s) throws Exception

Overrides org.python.indexer.ast.NNode.resolve.

Doc from org.python.indexer.ast.NNode.resolve.

Node should set the resolved type in its type field and also return it.

Annotations
@Override
resolveAliasback 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".

Parameters
scope:Scope

the scope into which names should be imported

mt:NModuleType

the non-null module "x[.y]". Could refer to either x/y.py or x/y/__init__.py.

a:NAlias

the "foo [as bar]" component of the import statement

toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Returns:String

a string representation of the object

Annotations
@Override
visitback to summary
public void visit(NNodeVisitor v)

Implements abstract org.python.indexer.ast.NNode.visit.

Doc from org.python.indexer.ast.NNode.visit.

Visits this node and optionally its children.

Parameters
v:NNodeVisitor

the object to call with this node. If the visitor returns true, the node also passes its children to the visitor.

Annotations
@Override