mercurial/util.py
changeset 48946 642e31cb55f0
parent 48940 2974cdda819b
child 48993 225659936fff
equal deleted inserted replaced
48945:55d132525155 48946:642e31cb55f0
   229 
   229 
   230 for k in DIGESTS_BY_STRENGTH:
   230 for k in DIGESTS_BY_STRENGTH:
   231     assert k in DIGESTS
   231     assert k in DIGESTS
   232 
   232 
   233 
   233 
   234 class digester(object):
   234 class digester:
   235     """helper to compute digests.
   235     """helper to compute digests.
   236 
   236 
   237     This helper can be used to compute one or more digests given their name.
   237     This helper can be used to compute one or more digests given their name.
   238 
   238 
   239     >>> d = digester([b'md5', b'sha1'])
   239     >>> d = digester([b'md5', b'sha1'])
   277             if k in supported:
   277             if k in supported:
   278                 return k
   278                 return k
   279         return None
   279         return None
   280 
   280 
   281 
   281 
   282 class digestchecker(object):
   282 class digestchecker:
   283     """file handle wrapper that additionally checks content against a given
   283     """file handle wrapper that additionally checks content against a given
   284     size and digests.
   284     size and digests.
   285 
   285 
   286         d = digestchecker(fh, size, {'md5': '...'})
   286         d = digestchecker(fh, size, {'md5': '...'})
   287 
   287 
   327 
   327 
   328 
   328 
   329 _chunksize = 4096
   329 _chunksize = 4096
   330 
   330 
   331 
   331 
   332 class bufferedinputpipe(object):
   332 class bufferedinputpipe:
   333     """a manually buffered input pipe
   333     """a manually buffered input pipe
   334 
   334 
   335     Python will not let us use buffered IO and lazy reading with 'polling' at
   335     Python will not let us use buffered IO and lazy reading with 'polling' at
   336     the same time. We cannot probe the buffer state and select will not detect
   336     the same time. We cannot probe the buffer state and select will not detect
   337     that data are ready to read if they are already buffered.
   337     that data are ready to read if they are already buffered.
   455         if os.fstat(fd).st_size == 0:
   455         if os.fstat(fd).st_size == 0:
   456             return b''
   456             return b''
   457         raise
   457         raise
   458 
   458 
   459 
   459 
   460 class fileobjectproxy(object):
   460 class fileobjectproxy:
   461     """A proxy around file objects that tells a watcher when events occur.
   461     """A proxy around file objects that tells a watcher when events occur.
   462 
   462 
   463     This type is intended to only be used for testing purposes. Think hard
   463     This type is intended to only be used for testing purposes. Think hard
   464     before using it in important code.
   464     before using it in important code.
   465     """
   465     """
   691     'gettimeout',
   691     'gettimeout',
   692     'setsockopt',
   692     'setsockopt',
   693 }
   693 }
   694 
   694 
   695 
   695 
   696 class socketproxy(object):
   696 class socketproxy:
   697     """A proxy around a socket that tells a watcher when events occur.
   697     """A proxy around a socket that tells a watcher when events occur.
   698 
   698 
   699     This is like ``fileobjectproxy`` except for sockets.
   699     This is like ``fileobjectproxy`` except for sockets.
   700 
   700 
   701     This type is intended to only be used for testing purposes. Think hard
   701     This type is intended to only be used for testing purposes. Think hard
   814         return object.__getattribute__(self, '_observedcall')(
   814         return object.__getattribute__(self, '_observedcall')(
   815             'setsockopt', *args, **kwargs
   815             'setsockopt', *args, **kwargs
   816         )
   816         )
   817 
   817 
   818 
   818 
   819 class baseproxyobserver(object):
   819 class baseproxyobserver:
   820     def __init__(self, fh, name, logdata, logdataapis):
   820     def __init__(self, fh, name, logdata, logdataapis):
   821         self.fh = fh
   821         self.fh = fh
   822         self.name = name
   822         self.name = name
   823         self.logdata = logdata
   823         self.logdata = logdata
   824         self.logdataapis = logdataapis
   824         self.logdataapis = logdataapis
  1254             return cache[args]
  1254             return cache[args]
  1255 
  1255 
  1256     return f
  1256     return f
  1257 
  1257 
  1258 
  1258 
  1259 class cow(object):
  1259 class cow:
  1260     """helper class to make copy-on-write easier
  1260     """helper class to make copy-on-write easier
  1261 
  1261 
  1262     Call preparewrite before doing any writes.
  1262     Call preparewrite before doing any writes.
  1263     """
  1263     """
  1264 
  1264 
  1347 
  1347 
  1348     Be sure to call d = d.preparewrite() before writing to d.
  1348     Be sure to call d = d.preparewrite() before writing to d.
  1349     """
  1349     """
  1350 
  1350 
  1351 
  1351 
  1352 class transactional(object):  # pytype: disable=ignored-metaclass
  1352 class transactional:  # pytype: disable=ignored-metaclass
  1353     """Base class for making a transactional type into a context manager."""
  1353     """Base class for making a transactional type into a context manager."""
  1354 
  1354 
  1355     __metaclass__ = abc.ABCMeta
  1355     __metaclass__ = abc.ABCMeta
  1356 
  1356 
  1357     @abc.abstractmethod
  1357     @abc.abstractmethod
  1398 @contextlib.contextmanager
  1398 @contextlib.contextmanager
  1399 def nullcontextmanager(enter_result=None):
  1399 def nullcontextmanager(enter_result=None):
  1400     yield enter_result
  1400     yield enter_result
  1401 
  1401 
  1402 
  1402 
  1403 class _lrucachenode(object):
  1403 class _lrucachenode:
  1404     """A node in a doubly linked list.
  1404     """A node in a doubly linked list.
  1405 
  1405 
  1406     Holds a reference to nodes on either side as well as a key-value
  1406     Holds a reference to nodes on either side as well as a key-value
  1407     pair for the dictionary entry.
  1407     pair for the dictionary entry.
  1408     """
  1408     """
  1422         self.key = _notset
  1422         self.key = _notset
  1423         self.value = None
  1423         self.value = None
  1424         self.cost = 0
  1424         self.cost = 0
  1425 
  1425 
  1426 
  1426 
  1427 class lrucachedict(object):
  1427 class lrucachedict:
  1428     """Dict that caches most recent accesses and sets.
  1428     """Dict that caches most recent accesses and sets.
  1429 
  1429 
  1430     The dict consists of an actual backing dict - indexed by original
  1430     The dict consists of an actual backing dict - indexed by original
  1431     key - and a doubly linked circular list defining the order of entries in
  1431     key - and a doubly linked circular list defining the order of entries in
  1432     the cache.
  1432     the cache.
  1753             return cache[args]
  1753             return cache[args]
  1754 
  1754 
  1755     return f
  1755     return f
  1756 
  1756 
  1757 
  1757 
  1758 class propertycache(object):
  1758 class propertycache:
  1759     def __init__(self, func):
  1759     def __init__(self, func):
  1760         self.func = func
  1760         self.func = func
  1761         self.name = func.__name__
  1761         self.name = func.__name__
  1762 
  1762 
  1763     def __get__(self, obj, type=None):
  1763     def __get__(self, obj, type=None):
  2212     _re2 = None
  2212     _re2 = None
  2213 except ImportError:
  2213 except ImportError:
  2214     _re2 = False
  2214     _re2 = False
  2215 
  2215 
  2216 
  2216 
  2217 class _re(object):
  2217 class _re:
  2218     def _checkre2(self):
  2218     def _checkre2(self):
  2219         global _re2
  2219         global _re2
  2220         global _re2_input
  2220         global _re2_input
  2221 
  2221 
  2222         check_pattern = br'\[([^\[]+)\]'
  2222         check_pattern = br'\[([^\[]+)\]'
  2414             pass
  2414             pass
  2415         raise
  2415         raise
  2416     return temp
  2416     return temp
  2417 
  2417 
  2418 
  2418 
  2419 class filestat(object):
  2419 class filestat:
  2420     """help to exactly detect change of a file
  2420     """help to exactly detect change of a file
  2421 
  2421 
  2422     'stat' attribute is result of 'os.stat()' if specified 'path'
  2422     'stat' attribute is result of 'os.stat()' if specified 'path'
  2423     exists. Otherwise, it is None. This can avoid preparative
  2423     exists. Otherwise, it is None. This can avoid preparative
  2424     'exists()' examination on client side of this class.
  2424     'exists()' examination on client side of this class.
  2520 
  2520 
  2521     def __ne__(self, other):
  2521     def __ne__(self, other):
  2522         return not self == other
  2522         return not self == other
  2523 
  2523 
  2524 
  2524 
  2525 class atomictempfile(object):
  2525 class atomictempfile:
  2526     """writable file object that atomically updates a file
  2526     """writable file object that atomically updates a file
  2527 
  2527 
  2528     All writes will go to a temporary copy of the original file. Call
  2528     All writes will go to a temporary copy of the original file. Call
  2529     close() when you are done writing, and atomictempfile will rename
  2529     close() when you are done writing, and atomictempfile will rename
  2530     the temporary copy to the original name, making the changes
  2530     the temporary copy to the original name, making the changes
  2663     # type: (bytes, bytes) -> None
  2663     # type: (bytes, bytes) -> None
  2664     with open(path, b'ab') as fp:
  2664     with open(path, b'ab') as fp:
  2665         fp.write(text)
  2665         fp.write(text)
  2666 
  2666 
  2667 
  2667 
  2668 class chunkbuffer(object):
  2668 class chunkbuffer:
  2669     """Allow arbitrary sized chunks of data to be efficiently read from an
  2669     """Allow arbitrary sized chunks of data to be efficiently read from an
  2670     iterator over chunks of arbitrary size."""
  2670     iterator over chunks of arbitrary size."""
  2671 
  2671 
  2672     def __init__(self, in_iter):
  2672     def __init__(self, in_iter):
  2673         """in_iter is the iterator that's iterating over the input chunks."""
  2673         """in_iter is the iterator that's iterating over the input chunks."""
  2768         if limit:
  2768         if limit:
  2769             limit -= len(s)
  2769             limit -= len(s)
  2770         yield s
  2770         yield s
  2771 
  2771 
  2772 
  2772 
  2773 class cappedreader(object):
  2773 class cappedreader:
  2774     """A file object proxy that allows reading up to N bytes.
  2774     """A file object proxy that allows reading up to N bytes.
  2775 
  2775 
  2776     Given a source file object, instances of this type allow reading up to
  2776     Given a source file object, instances of this type allow reading up to
  2777     N bytes from that source file object. Attempts to read past the allowed
  2777     N bytes from that source file object. Attempts to read past the allowed
  2778     limit are treated as EOF.
  2778     limit are treated as EOF.
  2856     (1, 1 << 10, _(b'%.2f KB')),
  2856     (1, 1 << 10, _(b'%.2f KB')),
  2857     (1, 1, _(b'%.0f bytes')),
  2857     (1, 1, _(b'%.0f bytes')),
  2858 )
  2858 )
  2859 
  2859 
  2860 
  2860 
  2861 class transformingwriter(object):
  2861 class transformingwriter:
  2862     """Writable file wrapper to transform data by function"""
  2862     """Writable file wrapper to transform data by function"""
  2863 
  2863 
  2864     def __init__(self, fp, encode):
  2864     def __init__(self, fp, encode):
  2865         self._fp = fp
  2865         self._fp = fp
  2866         self._encode = encode
  2866         self._encode = encode
  2964     (1, 0.000000001, _(b'%.3f ns')),
  2964     (1, 0.000000001, _(b'%.3f ns')),
  2965 )
  2965 )
  2966 
  2966 
  2967 
  2967 
  2968 @attr.s
  2968 @attr.s
  2969 class timedcmstats(object):
  2969 class timedcmstats:
  2970     """Stats information produced by the timedcm context manager on entering."""
  2970     """Stats information produced by the timedcm context manager on entering."""
  2971 
  2971 
  2972     # the starting value of the timer as a float (meaning and resulution is
  2972     # the starting value of the timer as a float (meaning and resulution is
  2973     # platform dependent, see util.timer)
  2973     # platform dependent, see util.timer)
  2974     start = attr.ib(default=attr.Factory(lambda: timer()))
  2974     start = attr.ib(default=attr.Factory(lambda: timer()))
  3065         return int(t)
  3065         return int(t)
  3066     except ValueError:
  3066     except ValueError:
  3067         raise error.ParseError(_(b"couldn't parse size: %s") % s)
  3067         raise error.ParseError(_(b"couldn't parse size: %s") % s)
  3068 
  3068 
  3069 
  3069 
  3070 class hooks(object):
  3070 class hooks:
  3071     """A collection of hook functions that can be used to extend a
  3071     """A collection of hook functions that can be used to extend a
  3072     function's behavior. Hooks are called in lexicographic order,
  3072     function's behavior. Hooks are called in lexicographic order,
  3073     based on the names of their sources."""
  3073     based on the names of their sources."""
  3074 
  3074 
  3075     def __init__(self):
  3075     def __init__(self):