summaryrefslogtreecommitdiff
path: root/cad/src/modelTree/Api.py
blob: 88944eecb0d7c72fd2b2fb6cda05a58320d305f7 (plain)
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
# Copyright 2006-2008 Nanorex, Inc.  See LICENSE file for details.
"""
Api.py - superclass for testing API compliance

Note: this is used in NE1 if certain private debug flags are set,
but has not been tested or maintained for a long time (as of 081216).
If it is ever verified to work and be useful, it can be moved into a
more general place.

@author: Will
@version: $Id$
@copyright: 2006-2008 Nanorex, Inc.  See LICENSE file for details.
"""

# Yet another experiment with testing API compliance in Python

def _inheritance_chains(klas, endpoint):
    if klas is endpoint:
        return [ (endpoint,) ]
    lst = [ ]
    for base in klas.__bases__:
        for seq in _inheritance_chains(base, endpoint):
            lst.append((klas,) + seq)
    return lst

# This little hack is a way to ensure that a class implementing an API does so completely. API
# compliance also requires that the caller not call any methods _not_ defined by the API, but
# that's a harder problem that we'll ignore for the moment.

class Api(object):
    #bruce 081216 added superclass object, untested
    def _verify_api_compliance(self):
        from types import MethodType
        myclass = self.__class__
        mystuff = myclass.__dict__
        ouch = False
        for legacy in _inheritance_chains(myclass, Api):
            assert len(legacy) >= 3
            api = legacy[-2]
            print api, api.__dict__
            for method in api.__dict__:
                if not method.startswith("__"):
                    assert type(getattr(api, method)) is MethodType
                    assert type(getattr(self, method)) is MethodType
                    this_method_ok = False
                    for ancestor in legacy[:-2]:
                        if method in ancestor.__dict__:
                            this_method_ok = True
                    if not this_method_ok:
                        print myclass, 'does not implement', method, 'from', api
                        ouch = True
        if ouch:
            raise Exception('Class does not comply with its API')

# end