from foo import bar and the ast module

Chris Angelico rosuav at gmail.com
Sun Aug 22 10:35:25 EDT 2021


On Mon, Aug 23, 2021 at 12:26 AM Dan Stromberg <drsalists at gmail.com> wrote:
>
>
> On Sun, Aug 22, 2021 at 7:14 AM Chris Angelico <rosuav at gmail.com> wrote:
>>
>> On Mon, Aug 23, 2021 at 12:08 AM Dan Stromberg <drsalists at gmail.com> wrote:
>> >
>> > In 'from foo import bar':
>> >
>> > With the ast module, I see how to get bar, but I do not yet see how to get
>> > the foo.
>> >
>> > There are clearly ast.Import and ast.ImportFrom, but I do not see the foo
>> > part in ast.ImportFrom.
>> >
>> > ?
>>
>> >>> import ast
>> >>> ast.dump(ast.parse("from foo import bar"))
>> "Module(body=[ImportFrom(module='foo', names=[alias(name='bar')],
>> level=0)], type_ignores=[])"
>> >>> ast.parse("from foo import bar").body[0].module
>> 'foo'
>
>
> With 'from . import bar', I get a module of None.
>
>  Does this seem strange?
>

No; it's just the AST so it can't bring in any additional information.
To distinguish package-relative imports, use the level attribute:

>>> ast.dump(ast.parse("from . import bar").body[0])
"ImportFrom(names=[alias(name='bar')], level=1)"
>>> ast.dump(ast.parse("from .foo import bar").body[0])
"ImportFrom(module='foo', names=[alias(name='bar')], level=1)"
>>> ast.dump(ast.parse("from foo.bar import bar").body[0])
"ImportFrom(module='foo.bar', names=[alias(name='bar')], level=0)"
>>> ast.dump(ast.parse("from .foo.bar import bar").body[0])
"ImportFrom(module='foo.bar', names=[alias(name='bar')], level=1)"
>>> ast.dump(ast.parse("from ..foo.bar import bar").body[0])
"ImportFrom(module='foo.bar', names=[alias(name='bar')], level=2)"

ChrisA


More information about the Python-list mailing list