~ubuntu-branches/ubuntu/trusty/boa-constructor/trusty

« back to all changes in this revision

Viewing changes to ExternalLib/Signature.py

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2007-01-23 21:32:29 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070123213229-1d9lxp9c4dutjwv5
Add a .desktop file (Closes: #349081)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
__version__ = 0,1,1
2
 
__doc__ = """\
3
 
This module, Signature, contains a single class Signature. This class
4
 
permits the convenient examination of the call signatures of Python
5
 
callable objects.
6
 
 
7
 
Here's some examples of its use:
8
 
 
9
 
    >>> def foo(x, y, z=-1.0, *args, **kw):
10
 
    ...     return (x+y)**z
11
 
    ...
12
 
    >>> f = Signature(foo)
13
 
 
14
 
    >>> print 'ordinary arglist:', f.ordinary_args()
15
 
    ordinary arglist: ('x', 'y', 'z')
16
 
 
17
 
    >>> print 'special_args:', f.special_args()
18
 
    special_args: {'keyword': 'kw', 'positional': 'args'}
19
 
 
20
 
    >>> print 'full_arglist:', f.full_arglist()
21
 
    full_arglist: ['x', 'y', 'z', 'args', 'kw']
22
 
 
23
 
    >>> print 'defaults:', f.defaults()
24
 
    defaults: {'z': -1.0}
25
 
 
26
 
    >>> print 'signature:', str(f)
27
 
    signature: foo(x, y, z=-1.0, *args, **kw)
28
 
 
29
 
The methods of the Signature class are documented below:
30
 
 
31
 
o Signature(func)
32
 
 
33
 
  Arguments: func -- this is any callable object written in Python
34
 
  Returns:   a Signature instance
35
 
  Raises:    TypeError, ValueError
36
 
 
37
 
  Behavior:
38
 
 
39
 
  The Signature constructor returns a Signature instance for the callable
40
 
  object func. If func is not callable, then a TypeError is raised. If
41
 
  it is callable, but can't be handled, then a ValueError is raised. (At
42
 
  the moment, the latter category are any C builtins.)
43
 
 
44
 
o Signature.ordinary_args()
45
 
 
46
 
  Returns:   A tuple of strings containing the names of all 'normal'
47
 
             arguments.
48
 
 
49
 
  Behavior:
50
 
 
51
 
  If the callable object has no arguments, the empty tuple is returned.
52
 
  The definition of 'normal' includes explicit keyword arguments and the
53
 
  'self' argument for methods, but does not include the special arguments
54
 
  specified with the '*' or '**' syntax.
55
 
 
56
 
o Signature.special_args()
57
 
 
58
 
  Returns: A dictionary with the names of the special arguments.
59
 
 
60
 
  Behavior:
61
 
 
62
 
  This method returns a dictionary of 0, 1, or 2 arguments. An entry
63
 
  with a key of 'positional' has the name of the '*'-argument as its
64
 
  value, and an entry with a key of 'keyword' has the name of the
65
 
  '**'-argument as its value. If the dictionary is empty, then there
66
 
  are no special arguments.
67
 
 
68
 
o Signature.full_arglist()
69
 
 
70
 
  Returns:   A list of all the arguments to the function, whether special
71
 
             or not.
72
 
 
73
 
  Behavior:
74
 
 
75
 
  If there are no special arguments, Signature.full_arglist()'s returns
76
 
  a list with the same elements as Signature.ordinary_args(). If there
77
 
  are are special arguments, they appended to the end of the list, with
78
 
  the '*'-argument preceding the '**'-argument. No asterisks are added
79
 
  to the argument names in the returned list.
80
 
 
81
 
o Signature.defaults()
82
 
 
83
 
  Returns:   A dictionary containing the argument names (as a string) as
84
 
             the keys and the default objects as values.
85
 
 
86
 
  Behavior:
87
 
 
88
 
  If there are no arguments with default values, then an empty dictionary
89
 
  is returned. The special arguments specified with the '*' and '**'
90
 
  syntax are not considered.
91
 
 
92
 
 
93
 
o Signature.__str__()
94
 
 
95
 
  Returns:   A string that should resemble the function or method
96
 
             declaration.
97
 
 
98
 
  Behavior:
99
 
 
100
 
  While it's impossible to exactly match the actual declaration, in most
101
 
  cases this should look pretty close.
102
 
"""
103
 
 
104
 
import types, string
105
 
 
106
 
class Signature:
107
 
    # Magic numbers: These are the bit masks in func_code.co_flags that
108
 
    # reveal whether or not the function has a *arg or **kw argument.
109
 
    #
110
 
    POS_LIST = 4
111
 
    KEY_DICT = 8
112
 
    def __init__(self, func):
113
 
        self.type = type(func)
114
 
        self.name, self.func = _getcode(func)
115
 
    def ordinary_args(self):
116
 
        n = self.func.func_code.co_argcount
117
 
        return self.func.func_code.co_varnames[0:n]
118
 
    def special_args(self):
119
 
        n = self.func.func_code.co_argcount
120
 
        x = {}
121
 
        #
122
 
        #
123
 
        #
124
 
        if self.func.func_code.co_flags & (self.POS_LIST|self.KEY_DICT):
125
 
            x['positional'] = self.func.func_code.co_varnames[n]
126
 
            try:
127
 
                x['keyword'] = self.func.func_code.co_varnames[n+1]
128
 
            except IndexError:
129
 
                x['keyword'] = x['positional']
130
 
                del x['positional']
131
 
        elif self.func.func_code.co_flags & self.POS_LIST:
132
 
            x['positional'] = self.func.func_code.co_varnames[n]
133
 
        elif self.func.func_code.co_flags & self.KEY_DICT:
134
 
            x['keyword'] = self.func.func_code.co_varnames[n]
135
 
        return x
136
 
    def full_arglist(self):
137
 
        base = list(self.ordinary_args())
138
 
        x = self.special_args()
139
 
        if x.has_key('positional'):
140
 
            base.append(x['positional'])
141
 
        if x.has_key('keyword'):
142
 
            base.append(x['keyword'])
143
 
        return base
144
 
    def defaults(self):
145
 
        defargs = self.func.func_defaults
146
 
        args = self.ordinary_args()
147
 
        mapping = {}
148
 
        if defargs is not None:
149
 
            for i in range(-1, -(len(defargs)+1), -1):
150
 
                mapping[args[i]] = defargs[i]
151
 
        else:
152
 
            pass
153
 
        return mapping
154
 
    def __str__(self):
155
 
        defaults = self.defaults()
156
 
        specials = self.special_args()
157
 
        l = []
158
 
        for arg in self.ordinary_args():
159
 
            if defaults.has_key(arg):
160
 
                l.append( arg + '=' + str(defaults[arg]) )
161
 
            else:
162
 
                l.append( arg )
163
 
        if specials.has_key('positional'):
164
 
            l.append( '*' + specials['positional'] )
165
 
        if specials.has_key('keyword'):
166
 
            l.append( '**' + specials['keyword'] )
167
 
        return "%s(%s)" % (self.name, string.join(l, ', '))
168
 
 
169
 
def _getcode(f):
170
 
    """_getcode(f)
171
 
 
172
 
    This function returns the name and """
173
 
    def method_get(f):
174
 
        return f.__name__, f.im_func
175
 
    def function_get(f):
176
 
        return f.__name__, f
177
 
    def instance_get(f):
178
 
        if hasattr(f, '__call__'):
179
 
            return ("%s%s" % (f.__class__.__name__, '__call__'),
180
 
                    f.__call__.im_func)
181
 
        else:
182
 
            s = ("Instance %s of class %s does not have a __call__ method" %
183
 
                 (f, f.__class__.__name__))
184
 
            raise TypeError, s
185
 
    def class_get(f):
186
 
        if hasattr(f, '__init__'):
187
 
            return f.__name__, f.__init__.im_func
188
 
        else:
189
 
            return f.__name__, lambda: None
190
 
    codedict = { types.UnboundMethodType: method_get,
191
 
                 types.MethodType       : method_get,
192
 
                 types.FunctionType     : function_get,
193
 
                 types.InstanceType     : instance_get,
194
 
                 types.ClassType        : class_get
195
 
                 }
196
 
    try:
197
 
        return codedict[type(f)](f)
198
 
    except KeyError:
199
 
        if callable(f): # eg, built-in functions and methods
200
 
            raise ValueError, "type %s not supported yet." % type(f)
201
 
        else:
202
 
            raise TypeError, ("object %s of type %s is not callable." %
203
 
                                     (f, type(f)))
204
 
 
205
 
if __name__ == '__main__':
206
 
    def foo(x, y, z=-1.0, *args, **kw):
207
 
        return (x+y)**z
208
 
    f = Signature(foo)
209
 
    print "ordinary arglist:", f.ordinary_args()
210
 
    print "special_args:", f.special_args()
211
 
    print "full_arglist:", f.full_arglist()
212
 
    print "defaults:", f.defaults()
213
 
    print "signature:",
 
1
__version__ = 0,1,1
 
2
__doc__ = """\
 
3
This module, Signature, contains a single class Signature. This class
 
4
permits the convenient examination of the call signatures of Python
 
5
callable objects.
 
6
 
 
7
Here's some examples of its use:
 
8
 
 
9
    >>> def foo(x, y, z=-1.0, *args, **kw):
 
10
    ...     return (x+y)**z
 
11
    ...
 
12
    >>> f = Signature(foo)
 
13
 
 
14
    >>> print 'ordinary arglist:', f.ordinary_args()
 
15
    ordinary arglist: ('x', 'y', 'z')
 
16
 
 
17
    >>> print 'special_args:', f.special_args()
 
18
    special_args: {'keyword': 'kw', 'positional': 'args'}
 
19
 
 
20
    >>> print 'full_arglist:', f.full_arglist()
 
21
    full_arglist: ['x', 'y', 'z', 'args', 'kw']
 
22
 
 
23
    >>> print 'defaults:', f.defaults()
 
24
    defaults: {'z': -1.0}
 
25
 
 
26
    >>> print 'signature:', str(f)
 
27
    signature: foo(x, y, z=-1.0, *args, **kw)
 
28
 
 
29
The methods of the Signature class are documented below:
 
30
 
 
31
o Signature(func)
 
32
 
 
33
  Arguments: func -- this is any callable object written in Python
 
34
  Returns:   a Signature instance
 
35
  Raises:    TypeError, ValueError
 
36
 
 
37
  Behavior:
 
38
 
 
39
  The Signature constructor returns a Signature instance for the callable
 
40
  object func. If func is not callable, then a TypeError is raised. If
 
41
  it is callable, but can't be handled, then a ValueError is raised. (At
 
42
  the moment, the latter category are any C builtins.)
 
43
 
 
44
o Signature.ordinary_args()
 
45
 
 
46
  Returns:   A tuple of strings containing the names of all 'normal'
 
47
             arguments.
 
48
 
 
49
  Behavior:
 
50
 
 
51
  If the callable object has no arguments, the empty tuple is returned.
 
52
  The definition of 'normal' includes explicit keyword arguments and the
 
53
  'self' argument for methods, but does not include the special arguments
 
54
  specified with the '*' or '**' syntax.
 
55
 
 
56
o Signature.special_args()
 
57
 
 
58
  Returns: A dictionary with the names of the special arguments.
 
59
 
 
60
  Behavior:
 
61
 
 
62
  This method returns a dictionary of 0, 1, or 2 arguments. An entry
 
63
  with a key of 'positional' has the name of the '*'-argument as its
 
64
  value, and an entry with a key of 'keyword' has the name of the
 
65
  '**'-argument as its value. If the dictionary is empty, then there
 
66
  are no special arguments.
 
67
 
 
68
o Signature.full_arglist()
 
69
 
 
70
  Returns:   A list of all the arguments to the function, whether special
 
71
             or not.
 
72
 
 
73
  Behavior:
 
74
 
 
75
  If there are no special arguments, Signature.full_arglist()'s returns
 
76
  a list with the same elements as Signature.ordinary_args(). If there
 
77
  are are special arguments, they appended to the end of the list, with
 
78
  the '*'-argument preceding the '**'-argument. No asterisks are added
 
79
  to the argument names in the returned list.
 
80
 
 
81
o Signature.defaults()
 
82
 
 
83
  Returns:   A dictionary containing the argument names (as a string) as
 
84
             the keys and the default objects as values.
 
85
 
 
86
  Behavior:
 
87
 
 
88
  If there are no arguments with default values, then an empty dictionary
 
89
  is returned. The special arguments specified with the '*' and '**'
 
90
  syntax are not considered.
 
91
 
 
92
 
 
93
o Signature.__str__()
 
94
 
 
95
  Returns:   A string that should resemble the function or method
 
96
             declaration.
 
97
 
 
98
  Behavior:
 
99
 
 
100
  While it's impossible to exactly match the actual declaration, in most
 
101
  cases this should look pretty close.
 
102
"""
 
103
 
 
104
import types, string
 
105
 
 
106
class Signature:
 
107
    # Magic numbers: These are the bit masks in func_code.co_flags that
 
108
    # reveal whether or not the function has a *arg or **kw argument.
 
109
    #
 
110
    POS_LIST = 4
 
111
    KEY_DICT = 8
 
112
    def __init__(self, func):
 
113
        self.type = type(func)
 
114
        self.name, self.func = _getcode(func)
 
115
    def ordinary_args(self):
 
116
        n = self.func.func_code.co_argcount
 
117
        return self.func.func_code.co_varnames[0:n]
 
118
    def special_args(self):
 
119
        n = self.func.func_code.co_argcount
 
120
        x = {}
 
121
        #
 
122
        #
 
123
        #
 
124
        if self.func.func_code.co_flags & (self.POS_LIST|self.KEY_DICT):
 
125
            x['positional'] = self.func.func_code.co_varnames[n]
 
126
            try:
 
127
                x['keyword'] = self.func.func_code.co_varnames[n+1]
 
128
            except IndexError:
 
129
                x['keyword'] = x['positional']
 
130
                del x['positional']
 
131
        elif self.func.func_code.co_flags & self.POS_LIST:
 
132
            x['positional'] = self.func.func_code.co_varnames[n]
 
133
        elif self.func.func_code.co_flags & self.KEY_DICT:
 
134
            x['keyword'] = self.func.func_code.co_varnames[n]
 
135
        return x
 
136
    def full_arglist(self):
 
137
        base = list(self.ordinary_args())
 
138
        x = self.special_args()
 
139
        if x.has_key('positional'):
 
140
            base.append(x['positional'])
 
141
        if x.has_key('keyword'):
 
142
            base.append(x['keyword'])
 
143
        return base
 
144
    def defaults(self):
 
145
        defargs = self.func.func_defaults
 
146
        args = self.ordinary_args()
 
147
        mapping = {}
 
148
        if defargs is not None:
 
149
            for i in range(-1, -(len(defargs)+1), -1):
 
150
                mapping[args[i]] = defargs[i]
 
151
        else:
 
152
            pass
 
153
        return mapping
 
154
    def __str__(self):
 
155
        defaults = self.defaults()
 
156
        specials = self.special_args()
 
157
        l = []
 
158
        for arg in self.ordinary_args():
 
159
            if defaults.has_key(arg):
 
160
                l.append( arg + '=' + str(defaults[arg]) )
 
161
            else:
 
162
                l.append( arg )
 
163
        if specials.has_key('positional'):
 
164
            l.append( '*' + specials['positional'] )
 
165
        if specials.has_key('keyword'):
 
166
            l.append( '**' + specials['keyword'] )
 
167
        return "%s(%s)" % (self.name, string.join(l, ', '))
 
168
 
 
169
def _getcode(f):
 
170
    """_getcode(f)
 
171
 
 
172
    This function returns the name and """
 
173
    def method_get(f):
 
174
        return f.__name__, f.im_func
 
175
    def function_get(f):
 
176
        return f.__name__, f
 
177
    def instance_get(f):
 
178
        if hasattr(f, '__call__'):
 
179
            return ("%s%s" % (f.__class__.__name__, '__call__'),
 
180
                    f.__call__.im_func)
 
181
        else:
 
182
            s = ("Instance %s of class %s does not have a __call__ method" %
 
183
                 (f, f.__class__.__name__))
 
184
            raise TypeError, s
 
185
    def class_get(f):
 
186
        if hasattr(f, '__init__'):
 
187
            return f.__name__, f.__init__.im_func
 
188
        else:
 
189
            return f.__name__, lambda: None
 
190
    codedict = { types.UnboundMethodType: method_get,
 
191
                 types.MethodType       : method_get,
 
192
                 types.FunctionType     : function_get,
 
193
                 types.InstanceType     : instance_get,
 
194
                 types.ClassType        : class_get
 
195
                 }
 
196
    try:
 
197
        return codedict[type(f)](f)
 
198
    except KeyError:
 
199
        if callable(f): # eg, built-in functions and methods
 
200
            raise ValueError, "type %s not supported yet." % type(f)
 
201
        else:
 
202
            raise TypeError, ("object %s of type %s is not callable." %
 
203
                                     (f, type(f)))
 
204
 
 
205
if __name__ == '__main__':
 
206
    def foo(x, y, z=-1.0, *args, **kw):
 
207
        return (x+y)**z
 
208
    f = Signature(foo)
 
209
    print "ordinary arglist:", f.ordinary_args()
 
210
    print "special_args:", f.special_args()
 
211
    print "full_arglist:", f.full_arglist()
 
212
    print "defaults:", f.defaults()
 
213
    print "signature:",