PageRenderTime 24ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Objects/methodobject.c

http://unladen-swallow.googlecode.com/
C | 492 lines | 415 code | 51 blank | 26 comment | 106 complexity | 0de397c7faf3941acc6e537f1d0af34c MD5 | raw file
Possible License(s): 0BSD, BSD-3-Clause
  1. /* Method object implementation */
  2. #include "Python.h"
  3. #include "structmember.h"
  4. /* Free list for method objects to safe malloc/free overhead
  5. * The m_self element is used to chain the objects.
  6. */
  7. static PyCFunctionObject *free_list = NULL;
  8. static int numfree = 0;
  9. #ifndef PyCFunction_MAXFREELIST
  10. #define PyCFunction_MAXFREELIST 256
  11. #endif
  12. int
  13. PyMethodDef_Ready(PyMethodDef *ml)
  14. {
  15. /* Rewrite the old METH_O/METH_NOARGS flags to the new METH_ARG_RANGE
  16. so we only have to implement METH_ARG_RANGE. */
  17. if (ml->ml_flags & METH_NOARGS) {
  18. ml->ml_flags &= ~METH_NOARGS;
  19. ml->ml_flags |= METH_ARG_RANGE;
  20. ml->ml_min_arity = 0;
  21. ml->ml_max_arity = 0;
  22. }
  23. else if (ml->ml_flags & METH_O) {
  24. ml->ml_flags &= ~METH_O;
  25. ml->ml_flags |= METH_ARG_RANGE;
  26. ml->ml_min_arity = 1;
  27. ml->ml_max_arity = 1;
  28. }
  29. /* Check that METH_ARG_RANGE methods have valid arities. */
  30. if (ml->ml_flags & METH_ARG_RANGE) {
  31. if (ml->ml_min_arity < 0 || ml->ml_min_arity > PY_MAX_ARITY ||
  32. ml->ml_max_arity < 0 || ml->ml_max_arity > PY_MAX_ARITY ||
  33. ml->ml_max_arity < ml->ml_min_arity) {
  34. PyErr_BadInternalCall();
  35. return -1;
  36. }
  37. }
  38. return 0;
  39. }
  40. PyObject *
  41. PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
  42. {
  43. PyCFunctionObject *op;
  44. /* Sanity check early, to avoid having to clean up from the mixed
  45. free list/allocation scheme below. */
  46. if (PyMethodDef_Ready(ml) < 0) {
  47. return NULL;
  48. }
  49. op = free_list;
  50. if (op != NULL) {
  51. free_list = (PyCFunctionObject *)(op->m_self);
  52. PyObject_INIT(op, &PyCFunction_Type);
  53. numfree--;
  54. }
  55. else {
  56. op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
  57. if (op == NULL)
  58. return NULL;
  59. }
  60. op->m_ml = ml;
  61. Py_XINCREF(self);
  62. op->m_self = self;
  63. Py_XINCREF(module);
  64. op->m_module = module;
  65. _PyObject_GC_TRACK(op);
  66. return (PyObject *)op;
  67. }
  68. PyCFunction
  69. PyCFunction_GetFunction(PyObject *op)
  70. {
  71. if (!PyCFunction_Check(op)) {
  72. PyErr_BadInternalCall();
  73. return NULL;
  74. }
  75. return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
  76. }
  77. PyObject *
  78. PyCFunction_GetSelf(PyObject *op)
  79. {
  80. if (!PyCFunction_Check(op)) {
  81. PyErr_BadInternalCall();
  82. return NULL;
  83. }
  84. return ((PyCFunctionObject *)op) -> m_self;
  85. }
  86. int
  87. PyCFunction_GetFlags(PyObject *op)
  88. {
  89. if (!PyCFunction_Check(op)) {
  90. PyErr_BadInternalCall();
  91. return -1;
  92. }
  93. return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
  94. }
  95. PyObject *
  96. PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
  97. {
  98. return PyMethodDef_Call(PyCFunction_GET_METHODDEF(func),
  99. PyCFunction_GET_SELF(func), arg, kw);
  100. }
  101. PyObject *
  102. PyMethodDef_Call(PyMethodDef *ml, PyObject *self, PyObject *arg, PyObject *kw)
  103. {
  104. PyCFunction meth = ml->ml_meth;
  105. Py_ssize_t size;
  106. switch (ml->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
  107. case METH_VARARGS:
  108. if (kw == NULL || PyDict_Size(kw) == 0)
  109. return (*meth)(self, arg);
  110. break;
  111. case METH_VARARGS | METH_KEYWORDS:
  112. case METH_OLDARGS | METH_KEYWORDS:
  113. return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
  114. case METH_ARG_RANGE:
  115. {
  116. if (kw == NULL || PyDict_Size(kw) == 0) {
  117. PyObject *args[PY_MAX_ARITY] = {NULL};
  118. int min_arity = ml->ml_min_arity;
  119. int max_arity = ml->ml_max_arity;
  120. size = PyTuple_GET_SIZE(arg);
  121. switch (size) {
  122. default:
  123. PyErr_BadInternalCall();
  124. return NULL;
  125. case 3: args[2] = PyTuple_GET_ITEM(arg, 2);
  126. case 2: args[1] = PyTuple_GET_ITEM(arg, 1);
  127. case 1: args[0] = PyTuple_GET_ITEM(arg, 0);
  128. case 0: break;
  129. }
  130. /* But wait, you ask, what about {un,bin}ary functions?
  131. Aren't we passing more arguments than it expects?
  132. Yes, but C allows this. Go C. */
  133. if (min_arity <= size && size <= max_arity)
  134. return (*(PyCFunctionThreeArgs)meth)
  135. (self, args[0], args[1], args[2]);
  136. if (max_arity == min_arity)
  137. PyErr_Format(PyExc_TypeError,
  138. "%.200s() takes exactly %d argument(s)"
  139. " (%zd given)",
  140. ml->ml_name, max_arity, size);
  141. else
  142. PyErr_Format(PyExc_TypeError,
  143. "%.200s() takes %d-%d arguments"
  144. " (%zd given)",
  145. ml->ml_name, min_arity, max_arity,
  146. size);
  147. return NULL;
  148. }
  149. break;
  150. }
  151. case METH_OLDARGS:
  152. /* the really old style */
  153. if (kw == NULL || PyDict_Size(kw) == 0) {
  154. size = PyTuple_GET_SIZE(arg);
  155. if (size == 1)
  156. arg = PyTuple_GET_ITEM(arg, 0);
  157. else if (size == 0)
  158. arg = NULL;
  159. return (*meth)(self, arg);
  160. }
  161. break;
  162. /* METH_O is deprecated; PyCFunction_NewEx is supposed to convert it to
  163. METH_ARG_RANGE and set ml_{min,max}_arity correctly. */
  164. case METH_O:
  165. default:
  166. PyErr_BadInternalCall();
  167. return NULL;
  168. }
  169. PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
  170. ml->ml_name);
  171. return NULL;
  172. }
  173. /* Methods (the standard built-in methods, that is) */
  174. static void
  175. meth_dealloc(PyCFunctionObject *m)
  176. {
  177. _PyObject_GC_UNTRACK(m);
  178. Py_XDECREF(m->m_self);
  179. Py_XDECREF(m->m_module);
  180. if (numfree < PyCFunction_MAXFREELIST) {
  181. m->m_self = (PyObject *)free_list;
  182. free_list = m;
  183. numfree++;
  184. }
  185. else {
  186. PyObject_GC_Del(m);
  187. }
  188. }
  189. static PyObject *
  190. meth_get__doc__(PyCFunctionObject *m, void *closure)
  191. {
  192. const char *doc = m->m_ml->ml_doc;
  193. if (doc != NULL)
  194. return PyString_FromString(doc);
  195. Py_INCREF(Py_None);
  196. return Py_None;
  197. }
  198. static PyObject *
  199. meth_get__name__(PyCFunctionObject *m, void *closure)
  200. {
  201. return PyString_FromString(m->m_ml->ml_name);
  202. }
  203. static int
  204. meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
  205. {
  206. Py_VISIT(m->m_self);
  207. Py_VISIT(m->m_module);
  208. return 0;
  209. }
  210. static PyObject *
  211. meth_get__self__(PyCFunctionObject *m, void *closure)
  212. {
  213. PyObject *self;
  214. if (PyEval_GetRestricted()) {
  215. PyErr_SetString(PyExc_RuntimeError,
  216. "method.__self__ not accessible in restricted mode");
  217. return NULL;
  218. }
  219. self = m->m_self;
  220. if (self == NULL)
  221. self = Py_None;
  222. Py_INCREF(self);
  223. return self;
  224. }
  225. static PyGetSetDef meth_getsets [] = {
  226. {"__doc__", (getter)meth_get__doc__, NULL, NULL},
  227. {"__name__", (getter)meth_get__name__, NULL, NULL},
  228. {"__self__", (getter)meth_get__self__, NULL, NULL},
  229. {0}
  230. };
  231. #define OFF(x) offsetof(PyCFunctionObject, x)
  232. static PyMemberDef meth_members[] = {
  233. {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
  234. {NULL}
  235. };
  236. static PyObject *
  237. meth_repr(PyCFunctionObject *m)
  238. {
  239. if (m->m_self == NULL)
  240. return PyString_FromFormat("<built-in function %s>",
  241. m->m_ml->ml_name);
  242. return PyString_FromFormat("<built-in method %s of %s object at %p>",
  243. m->m_ml->ml_name,
  244. m->m_self->ob_type->tp_name,
  245. m->m_self);
  246. }
  247. static int
  248. meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
  249. {
  250. if (a->m_self != b->m_self)
  251. return (a->m_self < b->m_self) ? -1 : 1;
  252. if (a->m_ml->ml_meth == b->m_ml->ml_meth)
  253. return 0;
  254. if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
  255. return -1;
  256. else
  257. return 1;
  258. }
  259. static PyObject *
  260. meth_richcompare(PyObject *self, PyObject *other, int op)
  261. {
  262. PyCFunctionObject *a, *b;
  263. PyObject *res;
  264. int eq;
  265. if (op != Py_EQ && op != Py_NE) {
  266. /* Py3K warning if comparison isn't == or !=. */
  267. if (PyErr_WarnPy3k("builtin_function_or_method order "
  268. "comparisons not supported in 3.x", 1) < 0) {
  269. return NULL;
  270. }
  271. Py_INCREF(Py_NotImplemented);
  272. return Py_NotImplemented;
  273. }
  274. else if (!PyCFunction_Check(self) || !PyCFunction_Check(other)) {
  275. Py_INCREF(Py_NotImplemented);
  276. return Py_NotImplemented;
  277. }
  278. a = (PyCFunctionObject *)self;
  279. b = (PyCFunctionObject *)other;
  280. eq = a->m_self == b->m_self;
  281. if (eq)
  282. eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
  283. if (op == Py_EQ)
  284. res = eq ? Py_True : Py_False;
  285. else
  286. res = eq ? Py_False : Py_True;
  287. Py_INCREF(res);
  288. return res;
  289. }
  290. static long
  291. meth_hash(PyCFunctionObject *a)
  292. {
  293. long x,y;
  294. if (a->m_self == NULL)
  295. x = 0;
  296. else {
  297. x = PyObject_Hash(a->m_self);
  298. if (x == -1)
  299. return -1;
  300. }
  301. y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
  302. if (y == -1)
  303. return -1;
  304. x ^= y;
  305. if (x == -1)
  306. x = -2;
  307. return x;
  308. }
  309. PyTypeObject PyCFunction_Type = {
  310. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  311. "builtin_function_or_method",
  312. sizeof(PyCFunctionObject),
  313. 0,
  314. (destructor)meth_dealloc, /* tp_dealloc */
  315. 0, /* tp_print */
  316. 0, /* tp_getattr */
  317. 0, /* tp_setattr */
  318. (cmpfunc)meth_compare, /* tp_compare */
  319. (reprfunc)meth_repr, /* tp_repr */
  320. 0, /* tp_as_number */
  321. 0, /* tp_as_sequence */
  322. 0, /* tp_as_mapping */
  323. (hashfunc)meth_hash, /* tp_hash */
  324. PyCFunction_Call, /* tp_call */
  325. 0, /* tp_str */
  326. PyObject_GenericGetAttr, /* tp_getattro */
  327. 0, /* tp_setattro */
  328. 0, /* tp_as_buffer */
  329. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
  330. 0, /* tp_doc */
  331. (traverseproc)meth_traverse, /* tp_traverse */
  332. 0, /* tp_clear */
  333. meth_richcompare, /* tp_richcompare */
  334. 0, /* tp_weaklistoffset */
  335. 0, /* tp_iter */
  336. 0, /* tp_iternext */
  337. 0, /* tp_methods */
  338. meth_members, /* tp_members */
  339. meth_getsets, /* tp_getset */
  340. 0, /* tp_base */
  341. 0, /* tp_dict */
  342. };
  343. /* List all methods in a chain -- helper for findmethodinchain */
  344. static PyObject *
  345. listmethodchain(PyMethodChain *chain)
  346. {
  347. PyMethodChain *c;
  348. PyMethodDef *ml;
  349. int i, n;
  350. PyObject *v;
  351. n = 0;
  352. for (c = chain; c != NULL; c = c->link) {
  353. for (ml = c->methods; ml->ml_name != NULL; ml++)
  354. n++;
  355. }
  356. v = PyList_New(n);
  357. if (v == NULL)
  358. return NULL;
  359. i = 0;
  360. for (c = chain; c != NULL; c = c->link) {
  361. for (ml = c->methods; ml->ml_name != NULL; ml++) {
  362. PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
  363. i++;
  364. }
  365. }
  366. if (PyErr_Occurred()) {
  367. Py_DECREF(v);
  368. return NULL;
  369. }
  370. PyList_Sort(v);
  371. return v;
  372. }
  373. /* Find a method in a method chain */
  374. PyObject *
  375. Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name)
  376. {
  377. if (name[0] == '_' && name[1] == '_') {
  378. if (strcmp(name, "__methods__") == 0) {
  379. if (PyErr_WarnPy3k("__methods__ not supported in 3.x",
  380. 1) < 0)
  381. return NULL;
  382. return listmethodchain(chain);
  383. }
  384. if (strcmp(name, "__doc__") == 0) {
  385. const char *doc = self->ob_type->tp_doc;
  386. if (doc != NULL)
  387. return PyString_FromString(doc);
  388. }
  389. }
  390. while (chain != NULL) {
  391. PyMethodDef *ml = chain->methods;
  392. for (; ml->ml_name != NULL; ml++) {
  393. if (name[0] == ml->ml_name[0] &&
  394. strcmp(name+1, ml->ml_name+1) == 0)
  395. /* XXX */
  396. return PyCFunction_New(ml, self);
  397. }
  398. chain = chain->link;
  399. }
  400. PyErr_SetString(PyExc_AttributeError, name);
  401. return NULL;
  402. }
  403. /* Find a method in a single method list */
  404. PyObject *
  405. Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name)
  406. {
  407. PyMethodChain chain;
  408. chain.methods = methods;
  409. chain.link = NULL;
  410. return Py_FindMethodInChain(&chain, self, name);
  411. }
  412. /* Clear out the free list */
  413. int
  414. PyCFunction_ClearFreeList(void)
  415. {
  416. int freelist_size = numfree;
  417. while (free_list) {
  418. PyCFunctionObject *v = free_list;
  419. free_list = (PyCFunctionObject *)(v->m_self);
  420. PyObject_GC_Del(v);
  421. numfree--;
  422. }
  423. assert(numfree == 0);
  424. return freelist_size;
  425. }
  426. void
  427. PyCFunction_Fini(void)
  428. {
  429. (void)PyCFunction_ClearFreeList();
  430. }
  431. /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
  432. but it's part of the API so we need to keep a function around that
  433. existing C extensions can call.
  434. */
  435. #undef PyCFunction_New
  436. PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
  437. PyObject *
  438. PyCFunction_New(PyMethodDef *ml, PyObject *self)
  439. {
  440. return PyCFunction_NewEx(ml, self, NULL);
  441. }