Skip to content

Commit

Permalink
argv: forward changes to sys.argv. Fixes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
lazka committed Nov 30, 2016
1 parent 76f9cc4 commit 9a4b4e8
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 23 deletions.
52 changes: 46 additions & 6 deletions senf/_argv.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@

import sys
import ctypes
import collections

from ._compat import PY2
from ._fsnative import is_unix
from ._fsnative import is_win, _fsn2legacy
from . import _winapi as winapi


def create_argv():
"""Returns a unicode argv under Windows and standard sys.argv otherwise"""
def _get_win_argv():
"""Returns a unicode argv under Windows and standard sys.argv otherwise
if is_unix or not PY2:
return sys.argv
Returns:
List[`fsnative`]
"""

assert is_win

argc = ctypes.c_int()
try:
Expand All @@ -43,4 +47,40 @@ def create_argv():
return res


argv = create_argv()
class Argv(collections.MutableSequence, list):
"""List[`fsnative`]: Like `sys.argv` but contains unicode
keys and values under Windows + Python 2
"""

def __init__(self):
if PY2 and is_win:
self._argv = _get_win_argv()
else:
self._argv = sys.argv

def __getitem__(self, index):
return self._argv[index]

def __setitem__(self, index, value):
self._argv[index] = value
try:
sys.argv[index] = _fsn2legacy(value)
except IndexError:
pass

def __delitem__(self, index):
del self._argv[index]
try:
del sys.argv[index]
except IndexError:
pass

def __len__(self):
return len(self._argv)

def insert(self, index, value):
self._argv.insert(index, value)
sys.argv.insert(index, _fsn2legacy(value))


argv = Argv()
18 changes: 1 addition & 17 deletions senf/_environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,10 @@
import collections

from ._compat import text_type, PY2
from ._fsnative import path2fsn, is_win, _encoding
from ._fsnative import path2fsn, is_win, _fsn2legacy
from . import _winapi as winapi


def _fsn2legacy(path):
"""Takes a fsnative path and returns a path that can be put into os.environ
or sys.argv. Might result in a mangled path on Python2 + Windows.
Can't fail.
Args:
path (fsnative)
Returns:
str
"""

if PY2 and is_win:
return path.encode(_encoding, "replace")
return path


def get_windows_env_var(key):
"""Get an env var.
Expand Down
16 changes: 16 additions & 0 deletions senf/_fsnative.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ def _decode_surrogatepass(data, codec):
raise


def _fsn2legacy(path):
"""Takes a fsnative path and returns a path that can be put into os.environ
or sys.argv. Might result in a mangled path on Python2 + Windows.
Can't fail.
Args:
path (fsnative)
Returns:
str
"""

if PY2 and is_win:
return path.encode(_encoding, "replace")
return path


def _fsnative(text):
if not isinstance(text, text_type):
raise TypeError("%r needs to be a text type (%r)" % (text, text_type))
Expand Down
30 changes: 30 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ def preserve_environ(environ=environ):
environ[key] = value


@contextlib.contextmanager
def preserve_argv(argv=argv):
old = argv[:]
if argv is not sys.argv:
with preserve_argv(sys.argv):
yield
else:
yield
argv[:] = old


@contextlib.contextmanager
def capture_output(data=None):
"""
Expand Down Expand Up @@ -614,6 +625,25 @@ def test_argv():
assert all(isinstance(v, fsnative) for v in argv)


def test_argv_change():
with preserve_argv():
argv.append(fsnative(u"\u1234"))
assert argv[-1] == fsnative(u"\u1234")
assert len(sys.argv) == len(argv)
assert sys.argv[-1] in (fsnative(u"\u1234"), "?")
argv[-1] = fsnative(u"X")
assert path2fsn(sys.argv[-1]) == argv[-1]
del argv[-1]
assert len(sys.argv) == len(argv)

with preserve_argv():
sys.argv[0] = sys.argv[0] + sys.argv[0]
if path2fsn(sys.argv[0]) != argv[0]:
del sys.argv[:]
argv[0] = fsnative(u"")
del argv[0]


def test_getcwd():
assert isinstance(getcwd(), fsnative)

Expand Down

0 comments on commit 9a4b4e8

Please sign in to comment.