Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3182680

Browse files
committed
Issue #16612: Add "Argument Clinic", a compile-time preprocessor
for C files to generate argument parsing code. (See PEP 436.)
1 parent 5ceae41 commit 3182680

12 files changed

Lines changed: 4017 additions & 277 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Projected release date: 2013-10-20
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #16612: Add "Argument Clinic", a compile-time preprocessor for
14+
C files to generate argument parsing code. (See PEP 436.)
15+
1316
- Issue #18810: Shift stat calls in importlib.machinery.FileFinder such that
1417
the code is optimistic that if something exists in a directory named exactly
1518
like the possible package being searched for that it's in actuality a

Modules/_cursesmodule.c

Lines changed: 114 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -549,68 +549,141 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
549549

550550
/* Addch, Addstr, Addnstr */
551551

552+
/*[clinic]
553+
module curses
554+
555+
class curses.window
556+
557+
curses.window.addch
558+
559+
[
560+
x: int
561+
X-coordinate.
562+
y: int
563+
Y-coordinate.
564+
]
565+
566+
ch: object
567+
Character to add.
568+
569+
[
570+
attr: long
571+
Attributes for the character.
572+
]
573+
/
574+
575+
Paint character ch at (y, x) with attributes attr.
576+
577+
Paint character ch at (y, x) with attributes attr,
578+
overwriting any character previously painted at that location.
579+
By default, the character position and attributes are the
580+
current settings for the window object.
581+
[clinic]*/
582+
583+
PyDoc_STRVAR(curses_window_addch__doc__,
584+
"Paint character ch at (y, x) with attributes attr.\n"
585+
"\n"
586+
"curses.window.addch([x, y,] ch, [attr])\n"
587+
" x\n"
588+
" X-coordinate.\n"
589+
" y\n"
590+
" Y-coordinate.\n"
591+
" ch\n"
592+
" Character to add.\n"
593+
" attr\n"
594+
" Attributes for the character.\n"
595+
"\n"
596+
"Paint character ch at (y, x) with attributes attr,\n"
597+
"overwriting any character previously painted at that location.\n"
598+
"By default, the character position and attributes are the\n"
599+
"current settings for the window object.");
600+
601+
#define CURSES_WINDOW_ADDCH_METHODDEF \
602+
{"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__},
603+
604+
static PyObject *
605+
curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr);
606+
607+
static PyObject *
608+
curses_window_addch(PyObject *self, PyObject *args)
609+
{
610+
PyObject *return_value = NULL;
611+
int group_left_1 = 0;
612+
int x;
613+
int y;
614+
PyObject *ch;
615+
int group_right_1 = 0;
616+
long attr;
617+
618+
switch (PyTuple_Size(args)) {
619+
case 1:
620+
if (!PyArg_ParseTuple(args, "O:addch", &ch))
621+
return NULL;
622+
break;
623+
case 2:
624+
if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr))
625+
return NULL;
626+
group_right_1 = 1;
627+
break;
628+
case 3:
629+
if (!PyArg_ParseTuple(args, "iiO:addch", &x, &y, &ch))
630+
return NULL;
631+
group_left_1 = 1;
632+
break;
633+
case 4:
634+
if (!PyArg_ParseTuple(args, "iiOl:addch", &x, &y, &ch, &attr))
635+
return NULL;
636+
group_right_1 = 1;
637+
group_left_1 = 1;
638+
break;
639+
default:
640+
PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments");
641+
return NULL;
642+
}
643+
return_value = curses_window_addch_impl(self, group_left_1, x, y, ch, group_right_1, attr);
644+
645+
return return_value;
646+
}
647+
552648
static PyObject *
553-
PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
649+
curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr)
650+
/*[clinic checksum: 98ade780397a48d0be48439763424b3b00c92089]*/
554651
{
555-
int rtn, x, y, use_xy = FALSE;
556-
PyObject *chobj;
652+
PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
653+
int coordinates_group = group_left_1;
654+
int attr_group = group_right_1;
655+
int rtn;
557656
int type;
558-
chtype ch;
657+
chtype cch;
559658
#ifdef HAVE_NCURSESW
560659
cchar_t wch;
561660
#endif
562-
attr_t attr = A_NORMAL;
563-
long lattr;
564661
const char *funcname;
565662

566-
switch (PyTuple_Size(args)) {
567-
case 1:
568-
if (!PyArg_ParseTuple(args, "O;ch or int", &chobj))
569-
return NULL;
570-
break;
571-
case 2:
572-
if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &chobj, &lattr))
573-
return NULL;
574-
attr = lattr;
575-
break;
576-
case 3:
577-
if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &chobj))
578-
return NULL;
579-
use_xy = TRUE;
580-
break;
581-
case 4:
582-
if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr",
583-
&y, &x, &chobj, &lattr))
584-
return NULL;
585-
attr = lattr;
586-
use_xy = TRUE;
587-
break;
588-
default:
589-
PyErr_SetString(PyExc_TypeError, "addch requires 1 to 4 arguments");
590-
return NULL;
591-
}
663+
if (!attr_group)
664+
attr = A_NORMAL;
592665

593666
#ifdef HAVE_NCURSESW
594-
type = PyCurses_ConvertToCchar_t(self, chobj, &ch, &wch);
667+
type = PyCurses_ConvertToCchar_t(cwself, ch, &cch, &wch);
595668
if (type == 2) {
596669
funcname = "add_wch";
597670
wch.attr = attr;
598-
if (use_xy == TRUE)
599-
rtn = mvwadd_wch(self->win,y,x, &wch);
671+
if (coordinates_group)
672+
rtn = mvwadd_wch(cwself->win,y,x, &wch);
600673
else {
601-
rtn = wadd_wch(self->win, &wch);
674+
rtn = wadd_wch(cwself->win, &wch);
602675
}
603676
}
604677
else
605678
#else
606-
type = PyCurses_ConvertToCchar_t(self, chobj, &ch);
679+
type = PyCurses_ConvertToCchar_t(cwself, chobj, &cch);
607680
#endif
608681
if (type == 1) {
609682
funcname = "addch";
610-
if (use_xy == TRUE)
611-
rtn = mvwaddch(self->win,y,x, ch | attr);
683+
if (coordinates_group)
684+
rtn = mvwaddch(cwself->win,y,x, cch | attr);
612685
else {
613-
rtn = waddch(self->win, ch | attr);
686+
rtn = waddch(cwself->win, cch | attr);
614687
}
615688
}
616689
else {
@@ -1954,7 +2027,7 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value)
19542027

19552028

19562029
static PyMethodDef PyCursesWindow_Methods[] = {
1957-
{"addch", (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS},
2030+
CURSES_WINDOW_ADDCH_METHODDEF
19582031
{"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
19592032
{"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
19602033
{"attroff", (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS},

Modules/_datetimemodule.c

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4143,31 +4143,73 @@ datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
41434143
tzinfo);
41444144
}
41454145

4146-
/* Return best possible local time -- this isn't constrained by the
4147-
* precision of a timestamp.
4148-
*/
4146+
/*[clinic]
4147+
module datetime
4148+
4149+
@classmethod
4150+
datetime.now
4151+
4152+
tz: object = None
4153+
Timezone object.
4154+
4155+
Returns new datetime object representing current time local to tz.
4156+
4157+
If no tz is specified, uses local timezone.
4158+
[clinic]*/
4159+
4160+
PyDoc_STRVAR(datetime_now__doc__,
4161+
"Returns new datetime object representing current time local to tz.\n"
4162+
"\n"
4163+
"datetime.now(tz=None)\n"
4164+
" tz\n"
4165+
" Timezone object.\n"
4166+
"\n"
4167+
"If no tz is specified, uses local timezone.");
4168+
4169+
#define DATETIME_NOW_METHODDEF \
4170+
{"now", (PyCFunction)datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_now__doc__},
4171+
4172+
static PyObject *
4173+
datetime_now_impl(PyObject *cls, PyObject *tz);
4174+
4175+
static PyObject *
4176+
datetime_now(PyObject *cls, PyObject *args, PyObject *kwargs)
4177+
{
4178+
PyObject *return_value = NULL;
4179+
static char *_keywords[] = {"tz", NULL};
4180+
PyObject *tz = Py_None;
4181+
4182+
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4183+
"|O:now", _keywords,
4184+
&tz))
4185+
goto exit;
4186+
return_value = datetime_now_impl(cls, tz);
4187+
4188+
exit:
4189+
return return_value;
4190+
}
4191+
41494192
static PyObject *
4150-
datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
4193+
datetime_now_impl(PyObject *cls, PyObject *tz)
4194+
/*[clinic checksum: 328b54387f4c2f8cb534997e1bd55f8cb38c4992]*/
41514195
{
41524196
PyObject *self;
4153-
PyObject *tzinfo = Py_None;
4154-
static char *keywords[] = {"tz", NULL};
41554197

4156-
if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4157-
&tzinfo))
4158-
return NULL;
4159-
if (check_tzinfo_subclass(tzinfo) < 0)
4198+
/* Return best possible local time -- this isn't constrained by the
4199+
* precision of a timestamp.
4200+
*/
4201+
if (check_tzinfo_subclass(tz) < 0)
41604202
return NULL;
41614203

41624204
self = datetime_best_possible(cls,
4163-
tzinfo == Py_None ? localtime : gmtime,
4164-
tzinfo);
4165-
if (self != NULL && tzinfo != Py_None) {
4205+
tz == Py_None ? localtime : gmtime,
4206+
tz);
4207+
if (self != NULL && tz != Py_None) {
41664208
/* Convert UTC to tzinfo's zone. */
41674209
PyObject *temp = self;
41684210
_Py_IDENTIFIER(fromutc);
41694211

4170-
self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
4212+
self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
41714213
Py_DECREF(temp);
41724214
}
41734215
return self;
@@ -5001,9 +5043,7 @@ static PyMethodDef datetime_methods[] = {
50015043

50025044
/* Class methods: */
50035045

5004-
{"now", (PyCFunction)datetime_now,
5005-
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5006-
PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
5046+
DATETIME_NOW_METHODDEF
50075047

50085048
{"utcnow", (PyCFunction)datetime_utcnow,
50095049
METH_NOARGS | METH_CLASS,

Modules/_dbmmodule.c

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static PyTypeObject Dbmtype;
4444
static PyObject *DbmError;
4545

4646
static PyObject *
47-
newdbmobject(char *file, int flags, int mode)
47+
newdbmobject(const char *file, int flags, int mode)
4848
{
4949
dbmobject *dp;
5050

@@ -361,16 +361,69 @@ static PyTypeObject Dbmtype = {
361361

362362
/* ----------------------------------------------------------------- */
363363

364+
/*[clinic]
365+
module dbm
366+
367+
dbm.open as dbmopen
368+
369+
filename: str
370+
The filename to open.
371+
372+
flags: str="r"
373+
How to open the file. "r" for reading, "w" for writing, etc.
374+
375+
mode: int(doc_default="0o666") = 0o666
376+
If creating a new file, the mode bits for the new file
377+
(e.g. os.O_RDWR).
378+
379+
/
380+
381+
Return a database object.
382+
383+
[clinic]*/
384+
385+
PyDoc_STRVAR(dbmopen__doc__,
386+
"Return a database object.\n"
387+
"\n"
388+
"dbm.open(filename, flags=\'r\', mode=0o666)\n"
389+
" filename\n"
390+
" The filename to open.\n"
391+
" flags\n"
392+
" How to open the file. \"r\" for reading, \"w\" for writing, etc.\n"
393+
" mode\n"
394+
" If creating a new file, the mode bits for the new file\n"
395+
" (e.g. os.O_RDWR).");
396+
397+
#define DBMOPEN_METHODDEF \
398+
{"open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__},
399+
400+
static PyObject *
401+
dbmopen_impl(PyObject *self, const char *filename, const char *flags, int mode);
402+
364403
static PyObject *
365404
dbmopen(PyObject *self, PyObject *args)
366405
{
367-
char *name;
368-
char *flags = "r";
406+
PyObject *return_value = NULL;
407+
const char *filename;
408+
const char *flags = "r";
409+
int mode = 438;
410+
411+
if (!PyArg_ParseTuple(args,
412+
"s|si:open",
413+
&filename, &flags, &mode))
414+
goto exit;
415+
return_value = dbmopen_impl(self, filename, flags, mode);
416+
417+
exit:
418+
return return_value;
419+
}
420+
421+
static PyObject *
422+
dbmopen_impl(PyObject *self, const char *filename, const char *flags, int mode)
423+
/*[clinic checksum: 61007c796d38af85c8035afa769fb4bb453429ee]*/
424+
{
369425
int iflags;
370-
int mode = 0666;
371426

372-
if ( !PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode) )
373-
return NULL;
374427
if ( strcmp(flags, "r") == 0 )
375428
iflags = O_RDONLY;
376429
else if ( strcmp(flags, "w") == 0 )
@@ -386,13 +439,11 @@ dbmopen(PyObject *self, PyObject *args)
386439
"arg 2 to open should be 'r', 'w', 'c', or 'n'");
387440
return NULL;
388441
}
389-
return newdbmobject(name, iflags, mode);
442+
return newdbmobject(filename, iflags, mode);
390443
}
391444

392445
static PyMethodDef dbmmodule_methods[] = {
393-
{ "open", (PyCFunction)dbmopen, METH_VARARGS,
394-
"open(path[, flag[, mode]]) -> mapping\n"
395-
"Return a database object."},
446+
DBMOPEN_METHODDEF
396447
{ 0, 0 },
397448
};
398449

0 commit comments

Comments
 (0)