Merge branch 'master' into hist_ref

This commit is contained in:
laerus 2016-07-23 12:30:24 +03:00
commit 52af21d482
10 changed files with 163 additions and 89 deletions

View file

@ -15,6 +15,33 @@ develop xonsh.
.. note:: All code changes must go through the pull request review procedure.
Making Your First Change
========================
First, install xonsh from source and open a xonsh shell in your favorite
terminal application. See installation instructions for details.
Next, make a trivial change (e.g. ``print("hello!")`` in ``main.py``).
Finally, run the following commands. You should see the effects of your change
(e.g. ``hello!``)::
$ $XONSH_DEBUG=1
$ xonsh
The xonsh build process collapses all Python source files into a single
``__amalgam__.py`` file. When xonsh is started with a falsy value for
`$XONSH_DEBUG <envvars.html>`_, it imports Python modules straight from
``__amalgam__.py``, which decreases startup times by eliminating the cost of
runtime imports. But setting ``$ $XONSH_DEBUG=1`` will suppress amalgamated
imports. Reloading the xonsh shell (``$ xonsh``) won't simply import the stale
``__amalgam__.py`` file that doesn't contain your new change, but will instead
import the unamalgamated source code which does contain your change. You can now
load every subsequent change by reloading xonsh, and if your code changes don't
seem to have any effect, make sure you check ``$XONSH_DEBUG`` first!
Changelog
=========
Pull requests will often have CHANGELOG entries associated with. However,
@ -169,7 +196,7 @@ Run all the tests using pytest::
$ py.test -q
Use "-q" to keep pytest from outputting a bunch of info for every test.
Use "-q" to keep pytest from outputting a bunch of info for every test.
----------------------------------
Running the Tests - Advanced

View file

@ -244,7 +244,9 @@ Contributing
We highly encourage contributions to xonsh! If you would like to contribute,
it is as easy as forking the repository on GitHub, making your changes, and
issuing a pull request. If you have any questions about this process don't
hesitate to ask the mailing list (xonsh@googlegroups.com).
hesitate to ask the mailing list (xonsh@googlegroups.com) or the `Gitter <https://gitter.im/xonsh/xonsh>`_ channel.
See the `Developer's Guide <devguide.html>`_ for more information about contributing.
==========
Contact Us

View file

@ -5,9 +5,9 @@ Here are some talks, articles, and other sundry about your favorite shell.
Talks
============
**PyCon 2016:** presented by Anthony Scopatz
**Python Nordeste 2016:** presented by Lucas Inojosa http://lucasicf.github.io/talks/shell_python/
**Python Nordeste 2016:** presented by Lucas Inojosa <http://lucasicf.github.io/talks/shell_python/>
**PyCon 2016:** presented by Anthony Scopatz
.. raw:: html

16
news/enc.rst Normal file
View file

@ -0,0 +1,16 @@
**Added:**
* ``xon.sh`` script now sets ``$LANG=C.UTF8`` in the event that no encoding
is detected.
**Changed:**
* xonfig command now dumps more encoding related settings.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

14
news/vox_opts.rst Normal file
View file

@ -0,0 +1,14 @@
**Added:** None
**Changed:**
* The vox xontrib now takes flags very similar to Python's venv tool. Use
``vox --help <command>`` to learn more.
**Deprecated:** None
**Removed:** None
**Fixed:** None
**Security:** None

View file

@ -1,2 +1,10 @@
#!/bin/sh
# set locale if it is totally undefined
if [ -z "${LC_ALL+x}" ] && [ -z "${LC_CTYPE+x}" ] && \
[ -z "${LANG+x}" ] && [ -z "${LANGUAGE+x}" ]; then
export LANG=C.UTF-8
fi
# run python
/usr/bin/env PYTHONUNBUFFERED=1 python3 -u -m xonsh $@

View file

@ -23,6 +23,7 @@ class _TeeOut(object):
self.buffer = buf
self.stdout = sys.stdout
self.encoding = self.stdout.encoding
self.errors = self.stdout.errors
sys.stdout = self
def __del__(self):
@ -55,6 +56,7 @@ class _TeeErr(object):
self.buffer = buf
self.stderr = sys.stderr
self.encoding = self.stderr.encoding
self.errors = self.stderr.errors
sys.stderr = self
def __del__(self):

View file

