mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Get rid of _once(); inlining it takes less code. :-)
Also, don't call gettempdir() in the default expression for the 'dir' argument to various functions; use 'dir=None' for the default and insert 'if dir is None: dir = gettemptir()' in the bodies. That way the work done by gettempdir is postponed until needed.
This commit is contained in:
		
							parent
							
								
									787410680b
								
							
						
					
					
						commit
						e888cdc683
					
				
					 2 changed files with 41 additions and 97 deletions
				
			
		| 
						 | 
					@ -80,33 +80,6 @@ def acquire(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_once_lock = _allocate_lock()
 | 
					_once_lock = _allocate_lock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _once(var, initializer):
 | 
					 | 
				
			||||||
    """Wrapper to execute an initialization operation just once,
 | 
					 | 
				
			||||||
    even if multiple threads reach the same point at the same time.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var is the name (as a string) of the variable to be entered into
 | 
					 | 
				
			||||||
    the current global namespace.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    initializer is a callable which will return the appropriate initial
 | 
					 | 
				
			||||||
    value for variable.  It will be called only if variable is not
 | 
					 | 
				
			||||||
    present in the global namespace, or its current value is None.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Do not call _once from inside an initializer routine, it will deadlock.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    vars = globals()
 | 
					 | 
				
			||||||
    # Check first outside the lock.
 | 
					 | 
				
			||||||
    if vars.get(var) is not None:
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        _once_lock.acquire()
 | 
					 | 
				
			||||||
        # Check again inside the lock.
 | 
					 | 
				
			||||||
        if vars.get(var) is not None:
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
        vars[var] = initializer()
 | 
					 | 
				
			||||||
    finally:
 | 
					 | 
				
			||||||
        _once_lock.release()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class _RandomNameSequence:
 | 
					class _RandomNameSequence:
 | 
				
			||||||
    """An instance of _RandomNameSequence generates an endless
 | 
					    """An instance of _RandomNameSequence generates an endless
 | 
				
			||||||
    sequence of unpredictable strings which can safely be incorporated
 | 
					    sequence of unpredictable strings which can safely be incorporated
 | 
				
			||||||
| 
						 | 
					@ -178,8 +151,7 @@ def _candidate_tempdir_list():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _get_default_tempdir():
 | 
					def _get_default_tempdir():
 | 
				
			||||||
    """Calculate the default directory to use for temporary files.
 | 
					    """Calculate the default directory to use for temporary files.
 | 
				
			||||||
    This routine should be called through '_once' (see above) as we
 | 
					    This routine should be called exactly once.
 | 
				
			||||||
    do not want multiple threads attempting this calculation simultaneously.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    We determine whether or not a candidate temp dir is usable by
 | 
					    We determine whether or not a candidate temp dir is usable by
 | 
				
			||||||
    trying to create and write to a file in that directory.  If this
 | 
					    trying to create and write to a file in that directory.  If this
 | 
				
			||||||
| 
						 | 
					@ -212,10 +184,19 @@ def _get_default_tempdir():
 | 
				
			||||||
    raise IOError, (_errno.ENOENT,
 | 
					    raise IOError, (_errno.ENOENT,
 | 
				
			||||||
                    ("No usable temporary directory found in %s" % dirlist))
 | 
					                    ("No usable temporary directory found in %s" % dirlist))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_name_sequence = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _get_candidate_names():
 | 
					def _get_candidate_names():
 | 
				
			||||||
    """Common setup sequence for all user-callable interfaces."""
 | 
					    """Common setup sequence for all user-callable interfaces."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _once('_name_sequence', _RandomNameSequence)
 | 
					    global _name_sequence
 | 
				
			||||||
 | 
					    if _name_sequence is None:
 | 
				
			||||||
 | 
					        _once_lock.acquire()
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if _name_sequence is None:
 | 
				
			||||||
 | 
					                _name_sequence = _RandomNameSequence()
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            _once_lock.release()
 | 
				
			||||||
    return _name_sequence
 | 
					    return _name_sequence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,12 +226,21 @@ def gettempprefix():
 | 
				
			||||||
    """Accessor for tempdir.template."""
 | 
					    """Accessor for tempdir.template."""
 | 
				
			||||||
    return template
 | 
					    return template
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tempdir = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def gettempdir():
 | 
					def gettempdir():
 | 
				
			||||||
    """Accessor for tempdir.tempdir."""
 | 
					    """Accessor for tempdir.tempdir."""
 | 
				
			||||||
    _once('tempdir', _get_default_tempdir)
 | 
					    global tempdir
 | 
				
			||||||
 | 
					    if tempdir is None:
 | 
				
			||||||
 | 
					        _once_lock.acquire()
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if tempdir is None:
 | 
				
			||||||
 | 
					                tempdir = _get_default_tempdir()
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            _once_lock.release()
 | 
				
			||||||
    return tempdir
 | 
					    return tempdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mkstemp(suffix="", prefix=template, dir=gettempdir(), text=False):
 | 
					def mkstemp(suffix="", prefix=template, dir=None, text=False):
 | 
				
			||||||
    """mkstemp([suffix, [prefix, [dir, [text]]]])
 | 
					    """mkstemp([suffix, [prefix, [dir, [text]]]])
 | 
				
			||||||
    User-callable function to create and return a unique temporary
 | 
					    User-callable function to create and return a unique temporary
 | 
				
			||||||
    file.  The return value is a pair (fd, name) where fd is the
 | 
					    file.  The return value is a pair (fd, name) where fd is the
 | 
				
			||||||
| 
						 | 
					@ -277,6 +267,9 @@ def mkstemp(suffix="", prefix=template, dir=gettempdir(), text=False):
 | 
				
			||||||
    Caller is responsible for deleting the file when done with it.
 | 
					    Caller is responsible for deleting the file when done with it.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if dir is None:
 | 
				
			||||||
 | 
					        dir = gettempdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if text:
 | 
					    if text:
 | 
				
			||||||
        flags = _text_openflags
 | 
					        flags = _text_openflags
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
| 
						 | 
					@ -285,7 +278,7 @@ def mkstemp(suffix="", prefix=template, dir=gettempdir(), text=False):
 | 
				
			||||||
    return _mkstemp_inner(dir, prefix, suffix, flags)
 | 
					    return _mkstemp_inner(dir, prefix, suffix, flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mkdtemp(suffix="", prefix=template, dir=gettempdir()):
 | 
					def mkdtemp(suffix="", prefix=template, dir=None):
 | 
				
			||||||
    """mkdtemp([suffix, [prefix, [dir]]])
 | 
					    """mkdtemp([suffix, [prefix, [dir]]])
 | 
				
			||||||
    User-callable function to create and return a unique temporary
 | 
					    User-callable function to create and return a unique temporary
 | 
				
			||||||
    directory.  The return value is the pathname of the directory.
 | 
					    directory.  The return value is the pathname of the directory.
 | 
				
			||||||
| 
						 | 
					@ -299,6 +292,9 @@ def mkdtemp(suffix="", prefix=template, dir=gettempdir()):
 | 
				
			||||||
    Caller is responsible for deleting the directory when done with it.
 | 
					    Caller is responsible for deleting the directory when done with it.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if dir is None:
 | 
				
			||||||
 | 
					        dir = gettempdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    names = _get_candidate_names()
 | 
					    names = _get_candidate_names()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for seq in xrange(TMP_MAX):
 | 
					    for seq in xrange(TMP_MAX):
 | 
				
			||||||
| 
						 | 
					@ -314,7 +310,7 @@ def mkdtemp(suffix="", prefix=template, dir=gettempdir()):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    raise IOError, (_errno.EEXIST, "No usable temporary directory name found")
 | 
					    raise IOError, (_errno.EEXIST, "No usable temporary directory name found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mktemp(suffix="", prefix=template, dir=gettempdir()):
 | 
					def mktemp(suffix="", prefix=template, dir=None):
 | 
				
			||||||
    """mktemp([suffix, [prefix, [dir]]])
 | 
					    """mktemp([suffix, [prefix, [dir]]])
 | 
				
			||||||
    User-callable function to return a unique temporary file name.  The
 | 
					    User-callable function to return a unique temporary file name.  The
 | 
				
			||||||
    file is not created.
 | 
					    file is not created.
 | 
				
			||||||
| 
						 | 
					@ -332,6 +328,9 @@ def mktemp(suffix="", prefix=template, dir=gettempdir()):
 | 
				
			||||||
    _warn("mktemp is a potential security risk to your program",
 | 
					    _warn("mktemp is a potential security risk to your program",
 | 
				
			||||||
          RuntimeWarning, stacklevel=2)
 | 
					          RuntimeWarning, stacklevel=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if dir is None:
 | 
				
			||||||
 | 
					        dir = gettempdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    names = _get_candidate_names()
 | 
					    names = _get_candidate_names()
 | 
				
			||||||
    for seq in xrange(TMP_MAX):
 | 
					    for seq in xrange(TMP_MAX):
 | 
				
			||||||
        name = names.next()
 | 
					        name = names.next()
 | 
				
			||||||
| 
						 | 
					@ -383,7 +382,7 @@ def __del__(self):
 | 
				
			||||||
            self.close()
 | 
					            self.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
					def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
				
			||||||
                       prefix=template, dir=gettempdir()):
 | 
					                       prefix=template, dir=None):
 | 
				
			||||||
    """Create and return a temporary file.
 | 
					    """Create and return a temporary file.
 | 
				
			||||||
    Arguments:
 | 
					    Arguments:
 | 
				
			||||||
    'prefix', 'suffix', 'dir' -- as for mkstemp.
 | 
					    'prefix', 'suffix', 'dir' -- as for mkstemp.
 | 
				
			||||||
| 
						 | 
					@ -396,6 +395,9 @@ def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
				
			||||||
    closed.
 | 
					    closed.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if dir is None:
 | 
				
			||||||
 | 
					        dir = gettempdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if 'b' in mode:
 | 
					    if 'b' in mode:
 | 
				
			||||||
        flags = _bin_openflags
 | 
					        flags = _bin_openflags
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
| 
						 | 
					@ -417,7 +419,7 @@ def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
else:
 | 
					else:
 | 
				
			||||||
    def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
					    def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
				
			||||||
                      prefix=template, dir=gettempdir()):
 | 
					                      prefix=template, dir=None):
 | 
				
			||||||
        """Create and return a temporary file.
 | 
					        """Create and return a temporary file.
 | 
				
			||||||
        Arguments:
 | 
					        Arguments:
 | 
				
			||||||
        'prefix', 'suffix', 'directory' -- as for mkstemp.
 | 
					        'prefix', 'suffix', 'directory' -- as for mkstemp.
 | 
				
			||||||
