fixed conflict

This commit is contained in:
Anthony Scopatz 2016-06-25 12:34:55 -04:00
commit e97d02db16
69 changed files with 1598 additions and 1969 deletions

View file

@ -1,9 +1,9 @@
version: 0.3.4.{build}
version: 0.4.1.{build}
os: Windows Server 2012 R2
install:
- C:\Python35\Scripts\pip install ply pyreadline nose pygments prompt_toolkit
- C:\Python35\Scripts\pip install ply pyreadline pytest pygments prompt_toolkit
build_script:
- C:\Python35\python setup.py install
test_script:
- C:\Python35\Scripts\nosetests -q
- C:\Python35\Scripts\py.test

3
.gitignore vendored
View file

@ -38,3 +38,6 @@ include/
# Editor project files
*.komodo*
.cache
.coverage

View file

@ -6,6 +6,6 @@ python:
install:
- pip install -r requirements-tests.txt
script:
- nosetests -q --with-coverage --cover-package=xonsh
- coverage run --source xonsh -m py.test -q
after_success:
- codecov

View file

@ -4,6 +4,185 @@ Xonsh Change Log
.. current developments
v0.4.1
====================
**Fixed:**
* ``setup.py`` will only amalgamate source files if ``amalgamate.py`` is
available. This fixes issues with installing from pip.
v0.4.0
====================
**Added:**
* A new class, ``xonsh.tools.EnvPath`` has been added. This class implements a
``MutableSequence`` object and overrides the ``__getitem__`` method so that
when its entries are requested (either explicitly or implicitly), variable
and user expansion is performed, and relative paths are resolved.
``EnvPath`` accepts objects (or lists of objects) of ``str``, ``bytes`` or
``pathlib.Path`` types.
* New amalgamate tool collapses modules inside of a package into a single
``__amalgam__.py`` module. This tool glues together all of the code from the
modules in a package, finds and removes intra-package imports, makes all
non-package imports lazy, and adds hooks into the ``__init__.py``.
This helps makes initial imports of modules fast and decreases startup time.
Packages and sub-packages must be amalgamated separately.
* New lazy and self-destructive module ``xonsh.lazyasd`` adds a suite of
classes for delayed creation of objects.
- A ``LazyObject`` won't be created until it has an attribute accessed.
- A ``LazyDict`` will load each value only when a key is accessed.
- A ``LazyBool`` will only be created when ``__bool__()`` is called.
Additionally, when fully loaded, the above objects will replace themselves
by name in the context that they were handed, thus derefenceing themselves.
This is useful for global variables that may be expensive to create,
should only be created once, and may not be used in any particular session.
* New ``xon.sh`` script added for launching xonsh from a sh environment.
This should be used if the normal ``xonsh`` script does not work for
some reason.
* Normal globbing is now available in Python mode via ``g````
* Backticks were expanded to allow searching using arbitrary functions, via
``@<func>````
* ``xonsh.platform`` now has a new ``PATH_DEFAULT`` variable.
* Tab completers can now raise ``StopIteration`` to prevent consideration of
remaining completers.
* Added tab completer for the ``completer`` alias.
* New ``Block`` and ``Functor`` context managers are now available as
part of the ``xonsh.contexts`` module.
* ``Block`` provides support for turning a context body into a non-executing
list of string lines. This is implmement via a syntax tree transformation.
This is useful for creating remote execution tools that seek to prevent
local execution.
* ``Functor`` is a subclass of the ``Block`` context manager that turns the
block into a callable object. The function object is available via the
``func()`` attribute. However, the ``Functor`` instance is itself callable
and will dispatch to ``func()``.
* New ``$VC_BRANCH_TIMEOUT`` environment variable is the time (in seconds)
of how long to spend attempting each individual version control branch
information command during ``$PROMPT`` formatting. This allows for faster
prompt resolution and faster startup times.
* New lazy methods added to CommandsCache allowing for testing and inspection
without the possibility of recomputing the cache.
* ``!(command)`` is now usefully iterable, yielding lines of stdout
* Added XonshCalledProcessError, which includes the relevant CompletedCommand.
Also handles differences between Py3.4 and 3.5 in CalledProcessError
* Tab completion of paths now includes zsh-style path expansion (subsequence
matching), toggleable with ``$SUBSEQUENCE_PATH_COMPLETION``
* Tab completion of paths now includes "fuzzy" matches that are accurate to
within a few characters, toggleable with ``$FUZZY_PATH_COMPLETION``
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* Arguments '+' and '-' for the ``fg`` command (job control)
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* ``!(command)`` is now usefully iterable, yielding lines of stdout
* Added XonshCalledProcessError, which includes the relevant CompletedCommand.
Also handles differences between Py3.4 and 3.5 in CalledProcessError
* XonshError and XonshCalledProcessError are now in builtins:
- ``history session``
- ``history xonsh``
- ``history all``
- ``history zsh``
- ``history bash``
- ``__xonsh_history__.show()``
* New ``pathsep_to_set()`` and ``set_to_pathsep()`` functions convert to/from
``os.pathsep`` separated strings to a set of strings.
**Changed:**
* Changed testing framework from nose to pytest
* All ``PATH``-like environment variables are now stored in an ``EnvPath``
object, so that non-absolute paths or paths containing environment variables
can be resolved properly.
* In ``VI_MODE``, the ``v`` key will enter character selection mode, not open
the editor. ``Ctrl-X Ctrl-E`` will still open an editor in any mode
* ``$XONSH_DEBUG`` will now supress amalgamted imports. This usually needs to be
set in the calling environment or prior to *any* xonsh imports.
* Restuctured ``xonsh.platform`` to be fully lazy.
* Restuctured ``xonsh.ansi_colors`` to be fully lazy.
* Ensured the ``pygments`` and ``xonsh.pyghooks`` are not imported until
actually needed.
* Yacc parser is now loaded in a background thread.
* Cleaned up argument parsing in ``xonsh.main.premain`` by removing the
``undo_args`` hack.
* Now complains on invalid arguments.
* ``Env`` now guarantees that the ``$PATH`` is available and mutable when
initialized.
* On Windows the ``PROMPT`` environment variable is reset to `$P$G` before
sourcing ``*.bat`` files.
* On Windows the ``PROMPT`` environment variable is reset to `$P$G` before starting
subprocesses. This prevents the unformatted xonsh ``PROMPT`` tempalte from showing up
when running batch files with ``ECHO ON```
* ``@()`` now passes through functions as well as strings, which allows for the
use of anonymous aliases and aliases not explicitly added to the ``aliases``
mapping.
* Functions in ``Execer`` now take ``transform`` kwarg instead of
``wrap_subproc``.
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* XonshError and XonshCalledProcessError are now in builtins
* ``__repr__`` on the environment only shows a short representation of the
object instead of printing the whole environment dictionary
* More informative prompt when configuring foreign shells in the wizard.
* ``CommandsCache`` is now a mapping from command names to a tuple of
(executable locations, has alias flags). This enables faster lookup times.
* ``locate_bin()`` now uses the ``CommandsCache``, rather than scanning the
``$PATH`` itself.
* ``$PATHEXT`` is now a set, rather than a list.
* Ignore case and leading a quotes when sorting completions
**Removed:**
* The ``'console_scripts'`` option to setuptools has been removed. It was found
to cause slowdowns of over 150 ms on every startup.
* Bash is no longer loaded by default as a foreign shell for initial
configuration. This was done to increase stock startup times. This
behaviour can be recovered by adding ``{"shell": "bash"}`` to your
``"foreign_shells"`` in your config.json file. For more details,
see http://xon.sh/xonshconfig.html#foreign-shells
* ``ensure_git()`` and ``ensure_hg()`` decorators removed.
* ``call_hg_command()`` function removed.
**Fixed:**
* Issue where ``xonsh`` did not expand user and environment variables in
``$PATH``, forcing the user to add absolute paths.
* Fixed a problem with aliases not always beeing found.
* Fixed issue where input was directed to the last process in a pipeline,
rather than the first.
* Bug where xonfig wizard can't find ENV docs
* Fixed ``xonsh.environ.locate_binary()`` to handle PATH variable are given as a tuple.
* Fixed missing completions for ``cd`` and ```rmdir`` when directories had spaces
in their names.
* Bug preventing `xonsh` executable being installed on macOS.
* Strip leading space in commands passed using the "-c" switch
* Fixed xonfig wizard failing on Windows due to colon in created filename.
* Ensured that the prompt_toolkit shell functions, even without a ``completer``
attribute.
* Fixed crash resulting from malformed ``$PROMPT`` or ``$TITLE``.
* xonsh no longer backgrounds itself after every command on Cygwin.
* Fixed an issue about ``os.killpg()`` on Cygwin which caused xonsh to crash
occasionally
* Fix crash on startup when Bash Windows Subsystem for Linux is on the Path.
* Fixed issue with setting and signaling process groups on Linux when the first
process is a function alias and has no pid.
* Fixed ``_list_completers`` such that it does not throw a ValueError if no completer is registered.
* Fixed ``_list_completers`` such that it does not throw an AttributeError if a completer has no docstring.
* Bug that caused command line argument ``--config-path`` to be ignored.
* Bug that caused xonsh to break on startup when prompt-toolkit < 1.0.0.
v0.3.4
====================

View file

@ -84,7 +84,7 @@ is open to interpretation.
recommendations from PEP8 are not required here.
* All Python code should be compliant with Python 3.4+. At some
unforeseen date in the future, Python 2.7 support *may* be supported.
* Tests should be written with nose using a procedural style. Do not use
* Tests should be written with pytest using a procedural style. Do not use
unittest directly or write tests in an object-oriented style.
* Test generators make more dots and the dots must flow!
@ -165,12 +165,11 @@ Prep your environment for running the tests::
Running the Tests - Basic
----------------------------------
Run all the tests using Nose::
Run all the tests using pytest::
$ nosetests -q
$ py.test -q
Use "-q" to keep nose from outputing a dot for every test. There are A LOT of tests
and you will waste time waiting for all the dots to get pushed through stdout.
Use "-q" to keep pytest from outputting a bunch of info for every test.
----------------------------------
Running the Tests - Advanced
@ -178,35 +177,16 @@ Running the Tests - Advanced
To perform all unit tests::
$ scripts/run_tests.xsh all
If you're working on a change and haven't yet committed it you can run the
tests associated with the change. This does not require that the change
include the unit test module. This will execute any unit tests that are
part of the change as well as the unit tests for xonsh source modules in
the change::
$ scripts/run_tests.xsh
$ py.test
If you want to run specific tests you can specify the test names to
execute. For example to run test_aliases::
$ scripts/run_tests.xsh aliases
The test name can be the bare test name (e.g., ``aliases``), include
the ``test_`` prefix and ``.py`` suffix without the directory
(e.g., ``test_aliases.py``), or the complete relative path (e.g.,
``tests/test_aliases.py``). For example:
$ py.test test_aliases.py
Note that you can pass multiple test names in the above examples::
$ scripts/run_tests.xsh aliases environ
As before, if you want to test the xonsh code that is installed on your
system first cd into the `tests` directory then run the tests::
$ cd tests
$ env XONSHRC='' nosetests test_aliases.py test_environ.py
$ py.test test_aliases.py test_environ.py
Happy testing!

View file

@ -0,0 +1,10 @@
.. _xonsh_commands_cache:
******************************************************
Commands Cache (``xonsh.commands_cache``)
******************************************************
.. automodule:: xonsh.commands_cache
:members:
:undoc-members:
:inherited-members:

View file

@ -4,7 +4,7 @@
File System Path Completer (``xonsh.completers.path``)
**********************************************************
.. automodule:: xonsh.completers.base
.. automodule:: xonsh.completers.path
:members:
:undoc-members:
:inherited-members:

View file

@ -55,6 +55,7 @@ For those of you who want the gritty details.
teepty
openpy
foreign_shells
commands_cache
tracer
main
pyghooks

View file

@ -1,68 +0,0 @@
**Added:**
* Tab completers can now raise ``StopIteration`` to prevent consideration of
remaining completers.
* Added tab completer for the ``completer`` alias.
* New ``Block`` and ``Functor`` context managers are now available as
part of the ``xonsh.contexts`` module.
* ``Block`` provides support for turning a context body into a non-executing
list of string lines. This is implmement via a syntax tree transformation.
This is useful for creating remote execution tools that seek to prevent
local execution.
* ``Functor`` is a subclass of the ``Block`` context manager that turns the
block into a callable object. The function object is available via the
``func()`` attribute. However, the ``Functor`` instance is itself callable
and will dispatch to ``func()``.
* New ``$VC_BRANCH_TIMEOUT`` environment variable is the time (in seconds)
of how long to spend attempting each individual version control branch
information command during ``$PROMPT`` formatting. This allows for faster
prompt resolution and faster startup times.
* New lazy methods added to CommandsCache allowing for testing and inspection
without the possibility of recomputing the cache.
* ``!(command)`` is now usefully iterable, yielding lines of stdout
* Added XonshCalledProcessError, which includes the relevant CompletedCommand.
Also handles differences between Py3.4 and 3.5 in CalledProcessError
* Tab completion of paths now includes zsh-style path expansion (subsequence
matching), toggleable with ``$SUBSEQUENCE_PATH_COMPLETION``
* Tab completion of paths now includes "fuzzy" matches that are accurate to
within a few characters, toggleable with ``$FUZZY_PATH_COMPLETION``
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* Arguments '+' and '-' for the ``fg`` command (job control)
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* ``!(command)`` is now usefully iterable, yielding lines of stdout
* Added XonshCalledProcessError, which includes the relevant CompletedCommand.
Also handles differences between Py3.4 and 3.5 in CalledProcessError
* XonshError and XonshCalledProcessError are now in builtins
**Changed:**
* Functions in ``Execer`` now take ``transform`` kwarg instead of
``wrap_subproc``.
* Provide ``$XONSH_SOURCE`` for scripts in the environment variables pointing to
the currently running script's path
* XonshError and XonshCalledProcessError are now in builtins
**Deprecated:** None
**Removed:**
* ``ensure_git()`` and ``ensure_hg()`` decorators removed.
* ``call_hg_command()`` function removed.
**Fixed:**
* Strip leading space in commands passed using the "-c" switch
* Fixed xonfig wizard failing on Windows due to colon in created filename.
* Ensured that the prompt_toolkit shell functions, even without a ``completer``
attribute.
* Fixed crash resulting from malformed ``$PROMPT`` or ``$TITLE``.
* xonsh no longer backgrounds itself after every command on Cygwin.
* Fixed an issue about ``os.killpg()`` on Cygwin which caused xonsh to crash
occasionally
* Fix crash on startup when Bash Windows Subsystem for Linux is on the Path.
**Security:** None

View file

@ -1,15 +0,0 @@
**Added:** None
**Changed:**
* ``@()`` now passes through functions as well as strings, which allows for the
use of anonymous aliases and aliases not explicitly added to the ``aliases``
mapping.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,15 +0,0 @@
**Added:**
* Normal globbing is now available in Python mode via ``g````
* Backticks were expanded to allow searching using arbitrary functions, via
``@<func>````
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,43 +0,0 @@
**Added:**
* New amalgamate tool collapses modules inside of a package into a single
``__amalgam__.py`` module. This tool glues together all of the code from the
modules in a package, finds and removes intra-package imports, makes all
non-package imports lazy, and adds hooks into the ``__init__.py``.
This helps makes initial imports of modules fast and decreases startup time.
Packages and sub-packages must be amalgamated separately.
* New lazy and self-destructive module ``xonsh.lazyasd`` adds a suite of
classes for delayed creation of objects.
- A ``LazyObject`` won't be created until it has an attribute accessed.
- A ``LazyDict`` will load each value only when a key is accessed.
- A ``LazyBool`` will only be created when ``__bool__()`` is called.
Additionally, when fully loaded, the above objects will replace themselves
by name in the context that they were handed, thus derefenceing themselves.
This is useful for global variables that may be expensive to create,
should only be created once, and may not be used in any particular session.
* New ``xon.sh`` script added for launching xonsh from a sh environment.
This should be used if the normal ``xonsh`` script does not work for
some reason.
**Changed:**
* ``$XONSH_DEBUG`` will now supress amalgamted imports. This usually needs to be
set in the calling environment or prior to *any* xonsh imports.
* Restuctured ``xonsh.platform`` to be fully lazy.
* Restuctured ``xonsh.ansi_colors`` to be fully lazy.
* Ensured the ``pygments`` and ``xonsh.pyghooks`` are not imported until
actually needed.
* Yacc parser is now loaded in a background thread.
**Deprecated:** None
**Removed:** None
* The ``'console_scripts'`` option to setuptools has been removed. It was found
to cause slowdowns of over 150 ms on every startup.
**Fixed:** None
**Security:** None

View file

@ -1,20 +0,0 @@
**Added:**
* New ``pathsep_to_set()`` and ``set_to_pathsep()`` functions convert to/from
``os.pathsep`` separated strings to a set of strings.
**Changed:**
* ``CommandsCache`` is now a mapping from command names to a tuple of
(executable locations, has alias flags). This enables faster lookup times.
* ``locate_bin()`` now uses the ``CommandsCache``, rather than scanning the
``$PATH`` itself.
* ``$PATHEXT`` is now a set, rather than a list.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:**
* Cleaned up argument parsing in ``xonsh.main.premain`` by removing the
``undo_args`` hack.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
* Fixed ``_list_completers`` such that it does not throw a ValueError if no completer is registered.
* Fixed ``_list_completers`` such that it does not throw an AttributeError if a completer has no docstring.
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
* Bug that caused command line argument ``--config-path`` to be ignored.
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Fixed a problem with aliases not always beeing found.
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Fixed issue where input was directed to the last process in a pipeline,
rather than the first.
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Bug where xonfig wizard can't find ENV docs
**Security:** None

View file

@ -1,18 +0,0 @@
**Added:**
- ``history session``
- ``history xonsh``
``history all``
- ``history zsh``
- ``history bash``
- ``__xonsh_history__.show()``
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
* Bug that caused xonsh to break on startup when prompt-toolkit < 1.0.0.
**Security:** None

View file

@ -1,25 +0,0 @@
**Added:**
* A new class, ``xonsh.tools.EnvPath`` has been added. This class implements a
``MutableSequence`` object and overrides the ``__getitem__`` method so that
when its entries are requested (either explicitly or implicitly), variable
and user expansion is performed, and relative paths are resolved.
``EnvPath`` accepts objects (or lists of objects) of ``str``, ``bytes`` or
``pathlib.Path`` types.
**Changed:**
* All ``PATH``-like environment variables are now stored in an ``EnvPath``
object, so that non-absolute paths or paths containing environment variables
can be resolved properly.
**Deprecated:** None
**Removed:** None
**Fixed:**
* Issue where ``xonsh`` did not expand user and environment variables in
``$PATH``, forcing the user to add absolute paths.
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Fixed ``xonsh.environ.locate_binary()`` to handle PATH variable are given as a tuple.
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Fixed issue with setting and signaling process groups on Linux when the first
process is a function alias and has no pid.
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:**
* Fixed missing completions for ``cd`` and ```rmdir`` when directories had spaces
in their names.
**Security:** None

View file

@ -1,15 +0,0 @@
**Added:** None
**Changed:**
* On Windows the ``PROMPT`` environment variable is reset to `$P$G` before starting
subprocesses. This prevents the unformatted xonsh ``PROMPT`` tempalte from showing up
when running batch files with ``ECHO ON```
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,22 +0,0 @@
**Added:**
* ``xonsh.platform`` now has a new ``PATH_DEFAULT`` variable.
**Changed:**
* ``Env`` now guarantees that the ``$PATH`` is available and mutable when
initialized.
**Deprecated:** None
**Removed:**
* Bash is no longer loaded by default as a foreign shell for initial
configuration. This was done to increase stock startup times. This
behaviour can be recovered by adding ``{"shell": "bash"}`` to your
``"foreign_shells"`` in your config.json file. For more details,
see http://xon.sh/xonshconfig.html#foreign-shells
**Fixed:** None
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:**
* ``__repr__`` on the environment only shows a short representation of the
object instead of printing the whole environment dictionary
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:**
* Ignore case and leading a quotes when sorting completions
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:**
* On Windows the ``PROMPT`` environment variable is reset to `$P$G` before
sourcing *.bat files.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,14 +0,0 @@
**Added:** None
**Changed:**
* In ``VI_MODE``, the ``v`` key will enter character selection mode, not open
the editor. ``Ctrl-X Ctrl-E`` will still open an editor in any mode
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:**
* More informative prompt when configuring foreign shells in the wizard.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,13 +0,0 @@
**Added:** None
**Changed:** None
**Deprecated:** None
**Removed:** None
**Fixed:** None
* Bug preventing `xonsh` executable being installed on macOS.
**Security:** None

View file

@ -1,5 +1,5 @@
ply
nose
pytest
prompt-toolkit
pygments
coverage

View file

@ -1,74 +0,0 @@
#!/usr/bin/env xonsh --no-rc
#
# Run all the nosetests or just the ones relevant for the edited files in the
# current uncommited git change or just the ones named on the command line.
# Your cwd must be the top of the project tree.
#
# Usage:
# run_tests.xsh [edited | all | list of test names]
#
# You can omit the "all" argument if you want all tests run.
#
import os.path
import sys
if not os.path.isdir('.git'):
print('No .git directory. The cwd must be the top of the project tree.',
file=sys.stderr)
sys.exit(1)
if len($ARGS) == 1:
# Run all tests.
# ensure lexer/parser table module is up to date
$[python3 -c 'import setup; setup.build_tables()']
$[env XONSHRC='' nosetests -q]
elif len($ARGS) == 2 and $ARG1 == 'all':
# Run all tests.
# ensure lexer/parser table module is up to date
$[python3 -c 'import setup; setup.build_tables()']
$[env XONSHRC='' nosetests -q]
elif len($ARGS) == 2 and $ARG1 == 'edited':
# Run just the tests for the files edited in the uncommited change.
tests = set()
for edited_fname in $(git status -s).split():
if not edited_fname.endswith('.py'):
continue
if edited_fname.startswith('xonsh/'):
test_fname = 'tests/test_' + edited_fname[len('xonsh/')]
if os.path.exists(test_fname):
tests.add(test_fname)
elif edited_fname.startswith('tests/'):
tests.add(edited_fname)
else:
print('Ignoring file because I cannot find a test for: {!r}.'.
format(edited_fname), file=sys.stderr)
if tests:
# ensure lexer/parser table module is up to date
$[python3 -c 'import setup; setup.build_tables()']
$[env XONSHRC='' nosetests -q -v @(sorted(tests))]
else:
print('Cannot find any tests in the pending changes.', file=sys.stderr)
else:
# Run the named tests.
tests = set()
for test_fname in $ARGS[1:]:
if not test_fname.startswith('tests/'):
if not test_fname.startswith('test_'):
test_fname = 'tests/test_' + test_fname
if not test_fname.endswith('.py'):
test_fname += '.py'
if os.path.exists(test_fname):
tests.add(test_fname)
else:
print('Cannot find test module {!r}; ignoring the argument.'.
format(test_fname), file=sys.stderr)
if tests:
# ensure lexer/parser table module is up to date
$[python3 -c 'import setup; setup.build_tables()']
$[env XONSHRC='' nosetests -q -v @(sorted(tests))]
else:
print('Cannot find any tests matching {}.'.format($ARGS[1:]),
file=sys.stderr)
sys.exit(1)

View file

@ -48,6 +48,16 @@ def clean_tables():
os.environ['XONSH_DEBUG'] = '1'
from xonsh import __version__ as XONSH_VERSION
def amalagamate_source():
"""Amalgamtes source files."""
try:
import amalgamate
except ImportError:
print('Could not import amalgamate, skipping.', file=sys.stderr)
return
amalgamate.main(['amalgamate', '--debug=XONSH_DEBUG', 'xonsh'])
def build_tables():
"""Build the lexer/parser modules."""
print('Building lexer and parser tables.')
@ -55,8 +65,7 @@ def build_tables():
from xonsh.parser import Parser
Parser(lexer_table='lexer_table', yacc_table='parser_table',
outputdir='xonsh')
import amalgamate
amalgamate.main(['amalgamate', '--debug=XONSH_DEBUG', 'xonsh'])
amalagamate_source()
sys.path.pop(0)

View file

@ -5,9 +5,7 @@ from __future__ import unicode_literals, print_function
import os
import tempfile
import nose
from nose.plugins.skip import SkipTest
from nose.tools import assert_equal
import pytest
import xonsh.built_ins as built_ins
from xonsh.aliases import Aliases
@ -29,34 +27,32 @@ ALIASES = Aliases({'o': ['omg', 'lala']},
RAW = ALIASES._raw
def test_imports():
assert_equal(RAW, {
expected = {
'o': ['omg', 'lala'],
'ls': ['ls', '- -'],
'color_ls': ['ls', '--color=true'],
'cd': cd,
'indirect_cd': ['cd', '..']
})
}
assert RAW == expected
def test_eval_normal():
with mock_xonsh_env({}):
assert_equal(ALIASES.get('o'), ['omg', 'lala'])
assert ALIASES.get('o') == ['omg', 'lala']
def test_eval_self_reference():
with mock_xonsh_env({}):
assert_equal(ALIASES.get('ls'), ['ls', '- -'])
assert ALIASES.get('ls') == ['ls', '- -']
def test_eval_recursive():
with mock_xonsh_env({}):
assert_equal(ALIASES.get('color_ls'), ['ls', '- -', '--color=true'])
assert ALIASES.get('color_ls') == ['ls', '- -', '--color=true']
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_eval_recursive_callable_partial():
if ON_WINDOWS:
raise SkipTest
built_ins.ENV = Env(HOME=os.path.expanduser('~'))
with mock_xonsh_env(built_ins.ENV):
assert_equal(ALIASES.get('indirect_cd')(['arg2', 'arg3']),
['..', 'arg2', 'arg3'])
assert ALIASES.get('indirect_cd')(['arg2', 'arg3']) == ['..', 'arg2', 'arg3']
class TestWhich:
# Tests for the _whichgen function which is the only thing we
@ -78,7 +74,7 @@ class TestWhich:
open(path, 'wb').write(b'')
os.chmod(path, 0o755)
def teardown(self):
def teardown_module(self):
for d in self.testdirs:
d.cleanup()
@ -138,7 +134,3 @@ class TestWhich:
return path1 == path2
else:
return os.path.samefile(path1, path2)
if __name__ == '__main__':
nose.runmodule()

View file

@ -1,6 +1,4 @@
"""Xonsh AST tests."""
from nose.tools import assert_equal
from xonsh import ast
from xonsh.ast import Tuple, Name, Store, min_line
@ -15,7 +13,7 @@ def test_gather_names_name():
node = Name(id='y', ctx=Store())
exp = {'y'}
obs = ast.gather_names(node)
assert_equal(exp, obs)
assert exp == obs
def test_gather_names_tuple():
@ -23,12 +21,11 @@ def test_gather_names_tuple():
Name(id='z', ctx=Store())])
exp = {'y', 'z'}
obs = ast.gather_names(node)
assert_equal(exp, obs)
assert exp == obs
def test_multilline_num():
code = ('x = 1\n'
'ls -l\n') # this second line wil be transformed
tree = check_parse(code)
lsnode = tree.body[1]
assert_equal(2, min_line(lsnode))
assert 2 == min_line(lsnode)

View file

@ -4,9 +4,7 @@ from __future__ import unicode_literals, print_function
import os
import re
import nose
from nose.plugins.skip import SkipTest
from nose.tools import assert_equal, assert_true, assert_not_in
import pytest
from xonsh import built_ins
from xonsh.built_ins import reglob, pathsearch, helper, superhelper, \
@ -21,11 +19,10 @@ from tools import mock_xonsh_env
def test_reglob_tests():
testfiles = reglob('test_.*')
for f in testfiles:
assert_true(f.startswith('test_'))
assert (f.startswith('test_'))
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_repath_backslash():
if ON_WINDOWS:
raise SkipTest
home = os.path.expanduser('~')
built_ins.ENV = Env(HOME=home)
with mock_xonsh_env(built_ins.ENV):
@ -33,48 +30,44 @@ def test_repath_backslash():
exp = {p for p in exp if re.match(r'\w\w.*', p)}
exp = {os.path.join(home, p) for p in exp}
obs = set(pathsearch(regexsearch, r'~/\w\w.*'))
assert_equal(exp, obs)
assert exp == obs
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_repath_home_itself():
if ON_WINDOWS:
raise SkipTest
exp = os.path.expanduser('~')
built_ins.ENV = Env(HOME=exp)
with mock_xonsh_env(built_ins.ENV):
obs = pathsearch(regexsearch, '~')
assert_equal(1, len(obs))
assert_equal(exp, obs[0])
assert 1 == len(obs)
assert exp == obs[0]
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_repath_home_contents():
if ON_WINDOWS:
raise SkipTest
home = os.path.expanduser('~')
built_ins.ENV = Env(HOME=home)
with mock_xonsh_env(built_ins.ENV):
exp = os.listdir(home)
exp = {os.path.join(home, p) for p in exp}
obs = set(pathsearch(regexsearch, '~/.*'))
assert_equal(exp, obs)
assert exp == obs
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_repath_home_var():
if ON_WINDOWS:
raise SkipTest
exp = os.path.expanduser('~')
built_ins.ENV = Env(HOME=exp)
with mock_xonsh_env(built_ins.ENV):
obs = pathsearch(regexsearch, '$HOME')
assert_equal(1, len(obs))
assert_equal(exp, obs[0])
assert 1 == len(obs)
assert exp == obs[0]
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_repath_home_var_brace():
if ON_WINDOWS:
raise SkipTest
exp = os.path.expanduser('~')
built_ins.ENV = Env(HOME=exp)
with mock_xonsh_env(built_ins.ENV):
obs = pathsearch(regexsearch, '${"HOME"}')
assert_equal(1, len(obs))
assert_equal(exp, obs[0])
assert 1 == len(obs)
assert exp == obs[0]
def test_helper_int():
with mock_xonsh_env({}):
@ -104,7 +97,7 @@ def test_ensure_list_of_strs():
cases = [(['yo'], 'yo'), (['yo'], ['yo']), (['42'], 42), (['42'], [42])]
for exp, inp in cases:
obs = ensure_list_of_strs(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_list_of_strs_or_callables():
f = lambda x: 20
@ -112,7 +105,4 @@ def test_list_of_strs_or_callables():
([f], f), ([f], [f])]
for exp, inp in cases:
obs = list_of_strs_or_callables(inp)
yield assert_equal, exp, obs
if __name__ == '__main__':
nose.runmodule()
assert exp == obs

View file

