Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > dca483b59ba61f3fa092de932ddd570e > files > 747

nuface-2.0.14-2mdv2009.1.i586.rpm

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Copyright(C) 2007 INL
Written by Damien Boucard <damien.boucard AT inl.fr>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.

---
unicity.py is a module which checks a given attribute is unique in a sequence of objects.
"""

class UnicityError(LookupError):
    pass

class IncreasingError(LookupError):
    pass

def check_unicity(attribute_name, sequence, *args, **kw):
    """
    This function checks if an attribute of sequence elements is unique.
    If more than 2 arguments are given, it will check recursively into the
    given sequence names which should be attributes of sub-elements. If None
    is given, the element itself is iterated.

    @type sequence: list or tupe or any iterable instance
    @param attribute_name: represents the name of the unique attribute of the sequence element.
    @type attribute_name: str
    @raise UnicityError: if unicity is not respected.
    @raise AttributeError: if attribute_name is not found in one of sequence elements.

    >>> class Test:
    ...     def __init__(self, id): self.id = id
    >>> check_unicity("id", (Test(1), Test(2), Test(42), Test(33)))
    True
    >>> check_unicity("id", (Test(1), Test(2), Test(42), Test(1))) #doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    UnicityError: id=1 is found twice.

    Example of recursive lookup:
    >>> check_unicity("id", [(Test(1), Test(2)), (Test(42), Test(33))], None)
    True
    """
    values = kw.get("values", [])
    for element in sequence:
        if len(args) > 0:
            if args[0] is None:
                subsequence = element
            else:
                subsequence = getattr(element, args[0])
            check_unicity(attribute_name, subsequence, *args[1:], **{"values":values})
        else:
            attribute = getattr(element, attribute_name)
            if attribute in values:
                raise UnicityError("%s=%s is found twice." %(attribute_name, attribute))
            else:
                values.append(attribute)
    return True

def check_increasing(element_name, attribute_name, sequence, *args, **kw):
    """
    This function checks if sequence elements have an attribute which increments
    between one element to another. If more than 2 arguments are given, it will
    check recursively into the given sequence names which should be attributes
    of sub-elements. If None is given, the element itself is iterated.

    @type sequence: list or tupe or any iterable instance
    @param attribute_name: represents the name of the unique attribute of the sequence element.
    @type attribute_name: str
    @keyword minimal_value: indicates the first id value expected (default: 1)
    @type minimal_value: int
    @raise UnicityError: if unicity is not respected.
    @raise AttributeError: if attribute_name is not found in one of sequence elements.

    >>> class Test:
    ...     def __init__(self, id): self.id = id

    #>>> check_increasing("test", "id", (Test(1), Test(2), Test(3), Test(4)))
    True
    #>>> check_increasing("test", "id", (Test(1), Test(2), Test(4), Test(5))) #doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    IncreasingError: id=3 of <test> is missing.
    #>>> check_increasing("test", "id", (Test(42), Test(43), Test(43), Test(44)), minimal_value=42) #doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    IncreasingError: id=43 of <test> is found twice.

    Example of recursive lookup:
    >>> check_increasing("test", "id", [(Test(1), Test(2)), (Test(3), Test(4))], None)
    True
    """
    name = kw.get("name", attribute_name)
    minimal_value = kw.get("minimal_value", 1)
    expected = kw.get("expected", [minimal_value,])
    for element in sequence:
        if len(args) > 0:
            if args[0] is None:
                subsequence = element
            else:
                subsequence = getattr(element, args[0])
            check_increasing(element_name, attribute_name, subsequence, *args[1:],
                      **{"minimal_value": minimal_value, "expected": expected})
        else:
            attribute = getattr(element, attribute_name)
            if attribute < minimal_value:
                raise IncreasingError("%s of <%s> must be greater than %s; %s found."
                                 %(attribute_name, element_name, minimal_value-1, attribute))
            elif attribute > expected[0]:
                raise IncreasingError("%s=%s of <%s> is missing."
                                                   %(attribute_name, expected[0], element_name))
            elif attribute < expected[0]:
                raise IncreasingError("%s=%s of <%s> is found twice."
                                                  %(attribute_name, attribute, element_name))
            else:
                expected[0] = expected[0] + 1
    return True

if __name__ == "__main__":
    from doctest import testmod
    from sys import exit
    failure, nb_test = testmod()
    if failure:
        exit(1)