# _compat.py - Python 2/3 compatibility import operator import os import subprocess import sys PY2 = (sys.version_info.major == 2) if PY2: string_classes = (str, unicode) # needed individually for sublassing text_type = unicode iteritems = operator.methodcaller('iteritems') def makedirs(name, mode=0o777, exist_ok=False): try: os.makedirs(name, mode) except OSError: if not exist_ok or not os.path.isdir(name): raise def stderr_write_bytes(data, flush=False): """Write data str to sys.stderr (flush if requested).""" sys.stderr.write(data) if flush: sys.stderr.flush() def Popen_stderr_devnull(*args, **kwargs): # noqa: N802 with open(os.devnull, 'w') as f: return subprocess.Popen(*args, stderr=f, **kwargs) class CalledProcessError(subprocess.CalledProcessError): def __init__(self, returncode, cmd, output=None, stderr=None): super(CalledProcessError, self).__init__(returncode, cmd, output) self.stderr = stderr @property # pragma: no cover def stdout(self): return self.output @stdout.setter # pragma: no cover def stdout(self, value): self.output = value else: string_classes = (str,) text_type = str def iteritems(d): return iter(d.items()) def makedirs(name, mode=0o777, exist_ok=False): # allow os.makedirs mocking return os.makedirs(name, mode, exist_ok=exist_ok) def stderr_write_bytes(data, flush=False): """Encode data str and write to sys.stderr (flush if requested).""" encoding = sys.stderr.encoding or sys.getdefaultencoding() sys.stderr.write(data.decode(encoding)) if flush: sys.stderr.flush() def Popen_stderr_devnull(*args, **kwargs): # noqa: N802 return subprocess.Popen(*args, stderr=subprocess.DEVNULL, **kwargs) CalledProcessError = subprocess.CalledProcessError