@ -1,8 +1,6 @@
"""Tests xonsh contexts."""
from nose.tools import assert_equal, assert_is, assert_is_not
from tools import (mock_xonsh_env, execer_setup, check_exec, check_eval,
check_parse, skip_if)
check_parse)
from xonsh.contexts import Block, Functor
@ -10,7 +8,7 @@ from xonsh.contexts import Block, Functor
# helpers
#
def setup():
def setup_module():
execer_setup()
@ -35,29 +33,29 @@ def block_checks_glb(name, glbs, body, obs=None):
block = glbs[name]
obs = obs or {}
for k, v in obs.items():
yield assert_equal, v, glbs[k]
assert v == glbs[k]
if isinstance(body, str):
body = body.splitlines()
yield assert_equal, body, block.lines
yield assert_is, glbs, block.glbs
yield assert_is, None, block.locs
assert body == block.lines
assert glbs is block.glbs
assert block.locs is None
def block_checks_func(name, glbs, body, obsg=None, obsl=None):
block = glbs[name]
obsg = obsg or {}
for k, v in obsg.items():
yield assert_equal, v, glbs[k]
assert v == glbs[k]
if isinstance(body, str):
body = body.splitlines()
yield assert_equal, body, block.lines
yield assert_is, glbs, block.glbs
assert body == block.lines
assert glbs is block.glbs
# local context tests
locs = block.locs
yield assert_is_not, None, locs
assert locs is not None
obsl = obsl or {}
for k, v in obsl.items():
yield assert_equal, v, locs[k]
assert v == locs[k]
#
@ -70,7 +68,7 @@ def test_block_noexec():
' x += 42\n')
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
assert_equal(1, glbs['x'])
assert 1 == glbs['x']
def test_block_oneline():
@ -78,7 +76,7 @@ def test_block_oneline():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body, {'x': 1})
block_checks_glb('b', glbs, body, {'x': 1})
def test_block_manylines():
@ -88,7 +86,7 @@ def test_block_manylines():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body, {'x': 1})
block_checks_glb('b', glbs, body, {'x': 1})
def test_block_leading_comment():
@ -98,7 +96,7 @@ def test_block_leading_comment():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
def test_block_trailing_comment():
@ -108,7 +106,7 @@ def test_block_trailing_comment():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
def test_block_trailing_line_continuation():
@ -117,7 +115,7 @@ def test_block_trailing_line_continuation():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body, {'x': 1})
block_checks_glb('b', glbs, body, {'x': 1})
def test_block_trailing_close_paren():
@ -126,7 +124,7 @@ def test_block_trailing_close_paren():
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body, {'x': 1})
block_checks_glb('b', glbs, body, {'x': 1})
def test_block_trailing_close_many():
@ -137,7 +135,7 @@ def test_block_trailing_close_many():
s = SIMPLE_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body)
block_checks_glb('b', glbs, body)
def test_block_trailing_triple_string():
@ -149,7 +147,7 @@ def test_block_trailing_triple_string():
s = SIMPLE_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('b', glbs, body)
block_checks_glb('b', glbs, body)
def test_block_func_oneline():
@ -157,7 +155,7 @@ def test_block_func_oneline():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_manylines():
@ -167,7 +165,7 @@ def test_block_func_manylines():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_leading_comment():
@ -177,7 +175,7 @@ def test_block_func_leading_comment():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, ' x += 42\n',
block_checks_func('rtn', glbs, ' x += 42\n',
FUNC_OBSG, FUNC_OBSL)
@ -188,7 +186,7 @@ def test_block_func_trailing_comment():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, ' x += 42\n',
block_checks_func('rtn', glbs, ' x += 42\n',
FUNC_OBSG, FUNC_OBSL)
@ -198,7 +196,7 @@ def test_blockfunc__trailing_line_continuation():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_close_paren():
@ -207,7 +205,7 @@ def test_block_func_trailing_close_paren():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_close_many():
@ -218,7 +216,7 @@ def test_block_func_trailing_close_many():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_triple_string():
@ -230,7 +228,7 @@ def test_block_func_trailing_triple_string():
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
#
@ -251,7 +249,7 @@ def test_functor_oneline_onecall_class():
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'x': 44})
block_checks_glb('f', glbs, body, {'x': 44})
def test_functor_oneline_onecall_func():
@ -261,7 +259,7 @@ def test_functor_oneline_onecall_func():
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'x': 44})
block_checks_glb('f', glbs, body, {'x': 44})
def test_functor_oneline_onecall_both():
@ -271,7 +269,7 @@ def test_functor_oneline_onecall_both():
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'x': 86})
block_checks_glb('f', glbs, body, {'x': 86})
XA_WITH = ('x = [1]\n'
@ -287,7 +285,7 @@ def test_functor_oneline_append():
s = XA_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'x': [1, 2, 3]})
block_checks_glb('f', glbs, body, {'x': [1, 2, 3]})
def test_functor_return():
@ -299,7 +297,7 @@ def test_functor_return():
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'res': 42})
block_checks_glb('f', glbs, body, {'res': 42})
def test_functor_args():
@ -311,7 +309,7 @@ def test_functor_args():
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'res': 44})
block_checks_glb('f', glbs, body, {'res': 44})
def test_functor_kwargs():
@ -323,7 +321,7 @@ def test_functor_kwargs():
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'res': 49})
block_checks_glb('f', glbs, body, {'res': 49})
def test_functor_fullsig():
@ -335,6 +333,6 @@ def test_functor_fullsig():
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
yield from block_checks_glb('f', glbs, body, {'res': 110})
block_checks_glb('f', glbs, body, {'res': 110})

View file

@ -7,8 +7,7 @@ from functools import wraps
import os
import builtins
from nose.tools import assert_equal, assert_not_equal
import nose
import pytest
from xonsh import dirstack
from xonsh.environ import Env
@ -33,30 +32,33 @@ def xonsh_env(env):
yield
builtins.__xonsh_env__ = old_env
@pytest.mark.skip(reason='BUG')
def test_simple():
load_builtins()
with xonsh_env(Env(CDPATH=PARENT, PWD=PARENT)):
with chdir(PARENT):
assert_not_equal(os.getcwd(), HERE)
assert os.getcwd() != HERE
dirstack.cd(["tests"])
assert_equal(os.getcwd(), HERE)
assert os.getcwd() == HERE
@pytest.mark.skip(reason='BUG')
def test_cdpath_simple():
with xonsh_env(Env(CDPATH=PARENT, PWD=HERE)):
with chdir(os.path.normpath("/")):
assert_not_equal(os.getcwd(), HERE)
assert os.getcwd() != HERE
dirstack.cd(["tests"])
assert_equal(os.getcwd(), HERE)
assert os.getcwd() == HERE
@pytest.mark.skip(reason='BUG')
def test_cdpath_collision():
with xonsh_env(Env(CDPATH=PARENT, PWD=HERE)):
sub_tests = os.path.join(HERE, "tests")
if not os.path.exists(sub_tests):
os.mkdir(sub_tests)
with chdir(HERE):
assert_equal(os.getcwd(), HERE)
assert os.getcwd() == HERE
dirstack.cd(["tests"])
assert_equal(os.getcwd(), os.path.join(HERE, "tests"))
assert os.getcwd() == os.path.join(HERE, "tests")
def test_cdpath_expansion():
with xonsh_env(Env(HERE=HERE, CDPATH=("~", "$HERE"))):
@ -72,6 +74,3 @@ def test_cdpath_expansion():
except Exception as e:
tuple(os.rmdir(_) for _ in test_dirs if os.path.exists(_))
raise e
if __name__ == '__main__':
nose.runmodule()

View file

@ -7,11 +7,6 @@ import builtins
from tempfile import TemporaryDirectory
from xonsh.tools import ON_WINDOWS
import nose
from nose.tools import (assert_equal, assert_true, assert_not_in,
assert_is_instance, assert_in, assert_raises)
from xonsh.environ import (Env, format_prompt, load_static_config,
locate_binary, partial_format_prompt)
@ -19,46 +14,40 @@ from tools import mock_xonsh_env
def test_env_normal():
env = Env(VAR='wakka')
assert_equal('wakka', env['VAR'])
assert 'wakka' == env['VAR']
def test_env_path_list():
env = Env(MYPATH=['/home/wakka'])
assert_equal(['/home/wakka'], env['MYPATH'].paths)
assert ['/home/wakka'] == env['MYPATH'].paths
env = Env(MYPATH=['wakka'])
assert_equal(['wakka'], env['MYPATH'].paths)
assert ['wakka'] == env['MYPATH'].paths
def test_env_path_str():
env = Env(MYPATH='/home/wakka' + os.pathsep + '/home/jawaka')
assert_equal(['/home/wakka', '/home/jawaka'], env['MYPATH'].paths)
assert ['/home/wakka', '/home/jawaka'] == env['MYPATH'].paths
env = Env(MYPATH='wakka' + os.pathsep + 'jawaka')
assert_equal(['wakka', 'jawaka'],
env['MYPATH'].paths)
assert ['wakka', 'jawaka'] == env['MYPATH'].paths
def test_env_detype():
env = Env(MYPATH=['wakka', 'jawaka'])
assert_equal('wakka' + os.pathsep + 'jawaka',
env.detype()['MYPATH'])
assert 'wakka' + os.pathsep + 'jawaka' == env.detype()['MYPATH']
def test_env_detype_mutable_access_clear():
env = Env(MYPATH=['/home/wakka', '/home/jawaka'])
assert_equal('/home/wakka' + os.pathsep + '/home/jawaka',
env.detype()['MYPATH'])
assert '/home/wakka' + os.pathsep + '/home/jawaka' == env.detype()['MYPATH']
env['MYPATH'][0] = '/home/woah'
assert_equal(None, env._detyped)
assert_equal('/home/woah' + os.pathsep + '/home/jawaka',
env.detype()['MYPATH'])
assert env._detyped is None
assert '/home/woah' + os.pathsep + '/home/jawaka' == env.detype()['MYPATH']
env = Env(MYPATH=['wakka', 'jawaka'])
assert_equal('wakka' + os.pathsep + 'jawaka',
env.detype()['MYPATH'])
assert 'wakka' + os.pathsep + 'jawaka' == env.detype()['MYPATH']
env['MYPATH'][0] = 'woah'
assert_equal(None, env._detyped)
assert_equal('woah' + os.pathsep + 'jawaka',
env.detype()['MYPATH'])
assert env._detyped is None
assert 'woah' + os.pathsep + 'jawaka' == env.detype()['MYPATH']
def test_env_detype_no_dict():
env = Env(YO={'hey': 42})
det = env.detype()
assert_not_in('YO', det)
assert 'YO' not in det
def test_format_prompt():
formatter_dict = {
@ -73,20 +62,20 @@ def test_format_prompt():
}
for p, exp in cases.items():
obs = format_prompt(template=p, formatter_dict=formatter_dict)
yield assert_equal, exp, obs
assert exp == obs
for p, exp in cases.items():
obs = partial_format_prompt(template=p, formatter_dict=formatter_dict)
yield assert_equal, exp, obs
assert exp == obs
def test_format_prompt_with_broken_template():
for p in ('{user', '{user}{hostname'):
assert_equal(partial_format_prompt(p), p)
assert_equal(format_prompt(p), p)
assert partial_format_prompt(p) == p
assert format_prompt(p) == p
# '{{user' will be parsed to '{user'
for p in ('{{user}', '{{user'):
assert_in('user', partial_format_prompt(p))
assert_in('user', format_prompt(p))
assert 'user' in partial_format_prompt(p)
assert 'user' in format_prompt(p)
def test_format_prompt_with_broken_template_in_func():
for p in (
@ -96,60 +85,60 @@ def test_format_prompt_with_broken_template_in_func():
lambda: '{user}{hostname',
):
# '{{user' will be parsed to '{user'
assert_in('user', partial_format_prompt(p))
assert_in('user', format_prompt(p))
assert 'user' in partial_format_prompt(p)
assert 'user' in format_prompt(p)
def test_format_prompt_with_invalid_func():
def p():
foo = bar # raises exception
return '{user}'
assert_is_instance(partial_format_prompt(p), str)
assert_is_instance(format_prompt(p), str)
assert isinstance(partial_format_prompt(p), str)
assert isinstance(format_prompt(p), str)
def test_HISTCONTROL():
env = Env(HISTCONTROL=None)
assert_is_instance(env['HISTCONTROL'], set)
assert_equal(len(env['HISTCONTROL']), 0)
assert isinstance(env['HISTCONTROL'], set)
assert len(env['HISTCONTROL']) == 0
env['HISTCONTROL'] = ''
assert_is_instance(env['HISTCONTROL'], set)
assert_equal(len(env['HISTCONTROL']), 0)
assert isinstance(env['HISTCONTROL'], set)
assert len(env['HISTCONTROL']) == 0
env['HISTCONTROL'] = 'ignoredups'
assert_is_instance(env['HISTCONTROL'], set)
assert_equal(len(env['HISTCONTROL']), 1)
assert_true('ignoredups' in env['HISTCONTROL'])
assert_true('ignoreerr' not in env['HISTCONTROL'])
assert isinstance(env['HISTCONTROL'], set)
assert len(env['HISTCONTROL']) == 1
assert ('ignoredups' in env['HISTCONTROL'])
assert ('ignoreerr' not in env['HISTCONTROL'])
env['HISTCONTROL'] = 'ignoreerr,ignoredups,ignoreerr'
assert_equal(len(env['HISTCONTROL']), 2)
assert_true('ignoreerr' in env['HISTCONTROL'])
assert_true('ignoredups' in env['HISTCONTROL'])
assert len(env['HISTCONTROL']) == 2
assert ('ignoreerr' in env['HISTCONTROL'])
assert ('ignoredups' in env['HISTCONTROL'])
def test_swap():
env = Env(VAR='wakka')
assert_equal(env['VAR'], 'wakka')
assert env['VAR'] == 'wakka'
# positional arg
with env.swap({'VAR': 'foo'}):
assert_equal(env['VAR'], 'foo')
assert env['VAR'] == 'foo'
# make sure the environment goes back outside the context manager
assert_equal(env['VAR'], 'wakka')
assert env['VAR'] == 'wakka'
# kwargs only
with env.swap(VAR1='foo', VAR2='bar'):
assert_equal(env['VAR1'], 'foo')
assert_equal(env['VAR2'], 'bar')
assert env['VAR1'] == 'foo'
assert env['VAR2'] == 'bar'
# positional and kwargs
with env.swap({'VAR3': 'baz'}, VAR1='foo', VAR2='bar'):
assert_equal(env['VAR1'], 'foo')
assert_equal(env['VAR2'], 'bar')
assert_equal(env['VAR3'], 'baz')
assert env['VAR1'] == 'foo'
assert env['VAR2'] == 'bar'
assert env['VAR3'] == 'baz'
# make sure the environment goes back outside the context manager
assert_equal(env['VAR'], 'wakka')
assert env['VAR'] == 'wakka'
assert 'VAR1' not in env
assert 'VAR2' not in env
assert 'VAR3' not in env
@ -162,8 +151,8 @@ def check_load_static_config(s, exp, loaded):
f.close()
conf = load_static_config(env, f.name)
os.unlink(f.name)
assert_equal(exp, conf)
assert_equal(env['LOADED_CONFIG'], loaded)
assert exp == conf
assert env['LOADED_CONFIG'] == loaded
def test_load_static_config_works():
s = b'{"best": "awash"}'
@ -187,13 +176,8 @@ if ON_WINDOWS:
f.write(fpath)
env = Env({'PATH': [tmpdir], 'PATHEXT': ['.COM', '.EXE', '.BAT']})
with mock_xonsh_env(env):
assert_equal( locate_binary('file1'), os.path.join(tmpdir,'file1.exe'))
assert_equal( locate_binary('file1.exe'), os.path.join(tmpdir,'file1.exe'))
assert_equal( locate_binary('file2'), os.path.join(tmpdir,'FILE2.BAT'))
assert_equal( locate_binary('file2.bat'), os.path.join(tmpdir,'FILE2.BAT'))
assert_equal( locate_binary('file3'), None)
if __name__ == '__main__':
nose.runmodule()
assert ( locate_binary('file1') == os.path.join(tmpdir,'file1.exe'))
assert ( locate_binary('file1.exe') == os.path.join(tmpdir,'file1.exe'))
assert ( locate_binary('file2') == os.path.join(tmpdir,'FILE2.BAT'))
assert ( locate_binary('file2.bat') == os.path.join(tmpdir,'FILE2.BAT'))
assert ( locate_binary('file3') is None)

View file

