Lichen

Annotated lib/operator/core.py

24:ee6bdbd33518
2016-09-04 Paul Boddie Store removed modules for debugging purposes.
paul@6 1
#!/usr/bin/env python
paul@6 2
paul@6 3
"""
paul@6 4
Operator support.
paul@6 5
paul@6 6
Copyright (C) 2010, 2013, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
paul@6 7
paul@6 8
This program is free software; you can redistribute it and/or modify it under
paul@6 9
the terms of the GNU General Public License as published by the Free Software
paul@6 10
Foundation; either version 3 of the License, or (at your option) any later
paul@6 11
version.
paul@6 12
paul@6 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@6 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@6 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@6 16
details.
paul@6 17
paul@6 18
You should have received a copy of the GNU General Public License along with
paul@6 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@6 20
"""
paul@6 21
paul@6 22
# Define "is" and "is not" in terms of native operations. They are imported by
paul@6 23
# the operator.binary module.
paul@6 24
paul@6 25
from native import _is as is_, _is_not as is_not
paul@6 26
paul@6 27
def binary_op(a, b, left_accessor, right_accessor):
paul@6 28
paul@6 29
    """
paul@6 30
    A single parameterised function providing the binary operator mechanism for
paul@6 31
    arguments 'a' and 'b' using accessors given as 'left_accessor' and
paul@6 32
    'right_accessor' which provide the methods for the operands.
paul@6 33
    """
paul@6 34
paul@6 35
    # First, try and get a method for the left argument, and then call it with
paul@6 36
    # the right argument.
paul@6 37
paul@6 38
    try:
paul@6 39
        fn = left_accessor(a)
paul@6 40
    except AttributeError:
paul@6 41
        pass
paul@6 42
    else:
paul@6 43
        result = fn(b)
paul@6 44
        if is_not(result, NotImplemented):
paul@6 45
            return result
paul@6 46
paul@6 47
    # Otherwise, try and get a method for the right argument, and then call it
paul@6 48
    # with the left argument.
paul@6 49
paul@6 50
    try:
paul@6 51
        fn = right_accessor(b)
paul@6 52
    except AttributeError:
paul@6 53
        pass
paul@6 54
    else:
paul@6 55
        result = fn(a)
paul@6 56
        if is_not(result, NotImplemented):
paul@6 57
            return result
paul@6 58
paul@6 59
    # Where no methods were available, or if neither method could support the
paul@6 60
    # operation, raise an exception.
paul@6 61
paul@6 62
    raise TypeError
paul@6 63
paul@6 64
def unary_op(a, accessor):
paul@6 65
paul@6 66
    """
paul@6 67
    A single parameterised function providing the unary operator mechanism for
paul@6 68
    the argument 'a' using the given 'accessor' to provide the method for the
paul@6 69
    operand.
paul@6 70
    """
paul@6 71
paul@6 72
    # First, try and get a method for the argument, and then call it.
paul@6 73
paul@6 74
    try:
paul@6 75
        fn = accessor(a)
paul@6 76
    except AttributeError:
paul@6 77
        pass
paul@6 78
    else:
paul@6 79
        result = fn()
paul@6 80
        if is_not(result, NotImplemented):
paul@6 81
            return result
paul@6 82
paul@6 83
    # Where no method was available, or if the method could not support the
paul@6 84
    # operation, raise an exception.
paul@6 85
paul@6 86
    raise TypeError
paul@6 87
paul@6 88
def augassign(a, b, augmented_accessor, left_accessor, right_accessor):
paul@6 89
paul@6 90
    """
paul@6 91
    A single parameterised function providing the augmented assignment mechanism
paul@6 92
    for arguments 'a' and 'b' either using 'augmented_accessor' (directly
paul@6 93
    affecting 'a') or using 'left_accessor' and 'right_accessor' (conventional
paul@6 94
    operator method accessors).
paul@6 95
paul@6 96
    The result of the assignment is returned.
paul@6 97
    """
paul@6 98
paul@6 99
    # First, try and get a method that directly affects the assignment target.
paul@6 100
paul@6 101
    try:
paul@6 102
        fn = augmented_accessor(a)
paul@6 103
    except AttributeError:
paul@6 104
        pass
paul@6 105
    else:
paul@6 106
        result = fn(b)
paul@6 107
        if is_not(result, NotImplemented):
paul@6 108
            return result
paul@6 109
paul@6 110
    # Otherwise, attempt a conventional binary operation.
paul@6 111
paul@6 112
    return binary_op(a, b, left_accessor, right_accessor)
paul@6 113
paul@6 114
# vim: tabstop=4 expandtab shiftwidth=4