Skip to content

Conversation

@kotfu
Copy link
Member

@kotfu kotfu commented May 24, 2018

In an attempt to resolve #369, this PR:

  • puts a robust set of default imports in cmd2/__init__.py so those modules and functions are available when you import cmd2. In between version 0.8.5 and where master is now, we removed those imports to speed up the wall time for import cmd2, which also broke backwards compatibility
  • defers many imports of infrequently used libraries until we actually need them. This reduces the number of modules that are imported when you do import cmd2.
  • reduces by 10% the lines of code in cmd2.py so there is less code to parse every time you import cmd2
  • adds a note to CHANGELOG.md about the still unresolved The default imports in __init__ causes significant lag #369.

#369 is still not resolved, and we continue to work that issue, but will go ahead with 0.9.0 without resolving.

@kotfu kotfu requested a review from tleonhardt as a code owner May 24, 2018 04:38
@codecov
Copy link

codecov bot commented May 24, 2018

Codecov Report

Merging #413 into master will increase coverage by <.01%.
The diff coverage is 94.3%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #413      +/-   ##
=========================================
+ Coverage    89.2%   89.2%   +<.01%     
=========================================
  Files           8       9       +1     
  Lines        2594    2613      +19     
=========================================
+ Hits         2314    2331      +17     
- Misses        280     282       +2
Impacted Files Coverage Δ
cmd2/utils.py 98.52% <100%> (+4.41%) ⬆️
cmd2/transcript.py 91.22% <91.22%> (ø)
cmd2/cmd2.py 90.61% <96.42%> (-0.37%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5d64ebe...190fecb. Read the comment docs.

@kotfu kotfu self-assigned this May 24, 2018
@kotfu kotfu added this to the 0.9.0 milestone May 24, 2018
tleonhardt
tleonhardt previously approved these changes May 24, 2018
Copy link
Member

@tleonhardt tleonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider my few substantive comments. But everything looks good to me.

setattr(func, HELP_CATEGORY, category)


def _which(editor: str) -> Optional[str]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for moving this to utils.py, that is a more appropriate location for it

method. Default passes a string of whatever the user typed.
With this decorator, the decorated method will receive a list
of arguments parsed from user input using shlex.split()."""
import functools
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about how Python importing works ...

If we call this function 1000 times, it just gets imported once right? i.e. there isn't a performance penalty here is there?

Also, if we then call the function below and hit the same import on line 184 below after calling this function, it doesn't import it again there right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. https://docs.python.org/3/reference/import.html#the-module-cache describes how the import machinery first looks to see if the module is already imported, if so, it just uses the module already in the cache. Think of "import functools" as "import functools if it hasn't already been imported"

cmd2/cmd2.py Outdated

Git repository on GitHub at https://github.com/python-cmd2/cmd2
"""
# many imports are lazy-loaded when they are needed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe briefly comment on why this is being done?

cmd2/cmd2.py Outdated
import sys
import tempfile
import traceback
from typing import Callable, List, Optional, Union, Tuple
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Optional is now an unused import

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup.

setattr(self.obj, attrib, getattr(self, attrib))


class OutputTrap(object):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for moving all of the transcript testing stuff to its own file. cmd2.py is now feeling a little more focused

@@ -0,0 +1,213 @@
#
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a brief comment regarding the overall purpose of the code in this file?


from cmd2 import cmd2

import cmd2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This general approach of importing looks nice and clean to me

def do_aprint(self, statement):
"""Print the argument string this basic command is called with."""
self.poutput('aprint was called with argument: {!r}'.format(arg))
self.poutput('aprint was called with argument: {!r}'.format(statement))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice little improvement

@@ -0,0 +1,99 @@
# Speedup Import
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the long run I don't think we want this file at the top level. But it should be fine for now (until we are happy we have the issue resolved).

return current

def which(editor: str) -> Optional[str]:
import subprocess
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a docstring comment? I know the original probably didn't have one, but now that it is separated from its immediate use it might be helpful.

@kotfu kotfu merged commit cad21a6 into master May 25, 2018
@kotfu kotfu deleted the speedup_import branch May 25, 2018 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The default imports in __init__ causes significant lag

3 participants