getargs.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /* getargs implementation copied from Python 3.8 and stripped down to only include
  2. * the functions we need.
  3. * We also add support for required kwonly args and accepting *args / **kwargs.
  4. * A good idea would be to also vendor in the Fast versions and get our stuff
  5. * working with *that*.
  6. * Another probably good idea is to strip out all the formatting stuff we don't need
  7. * and then add in custom stuff that we do need.
  8. *
  9. * DOCUMENTATION OF THE EXTENSIONS:
  10. * - Arguments given after a @ format specify are required keyword-only arguments.
  11. * The | and $ specifiers must both appear before @.
  12. * - If the first character of a format string is %, then the function can support
  13. * *args and **kwargs. On seeing a %, the parser will consume two arguments,
  14. * which should be pointers to variables to store the *args and **kwargs, respectively.
  15. * Either pointer can be NULL, in which case the function doesn't take that
  16. * variety of vararg.
  17. * Unlike most format specifiers, the caller takes ownership of these objects
  18. * and is responsible for decrefing them.
  19. * - All arguments must use the 'O' format.
  20. * - There's minimal error checking of format strings. They are generated
  21. * programmatically and can be assumed valid.
  22. */
  23. // These macro definitions are copied from pyport.h in Python 3.9 and later
  24. // https://bugs.python.org/issue19569
  25. #if defined(__clang__)
  26. #define _Py_COMP_DIAG_PUSH _Pragma("clang diagnostic push")
  27. #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \
  28. _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
  29. #define _Py_COMP_DIAG_POP _Pragma("clang diagnostic pop")
  30. #elif defined(__GNUC__) \
  31. && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
  32. #define _Py_COMP_DIAG_PUSH _Pragma("GCC diagnostic push")
  33. #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \
  34. _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
  35. #define _Py_COMP_DIAG_POP _Pragma("GCC diagnostic pop")
  36. #elif defined(_MSC_VER)
  37. #define _Py_COMP_DIAG_PUSH __pragma(warning(push))
  38. #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS __pragma(warning(disable: 4996))
  39. #define _Py_COMP_DIAG_POP __pragma(warning(pop))
  40. #else
  41. #define _Py_COMP_DIAG_PUSH
  42. #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS
  43. #define _Py_COMP_DIAG_POP
  44. #endif
  45. #include "Python.h"
  46. #include "pythonsupport.h"
  47. #include <ctype.h>
  48. #include <float.h>
  49. #ifndef PyDict_GET_SIZE
  50. #define PyDict_GET_SIZE(d) PyDict_Size(d)
  51. #endif
  52. #ifdef __cplusplus
  53. extern "C" {
  54. #endif
  55. int CPyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
  56. const char *, const char *, const char * const *, ...);
  57. /* Forward */
  58. static int vgetargskeywords(PyObject *, PyObject *,
  59. const char *, const char *, const char * const *, va_list *);
  60. static void skipitem(const char **, va_list *);
  61. /* Support for keyword arguments donated by
  62. Geoff Philbrick <philbric@delphi.hks.com> */
  63. /* Return false (0) for error, else true. */
  64. int
  65. CPyArg_ParseTupleAndKeywords(PyObject *args,
  66. PyObject *keywords,
  67. const char *format,
  68. const char *fname,
  69. const char * const *kwlist, ...)
  70. {
  71. int retval;
  72. va_list va;
  73. va_start(va, kwlist);
  74. retval = vgetargskeywords(args, keywords, format, fname, kwlist, &va);
  75. va_end(va);
  76. return retval;
  77. }
  78. #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
  79. static int
  80. vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
  81. const char *fname, const char * const *kwlist, va_list *p_va)
  82. {
  83. int min = INT_MAX;
  84. int max = INT_MAX;
  85. int required_kwonly_start = INT_MAX;
  86. int has_required_kws = 0;
  87. int i, pos, len;
  88. int skip = 0;
  89. Py_ssize_t nargs, nkwargs;
  90. PyObject *current_arg;
  91. int bound_pos_args;
  92. PyObject **p_args = NULL, **p_kwargs = NULL;
  93. assert(args != NULL && PyTuple_Check(args));
  94. assert(kwargs == NULL || PyDict_Check(kwargs));
  95. assert(format != NULL);
  96. assert(kwlist != NULL);
  97. assert(p_va != NULL);
  98. /* scan kwlist and count the number of positional-only parameters */
  99. for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
  100. }
  101. /* scan kwlist and get greatest possible nbr of args */
  102. for (len = pos; kwlist[len]; len++) {
  103. #ifdef DEBUG
  104. if (!*kwlist[len]) {
  105. PyErr_SetString(PyExc_SystemError,
  106. "Empty keyword parameter name");
  107. return 0;
  108. }
  109. #endif
  110. }
  111. if (*format == '%') {
  112. p_args = va_arg(*p_va, PyObject **);
  113. p_kwargs = va_arg(*p_va, PyObject **);
  114. format++;
  115. }
  116. nargs = PyTuple_GET_SIZE(args);
  117. nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
  118. if (unlikely(nargs + nkwargs > len && !p_args && !p_kwargs)) {
  119. /* Adding "keyword" (when nargs == 0) prevents producing wrong error
  120. messages in some special cases (see bpo-31229). */
  121. PyErr_Format(PyExc_TypeError,
  122. "%.200s%s takes at most %d %sargument%s (%zd given)",
  123. (fname == NULL) ? "function" : fname,
  124. (fname == NULL) ? "" : "()",
  125. len,
  126. (nargs == 0) ? "keyword " : "",
  127. (len == 1) ? "" : "s",
  128. nargs + nkwargs);
  129. return 0;
  130. }
  131. /* convert tuple args and keyword args in same loop, using kwlist to drive process */
  132. for (i = 0; i < len; i++) {
  133. if (*format == '|') {
  134. #ifdef DEBUG
  135. if (min != INT_MAX) {
  136. PyErr_SetString(PyExc_SystemError,
  137. "Invalid format string (| specified twice)");
  138. return 0;
  139. }
  140. #endif
  141. min = i;
  142. format++;
  143. #ifdef DEBUG
  144. if (max != INT_MAX) {
  145. PyErr_SetString(PyExc_SystemError,
  146. "Invalid format string ($ before |)");
  147. return 0;
  148. }
  149. #endif
  150. /* If there are optional args, figure out whether we have
  151. * required keyword arguments so that we don't bail without
  152. * enforcing them. */
  153. has_required_kws = strchr(format, '@') != NULL;
  154. }
  155. if (*format == '$') {
  156. #ifdef DEBUG
  157. if (max != INT_MAX) {
  158. PyErr_SetString(PyExc_SystemError,
  159. "Invalid format string ($ specified twice)");
  160. return 0;
  161. }
  162. #endif
  163. max = i;
  164. format++;
  165. #ifdef DEBUG
  166. if (max < pos) {
  167. PyErr_SetString(PyExc_SystemError,
  168. "Empty parameter name after $");
  169. return 0;
  170. }
  171. #endif
  172. if (skip) {
  173. /* Now we know the minimal and the maximal numbers of
  174. * positional arguments and can raise an exception with
  175. * informative message (see below). */
  176. break;
  177. }
  178. if (unlikely(max < nargs && !p_args)) {
  179. if (max == 0) {
  180. PyErr_Format(PyExc_TypeError,
  181. "%.200s%s takes no positional arguments",
  182. (fname == NULL) ? "function" : fname,
  183. (fname == NULL) ? "" : "()");
  184. }
  185. else {
  186. PyErr_Format(PyExc_TypeError,
  187. "%.200s%s takes %s %d positional argument%s"
  188. " (%zd given)",
  189. (fname == NULL) ? "function" : fname,
  190. (fname == NULL) ? "" : "()",
  191. (min < max) ? "at most" : "exactly",
  192. max,
  193. max == 1 ? "" : "s",
  194. nargs);
  195. }
  196. return 0;
  197. }
  198. }
  199. if (*format == '@') {
  200. #ifdef DEBUG
  201. if (min == INT_MAX && max == INT_MAX) {
  202. PyErr_SetString(PyExc_SystemError,
  203. "Invalid format string "
  204. "(@ without preceding | and $)");
  205. return 0;
  206. }
  207. if (required_kwonly_start != INT_MAX) {
  208. PyErr_SetString(PyExc_SystemError,
  209. "Invalid format string (@ specified twice)");
  210. return 0;
  211. }
  212. #endif
  213. required_kwonly_start = i;
  214. format++;
  215. }
  216. #ifdef DEBUG
  217. if (IS_END_OF_FORMAT(*format)) {
  218. PyErr_Format(PyExc_SystemError,
  219. "More keyword list entries (%d) than "
  220. "format specifiers (%d)", len, i);
  221. return 0;
  222. }
  223. #endif
  224. if (!skip) {
  225. if (i < nargs && i < max) {
  226. current_arg = PyTuple_GET_ITEM(args, i);
  227. }
  228. else if (nkwargs && i >= pos) {
  229. current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
  230. if (current_arg) {
  231. --nkwargs;
  232. }
  233. else if (PyErr_Occurred()) {
  234. return 0;
  235. }
  236. }
  237. else {
  238. current_arg = NULL;
  239. }
  240. if (current_arg) {
  241. PyObject **p = va_arg(*p_va, PyObject **);
  242. *p = current_arg;
  243. format++;
  244. continue;
  245. }
  246. if (i < min || i >= required_kwonly_start) {
  247. if (likely(i < pos)) {
  248. assert (min == INT_MAX);
  249. assert (max == INT_MAX);
  250. skip = 1;
  251. /* At that moment we still don't know the minimal and
  252. * the maximal numbers of positional arguments. Raising
  253. * an exception is deferred until we encounter | and $
  254. * or the end of the format. */
  255. }
  256. else {
  257. if (i >= max) {
  258. PyErr_Format(PyExc_TypeError,
  259. "%.200s%s missing required "
  260. "keyword-only argument '%s'",
  261. (fname == NULL) ? "function" : fname,
  262. (fname == NULL) ? "" : "()",
  263. kwlist[i]);
  264. }
  265. else {
  266. PyErr_Format(PyExc_TypeError,
  267. "%.200s%s missing required "
  268. "argument '%s' (pos %d)",
  269. (fname == NULL) ? "function" : fname,
  270. (fname == NULL) ? "" : "()",
  271. kwlist[i], i+1);
  272. }
  273. return 0;
  274. }
  275. }
  276. /* current code reports success when all required args
  277. * fulfilled and no keyword args left, with no further
  278. * validation. XXX Maybe skip this in debug build ?
  279. */
  280. if (!nkwargs && !skip && !has_required_kws &&
  281. !p_args && !p_kwargs)
  282. {
  283. return 1;
  284. }
  285. }
  286. /* We are into optional args, skip through to any remaining
  287. * keyword args */
  288. skipitem(&format, p_va);
  289. }
  290. if (unlikely(skip)) {
  291. PyErr_Format(PyExc_TypeError,
  292. "%.200s%s takes %s %d positional argument%s"
  293. " (%zd given)",
  294. (fname == NULL) ? "function" : fname,
  295. (fname == NULL) ? "" : "()",
  296. (Py_MIN(pos, min) < i) ? "at least" : "exactly",
  297. Py_MIN(pos, min),
  298. Py_MIN(pos, min) == 1 ? "" : "s",
  299. nargs);
  300. return 0;
  301. }
  302. #ifdef DEBUG
  303. if (!IS_END_OF_FORMAT(*format) &&
  304. (*format != '|') && (*format != '$') && (*format != '@'))
  305. {
  306. PyErr_Format(PyExc_SystemError,
  307. "more argument specifiers than keyword list entries "
  308. "(remaining format:'%s')", format);
  309. return 0;
  310. }
  311. #endif
  312. bound_pos_args = Py_MIN(nargs, Py_MIN(max, len));
  313. if (p_args) {
  314. *p_args = PyTuple_GetSlice(args, bound_pos_args, nargs);
  315. if (!*p_args) {
  316. return 0;
  317. }
  318. }
  319. if (p_kwargs) {
  320. /* This unfortunately needs to be special cased because if len is 0 then we
  321. * never go through the main loop. */
  322. if (unlikely(nargs > 0 && len == 0 && !p_args)) {
  323. PyErr_Format(PyExc_TypeError,
  324. "%.200s%s takes no positional arguments",
  325. (fname == NULL) ? "function" : fname,
  326. (fname == NULL) ? "" : "()");
  327. return 0;
  328. }
  329. *p_kwargs = PyDict_New();
  330. if (!*p_kwargs) {
  331. goto latefail;
  332. }
  333. }
  334. if (nkwargs > 0) {
  335. PyObject *key, *value;
  336. Py_ssize_t j;
  337. /* make sure there are no arguments given by name and position */
  338. for (i = pos; i < bound_pos_args && i < len; i++) {
  339. current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
  340. if (unlikely(current_arg != NULL)) {
  341. /* arg present in tuple and in dict */
  342. PyErr_Format(PyExc_TypeError,
  343. "argument for %.200s%s given by name ('%s') "
  344. "and position (%d)",
  345. (fname == NULL) ? "function" : fname,
  346. (fname == NULL) ? "" : "()",
  347. kwlist[i], i+1);
  348. goto latefail;
  349. }
  350. else if (unlikely(PyErr_Occurred() != NULL)) {
  351. goto latefail;
  352. }
  353. }
  354. /* make sure there are no extraneous keyword arguments */
  355. j = 0;
  356. while (PyDict_Next(kwargs, &j, &key, &value)) {
  357. int match = 0;
  358. if (unlikely(!PyUnicode_Check(key))) {
  359. PyErr_SetString(PyExc_TypeError,
  360. "keywords must be strings");
  361. goto latefail;
  362. }
  363. for (i = pos; i < len; i++) {
  364. if (CPyUnicode_EqualToASCIIString(key, kwlist[i])) {
  365. match = 1;
  366. break;
  367. }
  368. }
  369. if (!match) {
  370. if (unlikely(!p_kwargs)) {
  371. PyErr_Format(PyExc_TypeError,
  372. "'%U' is an invalid keyword "
  373. "argument for %.200s%s",
  374. key,
  375. (fname == NULL) ? "this function" : fname,
  376. (fname == NULL) ? "" : "()");
  377. goto latefail;
  378. } else {
  379. if (PyDict_SetItem(*p_kwargs, key, value) < 0) {
  380. goto latefail;
  381. }
  382. }
  383. }
  384. }
  385. }
  386. return 1;
  387. /* Handle failures that have happened after we have tried to
  388. * create *args and **kwargs, if they exist. */
  389. latefail:
  390. if (p_args) {
  391. Py_XDECREF(*p_args);
  392. }
  393. if (p_kwargs) {
  394. Py_XDECREF(*p_kwargs);
  395. }
  396. return 0;
  397. }
  398. static void
  399. skipitem(const char **p_format, va_list *p_va)
  400. {
  401. const char *format = *p_format;
  402. char c = *format++;
  403. if (p_va != NULL) {
  404. (void) va_arg(*p_va, PyObject **);
  405. }
  406. *p_format = format;
  407. }
  408. #ifdef __cplusplus
  409. };
  410. #endif