Index: third_party/psutil/psutil/compat.py |
diff --git a/third_party/psutil/psutil/compat.py b/third_party/psutil/psutil/compat.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9e05dfca9ca7df9519ea204108c643a557bb39fd |
--- /dev/null |
+++ b/third_party/psutil/psutil/compat.py |
@@ -0,0 +1,111 @@ |
+#!/usr/bin/env python |
+# |
+# $Id: compat.py 712 2010-10-20 15:25:57Z g.rodola $ |
+# |
+ |
+"""Module which provides compatibility with older Python versions.""" |
+ |
+from operator import itemgetter as _itemgetter |
+from keyword import iskeyword as _iskeyword |
+import sys as _sys |
+ |
+ |
+def namedtuple(typename, field_names, verbose=False, rename=False): |
+ """A collections.namedtuple implementation written in Python |
+ to support Python versions < 2.6. |
+ |
+ Taken from: http://code.activestate.com/recipes/500261/ |
+ """ |
+ # Parse and validate the field names. Validation serves two |
+ # purposes, generating informative error messages and preventing |
+ # template injection attacks. |
+ if isinstance(field_names, basestring): |
+ # names separated by whitespace and/or commas |
+ field_names = field_names.replace(',', ' ').split() |
+ field_names = tuple(map(str, field_names)) |
+ if rename: |
+ names = list(field_names) |
+ seen = set() |
+ for i, name in enumerate(names): |
+ if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name) |
+ or not name or name[0].isdigit() or name.startswith('_') |
+ or name in seen): |
+ names[i] = '_%d' % i |
+ seen.add(name) |
+ field_names = tuple(names) |
+ for name in (typename,) + field_names: |
+ if not min(c.isalnum() or c=='_' for c in name): |
+ raise ValueError('Type names and field names can only contain ' \ |
+ 'alphanumeric characters and underscores: %r' |
+ % name) |
+ if _iskeyword(name): |
+ raise ValueError('Type names and field names cannot be a keyword: %r' \ |
+ % name) |
+ if name[0].isdigit(): |
+ raise ValueError('Type names and field names cannot start with a ' \ |
+ 'number: %r' % name) |
+ seen_names = set() |
+ for name in field_names: |
+ if name.startswith('_') and not rename: |
+ raise ValueError('Field names cannot start with an underscore: %r' |
+ % name) |
+ if name in seen_names: |
+ raise ValueError('Encountered duplicate field name: %r' % name) |
+ seen_names.add(name) |
+ |
+ # Create and fill-in the class template |
+ numfields = len(field_names) |
+ # tuple repr without parens or quotes |
+ argtxt = repr(field_names).replace("'", "")[1:-1] |
+ reprtxt = ', '.join('%s=%%r' % name for name in field_names) |
+ template = '''class %(typename)s(tuple): |
+ '%(typename)s(%(argtxt)s)' \n |
+ __slots__ = () \n |
+ _fields = %(field_names)r \n |
+ def __new__(_cls, %(argtxt)s): |
+ return _tuple.__new__(_cls, (%(argtxt)s)) \n |
+ @classmethod |
+ def _make(cls, iterable, new=tuple.__new__, len=len): |
+ 'Make a new %(typename)s object from a sequence or iterable' |
+ result = new(cls, iterable) |
+ if len(result) != %(numfields)d: |
+ raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result)) |
+ return result \n |
+ def __repr__(self): |
+ return '%(typename)s(%(reprtxt)s)' %% self \n |
+ def _asdict(self): |
+ 'Return a new dict which maps field names to their values' |
+ return dict(zip(self._fields, self)) \n |
+ def _replace(_self, **kwds): |
+ 'Return a new %(typename)s object replacing specified fields with new values' |
+ result = _self._make(map(kwds.pop, %(field_names)r, _self)) |
+ if kwds: |
+ raise ValueError('Got unexpected field names: %%r' %% kwds.keys()) |
+ return result \n |
+ def __getnewargs__(self): |
+ return tuple(self) \n\n''' % locals() |
+ for i, name in enumerate(field_names): |
+ template += ' %s = _property(_itemgetter(%d))\n' % (name, i) |
+ if verbose: |
+ print template |
+ |
+ # Execute the template string in a temporary namespace |
+ namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, |
+ _property=property, _tuple=tuple) |
+ try: |
+ exec template in namespace |
+ except SyntaxError, e: |
+ raise SyntaxError(e.message + ':\n' + template) |
+ result = namespace[typename] |
+ |
+ # For pickling to work, the __module__ variable needs to be set |
+ # to the frame where the named tuple is created. Bypass this |
+ # step in enviroments where sys._getframe is not defined (Jython |
+ # for example) or sys._getframe is not defined for arguments |
+ # greater than 0 (IronPython). |
+ try: |
+ result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__') |
+ except (AttributeError, ValueError): |
+ pass |
+ |
+ return result |