home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Bureautique / LibreOffice / LibreOffice_4.3.5_Win_x86.msi / tempfile.py < prev    next >
Text File  |  2014-12-12  |  23KB  |  746 lines

  1. """Temporary files.
  2.  
  3. This module provides generic, low- and high-level interfaces for
  4. creating temporary files and directories.  The interfaces listed
  5. as "safe" just below can be used without fear of race conditions.
  6. Those listed as "unsafe" cannot, and are provided for backward
  7. compatibility only.
  8.  
  9. This module also provides some data items to the user:
  10.  
  11.   TMP_MAX  - maximum number of names that will be tried before
  12.              giving up.
  13.   tempdir  - If this is set to a string before the first use of
  14.              any routine from this module, it will be considered as
  15.              another candidate location to store temporary files.
  16. """
  17.  
  18. __all__ = [
  19.     "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
  20.     "SpooledTemporaryFile", "TemporaryDirectory",
  21.     "mkstemp", "mkdtemp",                  # low level safe interfaces
  22.     "mktemp",                              # deprecated unsafe interface
  23.     "TMP_MAX", "gettempprefix",            # constants
  24.     "tempdir", "gettempdir"
  25.    ]
  26.  
  27.  
  28. # Imports.
  29.  
  30. import atexit as _atexit
  31. import functools as _functools
  32. import warnings as _warnings
  33. import io as _io
  34. import os as _os
  35. import shutil as _shutil
  36. import errno as _errno
  37. from random import Random as _Random
  38.  
  39. try:
  40.     import fcntl as _fcntl
  41. except ImportError:
  42.     def _set_cloexec(fd):
  43.         pass
  44. else:
  45.     def _set_cloexec(fd):
  46.         try:
  47.             flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0)
  48.         except OSError:
  49.             pass
  50.         else:
  51.             # flags read successfully, modify
  52.             flags |= _fcntl.FD_CLOEXEC
  53.             _fcntl.fcntl(fd, _fcntl.F_SETFD, flags)
  54.  
  55.  
  56. try:
  57.     import _thread
  58. except ImportError:
  59.     import _dummy_thread as _thread
  60. _allocate_lock = _thread.allocate_lock
  61.  
  62. _text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
  63. if hasattr(_os, 'O_NOINHERIT'):
  64.     _text_openflags |= _os.O_NOINHERIT
  65. if hasattr(_os, 'O_NOFOLLOW'):
  66.     _text_openflags |= _os.O_NOFOLLOW
  67.  
  68. _bin_openflags = _text_openflags
  69. if hasattr(_os, 'O_BINARY'):
  70.     _bin_openflags |= _os.O_BINARY
  71.  
  72. if hasattr(_os, 'TMP_MAX'):
  73.     TMP_MAX = _os.TMP_MAX
  74. else:
  75.     TMP_MAX = 10000
  76.  
  77. # Although it does not have an underscore for historical reasons, this
  78. # variable is an internal implementation detail (see issue 10354).
  79. template = "tmp"
  80.  
  81. # Internal routines.
  82.  
  83. _once_lock = _allocate_lock()
  84.  
  85. if hasattr(_os, "lstat"):
  86.     _stat = _os.lstat
  87. elif hasattr(_os, "stat"):
  88.     _stat = _os.stat
  89. else:
  90.     # Fallback.  All we need is something that raises OSError if the
  91.     # file doesn't exist.
  92.     def _stat(fn):
  93.         f = open(fn)
  94.         f.close()
  95.  
  96. def _exists(fn):
  97.     try:
  98.         _stat(fn)
  99.     except OSError:
  100.         return False
  101.     else:
  102.         return True
  103.  
  104. class _RandomNameSequence:
  105.     """An instance of _RandomNameSequence generates an endless
  106.     sequence of unpredictable strings which can safely be incorporated
  107.     into file names.  Each string is six characters long.  Multiple
  108.     threads can safely use the same instance at the same time.
  109.  
  110.     _RandomNameSequence is an iterator."""
  111.  
  112.     characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
  113.  
  114.     @property
  115.     def rng(self):
  116.         cur_pid = _os.getpid()
  117.         if cur_pid != getattr(self, '_rng_pid', None):
  118.             self._rng = _Random()
  119.             self._rng_pid = cur_pid
  120.         return self._rng
  121.  
  122.     def __iter__(self):
  123.         return self
  124.  
  125.     def __next__(self):
  126.         c = self.characters
  127.         choose = self.rng.choice
  128.         letters = [choose(c) for dummy in "123456"]
  129.         return ''.join(letters)
  130.  
  131. def _candidate_tempdir_list():
  132.     """Generate a list of candidate temporary directories which
  133.     _get_default_tempdir will try."""
  134.  
  135.     dirlist = []
  136.  
  137.     # First, try the environment.
  138.     for envname in 'TMPDIR', 'TEMP', 'TMP':
  139.         dirname = _os.getenv(envname)
  140.         if dirname: dirlist.append(dirname)
  141.  
  142.     # Failing that, try OS-specific locations.
  143.     if _os.name == 'nt':
  144.         dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
  145.     else:
  146.         dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
  147.  
  148.     # As a last resort, the current directory.
  149.     try:
  150.         dirlist.append(_os.getcwd())
  151.     except (AttributeError, OSError):
  152.         dirlist.append(_os.curdir)
  153.  
  154.     return dirlist
  155.  
  156. def _get_default_tempdir():
  157.     """Calculate the default directory to use for temporary files.
  158.     This routine should be called exactly once.
  159.  
  160.     We determine whether or not a candidate temp dir is usable by
  161.     trying to create and write to a file in that directory.  If this
  162.     is successful, the test file is deleted.  To prevent denial of
  163.     service, the name of the test file must be randomized."""
  164.  
  165.     namer = _RandomNameSequence()
  166.     dirlist = _candidate_tempdir_list()
  167.  
  168.     for dir in dirlist:
  169.         if dir != _os.curdir:
  170.             dir = _os.path.normcase(_os.path.abspath(dir))
  171.         # Try only a few names per directory.
  172.         for seq in range(100):
  173.             name = next(namer)
  174.             filename = _os.path.join(dir, name)
  175.             try:
  176.                 fd = _os.open(filename, _bin_openflags, 0o600)
  177.                 try:
  178.                     try:
  179.                         with _io.open(fd, 'wb', closefd=False) as fp:
  180.                             fp.write(b'blat')
  181.                     finally:
  182.                         _os.close(fd)
  183.                 finally:
  184.                     _os.unlink(filename)
  185.                 return dir
  186.             except FileExistsError:
  187.                 pass
  188.             except OSError:
  189.                 break   # no point trying more names in this directory
  190.     raise FileNotFoundError(_errno.ENOENT,
  191.                             "No usable temporary directory found in %s" %
  192.                             dirlist)
  193.  
  194. _name_sequence = None
  195.  
  196. def _get_candidate_names():
  197.     """Common setup sequence for all user-callable interfaces."""
  198.  
  199.     global _name_sequence
  200.     if _name_sequence is None:
  201.         _once_lock.acquire()
  202.         try:
  203.             if _name_sequence is None:
  204.                 _name_sequence = _RandomNameSequence()
  205.         finally:
  206.             _once_lock.release()
  207.     return _name_sequence
  208.  
  209.  
  210. def _mkstemp_inner(dir, pre, suf, flags):
  211.     """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
  212.  
  213.     names = _get_candidate_names()
  214.  
  215.     for seq in range(TMP_MAX):
  216.         name = next(names)
  217.         file = _os.path.join(dir, pre + name + suf)
  218.         try:
  219.             fd = _os.open(file, flags, 0o600)
  220.             _set_cloexec(fd)
  221.             return (fd, _os.path.abspath(file))
  222.         except FileExistsError:
  223.             continue    # try again
  224.         except PermissionError:
  225.             # This exception is thrown when a directory with the chosen name
  226.             # already exists on windows.
  227.             if _os.name == 'nt':
  228.                 continue
  229.             else:
  230.                 raise
  231.  
  232.     raise FileExistsError(_errno.EEXIST,
  233.                           "No usable temporary file name found")
  234.  
  235.  
  236. # User visible interfaces.
  237.  
  238. def gettempprefix():
  239.     """Accessor for tempdir.template."""
  240.     return template
  241.  
  242. tempdir = None
  243.  
  244. def gettempdir():
  245.     """Accessor for tempfile.tempdir."""
  246.     global tempdir
  247.     if tempdir is None:
  248.         _once_lock.acquire()
  249.         try:
  250.             if tempdir is None:
  251.                 tempdir = _get_default_tempdir()
  252.         finally:
  253.             _once_lock.release()
  254.     return tempdir
  255.  
  256. def mkstemp(suffix="", prefix=template, dir=None, text=False):
  257.     """User-callable function to create and return a unique temporary
  258.     file.  The return value is a pair (fd, name) where fd is the
  259.     file descriptor returned by os.open, and name is the filename.
  260.  
  261.     If 'suffix' is specified, the file name will end with that suffix,
  262.     otherwise there will be no suffix.
  263.  
  264.     If 'prefix' is specified, the file name will begin with that prefix,
  265.     otherwise a default prefix is used.
  266.  
  267.     If 'dir' is specified, the file will be created in that directory,
  268.     otherwise a default directory is used.
  269.  
  270.     If 'text' is specified and true, the file is opened in text
  271.     mode.  Else (the default) the file is opened in binary mode.  On
  272.     some operating systems, this makes no difference.
  273.  
  274.     The file is readable and writable only by the creating user ID.
  275.     If the operating system uses permission bits to indicate whether a
  276.     file is executable, the file is executable by no one. The file
  277.     descriptor is not inherited by children of this process.
  278.  
  279.     Caller is responsible for deleting the file when done with it.
  280.     """
  281.  
  282.     if dir is None:
  283.         dir = gettempdir()
  284.  
  285.     if text:
  286.         flags = _text_openflags
  287.     else:
  288.         flags = _bin_openflags
  289.  
  290.     return _mkstemp_inner(dir, prefix, suffix, flags)
  291.  
  292.  
  293. def mkdtemp(suffix="", prefix=template, dir=None):
  294.     """User-callable function to create and return a unique temporary
  295.     directory.  The return value is the pathname of the directory.
  296.  
  297.     Arguments are as for mkstemp, except that the 'text' argument is
  298.     not accepted.
  299.  
  300.     The directory is readable, writable, and searchable only by the
  301.     creating user.
  302.  
  303.     Caller is responsible for deleting the directory when done with it.
  304.     """
  305.  
  306.     if dir is None:
  307.         dir = gettempdir()
  308.  
  309.     names = _get_candidate_names()
  310.  
  311.     for seq in range(TMP_MAX):
  312.         name = next(names)
  313.         file = _os.path.join(dir, prefix + name + suffix)
  314.         try:
  315.             _os.mkdir(file, 0o700)
  316.             return file
  317.         except FileExistsError:
  318.             continue    # try again
  319.  
  320.     raise FileExistsError(_errno.EEXIST,
  321.                           "No usable temporary directory name found")
  322.  
  323. def mktemp(suffix="", prefix=template, dir=None):
  324.     """User-callable function to return a unique temporary file name.  The
  325.     file is not created.
  326.  
  327.     Arguments are as for mkstemp, except that the 'text' argument is
  328.     not accepted.
  329.  
  330.     This function is unsafe and should not be used.  The file name
  331.     refers to a file that did not exist at some point, but by the time
  332.     you get around to creating it, someone else may have beaten you to
  333.     the punch.
  334.     """
  335.  
  336. ##    from warnings import warn as _warn
  337. ##    _warn("mktemp is a potential security risk to your program",
  338. ##          RuntimeWarning, stacklevel=2)
  339.  
  340.     if dir is None:
  341.         dir = gettempdir()
  342.  
  343.     names = _get_candidate_names()
  344.     for seq in range(TMP_MAX):
  345.         name = next(names)
  346.         file = _os.path.join(dir, prefix + name + suffix)
  347.         if not _exists(file):
  348.             return file
  349.  
  350.     raise FileExistsError(_errno.EEXIST,
  351.                           "No usable temporary filename found")
  352.  
  353.  
  354. class _TemporaryFileCloser:
  355.     """A separate object allowing proper closing of a temporary file's
  356.     underlying file object, without adding a __del__ method to the
  357.     temporary file."""
  358.  
  359.     # Set here since __del__ checks it
  360.     file = None
  361.     close_called = False
  362.  
  363.     def __init__(self, file, name, delete=True):
  364.         self.file = file
  365.         self.name = name
  366.         self.delete = delete
  367.  
  368.     # NT provides delete-on-close as a primitive, so we don't need
  369.     # the wrapper to do anything special.  We still use it so that
  370.     # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
  371.     if _os.name != 'nt':
  372.         # Cache the unlinker so we don't get spurious errors at
  373.         # shutdown when the module-level "os" is None'd out.  Note
  374.         # that this must be referenced as self.unlink, because the
  375.         # name TemporaryFileWrapper may also get None'd out before
  376.         # __del__ is called.
  377.  
  378.         def close(self, unlink=_os.unlink):
  379.             if not self.close_called and self.file is not None:
  380.                 self.close_called = True
  381.                 self.file.close()
  382.                 if self.delete:
  383.                     unlink(self.name)
  384.  
  385.         # Need to ensure the file is deleted on __del__
  386.         def __del__(self):
  387.             self.close()
  388.  
  389.     else:
  390.         def close(self):
  391.             if not self.close_called:
  392.                 self.close_called = True
  393.                 self.file.close()
  394.  
  395.  
  396. class _TemporaryFileWrapper:
  397.     """Temporary file wrapper
  398.  
  399.     This class provides a wrapper around files opened for
  400.     temporary use.  In particular, it seeks to automatically
  401.     remove the file when it is no longer needed.
  402.     """
  403.  
  404.     def __init__(self, file, name, delete=True):
  405.         self.file = file
  406.         self.name = name
  407.         self.delete = delete
  408.         self._closer = _TemporaryFileCloser(file, name, delete)
  409.  
  410.     def __getattr__(self, name):
  411.         # Attribute lookups are delegated to the underlying file
  412.         # and cached for non-numeric results
  413.         # (i.e. methods are cached, closed and friends are not)
  414.         file = self.__dict__['file']
  415.         a = getattr(file, name)
  416.         if hasattr(a, '__call__'):
  417.             func = a
  418.             @_functools.wraps(func)
  419.             def func_wrapper(*args, **kwargs):
  420.                 return func(*args, **kwargs)
  421.             # Avoid closing the file as long as the wrapper is alive,
  422.             # see issue #18879.
  423.             func_wrapper._closer = self._closer
  424.             a = func_wrapper
  425.         if not isinstance(a, int):
  426.             setattr(self, name, a)
  427.         return a
  428.  
  429.     # The underlying __enter__ method returns the wrong object
  430.     # (self.file) so override it to return the wrapper
  431.     def __enter__(self):
  432.         self.file.__enter__()
  433.         return self
  434.  
  435.     # Need to trap __exit__ as well to ensure the file gets
  436.     # deleted when used in a with statement
  437.     def __exit__(self, exc, value, tb):
  438.         result = self.file.__exit__(exc, value, tb)
  439.         self.close()
  440.         return result
  441.  
  442.     def close(self):
  443.         """
  444.         Close the temporary file, possibly deleting it.
  445.         """
  446.         self._closer.close()
  447.  
  448.     # iter() doesn't use __getattr__ to find the __iter__ method
  449.     def __iter__(self):
  450.         return iter(self.file)
  451.  
  452.  
  453. def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
  454.                        newline=None, suffix="", prefix=template,
  455.                        dir=None, delete=True):
  456.     """Create and return a temporary file.
  457.     Arguments:
  458.     'prefix', 'suffix', 'dir' -- as for mkstemp.
  459.     'mode' -- the mode argument to io.open (default "w+b").
  460.     'buffering' -- the buffer size argument to io.open (default -1).
  461.     'encoding' -- the encoding argument to io.open (default None)
  462.     'newline' -- the newline argument to io.open (default None)
  463.     'delete' -- whether the file is deleted on close (default True).
  464.     The file is created as mkstemp() would do it.
  465.  
  466.     Returns an object with a file-like interface; the name of the file
  467.     is accessible as file.name.  The file will be automatically deleted
  468.     when it is closed unless the 'delete' argument is set to False.
  469.     """
  470.  
  471.     if dir is None:
  472.         dir = gettempdir()
  473.  
  474.     flags = _bin_openflags
  475.  
  476.     # Setting O_TEMPORARY in the flags causes the OS to delete
  477.     # the file when it is closed.  This is only supported by Windows.
  478.     if _os.name == 'nt' and delete:
  479.         flags |= _os.O_TEMPORARY
  480.  
  481.     (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
  482.     file = _io.open(fd, mode, buffering=buffering,
  483.                     newline=newline, encoding=encoding)
  484.  
  485.     return _TemporaryFileWrapper(file, name, delete)
  486.  
  487. if _os.name != 'posix' or _os.sys.platform == 'cygwin':
  488.     # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
  489.     # while it is open.
  490.     TemporaryFile = NamedTemporaryFile
  491.  
  492. else:
  493.     def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
  494.                       newline=None, suffix="", prefix=template,
  495.                       dir=None):
  496.         """Create and return a temporary file.
  497.         Arguments:
  498.         'prefix', 'suffix', 'dir' -- as for mkstemp.
  499.         'mode' -- the mode argument to io.open (default "w+b").
  500.         'buffering' -- the buffer size argument to io.open (default -1).
  501.         'encoding' -- the encoding argument to io.open (default None)
  502.         'newline' -- the newline argument to io.open (default None)
  503.         The file is created as mkstemp() would do it.
  504.  
  505.         Returns an object with a file-like interface.  The file has no
  506.         name, and will cease to exist when it is closed.
  507.         """
  508.  
  509.         if dir is None:
  510.             dir = gettempdir()
  511.  
  512.         flags = _bin_openflags
  513.  
  514.         (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
  515.         try:
  516.             _os.unlink(name)
  517.             return _io.open(fd, mode, buffering=buffering,
  518.                             newline=newline, encoding=encoding)
  519.         except:
  520.             _os.close(fd)
  521.             raise
  522.  
  523. class SpooledTemporaryFile:
  524.     """Temporary file wrapper, specialized to switch from BytesIO
  525.     or StringIO to a real file when it exceeds a certain size or
  526.     when a fileno is needed.
  527.     """
  528.     _rolled = False
  529.  
  530.     def __init__(self, max_size=0, mode='w+b', buffering=-1,
  531.                  encoding=None, newline=None,
  532.                  suffix="", prefix=template, dir=None):
  533.         if 'b' in mode:
  534.             self._file = _io.BytesIO()
  535.         else:
  536.             # Setting newline="\n" avoids newline translation;
  537.             # this is important because otherwise on Windows we'd
  538.             # hget double newline translation upon rollover().
  539.             self._file = _io.StringIO(newline="\n")
  540.         self._max_size = max_size
  541.         self._rolled = False
  542.         self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
  543.                                    'suffix': suffix, 'prefix': prefix,
  544.                                    'encoding': encoding, 'newline': newline,
  545.                                    'dir': dir}
  546.  
  547.     def _check(self, file):
  548.         if self._rolled: return
  549.         max_size = self._max_size
  550.         if max_size and file.tell() > max_size:
  551.             self.rollover()
  552.  
  553.     def rollover(self):
  554.         if self._rolled: return
  555.         file = self._file
  556.         newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
  557.         del self._TemporaryFileArgs
  558.  
  559.         newfile.write(file.getvalue())
  560.         newfile.seek(file.tell(), 0)
  561.  
  562.         self._rolled = True
  563.  
  564.     # The method caching trick from NamedTemporaryFile
  565.     # won't work here, because _file may change from a
  566.     # BytesIO/StringIO instance to a real file. So we list
  567.     # all the methods directly.
  568.  
  569.     # Context management protocol
  570.     def __enter__(self):
  571.         if self._file.closed:
  572.             raise ValueError("Cannot enter context with closed file")
  573.         return self
  574.  
  575.     def __exit__(self, exc, value, tb):
  576.         self._file.close()
  577.  
  578.     # file protocol
  579.     def __iter__(self):
  580.         return self._file.__iter__()
  581.  
  582.     def close(self):
  583.         self._file.close()
  584.  
  585.     @property
  586.     def closed(self):
  587.         return self._file.closed
  588.  
  589.     @property
  590.     def encoding(self):
  591.         try:
  592.             return self._file.encoding
  593.         except AttributeError:
  594.             if 'b' in self._TemporaryFileArgs['mode']:
  595.                 raise
  596.             return self._TemporaryFileArgs['encoding']
  597.  
  598.     def fileno(self):
  599.         self.rollover()
  600.         return self._file.fileno()
  601.  
  602.     def flush(self):
  603.         self._file.flush()
  604.  
  605.     def isatty(self):
  606.         return self._file.isatty()
  607.  
  608.     @property
  609.     def mode(self):
  610.         try:
  611.             return self._file.mode
  612.         except AttributeError:
  613.             return self._TemporaryFileArgs['mode']
  614.  
  615.     @property
  616.     def name(self):
  617.         try:
  618.             return self._file.name
  619.         except AttributeError:
  620.             return None
  621.  
  622.     @property
  623.     def newlines(self):
  624.         try:
  625.             return self._file.newlines
  626.         except AttributeError:
  627.             if 'b' in self._TemporaryFileArgs['mode']:
  628.                 raise
  629.             return self._TemporaryFileArgs['newline']
  630.  
  631.     def read(self, *args):
  632.         return self._file.read(*args)
  633.  
  634.     def readline(self, *args):
  635.         return self._file.readline(*args)
  636.  
  637.     def readlines(self, *args):
  638.         return self._file.readlines(*args)
  639.  
  640.     def seek(self, *args):
  641.         self._file.seek(*args)
  642.  
  643.     @property
  644.     def softspace(self):
  645.         return self._file.softspace
  646.  
  647.     def tell(self):
  648.         return self._file.tell()
  649.  
  650.     def truncate(self, size=None):
  651.         if size is None:
  652.             self._file.truncate()
  653.         else:
  654.             if size > self._max_size:
  655.                 self.rollover()
  656.             self._file.truncate(size)
  657.  
  658.     def write(self, s):
  659.         file = self._file
  660.         rv = file.write(s)
  661.         self._check(file)
  662.         return rv
  663.  
  664.     def writelines(self, iterable):
  665.         file = self._file
  666.         rv = file.writelines(iterable)
  667.         self._check(file)
  668.         return rv
  669.  
  670.  
  671. class TemporaryDirectory(object):
  672.     """Create and return a temporary directory.  This has the same
  673.     behavior as mkdtemp but can be used as a context manager.  For
  674.     example:
  675.  
  676.         with TemporaryDirectory() as tmpdir:
  677.             ...
  678.  
  679.     Upon exiting the context, the directory and everything contained
  680.     in it are removed.
  681.     """
  682.  
  683.     # Handle mkdtemp raising an exception
  684.     name = None
  685.     _closed = False
  686.  
  687.     def __init__(self, suffix="", prefix=template, dir=None):
  688.         self.name = mkdtemp(suffix, prefix, dir)
  689.  
  690.     def __repr__(self):
  691.         return "<{} {!r}>".format(self.__class__.__name__, self.name)
  692.  
  693.     def __enter__(self):
  694.         return self.name
  695.  
  696.     def cleanup(self, _warn=False, _warnings=_warnings):
  697.         if self.name and not self._closed:
  698.             try:
  699.                 _shutil.rmtree(self.name)
  700.             except (TypeError, AttributeError) as ex:
  701.                 if "None" not in '%s' % (ex,):
  702.                     raise
  703.                 self._rmtree(self.name)
  704.             self._closed = True
  705.             if _warn and _warnings.warn:
  706.                 try:
  707.                     _warnings.warn("Implicitly cleaning up {!r}".format(self),
  708.                                    ResourceWarning)
  709.                 except:
  710.                     if _is_running:
  711.                         raise
  712.                     # Don't raise an exception if modules needed for emitting
  713.                     # a warning are already cleaned in shutdown process.
  714.  
  715.     def __exit__(self, exc, value, tb):
  716.         self.cleanup()
  717.  
  718.     def __del__(self):
  719.         # Issue a ResourceWarning if implicit cleanup needed
  720.         self.cleanup(_warn=True)
  721.  
  722.     def _rmtree(self, path, _OSError=OSError, _sep=_os.path.sep,
  723.                 _listdir=_os.listdir, _remove=_os.remove, _rmdir=_os.rmdir):
  724.         # Essentially a stripped down version of shutil.rmtree.  We can't
  725.         # use globals because they may be None'ed out at shutdown.
  726.         if not isinstance(path, str):
  727.             _sep = _sep.encode()
  728.         try:
  729.             for name in _listdir(path):
  730.                 fullname = path + _sep + name
  731.                 try:
  732.                     _remove(fullname)
  733.                 except _OSError:
  734.                     self._rmtree(fullname)
  735.             _rmdir(path)
  736.         except _OSError:
  737.             pass
  738.  
  739. _is_running = True
  740.  
  741. def _on_shutdown():
  742.     global _is_running
  743.     _is_running = False
  744.  
  745. _atexit.register(_on_shutdown)
  746.