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
|