documentation

This commit is contained in:
adam j hartz 2016-03-27 06:39:24 -04:00
parent 8eb3d92f60
commit a2285fd916
5 changed files with 69 additions and 7 deletions

View file

@ -30,6 +30,10 @@ Current Developments
* Added a new ``which`` alias that supports both regular ``which`` and also searches
through xonsh aliases
* Added support for prompt toolkit v1.0.0.
* Added ``$XONSH_CACHE_SCRIPTS`` and ``$XONSH_CACHE_EVERYTHING`` environment
variables to control caching of scripts and interactive commands. These can
also be controlled by command line options ``--no-script-cache`` and
``--cache-everything`` when starting xonsh.
**Changed:**
@ -38,7 +42,8 @@ Current Developments
Also avoids loading aliases and environments from foreign shells, as well as
loading bash completions.
* rc files are now compiled and cached, to avoid re-parsing when they haven't
changed.
changed. Scripts are also compiled and cached, and there is the option to
cache interactive commands.
* Left and Right arrows in the ``prompt_toolkit`` shell now wrap in multiline
environments
* Regexpath matching with backticks, now returns an empty list in python mode.

11
docs/api/codecache.rst Normal file
View file

@ -0,0 +1,11 @@
.. _xonsh_codecache:
*********************************************************
Compiling and Caching of Xonsh Code (``xonsh.codecache``)
*********************************************************
.. automodule:: xonsh.codecache
:members:
:undoc-members:
:inherited-members:

View file

@ -59,6 +59,7 @@ For those of you who want the gritty details.
jupyter_kernel
wizard
xonfig
codecache
vox

View file

@ -29,16 +29,24 @@ def _make_if_not_exists(dirname):
os.makedirs(dirname)
def should_use_cache(execer, mode):
"""
Return ``True`` if caching has been enabled for this mode (through command
line flags or environment variables)
"""
if mode == 'exec':
return ((execer.scriptcache or
execer.cacheall) and
(builtins.__xonsh_env__['XONSH_CACHE_SCRIPTS'] or
builtins.__xonsh_env__['XONSH_CACHE_EVERYTHING']))
else:
return (execer.cacheall or builtins.__xonsh_env__['XONSH_CACHE_EVERYTHING'])
return (execer.cacheall or
builtins.__xonsh_env__['XONSH_CACHE_EVERYTHING'])
def run_compiled_code(code, glb, loc, mode):
"""
Helper to run code in a given mode and context
"""
if mode in {'exec', 'single'}:
func = exec
else:
@ -47,6 +55,15 @@ def run_compiled_code(code, glb, loc, mode):
def get_cache_filename(fname, code=True):
"""
Return the filename of the cache for the given filename.
Cache filenames are similar to those used by the Mercurial DVCS for its
internal store.
The ``code`` switch should be true if we should use the code store rather
than the script store.
"""
datadir = builtins.__xonsh_env__['XONSH_DATA_DIR']
cachedir = os.path.join(datadir, 'xonsh_code_cache' if code else 'xonsh_script_cache')
cachefname = os.path.join(cachedir, *_cache_renamer(fname))
@ -54,13 +71,20 @@ def get_cache_filename(fname, code=True):
def update_cache(ccode, cache_file_name):
"""
Update the cache at ``cache_file_name`` to contain the compiled code
represented by ``ccode``.
"""
if cache_file_name is not None:
_make_if_not_exists(os.path.dirname(cache_file_name))
with open(cache_file_name, 'wb') as cfile:
marshal.dump(ccode, cfile)
def compile_code(filename, code, execer, glb, loc, mode, cache_file_name):
def compile_code(filename, code, execer, glb, loc, mode):
"""
Wrapper for ``execer.compile`` to compile the given code
"""
try:
if not code.endswith('\n'):
code += '\n'
@ -75,6 +99,13 @@ def compile_code(filename, code, execer, glb, loc, mode, cache_file_name):
def script_cache_check(filename, cachefname):
"""
Check whether the script cache for a particular file is valid.
Returns a tuple containing: a boolean representing whether the cached code
should be used, and the cached code (or ``None`` if the cache should not be
used).
"""
ccode = None
run_cached = False
if os.path.isfile(cachefname):
@ -98,13 +129,15 @@ def run_script_with_cache(filename, execer, glb=None, loc=None, mode='exec'):
if not run_cached:
with open(filename, 'r') as f:
code = f.read()
ccode = compile_code(filename, code, execer,
glb, loc, mode, cachefname)
ccode = compile_code(filename, code, execer, glb, loc, mode)
update_cache(ccode, cachefname)
run_compiled_code(ccode, glb, loc, mode)
def code_cache_name(code):
"""
Return an appropriate spoofed filename for the given code.
"""
if isinstance(code, str):
_code = code.encode()
else:
@ -113,6 +146,13 @@ def code_cache_name(code):
def code_cache_check(cachefname):
"""
Check whether the code cache for a particular piece of code is valid.
Returns a tuple containing: a boolean representing whether the cached code
should be used, and the cached code (or ``None`` if the cache should not be
used).
"""
ccode = None
run_cached = False
if os.path.isfile(cachefname):
@ -134,7 +174,6 @@ def run_code_with_cache(code, execer, glb=None, loc=None, mode='exec'):
if use_cache:
run_cached, ccode = code_cache_check(cachefname)
if not run_cached:
ccode = compile_code(filename, code, execer,
glb, loc, mode, cachefname)
ccode = compile_code(filename, code, execer, glb, loc, mode)
update_cache(ccode, cachefname)
run_compiled_code(ccode, glb, loc, mode)

View file

@ -428,6 +428,12 @@ DEFAULT_DOCS = {
'control file if there is a naming collision.', default=(
"On Linux & Mac OSX: ('/etc/xonshrc', '~/.xonshrc')\n"
"On Windows: ('%ALLUSERSPROFILE%\\xonsh\\xonshrc', '~/.xonshrc')")),
'XONSH_CACHE_SCRIPTS': VarDocs(
'Controls whether the code for scripts run from xonsh will be cached'
' (``True``) or re-compiled each time (``False``).'),
'XONSH_CACHE_EVERYTHING': VarDocs(
'Controls whether all code (including code enetered at the interactive'
' prompt) will be cached.'),
'XONSH_COLOR_STYLE': VarDocs(
'Sets the color style for xonsh colors. This is a style name, not '
'a color map.'),