1545cac483f21aacce887d69f3c87d05013375a7
[sfa.git] / sfa / storage / parameter.py
1 #
2 # Shared type definitions
3 #
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
6 #
7
8 from types import NoneType, IntType, LongType, FloatType, DictType, TupleType, ListType
9 from sfa.util.faults import SfaAPIError
10
11 from sfa.util.py23 import StringType
12
13
14 class Parameter:
15     """
16     Typed value wrapper. Use in accepts and returns to document method
17     parameters. Set the optional and default attributes for
18     sub-parameters (i.e., dict fields).
19     """
20
21     def __init__(self, type, doc="",
22                  min=None, max=None,
23                  optional=None,
24                  ro=False,
25                  nullok=False):
26         # Basic type of the parameter. Must be a builtin type
27         # that can be marshalled by XML-RPC.
28         self.type = type
29
30         # Documentation string for the parameter
31         self.doc = doc
32
33         # Basic value checking. For numeric types, the minimum and
34         # maximum possible values, inclusive. For string types, the
35         # minimum and maximum possible UTF-8 encoded byte lengths.
36         self.min = min
37         self.max = max
38
39         # Whether the sub-parameter is optional or not. If None,
40         # unknown whether it is optional.
41         self.optional = optional
42
43         # Whether the DB field is read-only.
44         self.ro = ro
45
46         # Whether the DB field can be NULL.
47         self.nullok = nullok
48
49     def type(self):
50         return self.type
51
52     def __repr__(self):
53         return repr(self.type)
54
55
56 class Mixed(tuple):
57     """
58     A list (technically, a tuple) of types. Use in accepts and returns
59     to document method parameters that may return mixed types.
60     """
61
62     def __new__(cls, *types):
63         return tuple.__new__(cls, types)
64
65
66 def python_type(arg):
67     """
68     Returns the Python type of the specified argument, which may be a
69     Python type, a typed value, or a Parameter.
70     """
71
72     if isinstance(arg, Parameter):
73         arg = arg.type
74
75     if isinstance(arg, type):
76         return arg
77     else:
78         return type(arg)
79
80
81 def xmlrpc_type(arg):
82     """
83     Returns the XML-RPC type of the specified argument, which may be a
84     Python type, a typed value, or a Parameter.
85     """
86
87     arg_type = python_type(arg)
88
89     if arg_type == NoneType:
90         return "nil"
91     elif arg_type == IntType or arg_type == LongType:
92         return "int"
93     elif arg_type == bool:
94         return "boolean"
95     elif arg_type == FloatType:
96         return "double"
97     elif issubclass(arg_type, StringType):
98         return "string"
99     elif arg_type == ListType or arg_type == TupleType:
100         return "array"
101     elif arg_type == DictType:
102         return "struct"
103     elif arg_type == Mixed:
104         # Not really an XML-RPC type but return "mixed" for
105         # documentation purposes.
106         return "mixed"
107     else:
108         raise SfaAPIError("XML-RPC cannot marshal %s objects" % arg_type)