File: contracts.py

package info (click to toggle)
glueviz 0.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 17,180 kB
  • ctags: 6,728
  • sloc: python: 37,111; makefile: 134; sh: 60
file content (111 lines) | stat: -rw-r--r-- 2,736 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""
An interface to PyContracts, to annotate functions with type information

The @contract decorator is disabled by default, to avoid
any runtime overhead when using Glue. To enable runtime
checking, run

glue.config.enable_contracts(True)

in a glue config file.

If PyContrats is imported, a no-op @contract decorator
is provided for compatibility

Glue code should only import contract through this module,
and never directly from the contracts package.
"""

from __future__ import absolute_import, division, print_function

from pandas import Series
from numpy import ndarray, s_

from glue.external.six import string_types
from glue.config import enable_contracts


def _build_custom_contracts():
    """
    Define some custom contracts if PyContracts is found
    """
    from contracts import new_contract

    @new_contract
    def cid_like(value):
        """
        Value is a ComponentID or a string
        """
        from glue.core import ComponentID
        return isinstance(value, (ComponentID, string_types))

    @new_contract
    def component_like(value):
        from glue.core import Component, ComponentLink
        return isinstance(value, (Component, ComponentLink,
                                  ndarray, list, Series))

    @new_contract
    def array_like(value):
        return isinstance(value, (ndarray, list))

    @new_contract
    def color(value):
        """
        A valid matplotlib color
        """
        from matplotlib.colors import colorConverter
        try:
            colorConverter.to_rgba(value)
        except ValueError:
            return False

    @new_contract
    def inst(value, *types):
        return isinstance(value, types)

    @new_contract
    def data_view(value):
        from glue.core import ComponentID

        if value is None:
            return
        if isinstance(value, ComponentID):
            return
        try:
            if not isinstance(value[0], ComponentID):
                return False
            s_[value[1:]]
        except:
            return False

    @new_contract
    def array_view(value):
        try:
            s_[value]
        except:
            return False

    @new_contract
    def callable(value):
        return hasattr(value, '__call__')

try:
    from contracts import contract, ContractsMeta

    if not enable_contracts():
        from contracts import disable_all
        disable_all()

    _build_custom_contracts()

except ImportError:
    # no-op interface if PyContracts isn't installed

    def contract(*args, **kwargs):
        if args:  # called as @contract
            return args[0]
        else:   # called as @contract(x='int', ...)
            return lambda func: func

    ContractsMeta = type