Source code for algebraixlib.undef

"""Class Undef (represents the concept of 'undefined') and associated constructs."""

# $Id: undef.py 22614 2015-07-15 18:14:53Z gfiedler $
# Copyright Algebraix Data Corporation 2015 - $Date: 2015-07-15 13:14:53 -0500 (Wed, 15 Jul 2015) $
#
# This file is part of algebraixlib <http://github.com/AlgebraixData/algebraixlib>.
#
# algebraixlib is free software: you can redistribute it and/or modify it under the terms of version
# 3 of the GNU Lesser General Public License as published by the Free Software Foundation.
#
# algebraixlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with algebraixlib.
# If not, see <http://www.gnu.org/licenses/>.
# --------------------------------------------------------------------------------------------------


[docs]class Undef: """A singleton class that represents the concept of "undefined". It can't be treated as a value by the Data Algebra library and specifically it will never appear as the value of an Atom.""" _instance = None
[docs] def __new__(cls): """Override __new__ to create a singleton class.""" if Undef._instance is None: Undef._instance = super().__new__(cls) return Undef._instance
[docs] def __str__(self): """Pretty-print Undef.""" return 'undef'
[docs] def __eq__(self, other): """Prevent comparisons on Undef; raise a TypeError.""" raise TypeError("== is not supported by Undef")
[docs] def __ne__(self, other): """Prevent comparisons on Undef; raise a TypeError.""" raise TypeError("!= is not supported by Undef")
def __bool__(self): """Prevent comparisons on Undef; raise a TypeError.""" raise TypeError("Boolean conversion is not supported by Undef")
[docs]class RaiseOnUndef: """Manage the level for make_or_raise_undef(). Implemented as static class.""" # Set the _reset_level to the desired 'normal' level. _reset_level = 0 _level = _reset_level def __init__(self): raise AssertionError("Don't instantiate RaiseOnUndef class. Use it as a static class only.") @staticmethod
[docs] def get_level(): """Return the current level for raising an UndefException. The exception is raised if the 'level' argument of make_or_raise_undef() is less than or equal to the value returned here. """ return RaiseOnUndef._level
@staticmethod
[docs] def set_level(temp_value): """Set the level for raising an UndefException temporarily to 'temp_value'.""" RaiseOnUndef._level = temp_value
@staticmethod
[docs] def reset(): """Reset the level for raising an UndefException back to its initial value.""" RaiseOnUndef._level = RaiseOnUndef._reset_level
[docs]class UndefException(Exception): """This exception is raised when the 'level' argument of make_or_raise_undef() is less than or equal to the RaiseOnUndef level.""" pass
[docs]def make_or_raise_undef(level=1): """Raise UndefException if level is less than or equal to the RaiseOnUndef level, otherwise return Undef(). :param level: An integer >= 1. Default is 1. .. note:: Use 1 (or no argument) for the cases that are most likely to be errors (like wrong argument types). Use higher numbers for cases that may return Undef() on purpose. """ if level <= RaiseOnUndef.get_level(): raise UndefException("Result is undefined. See also 'undef.RaiseOnUndef'.") return Undef()