@ -110,6 +110,7 @@ DEFAULT_ENSURERS = LazyObject(lambda: {
'IGNOREEOF': (is_bool, to_bool, bool_to_str),
'INTENSIFY_COLORS_ON_WIN': (always_false, intensify_colors_on_win_setter,
bool_to_str),
'LANG': (is_string, ensure_string, ensure_string),
'LC_COLLATE': (always_false, locale_convert('LC_COLLATE'), ensure_string),
'LC_CTYPE': (always_false, locale_convert('LC_CTYPE'), ensure_string),
'LC_MESSAGES': (always_false, locale_convert('LC_MESSAGES'), ensure_string),
@ -253,6 +254,7 @@ def DEFAULT_VALUES():
'IGNOREEOF': False,
'INDENT': ' ',
'INTENSIFY_COLORS_ON_WIN': True,
'LANG': 'C.UTF-8',
'LC_CTYPE': locale.setlocale(locale.LC_CTYPE),
'LC_COLLATE': locale.setlocale(locale.LC_COLLATE),
'LC_TIME': locale.setlocale(locale.LC_TIME),
@ -429,6 +431,7 @@ DEFAULT_DOCS = LazyObject(lambda: {
'which are hard to read, are replaced with cyan. Other colors are '
'generally replaced by their bright counter parts.',
configurable=ON_WINDOWS),
'LANG': VarDocs('Fallback locale setting for systems where it matters'),
'LOADED_CONFIG': VarDocs(
'Whether or not the xonsh config file was loaded',
configurable=False),

View file

@ -336,6 +336,7 @@ def _xonfig_format_json(data):
def _info(ns):
env = builtins.__xonsh_env__
data = [
('xonsh', XONSH_VERSION),
('Git SHA', githash()),
@ -343,9 +344,9 @@ def _info(ns):
('PLY', ply.__version__),
('have readline', is_readline_available()),
('prompt toolkit', ptk_version() or None),
('shell type', builtins.__xonsh_env__.get('SHELL_TYPE')),
('shell type', env.get('SHELL_TYPE')),
('pygments', pygments_version()),
('on posix', ON_POSIX),
('on posix', bool(ON_POSIX)),
('on linux', ON_LINUX)]
if ON_LINUX:
data.append(('distro', linux_distro()))
@ -355,6 +356,8 @@ def _info(ns):
('on cygwin', ON_CYGWIN),
('is superuser', is_superuser()),
('default encoding', DEFAULT_ENCODING),
('xonsh encoding', env.get('XONSH_ENCODING')),
('encoding errors', env.get('XONSH_ENCODING_ERRORS')),
])
formatter = _xonfig_format_json if ns.json else _xonfig_format_human
s = formatter(data)

View file

@ -2,77 +2,108 @@
import sys as _sys
import xontrib.voxapi as _voxapi
import xonsh.lazyasd as _lazyasd
class _VoxHandler:
"""Vox is a virtual environment manager for xonsh."""
def parser():
from argparse import ArgumentParser
parser = ArgumentParser(prog='vox', description=__doc__)
subparsers = parser.add_subparsers(dest='command')
create = subparsers.add_parser(
'new', aliases=['create'],
help='Create a new virtual environment'
)
create.add_argument('name', metavar='ENV',
help='The environments to create')
create.add_argument('--system-site-packages', default=False,
action='store_true', dest='system_site',
help='Give the virtual environment access to the '
'system site-packages dir.')
from xonsh.platform import ON_WINDOWS
group = create.add_mutually_exclusive_group()
group.add_argument('--symlinks', default=not ON_WINDOWS,
action='store_true', dest='symlinks',
help='Try to use symlinks rather than copies, '
'when symlinks are not the default for '
'the platform.')
group.add_argument('--copies', default=ON_WINDOWS,
action='store_false', dest='symlinks',
help='Try to use copies rather than symlinks, '
'even when symlinks are the default for '
'the platform.')
create.add_argument('--without-pip', dest='with_pip',
default=True, action='store_false',
help='Skips installing or upgrading pip in the '
'virtual environment (pip is bootstrapped '
'by default)')
activate = subparsers.add_parser(
'activate', aliases=['workon', 'enter'],
help='Activate virtual environment'
)
activate.add_argument('name', metavar='ENV',
help='The environment to activate')
subparsers.add_parser('deactivate', aliases=['exit'], help='Deactivate current virtual environment')
subparsers.add_parser('list', aliases=['ls'], help='List all available environments')
remove = subparsers.add_parser('remove', aliases=['rm', 'delete', 'del'], help='Remove virtual environment')
remove.add_argument('names', metavar='ENV', nargs='+',
help='The environments to remove')
subparsers.add_parser('help', help='Show this help message')
return parser
parser = _lazyasd.LazyObject(parser, locals(), 'parser')
aliases = {
'create': 'new',
'workon': 'activate',
'enter': 'activate',
'exit': 'deactivate',
'ls': 'list',
'rm': 'remove',
'delete': 'remove',
'del': 'remove',
}
def __init__(self):
"""Ensure that $VIRTUALENV_HOME is defined and declare the available vox commands"""
self.vox = _voxapi.Vox()
self.commands = {
('new',): self.create_env,
('activate', 'workon', 'enter'): self.activate_env,
('deactivate', 'exit'): self.deactivate_env,
('list', 'ls'): self.list_envs,
('remove', 'rm', 'delete', 'del'): self.remove_envs,
('help', '-h', '--help'): self.show_help
}
def __call__(self, args, stdin=None):
"""Call the right handler method for a given command."""
if not args:
self.show_help()
return None
args = self.parser.parse_args(args)
cmd = self.aliases.get(args.command, args.command)
if cmd is None:
self.parser.print_usage()
else:
getattr(self, 'cmd_'+cmd)(args, stdin)
command_name, params = args[0], args[1:]
try:
command = [
self.commands[aliases] for aliases in self.commands
if command_name in aliases
][0]
command(*params)
except IndexError:
print('Command "%s" doesn\'t exist.\n' % command_name)
self.print_commands()
def create_env(self, name):
def cmd_new(self, args, stdin=None):
"""Create a virtual environment in $VIRTUALENV_HOME with python3's ``venv``.
Parameters
----------
name : str
Virtual environment name
"""
print('Creating environment...')
self.vox.create(name)
self.vox.create(args.name)
msg = 'Environment {0!r} created. Activate it with "vox activate {0}".\n'
print(msg.format(name))
print(msg.format(args.name))
def activate_env(self, name):
def cmd_activate(self, args, stdin=None):
"""Activate a virtual environment.
Parameters
----------
name : str
Virtual environment name
"""
try:
self.vox.activate(name)
self.vox.activate(args.name)
except KeyError:
print('This environment doesn\'t exist. Create it with "vox new %s".\n' % name, file=_sys.stderr)
return None
else:
print('Activated "%s".\n' % name)
print('Activated "%s".\n' % args.name)
def deactivate_env(self):
def cmd_deactivate(self, args, stdin=None):
"""Deactive the active virtual environment."""
if self.vox.active() is None:
@ -81,11 +112,11 @@ class _VoxHandler:
env_name = self.vox.deactivate()
print('Deactivated "%s".\n' % env_name)
def list_envs(self):
def cmd_list(self, args, stdin=None):
"""List available virtual environments."""
try:
envs = list(self.vox.keys())
envs = sorted(self.vox.keys())
except PermissionError:
print('No permissions on VIRTUALENV_HOME')
return None
@ -97,15 +128,10 @@ class _VoxHandler:
print('Available environments:')
print('\n'.join(envs))
def remove_envs(self, *names):
def cmd_remove(self, args, stdin=None):
"""Remove virtual environments.
Parameters
----------
names : list
list of virtual environment names
"""
for name in names:
for name in args.names:
try:
del self.vox[name]
except _voxapi.EnvironmentInUse:
@ -116,35 +142,8 @@ class _VoxHandler:
print('Environment "%s" removed.' % name)
print()
def show_help(self):
"""Show help."""
print(self.__doc__, '\n')
self.print_commands()
@staticmethod
def print_commands():
"""Print available vox commands."""
print("""Available commands:
vox new <env>
Create new virtual environment in $VIRTUALENV_HOME
vox activate (workon, enter) <env>
Activate virtual environment
vox deactivate (exit)
Deactivate current virtual environment
vox list (ls)
List all available environments
vox remove (rm, delete, del) <env> <env2> ...
Remove virtual environments
vox help (-h, --help)
Show help
""")
def cmd_help(self, args, stdin=None):
self.parser.print_help()
@classmethod
def handle(cls, args, stdin=None):