| 
						 | 
					@ -429,6 +431,9 @@ def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
 | 
				
			||||||
        exist when it is closed.
 | 
					        exist when it is closed.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if dir is None:
 | 
				
			||||||
 | 
					            dir = gettempdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if 'b' in mode:
 | 
					        if 'b' in mode:
 | 
				
			||||||
            flags = _bin_openflags
 | 
					            flags = _bin_openflags
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,67 +84,6 @@ def test_exports(self):
 | 
				
			||||||
test_classes.append(test_exports)
 | 
					test_classes.append(test_exports)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class test__once(TC):
 | 
					 | 
				
			||||||
    """Test the internal function _once."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def setUp(self):
 | 
					 | 
				
			||||||
        tempfile.once_var = None
 | 
					 | 
				
			||||||
        self.already_called = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def tearDown(self):
 | 
					 | 
				
			||||||
        del tempfile.once_var
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def callMeOnce(self):
 | 
					 | 
				
			||||||
        self.failIf(self.already_called, "callMeOnce called twice")
 | 
					 | 
				
			||||||
        self.already_called = 1
 | 
					 | 
				
			||||||
        return 24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def do_once(self):
 | 
					 | 
				
			||||||
        tempfile._once('once_var', self.callMeOnce)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_once_initializes(self):
 | 
					 | 
				
			||||||
        """_once initializes its argument"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(tempfile.once_var, 24,
 | 
					 | 
				
			||||||
                         "once_var=%d, not 24" % tempfile.once_var)
 | 
					 | 
				
			||||||
        self.assertEqual(self.already_called, 1,
 | 
					 | 
				
			||||||
                         "already_called=%d, not 1" % self.already_called)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_once_means_once(self):
 | 
					 | 
				
			||||||
        """_once calls the callback just once"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_once_namespace_safe(self):
 | 
					 | 
				
			||||||
        """_once does not modify anything but its argument"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        env_copy = tempfile.__dict__.copy()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.do_once()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        env = tempfile.__dict__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        a = env.keys()
 | 
					 | 
				
			||||||
        a.sort()
 | 
					 | 
				
			||||||
        b = env_copy.keys()
 | 
					 | 
				
			||||||
        b.sort()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.failIf(len(a) != len(b))
 | 
					 | 
				
			||||||
        for i in xrange(len(a)):
 | 
					 | 
				
			||||||
            self.failIf(a[i] != b[i])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            key = a[i]
 | 
					 | 
				
			||||||
            if key != 'once_var':
 | 
					 | 
				
			||||||
                self.failIf(env[key] != env_copy[key])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_classes.append(test__once)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class test__RandomNameSequence(TC):
 | 
					class test__RandomNameSequence(TC):
 | 
				
			||||||
    """Test the internal iterator object _RandomNameSequence."""
 | 
					    """Test the internal iterator object _RandomNameSequence."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue