parameters: (cls, prefix='session-', rootdir=None, keep=3,
                            lock_timeout=172800)
return_statement: return udir
docstring: return unique directory with a number greater than the current
              maximum one.  The number is assumed to start directly after prefix.
              if keep is true directories with a number less than (maxnum-keep)
              will be removed. If .lock files are used (lock_timeout non-zero),
              algorithm is multi-process safe.
docstring_summary: return unique directory with a number greater than the current
              maximum one.  The number is assumed to start directly after prefix.
              if keep is true directories with a number less than (maxnum-keep)
              will be removed. If .lock files are used (lock_timeout non-zero),
              algorithm is multi-process safe.
docstring_tokens: return unique directory with a number greater than the current maximum one . The number is assumed to start directly after prefix . if keep is true directories with a number less than ( maxnum - keep ) will be removed . If . lock files are used ( lock_timeout non - zero ) algorithm is multi - process safe .
function: def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3,
                            lock_timeout=172800):   # two days
          """ return unique directory with a number greater than the current
              maximum one.  The number is assumed to start directly after prefix.
              if keep is true directories with a number less than (maxnum-keep)
              will be removed. If .lock files are used (lock_timeout non-zero),
              algorithm is multi-process safe.
          """
          if rootdir is None:
              rootdir = cls.get_temproot()
  
          nprefix = prefix.lower()
          def parse_num(path):
              """ parse the number out of a path (if it matches the prefix) """
              nbasename = path.basename.lower()
              if nbasename.startswith(nprefix):
                  try:
                      return int(nbasename[len(nprefix):])
                  except ValueError:
                      pass
  
          def create_lockfile(path):
              """ exclusively create lockfile. Throws when failed """
              mypid = os.getpid()
              lockfile = path.join('.lock')
              if hasattr(lockfile, 'mksymlinkto'):
                  lockfile.mksymlinkto(str(mypid))
              else:
                  fd = py.error.checked_call(os.open, str(lockfile), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
                  with os.fdopen(fd, 'w') as f:
                      f.write(str(mypid))
              return lockfile
  
          def atexit_remove_lockfile(lockfile):
              """ ensure lockfile is removed at process exit """
              mypid = os.getpid()
              def try_remove_lockfile():
                  # in a fork() situation, only the last process should
                  # remove the .lock, otherwise the other processes run the
                  # risk of seeing their temporary dir disappear.  For now
                  # we remove the .lock in the parent only (i.e. we assume
                  # that the children finish before the parent).
                  if os.getpid() != mypid:
                      return
                  try:
                      lockfile.remove()
                  except py.error.Error:
                      pass
              atexit.register(try_remove_lockfile)
  
          # compute the maximum number currently in use with the prefix
          lastmax = None
          while True:
              maxnum = -1
              for path in rootdir.listdir():
                  num = parse_num(path)
                  if num is not None:
                      maxnum = max(maxnum, num)
  
              # make the new directory
              try:
                  udir = rootdir.mkdir(prefix + str(maxnum+1))
                  if lock_timeout:
                      lockfile = create_lockfile(udir)
                      atexit_remove_lockfile(lockfile)
              except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY):
                  # race condition (1): another thread/process created the dir
                  #                     in the meantime - try again
                  # race condition (2): another thread/process spuriously acquired
                  #                     lock treating empty directory as candidate
                  #                     for removal - try again
                  # race condition (3): another thread/process tried to create the lock at
                  #                     the same time (happened in Python 3.3 on Windows)
                  # https://ci.appveyor.com/project/pytestbot/py/build/1.0.21/job/ffi85j4c0lqwsfwa
                  if lastmax == maxnum:
                      raise
                  lastmax = maxnum
                  continue
              break
  
          def get_mtime(path):
              """ read file modification time """
              try:
                  return path.lstat().mtime
              except py.error.Error:
                  pass
  
          garbage_prefix = prefix + 'garbage-'
  
          def is_garbage(path):
              """ check if path denotes directory scheduled for removal """
              bn = path.basename
              return bn.startswith(garbage_prefix)
  
          # prune old directories
          udir_time = get_mtime(udir)
          if keep and udir_time:
              for path in rootdir.listdir():
                  num = parse_num(path)
                  if num is not None and num <= (maxnum - keep):
                      try:
                          # try acquiring lock to remove directory as exclusive user
                          if lock_timeout:
                              create_lockfile(path)
                      except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY):
                          path_time = get_mtime(path)
                          if not path_time:
                              # assume directory doesn't exist now
                              continue
                          if abs(udir_time - path_time) < lock_timeout:
                              # assume directory with lockfile exists
                              # and lock timeout hasn't expired yet
                              continue
  
                      # path dir locked for exclusive use
                      # and scheduled for removal to avoid another thread/process
                      # treating it as a new directory or removal candidate
                      garbage_path = rootdir.join(garbage_prefix + str(uuid.uuid4()))
                      try:
                          path.rename(garbage_path)
                          garbage_path.remove(rec=1)
                      except KeyboardInterrupt:
                          raise
                      except: # this might be py.error.Error, WindowsError ...
                          pass
                  if is_garbage(path):
                      try:
                          path.remove(rec=1)
                      except KeyboardInterrupt:
                          raise
                      except: # this might be py.error.Error, WindowsError ...
                          pass
  
          # make link...
          try:
              username = os.environ['USER']           #linux, et al
          except KeyError:
              try:
                  username = os.environ['USERNAME']   #windows
              except KeyError:
                  username = 'current'
  
          src  = str(udir)
          dest = src[:src.rfind('-')] + '-' + username
          try:
              os.unlink(dest)
          except OSError:
              pass
          try:
              os.symlink(src, dest)
          except (OSError, AttributeError, NotImplementedError):
              pass
  
          return udir
