mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
fixed conflict
This commit is contained in:
commit
e97d02db16
69 changed files with 1598 additions and 1969 deletions
|
@ -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
3
.gitignore
vendored
|
@ -38,3 +38,6 @@ include/
|
|||
|
||||
# Editor project files
|
||||
*.komodo*
|
||||
.cache
|
||||
|
||||
.coverage
|
||||
|
|
|
@ -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
|
||||
|
|
179
CHANGELOG.rst
179
CHANGELOG.rst
|
@ -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
|
||||
====================
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
||||
|
|
10
docs/api/commands_cache.rst
Normal file
10
docs/api/commands_cache.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
.. _xonsh_commands_cache:
|
||||
|
||||
******************************************************
|
||||
Commands Cache (``xonsh.commands_cache``)
|
||||
******************************************************
|
||||
|
||||
.. automodule:: xonsh.commands_cache
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
|
@ -4,7 +4,7 @@
|
|||
File System Path Completer (``xonsh.completers.path``)
|
||||
**********************************************************
|
||||
|
||||
.. automodule:: xonsh.completers.base
|
||||
.. automodule:: xonsh.completers.path
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
|
|
@ -55,6 +55,7 @@ For those of you who want the gritty details.
|
|||
teepty
|
||||
openpy
|
||||
foreign_shells
|
||||
commands_cache
|
||||
tracer
|
||||
main
|
||||
pyghooks
|
||||
|
|
68
news/035.rst
68
news/035.rst
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
20
news/cc.rst
20
news/cc.rst
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,13 +0,0 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* Fixed a problem with aliases not always beeing found.
|
||||
|
||||
**Security:** None
|
|
@ -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
|
|
@ -1,13 +0,0 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* Bug where xonfig wizard can't find ENV docs
|
||||
|
||||
**Security:** None
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
14
news/pid.rst
14
news/pid.rst
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,13 +0,0 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:**
|
||||
|
||||
* Ignore case and leading a quotes when sorting completions
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:** None
|
||||
|
||||
**Security:** None
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,13 +0,0 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:** None
|
||||
|
||||
* Bug preventing `xonsh` executable being installed on macOS.
|
||||
|
||||
**Security:** None
|
|
@ -1,5 +1,5 @@
|
|||
ply
|
||||
nose
|
||||
pytest
|
||||
prompt-toolkit
|
||||
pygments
|
||||
coverage
|
||||
|
|
|
@ -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)
|
13
setup.py
13
setup.py
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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})
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
1176
tests/test_parser.py
1176
tests/test_parser.py
File diff suppressed because it is too large
Load diff
|
@ -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]
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
142
xonsh/commands_cache.py
Normal 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
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
139
xonsh/tools.py
139
xonsh/tools.py
|
@ -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 = {']', '}'}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue