1# -*- coding: utf-8 -*- 2# 3# (c) 2018, Toshio Kuratomi <a.badger@gmail.com> 4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5# 6# Note that the original author of this, Toshio Kuratomi, is trying to submit this to six. If 7# successful, the code in six will be available under six's more liberal license: 8# https://mail.python.org/pipermail/python-porting/2018-July/000539.html 9 10# Make coding more python3-ish 11from __future__ import (absolute_import, division, print_function) 12__metaclass__ = type 13 14import os 15import sys 16 17from ansible.module_utils.six import PY3 18from ansible.module_utils._text import to_bytes, to_text 19from ansible.module_utils.common._collections_compat import MutableMapping 20 21__all__ = ('environ',) 22 23 24class _TextEnviron(MutableMapping): 25 """ 26 Utility class to return text strings from the environment instead of byte strings 27 28 Mimics the behaviour of os.environ on Python3 29 """ 30 def __init__(self, env=None, encoding=None): 31 if env is None: 32 env = os.environ 33 self._raw_environ = env 34 self._value_cache = {} 35 # Since we're trying to mimic Python3's os.environ, use sys.getfilesystemencoding() 36 # instead of utf-8 37 if encoding is None: 38 # Since we're trying to mimic Python3's os.environ, use sys.getfilesystemencoding() 39 # instead of utf-8 40 self.encoding = sys.getfilesystemencoding() 41 else: 42 self.encoding = encoding 43 44 def __delitem__(self, key): 45 del self._raw_environ[key] 46 47 def __getitem__(self, key): 48 value = self._raw_environ[key] 49 if PY3: 50 return value 51 # Cache keys off of the undecoded values to handle any environment variables which change 52 # during a run 53 if value not in self._value_cache: 54 self._value_cache[value] = to_text(value, encoding=self.encoding, 55 nonstring='passthru', errors='surrogate_or_strict') 56 return self._value_cache[value] 57 58 def __setitem__(self, key, value): 59 self._raw_environ[key] = to_bytes(value, encoding=self.encoding, nonstring='strict', 60 errors='surrogate_or_strict') 61 62 def __iter__(self): 63 return self._raw_environ.__iter__() 64 65 def __len__(self): 66 return len(self._raw_environ) 67 68 69environ = _TextEnviron(encoding='utf-8') 70