mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-05 17:00:58 +01:00
commit
a165563520
9 changed files with 67 additions and 36 deletions
16
news/ntenv.rst
Normal file
16
news/ntenv.rst
Normal file
|
@ -0,0 +1,16 @@
|
|||
**Added:** None
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* On Windows, ``os.environ`` is case insensitive. This would potentially
|
||||
change the case of envrionment variables set into the environment.
|
||||
Xonsh now uses ``nt.envrion``, the case sensitive counterpart, to avoid
|
||||
these issues on Windows.
|
||||
|
||||
**Security:** None
|
|
@ -22,7 +22,7 @@ from xonsh.foreign_shells import load_foreign_envs, load_foreign_aliases
|
|||
from xonsh.xontribs import update_context, prompt_xontrib_install
|
||||
from xonsh.platform import (
|
||||
BASH_COMPLETIONS_DEFAULT, DEFAULT_ENCODING, PATH_DEFAULT,
|
||||
ON_WINDOWS, ON_LINUX
|
||||
ON_WINDOWS, ON_LINUX, os_environ
|
||||
)
|
||||
|
||||
from xonsh.tools import (
|
||||
|
@ -240,7 +240,7 @@ def default_xonshrc(env):
|
|||
"""Creates a new instance of the default xonshrc tuple."""
|
||||
if ON_WINDOWS:
|
||||
dxrc = (xonshconfig(env),
|
||||
os.path.join(os.environ['ALLUSERSPROFILE'],
|
||||
os.path.join(os_environ['ALLUSERSPROFILE'],
|
||||
'xonsh', 'xonshrc'),
|
||||
os.path.expanduser('~/.xonshrc'))
|
||||
else:
|
||||
|
@ -599,7 +599,7 @@ def DEFAULT_DOCS():
|
|||
'the possibilities. This currently only affects the prompt-toolkit shell.'
|
||||
),
|
||||
'UPDATE_OS_ENVIRON': VarDocs(
|
||||
"If True ``os.environ`` will always be updated "
|
||||
"If True ``os_environ`` will always be updated "
|
||||
"when the xonsh environment changes. The environment can be reset to "
|
||||
"the default value by calling ``__xonsh_env__.undo_replace_env()``"),
|
||||
'UPDATE_PROMPT_ON_KEYPRESS': VarDocs(
|
||||
|
@ -775,7 +775,7 @@ class Env(cabc.MutableMapping):
|
|||
_arg_regex = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""If no initial environment is given, os.environ is used."""
|
||||
"""If no initial environment is given, os_environ is used."""
|
||||
self._d = {}
|
||||
# sentinel value for non existing envvars
|
||||
self._no_value = object()
|
||||
|
@ -784,7 +784,7 @@ class Env(cabc.MutableMapping):
|
|||
self._defaults = DEFAULT_VALUES
|
||||
self._docs = DEFAULT_DOCS
|
||||
if len(args) == 0 and len(kwargs) == 0:
|
||||
args = (os.environ,)
|
||||
args = (os_environ,)
|
||||
for key, val in dict(*args, **kwargs).items():
|
||||
self[key] = val
|
||||
if 'PATH' not in self._d:
|
||||
|
@ -819,21 +819,21 @@ class Env(cabc.MutableMapping):
|
|||
return ctx
|
||||
|
||||
def replace_env(self):
|
||||
"""Replaces the contents of os.environ with a detyped version
|
||||
"""Replaces the contents of os_environ with a detyped version
|
||||
of the xonsh environement.
|
||||
"""
|
||||
if self._orig_env is None:
|
||||
self._orig_env = dict(os.environ)
|
||||
os.environ.clear()
|
||||
os.environ.update(self.detype())
|
||||
self._orig_env = dict(os_environ)
|
||||
os_environ.clear()
|
||||
os_environ.update(self.detype())
|
||||
|
||||
def undo_replace_env(self):
|
||||
"""Replaces the contents of os.environ with a detyped version
|
||||
"""Replaces the contents of os_environ with a detyped version
|
||||
of the xonsh environement.
|
||||
"""
|
||||
if self._orig_env is not None:
|
||||
os.environ.clear()
|
||||
os.environ.update(self._orig_env)
|
||||
os_environ.clear()
|
||||
os_environ.update(self._orig_env)
|
||||
self._orig_env = None
|
||||
|
||||
def get_ensurer(self, key,
|
||||
|
@ -952,7 +952,7 @@ class Env(cabc.MutableMapping):
|
|||
if self._orig_env is None:
|
||||
self.replace_env()
|
||||
else:
|
||||
os.environ[key] = ensurer.detype(val)
|
||||
os_environ[key] = ensurer.detype(val)
|
||||
if old_value is self._no_value:
|
||||
events.on_envvar_new.fire(name=key, value=val)
|
||||
elif old_value != val:
|
||||
|
@ -964,8 +964,8 @@ class Env(cabc.MutableMapping):
|
|||
val = self._d.pop(key)
|
||||
if self.detypeable(val):
|
||||
self._detyped = None
|
||||
if self.get('UPDATE_OS_ENVIRON') and key in os.environ:
|
||||
del os.environ[key]
|
||||
if self.get('UPDATE_OS_ENVIRON') and key in os_environ:
|
||||
del os_environ[key]
|
||||
|
||||
def get(self, key, default=None):
|
||||
"""The environment will look up default values from its own defaults if a
|
||||
|
@ -1047,10 +1047,10 @@ def load_static_config(ctx, config=None):
|
|||
config = env['XONSHCONFIG'] = xonshconfig(env)
|
||||
if os.path.isfile(config):
|
||||
# Note that an Env instance at __xonsh_env__ has not been started yet,
|
||||
# per se, so we have to use os.environ
|
||||
encoding = os.environ.get('XONSH_ENCODING',
|
||||
# per se, so we have to use os_environ
|
||||
encoding = os_environ.get('XONSH_ENCODING',
|
||||
DEFAULT_VALUES.get('XONSH_ENCODING', 'utf8'))
|
||||
errors = os.environ.get('XONSH_ENCODING_ERRORS',
|
||||
errors = os_environ.get('XONSH_ENCODING_ERRORS',
|
||||
DEFAULT_VALUES.get('XONSH_ENCODING_ERRORS',
|
||||
'surrogateescape'))
|
||||
with open(config, 'r', encoding=encoding, errors=errors) as f:
|
||||
|
@ -1109,8 +1109,8 @@ def windows_foreign_env_fixes(ctx):
|
|||
# /c/Windows/System32 syntax instead of C:\\Windows\\System32
|
||||
# which messes up these environment variables for xonsh.
|
||||
for ev in ['PATH', 'TEMP', 'TMP']:
|
||||
if ev in os.environ:
|
||||
ctx[ev] = os.environ[ev]
|
||||
if ev in os_environ:
|
||||
ctx[ev] = os_environ[ev]
|
||||
elif ev in ctx:
|
||||
del ctx[ev]
|
||||
ctx['PWD'] = _get_cwd() or ''
|
||||
|
@ -1181,7 +1181,7 @@ def default_env(env=None):
|
|||
"""Constructs a default xonsh environment."""
|
||||
# in order of increasing precedence
|
||||
ctx = dict(BASE_ENV)
|
||||
ctx.update(os.environ)
|
||||
ctx.update(os_environ)
|
||||
ctx['PWD'] = _get_cwd() or ''
|
||||
# other shells' PROMPT definitions generally don't work in XONSH:
|
||||
try:
|
||||
|
|
|
@ -14,7 +14,7 @@ import collections.abc as cabc
|
|||
|
||||
from xonsh.lazyasd import lazyobject
|
||||
from xonsh.tools import to_bool, ensure_string
|
||||
from xonsh.platform import ON_WINDOWS, ON_CYGWIN
|
||||
from xonsh.platform import ON_WINDOWS, ON_CYGWIN, os_environ
|
||||
|
||||
COMMAND = """{seterrprevcmd}
|
||||
{prevcmd}
|
||||
|
@ -539,7 +539,7 @@ def _get_shells(shells=None, config=None, issue_warning=True):
|
|||
elif shells is not None:
|
||||
pass
|
||||
else:
|
||||
env = getattr(builtins, '__xonsh_env__', os.environ)
|
||||
env = getattr(builtins, '__xonsh_env__', os_environ)
|
||||
if env.get('LOADED_CONFIG', False):
|
||||
conf = builtins.__xonsh_config__
|
||||
else:
|
||||
|
|
|
@ -359,6 +359,20 @@ def windows_bash_command():
|
|||
#
|
||||
|
||||
|
||||
@lazyobject
|
||||
def os_environ():
|
||||
"""This dispatches to the correct, case-senstive version of os.envrion.
|
||||
This is mainly a problem for Windows. See #2024 for more details.
|
||||
This can probably go away once support for Python v3.5 or v3.6 is
|
||||
dropped.
|
||||
"""
|
||||
if ON_WINDOWS:
|
||||
import nt
|
||||
return nt.environ
|
||||
else:
|
||||
return os.environ
|
||||
|
||||
|
||||
@functools.lru_cache(1)
|
||||
def bash_command():
|
||||
"""Determines the command for Bash on the current plaform."""
|
||||
|
|
|
@ -92,7 +92,7 @@ class PromptFormatter:
|
|||
@xl.lazyobject
|
||||
def PROMPT_FIELDS():
|
||||
return dict(
|
||||
user=os.environ.get('USERNAME' if xp.ON_WINDOWS else 'USER', '<user>'),
|
||||
user=xp.os_environ.get('USERNAME' if xp.ON_WINDOWS else 'USER', '<user>'),
|
||||
prompt_end='#' if xt.is_superuser() else '$',
|
||||
hostname=socket.gethostname().split('.', 1)[0],
|
||||
cwd=_dynamically_collapsed_pwd,
|
||||
|
|
|
@ -28,6 +28,7 @@ from xonsh.color_tools import (RE_BACKGROUND, BASE_XONSH_COLORS, make_pallete,
|
|||
find_closest_color)
|
||||
from xonsh.style_tools import norm_name
|
||||
from xonsh.lazyimps import terminal256
|
||||
from xonsh.platform import os_environ
|
||||
|
||||
load_module_in_background('pkg_resources', debug='XONSH_DEBUG',
|
||||
replacements={'pygments.plugin': 'pkg_resources'})
|
||||
|
@ -86,7 +87,7 @@ class XonshLexer(PythonLexer):
|
|||
if not hasattr(builtins, '__xonsh_env__'):
|
||||
setattr(builtins, '__xonsh_env__', {})
|
||||
if ON_WINDOWS:
|
||||
pathext = os.environ.get('PATHEXT', ['.EXE', '.BAT', '.CMD'])
|
||||
pathext = os_environ.get('PATHEXT', ['.EXE', '.BAT', '.CMD'])
|
||||
builtins.__xonsh_env__['PATHEXT'] = pathext.split(os.pathsep)
|
||||
if not hasattr(builtins, '__xonsh_commands_cache__'):
|
||||
setattr(builtins, '__xonsh_commands_cache__', CommandsCache())
|
||||
|
@ -735,7 +736,7 @@ def _default_style():
|
|||
Color.WHITE: '#ansilightgray',
|
||||
Color.YELLOW: '#ansibrown',
|
||||
}
|
||||
elif ON_WINDOWS and 'CONEMUANSI' not in os.environ:
|
||||
elif ON_WINDOWS and 'CONEMUANSI' not in os_environ:
|
||||
# These colors must match the color specification
|
||||
# in prompt_toolkit, so the colors are converted
|
||||
# correctly when using cmd.exe
|
||||
|
|
|
@ -28,7 +28,7 @@ from xonsh.ansi_colors import (ansi_partial_color_format, ansi_color_style_names
|
|||
from xonsh.prompt.base import multiline_prompt
|
||||
from xonsh.tools import (print_exception, check_for_partial_string, to_bool,
|
||||
columnize, carriage_return)
|
||||
from xonsh.platform import ON_WINDOWS, ON_CYGWIN, ON_DARWIN, ON_POSIX
|
||||
from xonsh.platform import ON_WINDOWS, ON_CYGWIN, ON_DARWIN, ON_POSIX, os_environ
|
||||
from xonsh.lazyimps import pygments, pyghooks, winutils
|
||||
from xonsh.events import events
|
||||
|
||||
|
@ -117,7 +117,7 @@ def setup_readline():
|
|||
else:
|
||||
readline.parse_and_bind("tab: complete")
|
||||
# try to load custom user settings
|
||||
inputrc_name = os.environ.get('INPUTRC')
|
||||
inputrc_name = os_environ.get('INPUTRC')
|
||||
if inputrc_name is None:
|
||||
if uses_libedit:
|
||||
inputrc_name = '.editrc'
|
||||
|
|
|
@ -40,7 +40,7 @@ import warnings
|
|||
from xonsh.lazyasd import LazyObject, LazyDict, lazyobject
|
||||
from xonsh.platform import (has_prompt_toolkit, scandir, DEFAULT_ENCODING,
|
||||
ON_LINUX, ON_WINDOWS, PYTHON_VERSION_INFO,
|
||||
expanduser)
|
||||
expanduser, os_environ)
|
||||
|
||||
|
||||
@functools.lru_cache(1)
|
||||
|
@ -85,7 +85,7 @@ class XonshCalledProcessError(XonshError, subprocess.CalledProcessError):
|
|||
def expand_path(s, expand_user=True):
|
||||
"""Takes a string path and expands ~ to home if expand_user is set
|
||||
and environment vars if EXPAND_ENV_VARS is set."""
|
||||
env = getattr(builtins, '__xonsh_env__', os.environ)
|
||||
env = getattr(builtins, '__xonsh_env__', os_environ)
|
||||
if env.get('EXPAND_ENV_VARS', False):
|
||||
s = expandvars(s)
|
||||
if expand_user:
|
||||
|
@ -106,7 +106,7 @@ def _expandpath(path):
|
|||
"""Performs environment variable / user expansion on a given path
|
||||
if EXPAND_ENV_VARS is set.
|
||||
"""
|
||||
env = getattr(builtins, '__xonsh_env__', os.environ)
|
||||
env = getattr(builtins, '__xonsh_env__', os_environ)
|
||||
expand_user = env.get('EXPAND_ENV_VARS', False)
|
||||
return expand_path(path, expand_user=expand_user)
|
||||
|
||||
|
@ -115,7 +115,7 @@ def decode_bytes(b):
|
|||
"""Tries to decode the bytes using XONSH_ENCODING if available,
|
||||
otherwise using sys.getdefaultencoding().
|
||||
"""
|
||||
env = getattr(builtins, '__xonsh_env__', os.environ)
|
||||
env = getattr(builtins, '__xonsh_env__', os_environ)
|
||||
enc = env.get('XONSH_ENCODING') or DEFAULT_ENCODING
|
||||
err = env.get('XONSH_ENCODING_ERRORS') or 'strict'
|
||||
return b.decode(encoding=enc, errors=err)
|
||||
|
@ -745,7 +745,7 @@ def print_exception(msg=None):
|
|||
env = getattr(builtins, '__xonsh_env__', None)
|
||||
# flags indicating whether the traceback options have been manually set
|
||||
if env is None:
|
||||
env = os.environ
|
||||
env = os_environ
|
||||
manually_set_trace = 'XONSH_SHOW_TRACEBACK' in env
|
||||
manually_set_logfile = 'XONSH_TRACEBACK_LOGFILE' in env
|
||||
else:
|
||||
|
|
|
@ -124,15 +124,15 @@ def which(args, stdin=None, stdout=None, stderr=None, spec=None):
|
|||
# which.whichgen gives the nicest 'verbose' output if PATH is taken
|
||||
# from os.environ so we temporarily override it with
|
||||
# __xosnh_env__['PATH']
|
||||
original_os_path = os.environ['PATH']
|
||||
os.environ['PATH'] = builtins.__xonsh_env__.detype()['PATH']
|
||||
original_os_path = xp.os_environ['PATH']
|
||||
xp.os_environ['PATH'] = builtins.__xonsh_env__.detype()['PATH']
|
||||
matches = _which.whichgen(arg, exts=exts, verbose=verbose)
|
||||
for abs_name, from_where in matches:
|
||||
print_path(abs_name, from_where, stdout, verbose, captured)
|
||||
nmatches += 1
|
||||
if not pargs.all:
|
||||
break
|
||||
os.environ['PATH'] = original_os_path
|
||||
xp.os_environ['PATH'] = original_os_path
|
||||
if not nmatches:
|
||||
failures.append(arg)
|
||||
if len(failures) == 0:
|
||||
|
|
Loading…
Add table
Reference in a new issue