001: // Copyright (c) Corporation for National Research Initiatives
002: package org.python.core;
003:
004: /**
005: * A python function.
006: */
007:
008: public class PyFunction extends PyObject {
009: public String __name__;
010: public PyObject __doc__;
011: public PyObject func_globals;
012: public PyObject[] func_defaults;
013: public PyCode func_code;
014: public PyObject __dict__;
015: public PyObject func_closure; // nested scopes: closure
016:
017: public PyFunction(PyObject globals, PyObject[] defaults,
018: PyCode code, PyObject doc, PyObject[] closure_cells) {
019: func_globals = globals;
020: __name__ = code.co_name;
021: if (doc == null)
022: __doc__ = Py.None;
023: else
024: __doc__ = doc;
025: func_defaults = defaults;
026: func_code = code;
027: if (closure_cells != null) {
028: func_closure = new PyTuple(closure_cells);
029: } else {
030: func_closure = null;
031: }
032: }
033:
034: public PyFunction(PyObject globals, PyObject[] defaults,
035: PyCode code, PyObject doc) {
036: this (globals, defaults, code, doc, null);
037: }
038:
039: public PyFunction(PyObject globals, PyObject[] defaults, PyCode code) {
040: this (globals, defaults, code, null, null);
041: }
042:
043: public PyFunction(PyObject globals, PyObject[] defaults,
044: PyCode code, PyObject[] closure_cells) {
045: this (globals, defaults, code, null, closure_cells);
046: }
047:
048: private static final String[] __members__ = { "__doc__",
049: "func_doc", "__name__", "func_name", "__dict__",
050: "func_globals", "func_defaults", "func_code",
051: "func_closure" };
052:
053: public PyObject __dir__() {
054: PyString members[] = new PyString[__members__.length];
055: for (int i = 0; i < __members__.length; i++)
056: members[i] = new PyString(__members__[i]);
057: PyList ret = new PyList(members);
058: PyDictionary accum = new PyDictionary();
059: addKeys(accum, "__dict__");
060: ret.extend(accum.keys());
061: ret.sort();
062: return ret;
063: }
064:
065: private void throwReadonly(String name) {
066: for (int i = 0; i < __members__.length; i++)
067: if (__members__[i] == name)
068: throw Py.TypeError("readonly attribute");
069: throw Py.AttributeError(name);
070: }
071:
072: public void __setattr__(String name, PyObject value) {
073: // TBD: in CPython, func_defaults, func_doc, __doc__ are
074: // writable. For now, only func_doc, __doc__ are writable in
075: // JPython.
076: if (name == "func_doc" || name == "__doc__")
077: __doc__ = value;
078: else if (name == "func_closure") {
079: throwReadonly(name);
080: }
081: // not yet implemented:
082: // func_defaults
083: else if (name == "__name__")
084: throwReadonly(name);
085: else if (name == "func_name")
086: throwReadonly(name);
087: else if (name == "func_defaults")
088: throwReadonly(name);
089: else if (name == "func_globals")
090: throwReadonly(name);
091: else if (name == "func_code") {
092: if (value instanceof PyCode)
093: func_code = (PyCode) value;
094: else
095: throw Py
096: .TypeError("func_code must be set to a code object");
097: } else if (name == "__dict__" || name == "func_dict") {
098: if (value instanceof PyDictionary
099: || value instanceof PyStringMap)
100: __dict__ = value;
101: else
102: throw Py.TypeError("setting function's dictionary "
103: + "to a non-dict");
104: } else {
105: if (__dict__ == null)
106: __dict__ = new PyStringMap();
107: __dict__.__setitem__(name, value);
108: }
109: }
110:
111: public void __delattr__(String name) {
112: if (name == "__dict__" || name == "func_dict") {
113: throw Py
114: .TypeError("function's dictionary may not be deleted");
115: } else if (name == "func_defaults") {
116: func_defaults = Py.EmptyObjects;
117: return;
118: } else if (name == "func_doc" || name == "__doc__") {
119: __doc__ = Py.None;
120: return;
121: }
122: if (__dict__ == null)
123: throw Py.AttributeError(name);
124: __dict__.__delitem__(name);
125: }
126:
127: public boolean isMappingType() {
128: return false;
129: }
130:
131: public boolean isNumberType() {
132: return false;
133: }
134:
135: public boolean isSequenceType() {
136: return false;
137: }
138:
139: public PyObject __findattr__(String name) {
140: // these are special, everything else is findable by reflection
141: if (name == "func_doc")
142: return __doc__;
143: if (name == "func_name")
144: return new PyString(__name__);
145: if (name == "func_closure") {
146: if (func_closure != null)
147: return func_closure;
148: return Py.None;
149: }
150: if (name == "func_defaults") {
151: if (func_defaults.length == 0)
152: return Py.None;
153: return new PyTuple(func_defaults);
154: }
155: if (name == "__dict__" || name == "func_dict") {
156: if (__dict__ == null)
157: __dict__ = new PyStringMap();
158: return __dict__;
159: }
160: if (__dict__ != null) {
161: PyObject ret = __dict__.__finditem__(name);
162: if (ret != null)
163: return ret;
164: }
165: return super .__findattr__(name);
166: }
167:
168: public PyObject _doget(PyObject container) {
169: //System.out.println("_doget(c):"+(container==null?null:container.safeRepr())); // debug
170: return _doget(container, null);
171: }
172:
173: public PyObject _doget(PyObject container, PyObject wherefound) {
174: //System.out.println("_doget(c,w):"+(container==null?null:container.safeRepr())
175: //+","+(wherefound==null?null:wherefound.safeRepr())); // debug
176: return new PyMethod(container, this , wherefound);
177: }
178:
179: public PyObject __call__() {
180: return func_code
181: .call(func_globals, func_defaults, func_closure);
182: }
183:
184: public PyObject __call__(PyObject arg) {
185: return func_code.call(arg, func_globals, func_defaults,
186: func_closure);
187: }
188:
189: public PyObject __call__(PyObject arg1, PyObject arg2) {
190: return func_code.call(arg1, arg2, func_globals, func_defaults,
191: func_closure);
192: }
193:
194: public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) {
195: return func_code.call(arg1, arg2, arg3, func_globals,
196: func_defaults, func_closure);
197: }
198:
199: public PyObject __call__(PyObject[] args, String[] keywords) {
200: return func_code.call(args, keywords, func_globals,
201: func_defaults, func_closure);
202: }
203:
204: public PyObject __call__(PyObject arg1, PyObject[] args,
205: String[] keywords) {
206: return func_code.call(arg1, args, keywords, func_globals,
207: func_defaults, func_closure);
208: }
209:
210: public String toString() {
211: return "<function " + __name__ + " " + Py.idstr(this ) + ">";
212: }
213: }
|