@ -5,29 +5,29 @@ import os
import sys
import ast
from nose.tools import assert_raises
from xonsh.execer import Execer
from xonsh.tools import ON_WINDOWS
from tools import (mock_xonsh_env, execer_setup, check_exec, check_eval,
check_parse, skip_if)
check_parse)
def setup():
import pytest
def setup_module():
execer_setup()
@skip_if(not ON_WINDOWS)
@pytest.mark.skipif(not ON_WINDOWS, reason='Windows only stuff')
def test_win_ipconfig():
yield (check_eval,
os.environ['SYSTEMROOT'] + '\\System32\\ipconfig.exe /all')
check_eval(os.environ['SYSTEMROOT'] + '\\System32\\ipconfig.exe /all')
@skip_if(not ON_WINDOWS)
@pytest.mark.skipif(not ON_WINDOWS, reason='Windows only bin')
def test_ipconfig():
yield check_eval, 'ipconfig /all'
check_eval('ipconfig /all')
@skip_if(ON_WINDOWS)
@pytest.mark.skipif(ON_WINDOWS, reason='dont expect ls on windows')
def test_bin_ls():
yield check_eval, '/bin/ls -l'
check_eval('/bin/ls -l')
def test_ls_dashl():
yield check_parse, 'ls -l'
@ -63,7 +63,8 @@ def test_simple_func_broken():
def test_bad_indent():
code = ('if True:\n'
'x = 1\n')
assert_raises(SyntaxError, check_parse, code)
with pytest.raises(SyntaxError):
check_parse(code)
def test_good_rhs_subproc():
# nonsense but parsebale
@ -73,7 +74,8 @@ def test_good_rhs_subproc():
def test_bad_rhs_subproc():
# nonsense but unparsebale
code = 'str().split() | grep exit\n'
assert_raises(SyntaxError, check_parse, code)
with pytest.raises(SyntaxError):
check_parse(code)
def test_indent_with_empty_line():
code = ('if True:\n'
@ -106,8 +108,3 @@ def test_echo_comma_val():
def test_echo_comma_2val():
code = 'echo 1,2\n'
yield check_parse, code
if __name__ == '__main__':
nose.runmodule()

View file

@ -4,9 +4,7 @@ from __future__ import unicode_literals, print_function
import os
import subprocess
import nose
from nose.plugins.skip import SkipTest
from nose.tools import assert_equal, assert_true, assert_false
import pytest
from xonsh.tools import ON_WINDOWS
from xonsh.foreign_shells import foreign_shell_data, parse_env, parse_aliases
@ -20,7 +18,7 @@ def test_parse_env():
'__XONSH_ENV_END__\n'
'more filth')
obs = parse_env(s)
assert_equal(exp, obs)
assert exp == obs
def test_parse_env_newline():
@ -33,7 +31,7 @@ def test_parse_env_newline():
'__XONSH_ENV_END__\n'
'more filth')
obs = parse_env(s)
assert_equal(exp, obs)
assert exp == obs
def test_parse_env_equals():
@ -46,7 +44,7 @@ def test_parse_env_equals():
'__XONSH_ENV_END__\n'
'more filth')
obs = parse_env(s)
assert_equal(exp, obs)
assert exp == obs
def test_parse_aliases():
@ -58,9 +56,10 @@ def test_parse_aliases():
'__XONSH_ALIAS_END__\n'
'more filth')
obs = parse_aliases(s)
assert_equal(exp, obs)
assert exp == obs
@pytest.mark.skipif(ON_WINDOWS, reason='Unix stuff')
def test_foreign_bash_data():
expenv = {"EMERALD": "SWORD", 'MIGHTY': 'WARRIOR'}
expaliases = {
@ -74,16 +73,14 @@ def test_foreign_bash_data():
extra_args=('--rcfile', rcfile),
safe=False)
except (subprocess.CalledProcessError, FileNotFoundError):
raise SkipTest
return
for key, expval in expenv.items():
yield assert_equal, expval, obsenv.get(key, False)
assert expval == obsenv.get(key, False)
for key, expval in expaliases.items():
yield assert_equal, expval, obsaliases.get(key, False)
assert expval == obsaliases.get(key, False)
def test_foreign_cmd_data():
if not ON_WINDOWS:
raise SkipTest
env = (('ENV_TO_BE_REMOVED','test'),)
batchfile = os.path.join(os.path.dirname(__file__), 'batch.bat')
source_cmd ='call "{}"\necho off'.format(batchfile)
@ -95,12 +92,7 @@ def test_foreign_cmd_data():
use_tmpfile=True,
safe=False)
except (subprocess.CalledProcessError, FileNotFoundError):
raise SkipTest
assert_true('ENV_TO_BE_ADDED' in obsenv)
assert_true(obsenv['ENV_TO_BE_ADDED']=='Hallo world')
assert_true('ENV_TO_BE_REMOVED' not in obsenv)
if __name__ == '__main__':
nose.runmodule()
return
assert 'ENV_TO_BE_ADDED' in obsenv
assert obsenv['ENV_TO_BE_ADDED']=='Hallo world'
assert 'ENV_TO_BE_REMOVED' not in obsenv

View file

@ -9,9 +9,6 @@ import io
import os
import sys
import nose
from nose.tools import assert_equal, assert_is_none, assert_is_not_none
from xonsh.lazyjson import LazyJSON
from xonsh.history import History
from xonsh import history
@ -28,7 +25,7 @@ def test_hist_init():
History(filename=FNAME, here='yup', **HIST_TEST_KWARGS)
with LazyJSON(FNAME) as lj:
obs = lj['here']
assert_equal('yup', obs)
assert 'yup' == obs
os.remove(FNAME)
@ -39,8 +36,8 @@ def test_hist_append():
hist = History(filename=FNAME, here='yup', **HIST_TEST_KWARGS)
with mock_xonsh_env({'HISTCONTROL': set()}):
hf = hist.append({'joco': 'still alive'})
yield assert_is_none, hf
yield assert_equal, 'still alive', hist.buffer[0]['joco']
assert hf is None
assert 'still alive' == hist.buffer[0]['joco']
os.remove(FNAME)
@ -50,16 +47,16 @@ def test_hist_flush():
FNAME += '.flush'
hist = History(filename=FNAME, here='yup', **HIST_TEST_KWARGS)
hf = hist.flush()
yield assert_is_none, hf
assert hf is None
with mock_xonsh_env({'HISTCONTROL': set()}):
hist.append({'joco': 'still alive'})
hf = hist.flush()
yield assert_is_not_none, hf
assert hf is not None
while hf.is_alive():
pass
with LazyJSON(FNAME) as lj:
obs = lj['cmds'][0]['joco']
yield assert_equal, 'still alive', obs
assert 'still alive' == obs
os.remove(FNAME)
@ -71,18 +68,18 @@ def test_cmd_field():
# in-memory
with mock_xonsh_env({'HISTCONTROL': set()}):
hf = hist.append({'rtn': 1})
yield assert_is_none, hf
yield assert_equal, 1, hist.rtns[0]
yield assert_equal, 1, hist.rtns[-1]
yield assert_equal, None, hist.outs[-1]
assert hf is None
assert 1 == hist.rtns[0]
assert 1 == hist.rtns[-1]
assert None == hist.outs[-1]
# slice
yield assert_equal, [1], hist.rtns[:]
assert [1] == hist.rtns[:]
# on disk
hf = hist.flush()
yield assert_is_not_none, hf
yield assert_equal, 1, hist.rtns[0]
yield assert_equal, 1, hist.rtns[-1]
yield assert_equal, None, hist.outs[-1]
assert hf is not None
assert 1 == hist.rtns[0]
assert 1 == hist.rtns[-1]
assert None == hist.outs[-1]
os.remove(FNAME)
@ -103,10 +100,10 @@ def test_show_cmd():
history._hist_main(hist, hist_args)
stdout.seek(0, io.SEEK_SET)
hist_lines = stdout.readlines()
yield assert_equal, len(commands), len(hist_lines)
assert len(commands) == len(hist_lines)
for idx, (cmd, actual) in enumerate(zip(commands, hist_lines)):
expected = format_hist_line(base_idx + idx * step, cmd)
yield assert_equal, expected, actual
assert expected == actual
hist = History(filename=FNAME, here='yup', **HIST_TEST_KWARGS)
stdout = io.StringIO()
@ -118,48 +115,38 @@ def test_show_cmd():
hist.append({'inp': cmd, 'rtn': 0, 'ts':(ts+1, ts+1.5)})
# Verify an implicit "show" emits show history
for x in run_show_cmd([], cmds):
yield x
run_show_cmd([], cmds)
# Verify an explicit "show" with no qualifiers emits
# show history.
for x in run_show_cmd(['show'], cmds):
yield x
run_show_cmd(['show'], cmds)
# Verify an explicit "show" with a reversed qualifier
# emits show history in reverse order.
for x in run_show_cmd(['show', '-r'], list(reversed(cmds)),
len(cmds) - 1, -1):
yield x
run_show_cmd(['show', '-r'], list(reversed(cmds)),
len(cmds) - 1, -1)
# Verify that showing a specific history entry relative to
# the start of the history works.
for x in run_show_cmd(['show', '0'], [cmds[0]], 0):
yield x
for x in run_show_cmd(['show', '1'], [cmds[1]], 1):
yield x
run_show_cmd(['show', '0'], [cmds[0]], 0)
run_show_cmd(['show', '1'], [cmds[1]], 1)
# Verify that showing a specific history entry relative to
# the end of the history works.
for x in run_show_cmd(['show', '-2'], [cmds[-2]],
len(cmds) - 2):
yield x
run_show_cmd(['show', '-2'], [cmds[-2]],
len(cmds) - 2)
# Verify that showing a history range relative to the start of the
# history works.
for x in run_show_cmd(['show', '0:2'], cmds[0:2], 0):
yield x
for x in run_show_cmd(['show', '1::2'], cmds[1::2], 1, 2):
yield x
run_show_cmd(['show', '0:2'], cmds[0:2], 0)
run_show_cmd(['show', '1::2'], cmds[1::2], 1, 2)
# Verify that showing a history range relative to the end of the
# history works.
for x in run_show_cmd(['show', '-2:'],
cmds[-2:], len(cmds) - 2):
yield x
for x in run_show_cmd(['show', '-4:-2'],
cmds[-4:-2], len(cmds) - 4):
yield x
run_show_cmd(['show', '-2:'],
cmds[-2:], len(cmds) - 2)
run_show_cmd(['show', '-4:-2'],
cmds[-4:-2], len(cmds) - 4)
sys.stdout = saved_stdout
os.remove(FNAME)
@ -171,60 +158,56 @@ def test_histcontrol():
hist = History(filename=FNAME, here='yup', **HIST_TEST_KWARGS)
with mock_xonsh_env({'HISTCONTROL': 'ignoredups,ignoreerr'}):
yield assert_equal, len(hist.buffer), 0
assert len(hist.buffer) == 0
# An error, buffer remains empty
hist.append({'inp': 'ls foo', 'rtn': 2})
yield assert_equal, len(hist.buffer), 0
assert len(hist.buffer) == 0
# Success
hist.append({'inp': 'ls foobazz', 'rtn': 0})
yield assert_equal, len(hist.buffer), 1
yield assert_equal, 'ls foobazz', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 1
assert 'ls foobazz' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# Error
hist.append({'inp': 'ls foo', 'rtn': 2})
yield assert_equal, len(hist.buffer), 1
yield assert_equal, 'ls foobazz', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 1
assert 'ls foobazz' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# File now exists, success
hist.append({'inp': 'ls foo', 'rtn': 0})
yield assert_equal, len(hist.buffer), 2
yield assert_equal, 'ls foo', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 2
assert 'ls foo' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# Success
hist.append({'inp': 'ls', 'rtn': 0})
yield assert_equal, len(hist.buffer), 3
yield assert_equal, 'ls', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 3
assert 'ls' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# Dup
hist.append({'inp': 'ls', 'rtn': 0})
yield assert_equal, len(hist.buffer), 3
assert len(hist.buffer) == 3
# Success
hist.append({'inp': '/bin/ls', 'rtn': 0})
yield assert_equal, len(hist.buffer), 4
yield assert_equal, '/bin/ls', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 4
assert '/bin/ls' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# Error
hist.append({'inp': 'ls bazz', 'rtn': 1})
yield assert_equal, len(hist.buffer), 4
yield assert_equal, '/bin/ls', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 4
assert '/bin/ls' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
# Error
hist.append({'inp': 'ls bazz', 'rtn': -1})
yield assert_equal, len(hist.buffer), 4
yield assert_equal, '/bin/ls', hist.buffer[-1]['inp']
yield assert_equal, 0, hist.buffer[-1]['rtn']
assert len(hist.buffer) == 4
assert '/bin/ls' == hist.buffer[-1]['inp']
assert 0 == hist.buffer[-1]['rtn']
os.remove(FNAME)
if __name__ == '__main__':
nose.runmodule()

View file

@ -2,9 +2,6 @@
"""Testing xonsh import hooks"""
from __future__ import unicode_literals, print_function
import nose
from nose.tools import assert_equal
from xonsh import imphooks # noqa
from xonsh import built_ins
from xonsh.execer import Execer
@ -15,38 +12,34 @@ LOADED_HERE = False
IMP_ENV = {'PATH': [], 'PATHEXT': []}
def setup():
def setup_module():
global LOADED_HERE
if built_ins.BUILTINS_LOADED:
unload_builtins() # make sure we have a clean env from other tests.
load_builtins(execer=Execer())
LOADED_HERE = True
def teardown():
def teardown_module():
if LOADED_HERE:
unload_builtins()
def test_import():
with mock_xonsh_env(IMP_ENV):
import sample
assert_equal('hello mom jawaka\n', sample.x)
assert ('hello mom jawaka\n' == sample.x)
def test_absolute_import():
with mock_xonsh_env(IMP_ENV):
from xpack import sample
assert_equal('hello mom jawaka\n', sample.x)
assert ('hello mom jawaka\n' == sample.x)
def test_relative_import():
with mock_xonsh_env(IMP_ENV):
from xpack import relimp
assert_equal('hello mom jawaka\n', relimp.sample.x)
assert_equal('hello mom jawaka\ndark chest of wonders', relimp.y)
assert ('hello mom jawaka\n' == relimp.sample.x)
assert ('hello mom jawaka\ndark chest of wonders' == relimp.y)
def test_sub_import():
with mock_xonsh_env(IMP_ENV):
from xpack.sub import sample
assert_equal('hello mom jawaka\n', sample.x)
if __name__ == '__main__':
nose.runmodule()
assert ('hello mom jawaka\n' == sample.x)

View file

@ -1,9 +1,6 @@
# -*- coding: utf-8 -*-
"""Testing inspectors"""
import inspect
from nose.tools import assert_equal, assert_not_equal
from xonsh.inspectors import getouterframes
@ -11,7 +8,3 @@ def test_getouterframes():
"""Just test that this works."""
curr = inspect.currentframe()
getouterframes(curr, context=0)
if __name__ == '__main__':
nose.runmodule()

View file

