py3: make osenvironb a proxy for, instead of a copy of os.environ where needed
Without this, TESTDIR and a few other variables weren't defined in the *.t test.
I didn't bother implementing all of the view functions for simplicity. All that
is actually used is __{get,set}item__(), get() and pop(), but the rest seems
easy enough to add for futureproofing.
--- a/tests/run-tests.py Tue May 22 16:16:11 2018 +0200
+++ b/tests/run-tests.py Tue Sep 18 22:14:03 2018 -0400
@@ -156,10 +156,33 @@
osenvironb = getattr(os, 'environb', None)
if osenvironb is None:
- # Windows lacks os.environb, for instance.
- osenvironb = {
- _bytespath(k): _bytespath(v) for k, v in os.environ.items()
- }
+ # Windows lacks os.environb, for instance. A proxy over the real thing
+ # instead of a copy allows the environment to be updated via bytes on
+ # all platforms.
+ class environbytes(object):
+ def __init__(self, strenv):
+ self.__len__ = strenv.__len__
+ self.clear = strenv.clear
+ self._strenv = strenv
+ def __getitem__(self, k):
+ v = self._strenv.__getitem__(_strpath(k))
+ return _bytespath(v)
+ def __setitem__(self, k, v):
+ self._strenv.__setitem__(_strpath(k), _strpath(v))
+ def __delitem__(self, k):
+ self._strenv.__delitem__(_strpath(k))
+ def __contains__(self, k):
+ return self._strenv.__contains__(_strpath(k))
+ def __iter__(self):
+ return iter([_bytespath(k) for k in iter(self._strenv)])
+ def get(self, k, default=None):
+ v = self._strenv.get(_strpath(k), _strpath(default))
+ return _bytespath(v)
+ def pop(self, k, default=None):
+ v = self._strenv.pop(_strpath(k), _strpath(default))
+ return _bytespath(v)
+
+ osenvironb = environbytes(os.environ)
elif sys.version_info >= (3, 0, 0):
print('%s is only supported on Python 3.5+ and 2.7, not %s' %