function_tokens: def make_numbered_dir ( cls , prefix = 'session-' , rootdir = None , keep = 3 , lock_timeout = 172800 ) : # two days if rootdir is None : rootdir = cls . get_temproot ( ) nprefix = prefix . lower ( ) def parse_num ( path ) : """ parse the number out of a path (if it matches the prefix) """ nbasename = path . basename . lower ( ) if nbasename . startswith ( nprefix ) : try : return int ( nbasename [ len ( nprefix ) : ] ) except ValueError : pass def create_lockfile ( path ) : """ exclusively create lockfile. Throws when failed """ mypid = os . getpid ( ) lockfile = path . join ( '.lock' ) if hasattr ( lockfile , 'mksymlinkto' ) : lockfile . mksymlinkto ( str ( mypid ) ) else : fd = py . error . checked_call ( os . open , str ( lockfile ) , os . O_WRONLY | os . O_CREAT | os . O_EXCL , 0o644 ) with os . fdopen ( fd , 'w' ) as f : f . write ( str ( mypid ) ) return lockfile def atexit_remove_lockfile ( lockfile ) : """ ensure lockfile is removed at process exit """ mypid = os . getpid ( ) def try_remove_lockfile ( ) : # in a fork() situation, only the last process should # remove the .lock, otherwise the other processes run the # risk of seeing their temporary dir disappear.  For now # we remove the .lock in the parent only (i.e. we assume # that the children finish before the parent). if os . getpid ( ) != mypid : return try : lockfile . remove ( ) except py . error . Error : pass atexit . register ( try_remove_lockfile ) # compute the maximum number currently in use with the prefix lastmax = None while True : maxnum = - 1 for path in rootdir . listdir ( ) : num = parse_num ( path ) if num is not None : maxnum = max ( maxnum , num ) # make the new directory try : udir = rootdir . mkdir ( prefix + str ( maxnum + 1 ) ) if lock_timeout : lockfile = create_lockfile ( udir ) atexit_remove_lockfile ( lockfile ) except ( py . error . EEXIST , py . error . ENOENT , py . error . EBUSY ) : # race condition (1): another thread/process created the dir #                     in the meantime - try again # race condition (2): another thread/process spuriously acquired #                     lock treating empty directory as candidate #                     for removal - try again # race condition (3): another thread/process tried to create the lock at #                     the same time (happened in Python 3.3 on Windows) # https://ci.appveyor.com/project/pytestbot/py/build/1.0.21/job/ffi85j4c0lqwsfwa if lastmax == maxnum : raise lastmax = maxnum continue break def get_mtime ( path ) : """ read file modification time """ try : return path . lstat ( ) . mtime except py . error . Error : pass garbage_prefix = prefix + 'garbage-' def is_garbage ( path ) : """ check if path denotes directory scheduled for removal """ bn = path . basename return bn . startswith ( garbage_prefix ) # prune old directories udir_time = get_mtime ( udir ) if keep and udir_time : for path in rootdir . listdir ( ) : num = parse_num ( path ) if num is not None and num <= ( maxnum - keep ) : try : # try acquiring lock to remove directory as exclusive user if lock_timeout : create_lockfile ( path ) except ( py . error . EEXIST , py . error . ENOENT , py . error . EBUSY ) : path_time = get_mtime ( path ) if not path_time : # assume directory doesn't exist now continue if abs ( udir_time - path_time ) < lock_timeout : # assume directory with lockfile exists # and lock timeout hasn't expired yet continue # path dir locked for exclusive use # and scheduled for removal to avoid another thread/process # treating it as a new directory or removal candidate garbage_path = rootdir . join ( garbage_prefix + str ( uuid . uuid4 ( ) ) ) try : path . rename ( garbage_path ) garbage_path . remove ( rec = 1 ) except KeyboardInterrupt : raise except : # this might be py.error.Error, WindowsError ... pass if is_garbage ( path ) : try : path . remove ( rec = 1 ) except KeyboardInterrupt : raise except : # this might be py.error.Error, WindowsError ... pass # make link... try : username = os . environ [ 'USER' ] #linux, et al except KeyError : try : username = os . environ [ 'USERNAME' ] #windows except KeyError : username = 'current' src = str ( udir ) dest = src [ : src . rfind ( '-' ) ] + '-' + username try : os . unlink ( dest ) except OSError : pass try : os . symlink ( src , dest ) except ( OSError , AttributeError , NotImplementedError ) : pass return udir