@ -3,53 +3,52 @@
from __future__ import unicode_literals, print_function
from io import StringIO
import nose
from nose.tools import assert_equal, assert_is_instance
assert_equal.__self__.maxDiff = None
import pytest
# assert_equal.__self__.maxDiff = None
from xonsh.lazyjson import index, ljdump, LazyJSON, LJNode
def test_index_int():
exp = {'offsets': 0, 'sizes': 2}
s, obs = index(42)
assert_equal(exp, obs)
assert exp == obs
def test_index_str():
exp = {'offsets': 0, 'sizes': 7}
s, obs = index('wakka')
assert_equal(exp, obs)
assert exp == obs
def test_index_list_ints():
exp = {'offsets': [1, 4, 0], 'sizes': [1, 2, 8]}
s, obs = index([1, 42])
assert_equal(exp, obs)
assert exp == obs
def test_index_list_str():
exp = {'offsets': [1, 10, 0], 'sizes': [7, 8, 20]}
s, obs = index(['wakka', 'jawaka'])
assert_equal(exp, obs)
assert exp == obs
def test_index_list_str_int():
exp = {'offsets': [1, 10, 0], 'sizes': [7, 2, 14]}
s, obs = index(['wakka', 42])
assert_equal(exp, obs)
assert exp == obs
def test_index_list_int_str():
exp = {'offsets': [1, 5, 14, 0], 'sizes': [2, 7, 8, 24]}
s, obs = index([42, 'wakka', 'jawaka'])
assert_equal(exp, obs)
assert exp == obs
def test_index_dict_int():
exp = {'offsets': {'wakka': 10, '__total__': 0},
'sizes': {'wakka': 2, '__total__': 14}}
s, obs = index({'wakka': 42})
assert_equal(exp, obs)
assert exp == obs
def test_index_dict_str():
exp = {'offsets': {'wakka': 10, '__total__': 0},
'sizes': {'wakka': 8, '__total__': 20}}
s, obs = index({'wakka': 'jawaka'})
assert_equal(exp, obs)
assert exp == obs
def test_index_dict_dict_int():
exp = {'offsets': {'wakka': {'jawaka': 21, '__total__': 10},
@ -59,29 +58,29 @@ def test_index_dict_dict_int():
'__total__': 27}
}
s, obs = index({'wakka': {'jawaka': 42}})
assert_equal(exp, obs)
assert exp == obs
def test_lazy_load_index():
f = StringIO()
ljdump({'wakka': 42}, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal({'wakka': 10, '__total__': 0}, lj.offsets)
assert_equal({'wakka': 2, '__total__': 14}, lj.sizes)
assert {'wakka': 10, '__total__': 0} == lj.offsets
assert {'wakka': 2, '__total__': 14} == lj.sizes
def test_lazy_int():
f = StringIO()
ljdump(42, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(42, lj.load())
assert 42 == lj.load()
def test_lazy_str():
f = StringIO()
ljdump('wakka', f)
f.seek(0)
lj = LazyJSON(f)
assert_equal('wakka', lj.load())
assert 'wakka' == lj.load()
def test_lazy_list_empty():
x = []
@ -89,8 +88,8 @@ def test_lazy_list_empty():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(0, len(lj))
assert_equal(x, lj.load())
assert 0 == len(lj)
assert x == lj.load()
def test_lazy_list_ints():
x = [0, 1, 6, 28, 496, 8128]
@ -98,10 +97,10 @@ def test_lazy_list_ints():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(28, lj[3])
assert_equal(x[:2:-2], lj[:2:-2])
assert_equal(x, [_ for _ in lj])
assert_equal(x, lj.load())
assert 28 == lj[3]
assert x[:2:-2] == lj[:2:-2]
assert x == [_ for _ in lj]
assert x == lj.load()
def test_lazy_list_ints():
x = [0, 1, 6, 28, 496, 8128]
@ -109,10 +108,10 @@ def test_lazy_list_ints():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(28, lj[3])
assert_equal(x[:2:-2], lj[:2:-2])
assert_equal(x, [_ for _ in lj])
assert_equal(x, lj.load())
assert 28 == lj[3]
assert x[:2:-2] == lj[:2:-2]
assert x == [_ for _ in lj]
assert x == lj.load()
def test_lazy_list_str():
x = ['I', 'have', 'seen', 'the', 'wind', 'blow']
@ -120,10 +119,10 @@ def test_lazy_list_str():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal('the', lj[3])
assert_equal(x[:2:-2], lj[:2:-2])
assert_equal(x, [_ for _ in lj])
assert_equal(x, lj.load())
assert 'the' == lj[3]
assert x[:2:-2] == lj[:2:-2]
assert x == [_ for _ in lj]
assert x == lj.load()
def test_lazy_list_ints():
x = [0, 1, 6, 28, 496, 8128]
@ -131,10 +130,10 @@ def test_lazy_list_ints():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(28, lj[3])
assert_equal(x[:2:-2], lj[:2:-2])
assert_equal(x, [_ for _ in lj])
assert_equal(x, lj.load())
assert 28 == lj[3]
assert x[:2:-2] == lj[:2:-2]
assert x == [_ for _ in lj]
assert x == lj.load()
def test_lazy_list_list_ints():
x = [[0, 1], [6, 28], [496, 8128]]
@ -142,10 +141,10 @@ def test_lazy_list_list_ints():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_is_instance(lj[1], LJNode)
assert_equal(28, lj[1][1])
assert_equal([6, 28], lj[1].load())
assert_equal(x, lj.load())
assert isinstance(lj[1], LJNode)
assert 28 == lj[1][1]
assert [6 == 28], lj[1].load()
assert x == lj.load()
def test_lazy_dict_empty():
x = {}
@ -153,18 +152,18 @@ def test_lazy_dict_empty():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(0, len(lj))
assert_equal(x, lj.load())
assert 0 == len(lj)
assert x == lj.load()
def test_lazy_dict():
f = StringIO()
ljdump({'wakka': 42}, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(['wakka'], list(lj.keys()))
assert_equal(42, lj['wakka'])
assert_equal(1, len(lj))
assert_equal({'wakka': 42}, lj.load())
assert ['wakka'] == list(lj.keys())
assert 42 == lj['wakka']
assert 1 == len(lj)
assert {'wakka': 42} == lj.load()
def test_lazy_dict_dict_int():
x = {'wakka': {'jawaka': 42}}
@ -172,13 +171,8 @@ def test_lazy_dict_dict_int():
ljdump(x, f)
f.seek(0)
lj = LazyJSON(f)
assert_equal(['wakka'], list(lj.keys()))
assert_is_instance(lj['wakka'], LJNode)
assert_equal(42, lj['wakka']['jawaka'])
assert_equal(1, len(lj))
assert_equal(x, lj.load())
if __name__ == '__main__':
nose.runmodule()
assert ['wakka'] == list(lj.keys())
assert isinstance(lj['wakka'], LJNode)
assert 42 == lj['wakka']['jawaka']
assert 1 == len(lj)
assert x == lj.load()

View file

@ -7,13 +7,11 @@ from collections import Sequence
sys.path.insert(0, os.path.abspath('..')) # FIXME
from pprint import pformat
import nose
try:
from ply.lex import LexToken
except ImportError:
from xonsh.ply.lex import LexToken
from xonsh.lexer import Lexer
@ -43,6 +41,7 @@ def assert_token_equal(x, y):
if not tokens_equal(x, y):
msg = 'The tokens differ: {0!r} != {1!r}'.format(x, y)
raise AssertionError(msg)
return True
def assert_tokens_equal(x, y):
"""Asserts that two token sequences are equal."""
@ -58,6 +57,7 @@ def assert_tokens_equal(x, y):
msg += ['', '- ' + repr(a), '+ ' + repr(b)]
msg = '\n'.join(msg)
raise AssertionError(msg)
return True
def check_token(inp, exp):
l = Lexer()
@ -67,49 +67,49 @@ def check_token(inp, exp):
msg = 'The observed sequence does not have length-1: {0!r} != 1\n'
msg += '# obs\n{1}'
raise AssertionError(msg.format(len(obs), pformat(obs)))
assert_token_equal(exp, obs[0])
return assert_token_equal(exp, obs[0])
def check_tokens(inp, exp):
l = Lexer()
l.input(inp)
obs = list(l)
assert_tokens_equal(exp, obs)
return assert_tokens_equal(exp, obs)
def check_tokens_subproc(inp, exp):
l = Lexer()
l.input('$[{}]'.format(inp))
obs = list(l)[1:-1]
assert_tokens_equal(exp, obs)
return assert_tokens_equal(exp, obs)
def test_int_literal():
yield check_token, '42', ['NUMBER', '42', 0]
assert check_token('42', ['NUMBER', '42', 0])
def test_hex_literal():
yield check_token, '0x42', ['NUMBER', '0x42', 0]
assert check_token('0x42', ['NUMBER', '0x42', 0])
def test_oct_o_literal():
yield check_token, '0o42', ['NUMBER', '0o42', 0]
assert check_token('0o42', ['NUMBER', '0o42', 0])
def test_bin_literal():
yield check_token, '0b101010', ['NUMBER', '0b101010', 0]
assert check_token('0b101010', ['NUMBER', '0b101010', 0])
def test_indent():
exp = [('INDENT', ' \t ', 0),
('NUMBER', '42', 5),
('DEDENT', '', 0)]
yield check_tokens, ' \t 42', exp
assert check_tokens(' \t 42', exp)
def test_post_whitespace():
inp = '42 \t '
exp = [('NUMBER', '42', 0)]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_internal_whitespace():
inp = '42 +\t65'
exp = [('NUMBER', '42', 0),
('PLUS', '+', 4),
('NUMBER', '65', 6),]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_indent_internal_whitespace():
inp = ' 42 +\t65'
@ -118,21 +118,21 @@ def test_indent_internal_whitespace():
('PLUS', '+', 5),
('NUMBER', '65', 7),
('DEDENT', '', 0)]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_assignment():
inp = 'x = 42'
exp = [('NAME', 'x', 0),
('EQUALS', '=', 2),
('NUMBER', '42', 4),]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_multiline():
inp = 'x\ny'
exp = [('NAME', 'x', 0),
('NEWLINE', '\n', 1),
('NAME', 'y', 0),]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_atdollar_expression():
inp = '@$(which python)'
@ -141,70 +141,66 @@ def test_atdollar_expression():
('WS', ' ', 8),
('NAME', 'python', 9),
('RPAREN', ')', 15)]
yield check_tokens, inp, exp
assert check_tokens(inp, exp)
def test_and():
yield check_token, 'and', ['AND', 'and', 0]
assert check_token('and', ['AND', 'and', 0])
def test_ampersand():
yield check_token, '&', ['AMPERSAND', '&', 0]
assert check_token('&', ['AMPERSAND', '&', 0])
def test_atdollar():
yield check_token, '@$', ['ATDOLLAR', '@$', 0]
assert check_token('@$', ['ATDOLLAR', '@$', 0])
def test_doubleamp():
yield check_token, '&&', ['AND', 'and', 0]
assert check_token('&&', ['AND', 'and', 0])
def test_pipe():
yield check_token, '|', ['PIPE', '|', 0]
assert check_token('|', ['PIPE', '|', 0])
def test_doublepipe():
yield check_token, '||', ['OR', 'or', 0]
assert check_token('||', ['OR', 'or', 0])
def test_single_quote_literal():
yield check_token, "'yo'", ['STRING', "'yo'", 0]
assert check_token("'yo'", ['STRING', "'yo'", 0])
def test_double_quote_literal():
yield check_token, '"yo"', ['STRING', '"yo"', 0]
assert check_token('"yo"', ['STRING', '"yo"', 0])
def test_triple_single_quote_literal():
yield check_token, "'''yo'''", ['STRING', "'''yo'''", 0]
assert check_token("'''yo'''", ['STRING', "'''yo'''", 0])
def test_triple_double_quote_literal():
yield check_token, '"""yo"""', ['STRING', '"""yo"""', 0]
assert check_token('"""yo"""', ['STRING', '"""yo"""', 0])
def test_single_raw_string_literal():
yield check_token, "r'yo'", ['STRING', "r'yo'", 0]
assert check_token("r'yo'", ['STRING', "r'yo'", 0])
def test_double_raw_string_literal():
yield check_token, 'r"yo"', ['STRING', 'r"yo"', 0]
assert check_token('r"yo"', ['STRING', 'r"yo"', 0])
def test_single_unicode_literal():
yield check_token, "u'yo'", ['STRING', "u'yo'", 0]
assert check_token("u'yo'", ['STRING', "u'yo'", 0])
def test_double_unicode_literal():
yield check_token, 'u"yo"', ['STRING', 'u"yo"', 0]
assert check_token('u"yo"', ['STRING', 'u"yo"', 0])
def test_single_bytes_literal():
yield check_token, "b'yo'", ['STRING', "b'yo'", 0]
assert check_token("b'yo'", ['STRING', "b'yo'", 0])
def test_regex_globs():
for i in ('.*', r'\d*', '.*#{1,2}'):
for p in ('', 'r', 'g', '@somethingelse'):
c = '{}`{}`'.format(p,i)
yield check_token, c, ['SEARCHPATH', c, 0]
assert check_token(c, ['SEARCHPATH', c, 0])
def test_float_literals():
cases = ['0.0', '.0', '0.', '1e10', '1.e42', '0.1e42', '0.5e-42',
'5E10', '5e+42']
for s in cases:
yield check_token, s, ['NUMBER', s, 0]
assert check_token(s, ['NUMBER', s, 0])
def test_ioredir():
cases = ['2>1', 'err>out', 'o>', 'all>', 'e>o', 'e>', 'out>', '2>&1']
for s in cases:
yield check_tokens_subproc, s, [('IOREDIRECT', s, 2)]
if __name__ == '__main__':
nose.runmodule()
assert check_tokens_subproc(s, [('IOREDIRECT', s, 2)])

View file

@ -4,34 +4,74 @@ from __future__ import unicode_literals, print_function
import builtins
from unittest.mock import patch
import nose
from nose.tools import assert_true, assert_false
import xonsh.main
from tools import mock_xonsh_env
def test_login_shell():
def Shell(*args, **kwargs):
pass
def Shell(*args, **kwargs):
pass
def test_premain():
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
with patch('sys.stdin.isatty') as faketty:
faketty.return_value = True
xonsh.main.premain([])
assert builtins.__xonsh_env__.get('XONSH_LOGIN')
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain([])
assert_true(builtins.__xonsh_env__.get('XONSH_LOGIN'))
xonsh.main.premain(['-i'])
assert (builtins.__xonsh_env__.get('XONSH_LOGIN'))
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-i'])
assert (builtins.__xonsh_env__.get('XONSH_INTERACTIVE'))
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-l', '-c', 'echo "hi"'])
assert_true(builtins.__xonsh_env__.get('XONSH_LOGIN'))
assert (builtins.__xonsh_env__.get('XONSH_LOGIN'))
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-c', 'echo "hi"'])
assert_false(builtins.__xonsh_env__.get('XONSH_LOGIN'))
assert not (builtins.__xonsh_env__.get('XONSH_LOGIN'))
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-l'])
assert_true(builtins.__xonsh_env__.get('XONSH_LOGIN'))
assert (builtins.__xonsh_env__.get('XONSH_LOGIN'))
if __name__ == '__main__':
nose.runmodule()
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-DTEST1=1616', '-DTEST2=LOL'])
assert (builtins.__xonsh_env__.get('TEST1') == '1616')
assert (builtins.__xonsh_env__.get('TEST2') == 'LOL')
def test_premain_with_file_argument():
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['tests/sample.xsh'])
assert not (builtins.__xonsh_env__.get('XONSH_INTERACTIVE'))
for case in ('-i', '-vERSION', '-hAALP','TTTT', '-TT', '--TTT'):
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['tests/sample.xsh', case])
assert not (builtins.__xonsh_env__.get('XONSH_INTERACTIVE'))
# interactive
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
xonsh.main.premain(['-i', 'tests/sample.xsh'])
assert (builtins.__xonsh_env__.get('XONSH_INTERACTIVE'))
def test_premain_invalid_arguments():
# pytest transition
# TODO: check for proper error msg in stdout (howto nose?)
with patch('xonsh.main.Shell', Shell), mock_xonsh_env({}):
for case in ('----', '--hep', '-TT', '--TTTT'):
try:
xonsh.main.premain([case])
except SystemExit:
pass
else:
assert False

View file

@ -2,9 +2,7 @@
import os
import tempfile
import nose
from nose.tools import assert_true
from nose.plugins.skip import SkipTest
import pytest
from xonsh.tools import ON_WINDOWS
from xonsh.completers.man import complete_from_man
@ -13,13 +11,13 @@ from tools import mock_xonsh_env
_OLD_MANPATH = None
def setup():
def setup_module():
global _OLD_MANPATH
_OLD_MANPATH = os.environ.get('MANPATH', None)
os.environ['MANPATH'] = os.path.dirname(os.path.abspath(__file__))
def teardown():
def teardown_module():
global _OLD_MANPATH
if _OLD_MANPATH is None:
del os.environ['MANPATH']
@ -27,15 +25,10 @@ def teardown():
os.environ['MANPATH'] = _OLD_MANPATH
@pytest.mark.skipif(ON_WINDOWS, reason='No man completions on Windows')
def test_man_completion():
if ON_WINDOWS:
raise SkipTest
with tempfile.TemporaryDirectory() as tempdir:
with mock_xonsh_env({'XONSH_DATA_DIR': tempdir}):
completions = complete_from_man('--', 'yes --', 4, 6, __xonsh_env__)
assert_true('--version' in completions)
assert_true('--help' in completions)
if __name__ == '__main__':
nose.runmodule()
assert ('--version' in completions)
assert ('--help' in completions)

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
"""Tests for the PromptToolkitHistory class."""
import os
import sys
import nose
from nose.tools import assert_equal
import pytest
def is_prompt_toolkit_available():
try:
@ -14,8 +13,7 @@ def is_prompt_toolkit_available():
return False
if not is_prompt_toolkit_available():
from nose.plugins.skip import SkipTest
raise SkipTest('prompt_toolkit is not available')
pytest.skip(msg='prompt_toolkit is not available')
from xonsh.ptk.history import PromptToolkitHistory
@ -24,10 +22,6 @@ from xonsh.ptk.history import PromptToolkitHistory
def test_obj():
history_obj = PromptToolkitHistory(load_prev=False)
history_obj.append('line10')
yield assert_equal, ['line10'], history_obj.strings
yield assert_equal, 1, len(history_obj)
yield assert_equal, ['line10'], [x for x in history_obj]
if __name__ == '__main__':
nose.runmodule()
assert ['line10'] == history_obj.strings
assert len(history_obj) == 1
assert ['line10'] == [x for x in history_obj]

View file

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
"""Tests sample inputs to PTK multiline and checks parser response"""
import nose
from nose.tools import assert_equal, with_setup
import pytest
from unittest.mock import MagicMock, patch
from prompt_toolkit.interface import CommandLineInterface
@ -10,14 +9,14 @@ from prompt_toolkit.buffer import Buffer, AcceptAction
from xonsh.environ import Env
from xonsh.tools import ON_WINDOWS
def setup():
def setup_module():
global indent_
global buffer
global bufaccept
global cli
global carriage_return
global builtins
import builtins
builtins.__xonsh_env__ = Env()
@ -31,14 +30,14 @@ def setup():
cli = MagicMock(name='cli', spec=CommandLineInterface)
buffer.accept_action = bufaccept
def teardown():
def teardown_module():
global indent_
global buffer
global bufaccept
global cli
global carriage_return
global builtins
del indent_
del buffer
del bufaccept
@ -50,18 +49,18 @@ def test_colon_indent():
document = Document('for i in range(5):')
buffer.set_document(document)
carriage_return(buffer, cli)
assert_equal(buffer.document.current_line, indent_)
assert buffer.document.current_line == indent_
def test_dedent():
document = Document('\n'+indent_+'pass')
buffer.set_document(document)
carriage_return(buffer, cli)
assert_equal(buffer.document.current_line, '')
assert buffer.document.current_line == ''
document = Document('\n'+2*indent_+'continue')
buffer.set_document(document)
carriage_return(buffer, cli)
assert_equal(buffer.document.current_line,indent_)
assert buffer.document.current_line == indent_
def test_nodedent():
'''don't dedent if first line of buffer'''
@ -84,7 +83,7 @@ def test_continuation_line():
document = Document('\nsecond line')
buffer.set_document(document)
carriage_return(buffer, cli)
assert_equal(buffer.document.current_line, '')
assert buffer.document.current_line == ''
def test_trailing_slash():
mock = MagicMock(return_value = True)
@ -93,7 +92,7 @@ def test_trailing_slash():
buffer.set_document(document)
carriage_return(buffer, cli)
if not ON_WINDOWS:
assert_equal(buffer.document.current_line, '')
assert buffer.document.current_line == ''
else:
assert bufaccept.mock_calls is not None
@ -103,7 +102,7 @@ def test_cant_compile_newline():
document = Document('for i in (1, 2, ')
buffer.set_document(document)
carriage_return(buffer, cli)
assert_equal(buffer.document.current_line, '')
assert buffer.document.current_line == ''
def test_can_compile_and_executes():
mock = MagicMock(return_value = True)
@ -112,6 +111,3 @@ def test_can_compile_and_executes():
buffer.set_document(document)
carriage_return(buffer, cli)
assert bufaccept.mock_calls is not None
if __name__ == '__main__':
nose.runmodule()

View file

@ -5,22 +5,22 @@ import os
import builtins
from contextlib import contextmanager
import nose
from nose.tools import assert_equal, assert_true
import pytest
from xonsh.tools import swap
from xonsh.shell import Shell
from xonsh.replay import Replayer
from tools import ON_MAC, skip_if
from tools import ON_DARWIN
SHELL = Shell({'PATH': []})
HISTDIR = os.path.join(os.path.dirname(__file__), 'histories')
def run_replay(re_file):
with swap(builtins, '__xonsh_shell__', SHELL):
r = Replayer(re_file)
hist = r.replay()
with swap(builtins, '__xonsh_exit__', False):
r = Replayer(re_file)
hist = r.replay()
return hist
@ -38,27 +38,22 @@ def a_replay(re_file):
cleanup_replay(hist)
@skip_if(ON_MAC)
@pytest.mark.skipif(ON_DARWIN, reason='Not mac friendly')
def test_echo():
f = os.path.join(HISTDIR, 'echo.json')
with a_replay(f) as hist:
yield assert_equal, 2, len(hist)
assert 2 == len(hist)
@skip_if(ON_MAC)
@pytest.mark.skipif(ON_DARWIN, reason='also not mac friendly')
def test_reecho():
f = os.path.join(HISTDIR, 'echo.json')
with a_replay(f) as hist:
yield assert_equal, 2, len(hist)
assert 2 == len(hist)
@skip_if(ON_MAC)
@pytest.mark.skipif(ON_DARWIN, reason='also not mac friendly')
def test_simple_python():
f = os.path.join(HISTDIR, 'simple-python.json')
with a_replay(f) as hist:
yield assert_equal, 4, len(hist)
yield assert_equal, "print('The Turtles')", hist.inps[0].strip()
if __name__ == '__main__':
nose.runmodule()
assert 4 == len(hist)
assert "print('The Turtles')" == hist.inps[0].strip()

View file

@ -5,14 +5,13 @@ import pathlib
from tempfile import TemporaryDirectory
import stat
import nose
from nose.tools import assert_equal, assert_true, assert_false
import pytest
from xonsh.platform import ON_WINDOWS
from xonsh.lexer import Lexer
from xonsh.tools import (
CommandsCache, EnvPath, always_false, always_true, argvquote,
EnvPath, always_false, always_true, argvquote,
bool_or_int_to_str, bool_to_str, check_for_partial_string,
dynamic_cwd_tuple_to_str, ensure_int_or_slice, ensure_string,
env_path_to_str, escape_windows_cmd_string, executables_in,
@ -25,44 +24,50 @@ from xonsh.tools import (
is_string_seq, pathsep_to_seq, seq_to_pathsep, is_nonstring_seq_of_strings,
pathsep_to_upper_seq, seq_to_upper_pathsep,
)
from xonsh.commands_cache import CommandsCache
from tools import mock_xonsh_env
LEXER = Lexer()
LEXER.build()
INDENT = ' '
TOOLS_ENV = {'EXPAND_ENV_VARS': True, 'XONSH_ENCODING_ERRORS':'strict'}
ENCODE_ENV_ONLY = {'XONSH_ENCODING_ERRORS': 'strict'}
PATHEXT_ENV = {'PATHEXT': ['.COM', '.EXE', '.BAT']}
def test_subproc_toks_x():
exp = '![x]'
obs = subproc_toks('x', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_l():
exp = '![ls -l]'
obs = subproc_toks('ls -l', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_git():
s = 'git commit -am "hello doc"'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_git_semi():
s = 'git commit -am "hello doc"'
exp = '![{0}];'.format(s)
obs = subproc_toks(s + ';', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_git_nl():
s = 'git commit -am "hello doc"'
exp = '![{0}]\n'.format(s)
obs = subproc_toks(s + '\n', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls():
@ -70,7 +75,7 @@ def test_subproc_toks_indent_ls():
exp = INDENT + '![{0}]'.format(s)
obs = subproc_toks(INDENT + s, mincol=len(INDENT), lexer=LEXER,
returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_nl():
@ -78,35 +83,35 @@ def test_subproc_toks_indent_ls_nl():
exp = INDENT + '![{0}]\n'.format(s)
obs = subproc_toks(INDENT + s + '\n', mincol=len(INDENT), lexer=LEXER,
returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_no_min():
s = 'ls -l'
exp = INDENT + '![{0}]'.format(s)
obs = subproc_toks(INDENT + s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_no_min_nl():
s = 'ls -l'
exp = INDENT + '![{0}]\n'.format(s)
obs = subproc_toks(INDENT + s + '\n', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_no_min_semi():
s = 'ls'
exp = INDENT + '![{0}];'.format(s)
obs = subproc_toks(INDENT + s + ';', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_no_min_semi_nl():
s = 'ls'
exp = INDENT + '![{0}];\n'.format(s)
obs = subproc_toks(INDENT + s + ';\n', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_comment():
@ -114,7 +119,7 @@ def test_subproc_toks_ls_comment():
com = ' # lets list'
exp = '![{0}]{1}'.format(s, com)
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_42_comment():
@ -122,7 +127,7 @@ def test_subproc_toks_ls_42_comment():
com = ' # lets list'
exp = '![{0}]{1}'.format(s, com)
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_str_comment():
@ -130,7 +135,7 @@ def test_subproc_toks_ls_str_comment():
com = ' # lets list'
exp = '![{0}]{1}'.format(s, com)
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_comment():
@ -139,7 +144,7 @@ def test_subproc_toks_indent_ls_comment():
com = ' # lets list'
exp = '{0}![{1}]{2}'.format(ind, s, com)
obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_indent_ls_str():
@ -148,7 +153,7 @@ def test_subproc_toks_indent_ls_str():
com = ' # lets list'
exp = '{0}![{1}]{2}'.format(ind, s, com)
obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_l_semi_ls_first():
@ -157,7 +162,7 @@ def test_subproc_toks_ls_l_semi_ls_first():
s = '{0}; {1}'.format(lsdl, ls)
exp = '![{0}]; {1}'.format(lsdl, ls)
obs = subproc_toks(s, lexer=LEXER, maxcol=6, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_ls_l_semi_ls_second():
@ -166,7 +171,7 @@ def test_subproc_toks_ls_l_semi_ls_second():
s = '{0}; {1}'.format(lsdl, ls)
exp = '{0}; ![{1}]'.format(lsdl, ls)
obs = subproc_toks(s, lexer=LEXER, mincol=7, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_hello_mom_first():
@ -175,7 +180,7 @@ def test_subproc_toks_hello_mom_first():
s = '{0}; {1}'.format(fst, sec)
exp = '![{0}]; {1}'.format(fst, sec)
obs = subproc_toks(s, lexer=LEXER, maxcol=len(fst)+1, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_hello_mom_second():
@ -184,69 +189,69 @@ def test_subproc_toks_hello_mom_second():
s = '{0}; {1}'.format(fst, sec)
exp = '{0}; ![{1}]'.format(fst, sec)
obs = subproc_toks(s, lexer=LEXER, mincol=len(fst), returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_comment():
exp = None
obs = subproc_toks('# I am a comment', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_not():
exp = 'not ![echo mom]'
obs = subproc_toks('not echo mom', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_paren():
exp = '(![echo mom])'
obs = subproc_toks('(echo mom)', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_paren_ws():
exp = '(![echo mom]) '
obs = subproc_toks('(echo mom) ', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_not_paren():
exp = 'not (![echo mom])'
obs = subproc_toks('not (echo mom)', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_and_paren():
exp = 'True and (![echo mom])'
obs = subproc_toks('True and (echo mom)', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_paren_and_paren():
exp = '(![echo a]) and (echo b)'
obs = subproc_toks('(echo a) and (echo b)', maxcol=9, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_semicolon_only():
exp = None
obs = subproc_toks(';', lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_pyeval():
s = 'echo @(1+1)'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_twopyeval():
s = 'echo @(1+1) @(40 + 2)'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_pyeval_parens():
@ -254,7 +259,7 @@ def test_subproc_toks_pyeval_parens():
inp = '({0})'.format(s)
exp = '(![{0}])'.format(s)
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_twopyeval_parens():
@ -262,14 +267,14 @@ def test_subproc_toks_twopyeval_parens():
inp = '({0})'.format(s)
exp = '(![{0}])'.format(s)
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_pyeval_nested():
s = 'echo @(min(1, 42))'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_pyeval_nested_parens():
@ -277,21 +282,21 @@ def test_subproc_toks_pyeval_nested_parens():
inp = '({0})'.format(s)
exp = '(![{0}])'.format(s)
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_capstdout():
s = 'echo $(echo bat)'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_capproc():
s = 'echo !(echo bat)'
exp = '![{0}]'.format(s)
obs = subproc_toks(s, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subproc_toks_pyeval_redirect():
@ -299,7 +304,7 @@ def test_subproc_toks_pyeval_redirect():
inp = '{0}'.format(s)
exp = '![{0}]'.format(s)
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
assert_equal(exp, obs)
assert (exp == obs)
def test_subexpr_from_unbalanced_parens():
@ -310,7 +315,7 @@ def test_subexpr_from_unbalanced_parens():
]
for expr, exp in cases:
obs = subexpr_from_unbalanced(expr, '(', ')')
yield assert_equal, exp, obs
assert exp == obs
def test_find_next_break():
cases = [
@ -323,7 +328,7 @@ def test_find_next_break():
]
for line, mincol, exp in cases:
obs = find_next_break(line, mincol=mincol, lexer=LEXER)
yield assert_equal, exp, obs
assert exp == obs
def test_is_int():
@ -339,7 +344,7 @@ def test_is_int():
]
for inp, exp in cases:
obs = is_int(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_int_as_str():
@ -356,7 +361,7 @@ def test_is_int_as_str():
]
for inp, exp in cases:
obs = is_int_as_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_float():
@ -375,7 +380,7 @@ def test_is_float():
]
for inp, exp in cases:
obs = is_float(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_slice_as_str():
@ -399,33 +404,33 @@ def test_is_slice_as_str():
]
for inp, exp in cases:
obs = is_slice_as_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_string():
yield assert_true, is_string('42.0')
yield assert_false, is_string(42.0)
assert is_string('42.0')
assert not is_string(42.0)
def test_is_callable():
yield assert_true, is_callable(lambda: 42.0)
yield assert_false, is_callable(42.0)
assert is_callable(lambda: 42.0)
assert not is_callable(42.0)
def test_is_string_or_callable():
yield assert_true, is_string_or_callable('42.0')
yield assert_true, is_string_or_callable(lambda: 42.0)
yield assert_false, is_string(42.0)
assert is_string_or_callable('42.0')
assert is_string_or_callable(lambda: 42.0)
assert not is_string(42.0)
def test_always_true():
yield assert_true, always_true(42)
yield assert_true, always_true('42')
assert always_true(42)
assert always_true('42')
def test_always_false():
yield assert_false, always_false(42)
yield assert_false, always_false('42')
assert not always_false(42)
assert not always_false('42')
def test_ensure_string():
@ -435,7 +440,7 @@ def test_ensure_string():
]
for inp, exp in cases:
obs = ensure_string(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_pathsep_to_set():
@ -447,7 +452,7 @@ def test_pathsep_to_set():
]
for inp, exp in cases:
obs = pathsep_to_set(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_set_to_pathsep():
@ -459,19 +464,19 @@ def test_set_to_pathsep():
]
for inp, exp in cases:
obs = set_to_pathsep(inp, sort=(len(inp) > 1))
yield assert_equal, exp, obs
assert exp == obs
def test_is_string_seq():
yield assert_true, is_string_seq('42.0')
yield assert_true, is_string_seq(['42.0'])
yield assert_false, is_string_seq([42.0])
assert is_string_seq('42.0')
assert is_string_seq(['42.0'])
assert not is_string_seq([42.0])
def test_is_nonstring_seq_of_strings():
yield assert_false, is_nonstring_seq_of_strings('42.0')
yield assert_true, is_nonstring_seq_of_strings(['42.0'])
yield assert_false, is_nonstring_seq_of_strings([42.0])
assert not is_nonstring_seq_of_strings('42.0')
assert is_nonstring_seq_of_strings(['42.0'])
assert not is_nonstring_seq_of_strings([42.0])
def test_pathsep_to_seq():
@ -483,7 +488,7 @@ def test_pathsep_to_seq():
]
for inp, exp in cases:
obs = pathsep_to_seq(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_seq_to_pathsep():
@ -495,7 +500,7 @@ def test_seq_to_pathsep():
]
for inp, exp in cases:
obs = seq_to_pathsep(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_pathsep_to_upper_seq():
@ -507,7 +512,7 @@ def test_pathsep_to_upper_seq():
]
for inp, exp in cases:
obs = pathsep_to_upper_seq(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_seq_to_upper_pathsep():
@ -519,7 +524,7 @@ def test_seq_to_upper_pathsep():
]
for inp, exp in cases:
obs = seq_to_upper_pathsep(inp)
yield assert_equal, exp, obs
assert exp == obs
@ -534,7 +539,7 @@ def test_is_env_path():
]
for inp, exp in cases:
obs = is_env_path(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_str_to_env_path():
@ -546,7 +551,7 @@ def test_str_to_env_path():
]
for inp, exp in cases:
obs = str_to_env_path(inp)
yield assert_equal, exp, obs.paths
assert exp == obs.paths
def test_env_path_to_str():
@ -557,7 +562,7 @@ def test_env_path_to_str():
]
for inp, exp in cases:
obs = env_path_to_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_env_path():
@ -570,9 +575,15 @@ def test_env_path():
('~/', '~/'),
(b'~/../', '~/../'),
]
for inp, exp in getitem_cases:
obs = EnvPath(inp)[0] # call to __getitem__
yield assert_equal, expand(exp), obs
with mock_xonsh_env(TOOLS_ENV):
for inp, exp in getitem_cases:
obs = EnvPath(inp)[0] # call to __getitem__
assert expand(exp) == obs
with mock_xonsh_env(ENCODE_ENV_ONLY):
for inp, exp in getitem_cases:
obs = EnvPath(inp)[0] # call to __getitem__
assert exp == obs
# cases that involve path-separated strings
multipath_cases = [
@ -581,9 +592,15 @@ def test_env_path():
('/home/wakka' + os.pathsep + '/home/jakka' + os.pathsep + '~/',
['/home/wakka', '/home/jakka', '~/'])
]
for inp, exp in multipath_cases:
obs = [i for i in EnvPath(inp)]
yield assert_equal, [expand(i) for i in exp], obs
with mock_xonsh_env(TOOLS_ENV):
for inp, exp in multipath_cases:
obs = [i for i in EnvPath(inp)]
assert [expand(i) for i in exp] == obs
with mock_xonsh_env(ENCODE_ENV_ONLY):
for inp, exp in multipath_cases:
obs = [i for i in EnvPath(inp)]
assert [i for i in exp] == obs
# cases that involve pathlib.Path objects
pathlib_cases = [
@ -598,11 +615,11 @@ def test_env_path():
['/home/wakka', '~', '~/']),
]
for inp, exp in pathlib_cases:
# iterate over EnvPath to acquire all expanded paths
obs = [i for i in EnvPath(inp)]
yield assert_equal, [expand(i) for i in exp], obs
with mock_xonsh_env(TOOLS_ENV):
for inp, exp in pathlib_cases:
# iterate over EnvPath to acquire all expanded paths
obs = [i for i in EnvPath(inp)]
assert [expand(i) for i in exp] == obs
def test_env_path_slices():
# build os-dependent paths properly
@ -618,7 +635,7 @@ def test_env_path_slices():
for inp, exp in slice_last:
obs = EnvPath(inp)[:-1]
yield assert_equal, exp, obs
assert exp == obs
# get all except the first element in a slice
slice_first = [
@ -630,7 +647,7 @@ def test_env_path_slices():
for inp, exp in slice_first:
obs = EnvPath(inp)[1:]
yield assert_equal, exp, obs
assert exp == obs
# slice paths with a step
slice_step = [
@ -645,9 +662,9 @@ def test_env_path_slices():
for inp, exp_a, exp_b in slice_step:
obs_a = EnvPath(inp)[0::2]
yield assert_equal, exp_a, obs_a
assert exp_a == obs_a
obs_b = EnvPath(inp)[1::2]
yield assert_equal, exp_b, obs_b
assert exp_b == obs_b
# keep only non-home paths
slice_normal = [
@ -661,14 +678,14 @@ def test_env_path_slices():
for inp, exp in slice_normal:
obs = EnvPath(inp)[2:4]
yield assert_equal, exp, obs
assert exp == obs
def test_is_bool():
yield assert_equal, True, is_bool(True)
yield assert_equal, True, is_bool(False)
yield assert_equal, False, is_bool(1)
yield assert_equal, False, is_bool('yooo hooo!')
assert True == is_bool(True)
assert True == is_bool(False)
assert False == is_bool(1)
assert False == is_bool('yooo hooo!')
def test_to_bool():
@ -687,12 +704,12 @@ def test_to_bool():
]
for inp, exp in cases:
obs = to_bool(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_bool_to_str():
yield assert_equal, '1', bool_to_str(True)
yield assert_equal, '', bool_to_str(False)
assert '1' == bool_to_str(True)
assert '' == bool_to_str(False)
def test_is_bool_or_int():
@ -706,7 +723,7 @@ def test_is_bool_or_int():
]
for inp, exp in cases:
obs = is_bool_or_int(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_to_bool_or_int():
@ -725,7 +742,7 @@ def test_to_bool_or_int():
]
for inp, exp in cases:
obs = to_bool_or_int(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_bool_or_int_to_str():
@ -737,7 +754,7 @@ def test_bool_or_int_to_str():
]
for inp, exp in cases:
obs = bool_or_int_to_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_ensure_int_or_slice():
@ -757,7 +774,7 @@ def test_ensure_int_or_slice():
]
for inp, exp in cases:
obs = ensure_int_or_slice(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_dynamic_cwd_width():
@ -771,7 +788,7 @@ def test_is_dynamic_cwd_width():
]
for inp, exp in cases:
obs = is_dynamic_cwd_width(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_is_logfile_opt():
cases = [
@ -789,7 +806,7 @@ def test_is_logfile_opt():
cases.append(('/dev/null', True))
for inp, exp in cases:
obs = is_logfile_opt(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_to_logfile_opt():
cases = [
@ -804,7 +821,7 @@ def test_to_logfile_opt():
cases.append(('/dev/nonexistent_dev', None))
for inp, exp in cases:
obs = to_logfile_opt(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_logfile_opt_to_str():
cases = [
@ -815,7 +832,7 @@ def test_logfile_opt_to_str():
]
for inp, exp in cases:
obs = logfile_opt_to_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_to_dynamic_cwd_tuple():
cases = [
@ -829,7 +846,7 @@ def test_to_dynamic_cwd_tuple():
]
for inp, exp in cases:
obs = to_dynamic_cwd_tuple(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_dynamic_cwd_tuple_to_str():
@ -840,7 +857,7 @@ def test_dynamic_cwd_tuple_to_str():
]
for inp, exp in cases:
obs = dynamic_cwd_tuple_to_str(inp)
yield assert_equal, exp, obs
assert exp == obs
def test_escape_windows_cmd_string():
@ -854,7 +871,7 @@ def test_escape_windows_cmd_string():
]
for st, esc in cases:
obs = escape_windows_cmd_string(st)
yield assert_equal, esc, obs
assert esc == obs
def test_argvquote():
@ -870,7 +887,7 @@ def test_argvquote():
]
for st, esc in cases:
obs = argvquote(st)
yield assert_equal, esc, obs
assert esc == obs
_leaders = ('', 'not empty')
@ -891,28 +908,28 @@ inners = "this is a string"
def test_partial_string():
# single string at start
yield assert_equal, check_for_partial_string('no strings here'), (None, None, None)
yield assert_equal, check_for_partial_string(''), (None, None, None)
assert check_for_partial_string('no strings here') == (None, None, None)
assert check_for_partial_string('') == (None, None, None)
for s, e in _startend.items():
_test = s + inners + e
for l in _leaders:
for f in _leaders:
# single string
_res = check_for_partial_string(l + _test + f)
yield assert_equal, _res, (len(l), len(l) + len(_test), s)
assert _res == (len(l), len(l) + len(_test), s)
# single partial
_res = check_for_partial_string(l + f + s + inners)
yield assert_equal, _res, (len(l+f), None, s)
assert _res == (len(l+f), None, s)
for s2, e2 in _startend.items():
_test2 = s2 + inners + e2
for l2 in _leaders:
for f2 in _leaders:
# two strings
_res = check_for_partial_string(l + _test + f + l2 + _test2 + f2)
yield assert_equal, _res, (len(l+_test+f+l2), len(l+_test+f+l2+_test2), s2)
assert _res == (len(l+_test+f+l2), len(l+_test+f+l2+_test2), s2)
# one string, one partial
_res = check_for_partial_string(l + _test + f + l2 + s2 + inners)
yield assert_equal, _res, (len(l+_test+f+l2), None, s2)
assert _res == (len(l+_test+f+l2), None, s2)
def test_executables_in():
@ -947,8 +964,12 @@ def test_executables_in():
os.remove(tmp_path)
if executable and not _type == 'brokensymlink':
os.chmod(path, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR)
result = set(executables_in(test_path))
assert_equal(expected, result)
if ON_WINDOWS:
with mock_xonsh_env(PATHEXT_ENV):
result = set(executables_in(test_path))
else:
result = set(executables_in(test_path))
assert (expected == result)
def test_expand_case_matching():
@ -961,15 +982,11 @@ def test_expand_case_matching():
}
for inp, exp in cases.items():
obs = expand_case_matching(inp)
yield assert_equal, exp, obs
assert 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()
assert not cc.lazyin('xonsh')
assert 0 == len(list(cc.lazyiter()))
assert 0 == cc.lazylen()

View file

@ -3,8 +3,7 @@
from __future__ import unicode_literals, print_function
import os
import nose
from nose.tools import assert_equal, assert_true, assert_false
import pytest
from xonsh.wizard import (Node, Wizard, Pass, PrettyFormatter,
Message, Question, StateVisitor)
@ -19,9 +18,9 @@ def test_pretty_format_tree0():
" Message('yo')\n"
'])')
obs = PrettyFormatter(TREE0).visit()
yield assert_equal, exp, obs
yield assert_equal, exp, str(TREE0)
yield assert_equal, exp.replace('\n', ''), repr(TREE0)
assert exp == obs
assert exp == str(TREE0)
assert exp.replace('\n', '') == repr(TREE0)
def test_pretty_format_tree1():
@ -32,9 +31,9 @@ def test_pretty_format_tree1():
' }\n'
')')
obs = PrettyFormatter(TREE1).visit()
yield assert_equal, exp, obs
yield assert_equal, exp, str(TREE1)
yield assert_equal, exp.replace('\n', ''), repr(TREE1)
assert exp == obs
assert exp == str(TREE1)
assert exp.replace('\n', '') == repr(TREE1)
def test_state_visitor_store():
@ -42,12 +41,8 @@ def test_state_visitor_store():
sv = StateVisitor()
sv.store('/rick/2/and', 'morty')
obs = sv.state
yield assert_equal, exp, obs
assert exp == obs
exp['rick'][1]['mr'] = 'meeseeks'
sv.store('/rick/-2/mr', 'meeseeks')
yield assert_equal, exp, obs
if __name__ == '__main__':
nose.runmodule()
assert exp == obs

View file

@ -9,10 +9,11 @@ import subprocess
from collections import defaultdict
from contextlib import contextmanager
from nose.plugins.skip import SkipTest
import pytest
from xonsh.built_ins import ensure_list_of_strs
builtins.__xonsh_env__ = {}
from xonsh.environ import Env
builtins.__xonsh_env__ = Env()
from xonsh.base_shell import BaseShell
from xonsh.execer import Execer
from xonsh.tools import XonshBlockError
@ -22,9 +23,18 @@ VER_3_4 = (3, 4)
VER_3_5 = (3, 5)
VER_MAJOR_MINOR = sys.version_info[:2]
VER_FULL = sys.version_info[:3]
ON_MAC = (platform.system() == 'Darwin')
ON_DARWIN = (platform.system() == 'Darwin')
ON_WINDOWS = (platform.system() == 'Windows')
skip_if_py34 = pytest.mark.skipif(VER_MAJOR_MINOR < VER_3_5,
reason="Py3.5+ only test")
skip_if_py35plus = pytest.mark.skipif(VER_MAJOR_MINOR < VER_3_5,
reason="Py3.5+ only test")
def sp(cmd):
return subprocess.check_output(cmd, universal_newlines=True)
@ -89,19 +99,6 @@ def mock_xonsh_env(xenv):
del builtins.aliases
def skipper():
"""Raises SkipTest"""
raise SkipTest
def skip_if(cond):
"""Skips a test under a given condition."""
def dec(f):
if cond:
return skipper
else:
return f
return dec
#
# Execer tools
#

View file

@ -1,4 +1,4 @@
__version__ = '0.3.4'
__version__ = '0.4.1'
# amalgamate exclude jupyter_kernel parser_table parser_test_table pyghooks
# amalgamate exclude winutils wizard
@ -57,6 +57,8 @@ else:
_sys.modules['xonsh.proc'] = __amalgam__
xontribs = __amalgam__
_sys.modules['xonsh.xontribs'] = __amalgam__
commands_cache = __amalgam__
_sys.modules['xonsh.commands_cache'] = __amalgam__
environ = __amalgam__
_sys.modules['xonsh.environ'] = __amalgam__
history = __amalgam__
@ -88,4 +90,4 @@ else:
pass
del _sys
del _os
# amalgamate end
# amalgamate end

View file

@ -9,7 +9,6 @@ import builtins
from collections import Sequence
from contextlib import contextmanager
import inspect
from glob import iglob
import os
import re
import shlex
@ -21,7 +20,6 @@ import time
from xonsh.lazyasd import LazyObject
from xonsh.history import History
from xonsh.tokenize import SearchPath
from xonsh.inspectors import Inspector
from xonsh.aliases import Aliases, make_default_aliases
from xonsh.environ import Env, default_env, locate_binary
@ -32,9 +30,10 @@ from xonsh.proc import (ProcProxy, SimpleProcProxy, ForegroundProcProxy,
SimpleForegroundProcProxy, TeePTYProc,
CompletedCommand, HiddenCompletedCommand)
from xonsh.tools import (
suggest_commands, expandvars, CommandsCache, globpath, XonshError,
suggest_commands, expandvars, globpath, XonshError,
XonshCalledProcessError, XonshBlockError
)
from xonsh.commands_cache import CommandsCache
ENV = None
@ -417,14 +416,18 @@ def run_subproc(cmds, captured=False):
elif builtins.__xonsh_stderr_uncaptured__ is not None:
stderr = builtins.__xonsh_stderr_uncaptured__
uninew = (ix == last_cmd) and (not _capture_streams)
# find alias
if callable(cmd[0]):
alias = cmd[0]
else:
alias = builtins.aliases.get(cmd[0], None)
binary_loc = locate_binary(cmd[0])
procinfo['alias'] = alias
# find binary location, if not callable
if alias is None:
binary_loc = locate_binary(cmd[0])
elif not callable(alias):
binary_loc = locate_binary(alias[0])
# implement AUTO_CD
if (alias is None and
builtins.__xonsh_env__.get('AUTO_CD') and
len(cmd) == 1 and
@ -451,8 +454,8 @@ def run_subproc(cmds, captured=False):
if (stdin is not None and
ENV.get('XONSH_STORE_STDIN') and
captured == 'object' and
'cat' in __xonsh_commands_cache__ and
'tee' in __xonsh_commands_cache__):
__xonsh_commands_cache__.lazy_locate_binary('cat') and
__xonsh_commands_cache__.lazy_locate_binary('tee')):
_stdin_file = tempfile.NamedTemporaryFile()
cproc = Popen(['cat'],
stdin=stdin,

142
xonsh/commands_cache.py Normal file
View file

@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-
import builtins
import os
import collections.abc as abc
from xonsh.dirstack import _get_cwd
from xonsh.platform import ON_WINDOWS
from xonsh.tools import executables_in
class CommandsCache(abc.Mapping):
"""A lazy cache representing the commands available on the file system.
The keys are the command names and the values a tuple of (loc, has_alias)
where loc is either a str pointing to the executable on the file system or
None (if no executable exists) and has_alias is a boolean flag for whether
the command has an alias.
"""
def __init__(self):
self._cmds_cache = {}
self._path_checksum = None
self._alias_checksum = None
self._path_mtime = -1
def __contains__(self, key):
return key in self.all_commands
def __iter__(self):
return iter(self.all_commands)
def __len__(self):
return len(self.all_commands)
def __getitem__(self, key):
return self.all_commands[key]
def is_empty(self):
"""Returns whether the cache is populated or not."""
return len(self._cmds_cache) == 0
@staticmethod
def get_possible_names(name):
"""Generates the possible `PATHEXT` extension variants of a given executable
name on Windows as a list, conserving the ordering in `PATHEXT`.
Returns a list as `name` being the only item in it on other platforms."""
if ON_WINDOWS:
name = name.upper()
return [
name + ext
for ext in ([''] + builtins.__xonsh_env__['PATHEXT'])
]
else:
return [name]
@property
def all_commands(self):
paths = builtins.__xonsh_env__.get('PATH', [])
pathset = frozenset(x for x in paths if os.path.isdir(x))
# did PATH change?
path_hash = hash(pathset)
cache_valid = path_hash == self._path_checksum
self._path_checksum = path_hash
# did aliases change?
alss = getattr(builtins, 'aliases', set())
al_hash = hash(frozenset(alss))
cache_valid = cache_valid and al_hash == self._alias_checksum
self._alias_checksum = al_hash
# did the contents of any directory in PATH change?
max_mtime = 0
for path in pathset:
mtime = os.stat(path).st_mtime
if mtime > max_mtime:
max_mtime = mtime
cache_valid = cache_valid and (max_mtime <= self._path_mtime)
self._path_mtime = max_mtime
if cache_valid:
return self._cmds_cache
allcmds = {}
for path in reversed(paths):
# iterate backwards so that entries at the front of PATH overwrite
# entries at the back.
for cmd in executables_in(path):
key = cmd.upper() if ON_WINDOWS else cmd
allcmds[key] = (os.path.join(path, cmd), cmd in alss)
only_alias = (None, True)
for cmd in alss:
if cmd not in allcmds:
allcmds[cmd] = only_alias
self._cmds_cache = allcmds
return allcmds
def lazyin(self, key):
"""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 key 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 precisely
what is on the $PATH.
"""
return len(self._cmds_cache)
def lazyget(self, key, default=None):
"""A lazy value getter."""
return self._cmds_cache.get(key, default)
def locate_binary(self, name):
"""Locates an executable on the file system using the cache."""
# make sure the cache is up to date by accessing the property
_ = self.all_commands
return self.lazy_locate_binary(name)
def lazy_locate_binary(self, name):
"""Locates an executable in the cache, without checking its validity."""
possibilities = self.get_possible_names(name)
if ON_WINDOWS:
# Windows users expect to be able to execute files in the same
# directory without `./`
cwd = _get_cwd()
local_bin = next((
full_name for full_name in possibilities
if os.path.isfile(full_name)
), None)
if local_bin:
return os.path.abspath(os.path.relpath(local_bin, cwd))
cached = next((cmd for cmd in possibilities if cmd in self._cmds_cache), None)
if cached:
return self._cmds_cache[cached][0]
elif os.path.isfile(name) and name != os.path.basename(name):
return name

View file

@ -7,7 +7,6 @@ import json
import locale
import builtins
from contextlib import contextmanager
from functools import wraps
from itertools import chain
from pprint import pformat
import re
@ -16,30 +15,33 @@ import string
import subprocess
import shutil
from warnings import warn
from collections import (Mapping, MutableMapping, MutableSequence, MutableSet,
namedtuple)
from collections import (
Mapping, MutableMapping, MutableSequence, MutableSet,
namedtuple
)
from xonsh import __version__ as XONSH_VERSION
from xonsh.jobs import get_next_task
from xonsh.codecache import run_script_with_cache
from xonsh.dirstack import _get_cwd
from xonsh.foreign_shells import load_foreign_envs
from xonsh.platform import (BASH_COMPLETIONS_DEFAULT, ON_ANACONDA, ON_LINUX,
ON_WINDOWS, DEFAULT_ENCODING, ON_CYGWIN, PATH_DEFAULT)
from xonsh.platform import (
BASH_COMPLETIONS_DEFAULT, DEFAULT_ENCODING, PATH_DEFAULT,
ON_WINDOWS, ON_ANACONDA, ON_LINUX, ON_CYGWIN,
)
from xonsh.tools import (
is_superuser, always_true, always_false, ensure_string, is_env_path,
str_to_env_path, env_path_to_str, is_bool, to_bool, bool_to_str,
is_history_tuple, to_history_tuple, history_tuple_to_str, is_float,
is_string, is_callable, is_string_or_callable,
is_string, is_string_or_callable,
is_completions_display_value, to_completions_display_value,
is_string_set, csv_to_set, set_to_csv, get_sep, is_int, is_bool_seq,
is_bool_or_int, to_bool_or_int, bool_or_int_to_str,
to_bool_or_int, bool_or_int_to_str,
csv_to_bool_seq, bool_seq_to_csv, DefaultNotGiven, print_exception,
setup_win_unicode_console, intensify_colors_on_win_setter, format_color,
is_dynamic_cwd_width, to_dynamic_cwd_tuple, dynamic_cwd_tuple_to_str,
is_logfile_opt, to_logfile_opt, logfile_opt_to_str, executables_in,
pathsep_to_set, set_to_pathsep, pathsep_to_seq, seq_to_pathsep,
is_string_seq, is_nonstring_seq_of_strings, pathsep_to_upper_seq,
is_nonstring_seq_of_strings, pathsep_to_upper_seq,
seq_to_upper_pathsep,
)
@ -823,31 +825,7 @@ def _yield_executables(directory, name):
def locate_binary(name):
"""Locates an executable on the file system."""
if ON_WINDOWS:
# Windows users expect to be able to execute files in the same
# directory without `./`
cwd = _get_cwd()
if os.path.isfile(name):
return os.path.abspath(os.path.relpath(name, cwd))
exts = builtins.__xonsh_env__['PATHEXT']
for ext in exts:
namext = name + ext
if os.path.isfile(namext):
return os.path.abspath(os.path.relpath(namext, cwd))
elif os.path.isfile(name) and name != os.path.basename(name):
return name
cc = builtins.__xonsh_commands_cache__
if ON_WINDOWS:
upname = name.upper()
if upname in cc:
return cc.lazyget(upname)[0]
for ext in exts:
upnamext = upname + ext
if cc.lazyin(upnamext):
return cc.lazyget(upnamext)[0]
elif name in cc:
# can be lazy here since we know name is already available
return cc.lazyget(name)[0]
return builtins.__xonsh_commands_cache__.locate_binary(name)
def get_git_branch():
@ -957,14 +935,14 @@ def _first_branch_timeout_message():
def current_branch(pad=True):
"""Gets the branch for a current working directory. Returns an empty string
if the cwd is not a repository. This currently only works for git and hg
and should be extended in the future. If a timeout occured, the string
and should be extended in the future. If a timeout occurred, the string
'<branch-timeout>' is returned.
"""
branch = ''
cmds = builtins.__xonsh_commands_cache__
if cmds.lazyin('git') or cmds.lazylen() == 0:
if cmds.lazy_locate_binary('git') or cmds.is_empty():
branch = get_git_branch()
if (cmds.lazyin('hg') or cmds.lazylen() == 0) and not branch:
if (cmds.lazy_locate_binary('hg') or cmds.is_empty()) and not branch:
branch = get_hg_branch()
if isinstance(branch, subprocess.TimeoutExpired):
branch = '<branch-timeout>'
@ -1028,16 +1006,16 @@ def dirty_working_directory(cwd=None):
"""
dwd = None
cmds = builtins.__xonsh_commands_cache__
if cmds.lazyin('git') or cmds.lazylen() == 0:
if cmds.lazy_locate_binary('git') or cmds.is_empty():
dwd = git_dirty_working_directory()
if (cmds.lazyin('hg') or cmds.lazylen() == 0) and (dwd is None):
if (cmds.lazy_locate_binary('hg') or cmds.is_empty()) and (dwd is None):
dwd = hg_dirty_working_directory()
return dwd
def branch_color():
"""Return red if the current branch is dirty, yellow if the dirtiness can
not be determined, and green if it clean. Thes are bold, intesnse colors
not be determined, and green if it clean. These are bold, intense colors
for the foreground.
"""
dwd = dirty_working_directory()

View file

@ -152,7 +152,7 @@ else:
_libc.sigprocmask(ctypes.c_int(signal.SIG_BLOCK),
ctypes.byref(mask),
ctypes.byref(omask))
_libc.tcsetpgrp(ctypes.c_int(shtty), ctypes.c_int(pgid))
_libc.tcsetpgrp(ctypes.c_int(st), ctypes.c_int(pgid))
_libc.sigprocmask(ctypes.c_int(signal.SIG_SETMASK),
ctypes.byref(omask), None)
else:

View file

@ -6,6 +6,7 @@ import enum
import builtins
import importlib
from contextlib import contextmanager
import argparse
from argparse import ArgumentParser, ArgumentTypeError
try:
@ -95,7 +96,7 @@ parser.add_argument('-D',
help='define an environment variable, in the form of '
'-DNAME=VAL. May be used many times.',
metavar='ITEM',
nargs='*',
action='append',
default=None)
parser.add_argument('--shell-type',
help='What kind of shell should be used. '
@ -114,7 +115,7 @@ parser.add_argument('args',
metavar='args',
help='Additional arguments to the script specified '
'by script-file',
nargs='*',
nargs=argparse.REMAINDER,
default=[])
@ -147,30 +148,19 @@ class XonshMode(enum.Enum):
def premain(argv=None):
"""Setup for main xonsh entry point, returns parsed arguments."""
if argv is None:
argv = sys.argv[1:]
if setproctitle is not None:
setproctitle(' '.join(['xonsh'] + sys.argv[1:]))
setproctitle(' '.join(['xonsh'] + argv))
builtins.__xonsh_ctx__ = {}
args, other = parser.parse_known_args(argv)
if args.file is not None:
arguments = (argv or sys.argv)
file_index = arguments.index(args.file)
# A script-file was passed and is to be executed. The argument parser
# might have parsed switches intended for the script, so reset the
# parsed switches to their default values
old_args = args
args = parser.parse_known_args('')[0]
args.file = old_args.file
# Save the arguments that are intended for the script-file. Switches
# and positional arguments passed before the path to the script-file are
# ignored.
args.args = arguments[file_index+1:]
args = parser.parse_args(argv)
if args.help:
parser.print_help()
exit()
parser.exit()
if args.version:
version = '/'.join(('xonsh', __version__)),
print(version)
exit()
parser.exit()
shell_kwargs = {'shell_type': args.shell_type,
'completer': False,
'login': False,
@ -203,7 +193,7 @@ def premain(argv=None):
env['XONSH_LOGIN'] = shell_kwargs['login']
if args.defines is not None:
env.update([x.split('=', 1) for x in args.defines])
env['XONSH_INTERACTIVE'] = False
env['XONSH_INTERACTIVE'] = args.force_interactive
if ON_WINDOWS:
setup_win_unicode_console(env.get('WIN_UNICODE_CONSOLE', True))
return args
@ -211,10 +201,23 @@ def premain(argv=None):
def main(argv=None):
"""Main entry point for xonsh cli."""
if argv is None:
argv = sys.argv[1:]
args = premain(argv)
env = builtins.__xonsh_env__
shell = builtins.__xonsh_shell__
if args.mode == XonshMode.single_command:
if args.mode == XonshMode.interactive:
# enter the shell
env['XONSH_INTERACTIVE'] = True
ignore_sigtstp()
if (env['XONSH_INTERACTIVE'] and
not env['LOADED_CONFIG'] and
not any(os.path.isfile(i) for i in env['XONSHRC'])):
print('Could not find xonsh configuration or run control files.',
file=sys.stderr)
xonfig_main(['wizard', '--confirm'])
shell.shell.cmdloop()
elif args.mode == XonshMode.single_command:
# run a single command and exit
run_code_with_cache(args.command.lstrip(), shell.execer, mode='single')
elif args.mode == XonshMode.script_from_file:
@ -233,17 +236,6 @@ def main(argv=None):
code = sys.stdin.read()
run_code_with_cache(code, shell.execer, glb=shell.ctx, loc=None,
mode='exec')
else:
# otherwise, enter the shell
env['XONSH_INTERACTIVE'] = True
ignore_sigtstp()
if (env['XONSH_INTERACTIVE'] and
not env['LOADED_CONFIG'] and
not any(os.path.isfile(i) for i in env['XONSHRC'])):
print('Could not find xonsh configuration or run control files.',
file=sys.stderr)
xonfig_main(['wizard', '--confirm'])
shell.shell.cmdloop()
postmain(args)

View file

@ -81,7 +81,7 @@ def pygments_version():
@functools.lru_cache(1)
def has_prompt_toolkit():
""" Tests if the `prompt_toolkit` is available. """
spec = importlib.util.find_spec('pygments')
spec = importlib.util.find_spec('prompt_toolkit')
return (spec is not None)

View file

@ -69,7 +69,7 @@ class PromptToolkitHistoryAdder(Thread):
continue
buf.reset(initial_document=buf.document)
lj.close()
except (IOError, OSError):
except (IOError, OSError, ValueError):
continue
def _buf(self):

View file

@ -469,5 +469,5 @@ class ReadlineHistoryAdder(Thread):
RL_LIB.history_set_pos(i)
i += 1
lj.close()
except (IOError, OSError):
except (IOError, OSError, ValueError):
continue

View file

@ -17,30 +17,32 @@ Implementations:
* indent()
"""
import os
import re
import sys
import ast
import glob
import string
import ctypes
import builtins
import pathlib
import warnings
import functools
import threading
import traceback
import subprocess
import collections
import collections.abc as abc
import ctypes
import functools
import glob
import os
import pathlib
import re
import string
import subprocess
import sys
import threading
import traceback
import warnings
from contextlib import contextmanager
from subprocess import CalledProcessError
# adding further imports from xonsh modules is discouraged to avoid cirular
# adding further imports from xonsh modules is discouraged to avoid circular
# dependencies
from xonsh.lazyasd import LazyObject, LazyDict
from xonsh.platform import (has_prompt_toolkit, scandir,
DEFAULT_ENCODING, ON_LINUX, ON_WINDOWS, PYTHON_VERSION_INFO)
from xonsh.platform import (
has_prompt_toolkit, scandir,
DEFAULT_ENCODING, ON_LINUX, ON_WINDOWS, PYTHON_VERSION_INFO,
)
@functools.lru_cache(1)
def is_superuser():
@ -118,7 +120,7 @@ def decode_bytes(path):
env = getattr(builtins, '__xonsh_env__', os.environ)
enc = env.get('XONSH_ENCODING', DEFAULT_ENCODING)
return path.decode(encoding=enc,
errors=env.get('XONSH_ENCODING_ERRORS'))
errors=env.get('XONSH_ENCODING_ERRORS') or 'strict')
class EnvPath(collections.MutableSequence):
@ -583,10 +585,15 @@ def suggest_commands(cmd, env, aliases):
def print_exception(msg=None):
"""Print exceptions with/without traceback."""
env = getattr(builtins, '__xonsh_env__', os.environ)
env = getattr(builtins, '__xonsh_env__', None)
# flags indicating whether the traceback options have been manually set
manually_set_trace = env.is_manually_set('XONSH_SHOW_TRACEBACK')
manually_set_logfile = env.is_manually_set('XONSH_TRACEBACK_LOGFILE')
if env is None:
env = os.environ
manually_set_trace = 'XONSH_SHOW_TRACEBACK' in env
manually_set_logfile ='XONSH_TRACEBACK_LOGFILE' in env
else:
manually_set_trace = env.is_manually_set('XONSH_SHOW_TRACEBACK')
manually_set_logfile = env.is_manually_set('XONSH_TRACEBACK_LOGFILE')
if (not manually_set_trace) and (not manually_set_logfile):
# Notify about the traceback output possibility if neither of
# the two options have been manually set
@ -604,7 +611,6 @@ def print_exception(msg=None):
sys.stderr.write('xonsh: To log full traceback to a file set: '
'$XONSH_TRACEBACK_LOGFILE = <filename>\n')
traceback.print_exc()
# additionally, check if a file for traceback logging has been
# specified and convert to a proper option if needed
log_file = env.get('XONSH_TRACEBACK_LOGFILE', None)
@ -1546,101 +1552,12 @@ def expanduser_abs_path(inp):
return os.path.abspath(os.path.expanduser(inp))
class CommandsCache(abc.Mapping):
"""A lazy cache representing the commands available on the file system.
The keys are the command names and the values a tuple of (loc, has_alias)
where loc is either a str pointing to the executable on the file system or
None (if no executable exists) and has_alias is a boolean flag for whether
the command has an alias.
"""
def __init__(self):
self._cmds_cache = {}
self._path_checksum = None
self._alias_checksum = None
self._path_mtime = -1
def __contains__(self, key):
return key in self.all_commands
def __iter__(self):
return iter(self.all_commands)
def __len__(self):
return len(self.all_commands)
def __getitem__(self, key):
return self.all_commands[key]
@property
def all_commands(self):
paths = builtins.__xonsh_env__.get('PATH', [])
pathset = frozenset(x for x in paths if os.path.isdir(x))
# did PATH change?
path_hash = hash(pathset)
cache_valid = path_hash == self._path_checksum
self._path_checksum = path_hash
# did aliases change?
alss = getattr(builtins, 'aliases', set())
al_hash = hash(frozenset(alss))
cache_valid = cache_valid and al_hash == self._alias_checksum
self._alias_checksum = al_hash
# did the contents of any directory in PATH change?
max_mtime = 0
for path in pathset:
mtime = os.stat(path).st_mtime
if mtime > max_mtime:
max_mtime = mtime
cache_valid = cache_valid and (max_mtime <= self._path_mtime)
self._path_mtime = max_mtime
if cache_valid:
return self._cmds_cache
allcmds = {}
for path in reversed(paths):
# iterate backwards so that entries at the front of PATH overwrite
# entries at the back.
for cmd in executables_in(path):
key = cmd.upper() if ON_WINDOWS else cmd
allcmds[key] = (os.path.join(path, cmd), cmd in alss)
only_alias = (None, True)
for cmd in alss:
if cmd not in allcmds:
allcmds[cmd] = only_alias
self._cmds_cache = allcmds
return allcmds
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)
def lazyget(self, key, default=None):
"""A lazy value getter."""
return self._cmds_cache.get(key, default)
WINDOWS_DRIVE_MATCHER = LazyObject(lambda: re.compile(r'^\w:'),
globals(), 'WINDOWS_DRIVE_MATCHER')
def expand_case_matching(s):
"""Expands a string to a case insenstive globable string."""
"""Expands a string to a case insensitive globable string."""
t = []
openers = {'[', '{'}
closers = {']', '}'}

View file

@ -35,10 +35,15 @@
"bit of the startup time when running your favorite, minimal ",
"text editor."]
},
{"name": "xonsh-apt-tabcomplete",
{"name": "apt_tabcomplete",
"package": "xonsh-apt-tabcomplete",
"url": "https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete",
"description": ["Adds tabcomplete functionality to apt-get/apt-cache inside of xonsh."]
},
{"name": "pacman_tabcomplete",
"package": "xonsh-pacman-tabcomplete",
"url": "https://github.com/gforsyth/xonsh-pacman-tabcomplete",
"description": ["Adds tabcomplete functionality to pacman inside of xonsh."]
}
],
"packages": {
@ -71,6 +76,13 @@
"install": {
"pip": "pip install xonsh-apt-tabcomplete"
}
},
"xonsh-pacman-tabcomplete": {
"license": "MIT",
"url": "https://github.com/gforsyth/xonsh-pacman-tabcomplete",
"install": {
"pip": "pip install xonsh-pacman-tabcomplete"
}
}
}
}