home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Objects / funcobject.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  5.6 KB  |  258 lines

  1.  
  2. /* Function object implementation */
  3.  
  4. #include "Python.h"
  5. #include "compile.h"
  6. #include "structmember.h"
  7.  
  8. PyObject *
  9. PyFunction_New(PyObject *code, PyObject *globals)
  10. {
  11.     PyFunctionObject *op = PyObject_NEW(PyFunctionObject,
  12.                         &PyFunction_Type);
  13.     if (op != NULL) {
  14.         PyObject *doc;
  15.         PyObject *consts;
  16.         Py_INCREF(code);
  17.         op->func_code = code;
  18.         Py_INCREF(globals);
  19.         op->func_globals = globals;
  20.         op->func_name = ((PyCodeObject *)code)->co_name;
  21.         Py_INCREF(op->func_name);
  22.         op->func_defaults = NULL; /* No default arguments */
  23.         consts = ((PyCodeObject *)code)->co_consts;
  24.         if (PyTuple_Size(consts) >= 1) {
  25.             doc = PyTuple_GetItem(consts, 0);
  26.             if (!PyString_Check(doc) && !PyUnicode_Check(doc))
  27.                 doc = Py_None;
  28.         }
  29.         else
  30.             doc = Py_None;
  31.         Py_INCREF(doc);
  32.         op->func_doc = doc;
  33.     }
  34.     PyObject_GC_Init(op);
  35.     return (PyObject *)op;
  36. }
  37.  
  38. PyObject *
  39. PyFunction_GetCode(PyObject *op)
  40. {
  41.     if (!PyFunction_Check(op)) {
  42.         PyErr_BadInternalCall();
  43.         return NULL;
  44.     }
  45.     return ((PyFunctionObject *) op) -> func_code;
  46. }
  47.  
  48. PyObject *
  49. PyFunction_GetGlobals(PyObject *op)
  50. {
  51.     if (!PyFunction_Check(op)) {
  52.         PyErr_BadInternalCall();
  53.         return NULL;
  54.     }
  55.     return ((PyFunctionObject *) op) -> func_globals;
  56. }
  57.  
  58. PyObject *
  59. PyFunction_GetDefaults(PyObject *op)
  60. {
  61.     if (!PyFunction_Check(op)) {
  62.         PyErr_BadInternalCall();
  63.         return NULL;
  64.     }
  65.     return ((PyFunctionObject *) op) -> func_defaults;
  66. }
  67.  
  68. int
  69. PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
  70. {
  71.     if (!PyFunction_Check(op)) {
  72.         PyErr_BadInternalCall();
  73.         return -1;
  74.     }
  75.     if (defaults == Py_None)
  76.         defaults = NULL;
  77.     else if (PyTuple_Check(defaults)) {
  78.         Py_XINCREF(defaults);
  79.     }
  80.     else {
  81.         PyErr_SetString(PyExc_SystemError, "non-tuple default args");
  82.         return -1;
  83.     }
  84.     Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
  85.     ((PyFunctionObject *) op) -> func_defaults = defaults;
  86.     return 0;
  87. }
  88.  
  89. /* Methods */
  90.  
  91. #define OFF(x) offsetof(PyFunctionObject, x)
  92.  
  93. static struct memberlist func_memberlist[] = {
  94.     {"func_code",    T_OBJECT,    OFF(func_code)},
  95.     {"func_globals",T_OBJECT,    OFF(func_globals),    READONLY},
  96.     {"func_name",    T_OBJECT,    OFF(func_name),        READONLY},
  97.     {"__name__",    T_OBJECT,    OFF(func_name),        READONLY},
  98.     {"func_defaults",T_OBJECT,    OFF(func_defaults)},
  99.     {"func_doc",    T_OBJECT,    OFF(func_doc)},
  100.     {"__doc__",    T_OBJECT,    OFF(func_doc)},
  101.     {NULL}    /* Sentinel */
  102. };
  103.  
  104. static PyObject *
  105. func_getattr(PyFunctionObject *op, char *name)
  106. {
  107.     if (name[0] != '_' && PyEval_GetRestricted()) {
  108.         PyErr_SetString(PyExc_RuntimeError,
  109.           "function attributes not accessible in restricted mode");
  110.         return NULL;
  111.     }
  112.     return PyMember_Get((char *)op, func_memberlist, name);
  113. }
  114.  
  115. static int
  116. func_setattr(PyFunctionObject *op, char *name, PyObject *value)
  117. {
  118.     if (PyEval_GetRestricted()) {
  119.         PyErr_SetString(PyExc_RuntimeError,
  120.           "function attributes not settable in restricted mode");
  121.         return -1;
  122.     }
  123.     if (strcmp(name, "func_code") == 0) {
  124.         if (value == NULL || !PyCode_Check(value)) {
  125.             PyErr_SetString(
  126.                 PyExc_TypeError,
  127.                 "func_code must be set to a code object");
  128.             return -1;
  129.         }
  130.     }
  131.     else if (strcmp(name, "func_defaults") == 0) {
  132.         if (value != Py_None && !PyTuple_Check(value)) {
  133.             PyErr_SetString(
  134.                 PyExc_TypeError,
  135.                 "func_defaults must be set to a tuple object");
  136.             return -1;
  137.         }
  138.         if (value == Py_None)
  139.             value = NULL;
  140.     }
  141.     return PyMember_Set((char *)op, func_memberlist, name, value);
  142. }
  143.  
  144. static void
  145. func_dealloc(PyFunctionObject *op)
  146. {
  147.     PyObject_GC_Fini(op);
  148.     Py_DECREF(op->func_code);
  149.     Py_DECREF(op->func_globals);
  150.     Py_DECREF(op->func_name);
  151.     Py_XDECREF(op->func_defaults);
  152.     Py_XDECREF(op->func_doc);
  153.     op = (PyFunctionObject *) PyObject_AS_GC(op);
  154.     PyObject_DEL(op);
  155. }
  156.  
  157. static PyObject*
  158. func_repr(PyFunctionObject *op)
  159. {
  160.     char buf[140];
  161.     if (op->func_name == Py_None)
  162.         sprintf(buf, "<anonymous function at %p>", op);
  163.     else
  164.         sprintf(buf, "<function %.100s at %p>",
  165.             PyString_AsString(op->func_name),
  166.             op);
  167.     return PyString_FromString(buf);
  168. }
  169.  
  170. static int
  171. func_compare(PyFunctionObject *f, PyFunctionObject *g)
  172. {
  173.     int c;
  174.     if (f->func_globals != g->func_globals)
  175.         return (f->func_globals < g->func_globals) ? -1 : 1;
  176.     if (f->func_defaults != g->func_defaults) {
  177.         if (f->func_defaults == NULL)
  178.             return -1;
  179.         if (g->func_defaults == NULL)
  180.             return 1;
  181.         c = PyObject_Compare(f->func_defaults, g->func_defaults);
  182.         if (c != 0)
  183.             return c;
  184.     }
  185.     return PyObject_Compare(f->func_code, g->func_code);
  186. }
  187.  
  188. static long
  189. func_hash(PyFunctionObject *f)
  190. {
  191.     long h,x;
  192.     h = PyObject_Hash(f->func_code);
  193.     if (h == -1) return h;
  194.     x = _Py_HashPointer(f->func_globals);
  195.     if (x == -1) return x;
  196.     h ^= x;
  197.     if (h == -1) h = -2;
  198.     return h;
  199. }
  200.  
  201. static int
  202. func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
  203. {
  204.     int err;
  205.     if (f->func_code) {
  206.         err = visit(f->func_code, arg);
  207.         if (err)
  208.             return err;
  209.     }
  210.     if (f->func_globals) {
  211.         err = visit(f->func_globals, arg);
  212.         if (err)
  213.             return err;
  214.     }
  215.     if (f->func_defaults) {
  216.         err = visit(f->func_defaults, arg);
  217.         if (err)
  218.             return err;
  219.     }
  220.     if (f->func_doc) {
  221.         err = visit(f->func_doc, arg);
  222.         if (err)
  223.             return err;
  224.     }
  225.     if (f->func_name) {
  226.         err = visit(f->func_name, arg);
  227.         if (err)
  228.             return err;
  229.     }
  230.     return 0;
  231. }
  232.  
  233. PyTypeObject PyFunction_Type = {
  234.     PyObject_HEAD_INIT(&PyType_Type)
  235.     0,
  236.     "function",
  237.     sizeof(PyFunctionObject) + PyGC_HEAD_SIZE,
  238.     0,
  239.     (destructor)func_dealloc, /*tp_dealloc*/
  240.     0,        /*tp_print*/
  241.     (getattrfunc)func_getattr, /*tp_getattr*/
  242.     (setattrfunc)func_setattr, /*tp_setattr*/
  243.     (cmpfunc)func_compare, /*tp_compare*/
  244.     (reprfunc)func_repr, /*tp_repr*/
  245.     0,        /*tp_as_number*/
  246.     0,        /*tp_as_sequence*/
  247.     0,        /*tp_as_mapping*/
  248.     (hashfunc)func_hash, /*tp_hash*/
  249.     0,        /*tp_call*/
  250.     0,        /*tp_str*/
  251.     0,        /*tp_getattro*/
  252.     0,        /*tp_setattro*/
  253.     0,        /* tp_as_buffer */
  254.     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
  255.     0,        /* tp_doc */
  256.     (traverseproc)func_traverse,    /* tp_traverse */
  257. };
  258.