[tor-commits] [ooni-probe/master] * Added utilities file for assertions and checks.
isis at torproject.org
isis at torproject.org
Thu Nov 1 12:14:01 UTC 2012
commit 63c11a5acf05a5ccf7cf360c0cf13d8372cbb63d
Author: Isis Lovecruft <isis at torproject.org>
Date: Wed Oct 31 16:29:07 2012 +0000
* Added utilities file for assertions and checks.
* Moved the usage.Options ValueChecker class to the utils.assertions file.
---
ooni/utils/assertions.py | 180 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 180 insertions(+), 0 deletions(-)
diff --git a/ooni/utils/assertions.py b/ooni/utils/assertions.py
new file mode 100644
index 0000000..875dcf5
--- /dev/null
+++ b/ooni/utils/assertions.py
@@ -0,0 +1,180 @@
+#-*- coding: utf-8 -*-
+#
+# assertions.py
+# -------------
+# Collection of utilies for checks and assertions.
+#
+# :authors: Isis Lovecruft
+# :version: 0.1.0-alpha
+# :license: see included LICENSE file
+# :copyright: 2012 Isis Lovecruft, The Tor Project Inc.
+#
+
+class ValueChecker(object):
+ """
+ A class for general purpose value checks on commandline parameters
+ passed to subclasses of :class:`twisted.python.usage.Options`.
+ """
+ default_doc = "fix me"
+
+ def __init__(self, coerce_doc=None):
+ if not coerce_doc:
+ self.coerce_doc = default_doc
+ else:
+ self.coerce_doc = coerce_doc
+
+ @classmethod
+ def port_check(cls, port,
+ range_min=1024, range_max=65535,
+ coerce_doc=None):
+ """
+ Check that given ports are in the allowed range for an unprivileged
+ user.
+
+ :param port:
+ The port to check.
+ :param range_min:
+ The minimum allowable port number.
+ :param range_max:
+ The minimum allowable port number.
+ :param coerce_doc:
+ The documentation string to show in the optParameters menu, see
+ :class:`twisted.python.usage.Options`.
+ """
+ if not coerce_doc:
+ coerceDoc = cls.default_doc
+
+ assert isinstance(port, int)
+ if port not in range(range_min, range_max):
+ raise ValueError("Port out of range")
+ log.err()
+
+ @staticmethod
+ def uid_check(error_message):
+ """
+ Check that we're not root. If we are, setuid(1000) to normal user if
+ we're running on a posix-based system, and if we're on Windows just
+ tell the user that we can't be run as root with the specified options
+ and then exit.
+
+ :param error_message:
+ The string to log as an error message when the uid check fails.
+ """
+ uid, gid = os.getuid(), os.getgid()
+ if uid == 0 and gid == 0:
+ log.msg(error_message)
+ if os.name == 'posix':
+ log.msg("Dropping privileges to normal user...")
+ os.setgid(1000)
+ os.setuid(1000)
+ else:
+ sys.exit(0)
+
+ @staticmethod
+ def dir_check(d):
+ """Check that the given directory exists."""
+ if not os.path.isdir(d):
+ raise ValueError("%s doesn't exist, or has wrong permissions" % d)
+
+ @staticmethod
+ def file_check(f):
+ """Check that the given file exists."""
+ if not os.path.isfile(f):
+ raise ValueError("%s does not exist, or has wrong permissions" % f)
+
+def isNewStyleClass(obj):
+ """
+ Check if :param:`obj` is a new-style class, which is any class
+ derived by either
+
+ NewStyleClass = type('NewStyleClass')
+ or
+ class NewStyleClass(object):
+ pass
+
+ whereas old-style classes are (only in Python 2.x) derived by:
+
+ class OldStyleClass:
+ pass
+
+ There are recently implemented classes in many Python libraries,
+ including a few in Twisted, which are derived from old-style classes.
+ Thus, calling super() or attempting to retrieve the MRO of any
+ subclass of old-style classes can cause issues such as:
+
+ o Calling Subclass.mro() goes through the class hierarchy until it
+ reaches OldStyleClass, which has no mro(), and raises an
+ AttributeError.
+
+ o Calling super(Subclass, subcls) produces an ambiguous, rather than
+ algorithmic, class hierarchy, which (especially in Twisted's case)
+ breaks multiple inheritance.
+
+ o Expected Subclass instance attributes, in particular __bases__ and
+ __class__, can be missing, which in turn leads to problems with
+ a whole bunch of builtin methods and modules.
+
+ For more information, see:
+ http://www.python.org/download/releases/2.3/mro/
+ http://www.cafepy.com/article/python_attributes_and_methods/
+
+ :return:
+ True if :param:`obj` is a new-style class derived from object;
+ False if :param:`obj` is an old-style class (or derived from
+ one).
+ """
+ from types import ClassType
+ return not isinstance(type(object), ClassType)
+
+def isOldStyleClass(obj):
+ """
+ Check if :param:`obj` is an old-style class, which is any class
+ derived in Python 2.x with:
+
+ class OldStyleClass:
+ pass
+
+ There are recently implemented classes in many Python libraries,
+ including a few in Twisted, which are derived from old-style classes,
+ and thus their types, bases, and attributes are generally just messed
+ up.
+
+ :return:
+ True if :param:`obj` is a new-style class derived from object;
+ False if :param:`obj` is an old-style class (or derived from
+ one).
+ """
+ from types import ClassType
+ return not isinstance(type(object), ClassType)
+
+def isClass(obj):
+ """
+ Check if an object is *a* class (not a specific class), without trying
+ to call the obj.__class__ attribute, as that is not available in some
+ cases. This function will return True for both old- and new-style
+ classes, however, it will return False for class instances of either
+ style. An alternate way to do this (although it presumes that
+ :param:`obj` is a class instance) would be:
+
+ from types import TypeType
+ return isinstance(object.__class__, TypeType)
+
+ It turns out that objects with <type 'type'>, i.e. classes, don't
+ actually have the __class__ attribute...go figure. Instead, class
+ objects are only required to have the __doc__ and __module__
+ attributes.
+
+ :param obj:
+ Any object.
+ :return:
+ True if :param:`obj` is a class, False if otherwise (even if
+ :param:`obj` is an instance of a class).
+ """
+ from types import ClassType
+ return isinstance(object, (type, ClassType))
+
+def isNotClass(object):
+ """
+ See :func:`isClass`.
+ """
+ return True if not isClass(object) else False
More information about the tor-commits
mailing list