added some laziness to commands cache

This commit is contained in:
Anthony Scopatz 2016-06-07 22:12:02 -04:00
parent 92ef5ba6e1
commit 101f41511c
3 changed files with 47 additions and 20 deletions

View file

@ -15,7 +15,7 @@ from xonsh.tools import (
escape_windows_cmd_string, is_bool, to_bool, bool_to_str,
is_bool_or_int, to_bool_or_int, bool_or_int_to_str,
ensure_int_or_slice, is_float, is_string, is_callable,
is_string_or_callable, check_for_partial_string,
is_string_or_callable, check_for_partial_string, CommandsCache,
is_dynamic_cwd_width, to_dynamic_cwd_tuple, dynamic_cwd_tuple_to_str,
argvquote, executables_in, find_next_break, expand_case_matching)
@ -649,5 +649,13 @@ def test_expand_case_matching():
obs = expand_case_matching(inp)
yield assert_equal, exp, obs
def test_commands_cache_lazy():
cc = CommandsCache()
yield assert_false, cc.lazyin('xonsh')
yield assert_equal, 0, len(list(cc.lazyiter()))
yield assert_equal, 0, cc.lazylen()
if __name__ == '__main__':
nose.runmodule()

View file

@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
"""Environment for the xonsh shell."""
import os
import time
import json
import locale
import builtins
from contextlib import contextmanager
from functools import wraps
from itertools import chain
import json
import locale
import os
from pprint import pformat
import re
import socket
@ -769,14 +770,11 @@ def _yield_executables(directory, name):
def locate_binary(name):
if os.path.isfile(name) and name != os.path.basename(name):
return name
directories = builtins.__xonsh_env__.get('PATH')
# Windows users expect t obe able to execute files in the same directory
# Windows users expect to be able to execute files in the same directory
# without `./`
if ON_WINDOWS:
directories = [_get_cwd()] + directories
try:
return next(chain.from_iterable(_yield_executables(directory, name) for
directory in directories if os.path.isdir(directory)))
@ -790,10 +788,8 @@ def _get_parent_dir_for(path, dir_name):
while path != previous_path:
if os.path.isdir(os.path.join(path, dir_name)):
return path
previous_path = path
path, _ = os.path.split(path)
return False
@ -842,28 +838,26 @@ def ensure_hg(func):
return wrapper
@ensure_git
#@ensure_git
def get_git_branch(cwd=None):
branch = None
if not ON_WINDOWS:
prompt_scripts = ['/usr/lib/git-core/git-sh-prompt',
'/usr/local/etc/bash_completion.d/git-prompt.sh']
for script in prompt_scripts:
# note that this is about 10x faster than bash -i "__git_ps1"
_input = ('source {}; __git_ps1 "${{1:-%s}}"'.format(script))
try:
branch = subprocess.check_output(['bash', ],
branch = subprocess.check_output(['bash'],
cwd=cwd,
input=_input,
stderr=subprocess.PIPE,
universal_newlines=True)
if len(branch) == 0:
branch = None
break
except (subprocess.CalledProcessError, FileNotFoundError):
continue
# fall back to using the git binary if the above failed
if branch is None:
try:
@ -883,7 +877,6 @@ def get_git_branch(cwd=None):
branch = s
except (subprocess.CalledProcessError, FileNotFoundError):
pass
return branch
@ -905,7 +898,7 @@ def call_hg_command(command, cwd):
return s
@ensure_hg
#@ensure_hg
def get_hg_branch(cwd=None, root=None):
branch = None
active_bookmark = None
@ -937,10 +930,8 @@ def current_branch(pad=True):
and should be extended in the future.
"""
branch = get_git_branch() or get_hg_branch()
if pad and branch is not None:
branch = ' ' + branch
return branch or ''
@ -966,7 +957,7 @@ def git_dirty_working_directory(cwd=None, include_untracked=False):
return False
@ensure_hg
#@ensure_hg
def hg_dirty_working_directory(cwd=None, root=None):
id = call_hg_command(['identify', '--id'], cwd)
if id is None:
@ -1140,6 +1131,7 @@ def format_prompt(template=DEFAULT_PROMPT, formatter_dict=None):
for name in included_names:
if name is None:
continue
#t0 = time.time()
if name.startswith('$'):
v = builtins.__xonsh_env__[name[1:]]
else:
@ -1147,6 +1139,8 @@ def format_prompt(template=DEFAULT_PROMPT, formatter_dict=None):
val = v() if callable(v) else v
val = '' if val is None else val
fmt[name] = val
#t1 = time.time()
#print(name, t1 - t0)
return template.format(**fmt)
@ -1178,10 +1172,13 @@ def _partial_format_prompt_main(template=DEFAULT_PROMPT, formatter_dict=None):
toks.append(v)
continue
elif field in fmtter:
t0 = time.time()
v = fmtter[field]
val = v() if callable(v) else v
val = '' if val is None else val
toks.append(val)
t1 = time.time()
print(field, t1 - t0)
else:
toks.append(bopen)
toks.append(field)

View file

@ -1227,6 +1227,28 @@ class CommandsCache(Set):
self._cmds_cache = frozenset(allcmds)
return self._cmds_cache
def lazyin(self, value):
"""Checks if the value is in the current cache without the potential to
update the cache. It just says whether the value is known *now*. This
may not reflect precisely what is on the $PATH.
"""
return value in self._cmds_cache
def lazyiter(self):
"""Returns an iterator over the current cache contents without the
potential to update the cache. This may not reflect what is on the
$PATH.
"""
return iter(self._cmds_cache)
def lazylen(self):
"""Returns the length of the current cache contents without the
potential to update the cache. This may not reflect precicesly
what is on the $PATH.
"""
return len(self._cmds_cache)
WINDOWS_DRIVE_MATCHER = re.compile(r'^\w:')