Parses a superset of Python allowing for inline module import expressions

hacktoberfest, python, python-ast, repl
pip install import-expression==0.3.5


Import Expression Parser (for lack of a better name)

Build Status Coverage Status

Import Expression Parser converts code like this:

urllib.parse!.quote('hello there')

Into this equivalent code:

importlib.import_module('urllib.parse').quote('hello there')


>>> import import_expression
>>> import_expression.eval('collections!.Counter("bccdddeeee")')
Counter({'e': 4, 'd': 3, 'c': 2, 'b': 1})

The other public functions are exec, compile, parse, find_imports, and update_globals. See their docstrings for details.

By default, the filename for SyntaxErrors is <string>. To change this, pass in a filename via the filename kwarg.

Reusing compiled code objects

import_expression.eval/exec/compile should not be passed strings in a tight loop.
Doing so will recompile the string every time. Instead, you should pre-compile the string to a code object and pass that to import_expression.eval / import_expression.exec. For example, instead of this:

for line in sys.stdin:
	print(import_expression.eval('foo!.bar(l)', dict(l=line))

Prefer this:

code = import_expression.compile('foo!.bar(l)', mode='eval')
for line in sys.stdin:
	print(import_expression.eval(code, dict(l=line)))

Custom encoding

# encoding: import_expression

This file, when run, will print True/False. For maximum laziness you can also do #coding:ie.

REPL usage

Run import-expression for an import expression enabled REPL.
Run import-expression -a for a REPL that supports both import expressions and top level await (3.8+).

See import-expression --help for more details.

Running a file

Run import-expression <>.

File rewriter

Run import-expression-rewrite <> to rewrite a file containing import expressions to standard Python.
Add the -i flag to rewrite in-place.

Limitations / Known Issues

  • Due to the hell that is f-string parsing, and because ! is already an operator inside f-strings, import expressions inside f-strings will likely never be supported.
  • Due to python limitations, results of import_expression.exec will have no effect on the caller's globals or locals without an explicit globals argument.
  • Unlike real operators, spaces before and after the import expression operator (such as x ! .y) are not supported.


Copyright © 2018–2019 Io Mintz <>. All Rights Reserved.
Licensed under the MIT License. See the LICENSE file for details.