Skip to content

Commit 67ae454

Browse files
[3.7] bpo-40179: Fix translation of #elif in Argument Clinic (GH-19364) (GH-19584)
Co-authored-by: Ammar Askar <[email protected]> (cherry picked from commit 12446e6)
1 parent 9c7727b commit 67ae454

File tree

4 files changed

+124
-24
lines changed

4 files changed

+124
-24
lines changed

Lib/test/clinic.test

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,3 +1203,107 @@ static PyObject *
12031203
test_Py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b,
12041204
Py_buffer *c, Py_buffer *d, Py_buffer *e)
12051205
/*[clinic end generated code: output=92937215f10bc937 input=6a9da0f56f9525fd]*/
1206+
1207+
/*[clinic input]
1208+
output push
1209+
output preset buffer
1210+
[clinic start generated code]*/
1211+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5bff3376ee0df0b5]*/
1212+
1213+
#ifdef CONDITION_A
1214+
/*[clinic input]
1215+
test_preprocessor_guarded_condition_a
1216+
[clinic start generated code]*/
1217+
1218+
static PyObject *
1219+
test_preprocessor_guarded_condition_a_impl(PyObject *module)
1220+
/*[clinic end generated code: output=ad012af18085add6 input=8edb8706a98cda7e]*/
1221+
#elif CONDITION_B
1222+
/*[clinic input]
1223+
test_preprocessor_guarded_elif_condition_b
1224+
[clinic start generated code]*/
1225+
1226+
static PyObject *
1227+
test_preprocessor_guarded_elif_condition_b_impl(PyObject *module)
1228+
/*[clinic end generated code: output=615f2dee82b138d1 input=53777cebbf7fee32]*/
1229+
#else
1230+
/*[clinic input]
1231+
test_preprocessor_guarded_else
1232+
[clinic start generated code]*/
1233+
1234+
static PyObject *
1235+
test_preprocessor_guarded_else_impl(PyObject *module)
1236+
/*[clinic end generated code: output=13af7670aac51b12 input=6657ab31d74c29fc]*/
1237+
#endif
1238+
1239+
/*[clinic input]
1240+
dump buffer
1241+
output pop
1242+
[clinic start generated code]*/
1243+
1244+
#if defined(CONDITION_A)
1245+
1246+
PyDoc_STRVAR(test_preprocessor_guarded_condition_a__doc__,
1247+
"test_preprocessor_guarded_condition_a($module, /)\n"
1248+
"--\n"
1249+
"\n");
1250+
1251+
#define TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF \
1252+
{"test_preprocessor_guarded_condition_a", (PyCFunction)test_preprocessor_guarded_condition_a, METH_NOARGS, test_preprocessor_guarded_condition_a__doc__},
1253+
1254+
static PyObject *
1255+
test_preprocessor_guarded_condition_a(PyObject *module, PyObject *Py_UNUSED(ignored))
1256+
{
1257+
return test_preprocessor_guarded_condition_a_impl(module);
1258+
}
1259+
1260+
#endif /* defined(CONDITION_A) */
1261+
1262+
#if !defined(CONDITION_A) && (CONDITION_B)
1263+
1264+
PyDoc_STRVAR(test_preprocessor_guarded_elif_condition_b__doc__,
1265+
"test_preprocessor_guarded_elif_condition_b($module, /)\n"
1266+
"--\n"
1267+
"\n");
1268+
1269+
#define TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF \
1270+
{"test_preprocessor_guarded_elif_condition_b", (PyCFunction)test_preprocessor_guarded_elif_condition_b, METH_NOARGS, test_preprocessor_guarded_elif_condition_b__doc__},
1271+
1272+
static PyObject *
1273+
test_preprocessor_guarded_elif_condition_b(PyObject *module, PyObject *Py_UNUSED(ignored))
1274+
{
1275+
return test_preprocessor_guarded_elif_condition_b_impl(module);
1276+
}
1277+
1278+
#endif /* !defined(CONDITION_A) && (CONDITION_B) */
1279+
1280+
#if !defined(CONDITION_A) && !(CONDITION_B)
1281+
1282+
PyDoc_STRVAR(test_preprocessor_guarded_else__doc__,
1283+
"test_preprocessor_guarded_else($module, /)\n"
1284+
"--\n"
1285+
"\n");
1286+
1287+
#define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF \
1288+
{"test_preprocessor_guarded_else", (PyCFunction)test_preprocessor_guarded_else, METH_NOARGS, test_preprocessor_guarded_else__doc__},
1289+
1290+
static PyObject *
1291+
test_preprocessor_guarded_else(PyObject *module, PyObject *Py_UNUSED(ignored))
1292+
{
1293+
return test_preprocessor_guarded_else_impl(module);
1294+
}
1295+
1296+
#endif /* !defined(CONDITION_A) && !(CONDITION_B) */
1297+
1298+
#ifndef TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF
1299+
#define TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF
1300+
#endif /* !defined(TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF) */
1301+
1302+
#ifndef TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF
1303+
#define TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF
1304+
#endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF) */
1305+
1306+
#ifndef TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF
1307+
#define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF
1308+
#endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF) */
1309+
/*[clinic end generated code: output=3804bb18d454038c input=3fc80c9989d2f2e1]*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed translation of ``#elif`` in Argument Clinic.

Modules/clinic/posixmodule.c.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/clinic/cpp.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,15 @@ def pop_stack():
141141
token = fields[0].lower()
142142
condition = ' '.join(fields[1:]).strip()
143143

144-
if_tokens = {'if', 'ifdef', 'ifndef'}
145-
all_tokens = if_tokens | {'elif', 'else', 'endif'}
146-
147-
if token not in all_tokens:
148-
return
149-
150-
# cheat a little here, to reuse the implementation of if
151-
if token == 'elif':
152-
pop_stack()
153-
token = 'if'
154-
155-
if token in if_tokens:
144+
if token in {'if', 'ifdef', 'ifndef', 'elif'}:
156145
if not condition:
157146
self.fail("Invalid format for #" + token + " line: no argument!")
158-
if token == 'if':
147+
if token in {'if', 'elif'}:
159148
if not self.is_a_simple_defined(condition):
160149
condition = "(" + condition + ")"
150+
if token == 'elif':
151+
previous_token, previous_condition = pop_stack()
152+
self.stack.append((previous_token, negate(previous_condition)))
161153
else:
162154
fields = condition.split()
163155
if len(fields) != 1:
@@ -166,18 +158,21 @@ def pop_stack():
166158
condition = 'defined(' + symbol + ')'
167159
if token == 'ifndef':
168160
condition = '!' + condition
161+
token = 'if'
169162

170-
self.stack.append(("if", condition))
171-
if self.verbose:
172-
print(self.status())
173-
return
163+
self.stack.append((token, condition))
174164

175-
previous_token, previous_condition = pop_stack()
165+
elif token == 'else':
166+
previous_token, previous_condition = pop_stack()
167+
self.stack.append((previous_token, negate(previous_condition)))
176168

177-
if token == 'else':
178-
self.stack.append(('else', negate(previous_condition)))
179169
elif token == 'endif':
180-
pass
170+
while pop_stack()[0] != 'if':
171+
pass
172+
173+
else:
174+
return
175+
181176
if self.verbose:
182177
print(self.status())
183178

0 commit comments

Comments
 (0)