Skip to content

Commit

Permalink
regmap: Delay importing shells to reduce load time
Browse files Browse the repository at this point in the history
Importing the shells takes on average 220ms, which makes starting up a regmap
based command line tool slower than necessary when they aren't being used. This
change delays the import of the shell packages until invoked by a command line
request. The loading time for importing regmap_esnet_smartnic.regio decreases
from on average 310ms to 90ms.

Import time was measured using:
- python3 -X importtime -c 'import regmap_esnet_smartnic.regio'
- python3 -X importtime -c 'import IPython'

The importtime directive displays it's measurements in microseconds, with the
first column being the time for a module, excluding nested imports, and the
second being the cumulative time, including nested imports.

https://docs.python.org/3/using/cmdline.html?highlight=importtime#cmdoption-X
  • Loading branch information
jranger-es-net committed Jan 20, 2024
1 parent 7273ece commit 1a35d98
Showing 1 changed file with 33 additions and 50 deletions.
83 changes: 33 additions & 50 deletions src/regio/regmap/proxy/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,7 @@
import pathlib
import sys

try:
import click, click.shell_completion
import jedi
except ImportError:
click = None

try:
import IPython
except ImportError:
IPython = None

_ptipython = None
try:
import ptpython as _ptpython
except ImportError:
_ptpython = None
else:
if IPython is not None:
import ptpython.ipython as _ptipython
import click, click.shell_completion

from . import proxy, variable

Expand Down Expand Up @@ -214,7 +196,9 @@ def python_shell(self):
shell.interact()

def ipython_shell(self):
if IPython is None:
try:
import IPython
except ImportError:
raise NotImplementedError('Missing IPython module.')

# Create the shell or re-use the previously cached one. This allows maintaining state
Expand All @@ -230,15 +214,17 @@ def ipython_shell(self):
shell(local_ns=self._namespace, module=self._mod)

def ptpython_shell(self):
if _ptpython is None:
try:
import ptpython
except ImportError:
raise NotImplementedError('Missing ptpython module.')

# Create the shell or re-use the previously cached one. This allows maintaining state
# between invocations.
try:
shell = self._ptpython_shell
except AttributeError:
shell = _ptpython.repl.PythonRepl(
shell = ptpython.repl.PythonRepl(
get_globals=lambda: self._namespace,
get_locals=lambda: self._namespace)
self._ptpython_shell = shell
Expand All @@ -248,13 +234,15 @@ def ptpython_shell(self):
shell.run()

def ptipython_shell(self):
if _ptipython is None:
try:
import ptpython.ipython as ptipython
except ImportError:
raise NotImplementedError('Missing ptpython and/or IPython module(s).')

try:
shell = self._ptipython_shell
except AttributeError:
shell = _ptipython.InteractiveShellEmbed()
shell = ptipython.InteractiveShellEmbed()
self._ptipython_shell = shell

# Run the interactive shell.
Expand All @@ -265,9 +253,6 @@ def ptipython_shell(self):
class ClickEnvironment(Environment):
def __init__(self, parent, *pargs, **kargs):
super().__init__(*pargs, **kargs)

if click is None:
raise NotImplementedError('Missing click module.')
self._add_click_commands(parent)

def _eval_expr_complete(self, ctx, param, incomplete):
Expand All @@ -280,6 +265,7 @@ def _eval_expr_complete(self, ctx, param, incomplete):
kargs['test_io'] = 'zero'
main.invoke(main.command, **kargs)

import jedi
interp = jedi.Interpreter(incomplete, [self._namespace])
return [
click.shell_completion.CompletionItem(incomplete + compl.complete)
Expand Down Expand Up @@ -328,29 +314,26 @@ def python():
'''
self.python_shell()

if IPython is not None:
@shell.command()
def ipython():
'''
Enter the IPython shell.
'''
self.ipython_shell()

if _ptpython is not None:
@shell.command()
def ptpython():
'''
Enter the Prompt Toolkit shell.
'''
self.ptpython_shell()

if _ptipython is not None:
@shell.command()
def ptipython():
'''
Enter the Prompt Toolkit IPython shell.
'''
self.ptipython_shell()
@shell.command()
def ipython():
'''
Enter the IPython shell.
'''
self.ipython_shell()

@shell.command()
def ptpython():
'''
Enter the Prompt Toolkit shell.
'''
self.ptpython_shell()

@shell.command()
def ptipython():
'''
Enter the Prompt Toolkit IPython shell.
'''
self.ptipython_shell()

@parent.group()
def completions():
Expand Down

0 comments on commit 1a35d98

Please sign in to comment.