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