8000 The BDFL has retired! Long live the FLUFL (Friendly Language Uncle Fo… · python/cpython@e3944a5 · GitHub
[go: up one dir, main page]

Skip to content

Commit e3944a5

Browse files
committed
The BDFL has retired! Long live the FLUFL (Friendly Language Uncle For Life)!
1 parent 4ed72ac commit e3944a5

File tree

13 files changed

+168
-121
lines changed

13 files changed

+168
-121
lines changed

Grammar/Grammar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ or_test: and_test ('or' and_test)*
8787
and_test: not_test ('and' not_test)*
8888
not_test: 'not' not_test | comparison
8989
comparison: star_expr (comp_op star_expr)*
90-
comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
90+
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
9191
star_expr: ['*'] expr
9292
expr: xor_expr ('|' xor_expr)*
9393
xor_expr: and_expr ('^' and_expr)*

Include/code.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ typedef struct {
5252
#define CO_FUTURE_UNICODE_LITERALS 0x20000
5353
#endif
5454

55+
#define CO_FUTURE_BARRY_AS_BDFL 0x40000
56+
5557
/* This should be defined if a future statement modifies the syntax.
5658
For example, when a keyword is added.
5759
*/
58-
/* #define PY_PARSER_REQUIRES_FUTURE_KEYWORD */
60+
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
5961

6062
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
6163

Include/compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef struct {
2626
#define FUTURE_WITH_STATEMENT "with_statement"
2727
#define FUTURE_PRINT_FUNCTION "print_function"
2828
#define FUTURE_UNICODE_LITERALS "unicode_literals"
29+
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
2930

3031
struct _mod; /* Declare the existence of this type */
3132
PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,

Include/parsetok.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ typedef struct {
3030
#endif
3131

3232
#define PyPARSE_IGNORE_COOKIE 0x0010
33+
#define PyPARSE_BARRY_AS_BDFL 0x0020
3334

3435
PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int,
3536
perrdetail *);

Include/pythonrun.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
extern < 6D47 span class=pl-s>"C" {
88
#endif
99

10-
#define PyCF_MASK 0
10+
#define PyCF_MASK CO_FUTURE_BARRY_AS_BDFL
1111
#define PyCF_MASK_OBSOLETE 0
1212
#define PyCF_SOURCE_IS_UTF8 0x0100
1313
#define PyCF_DONT_IMPLY_DEDENT 0x0200

Lib/__future__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement
7171
CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function
7272
CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals
73+
CO_FUTURE_BARRY_AS_BDFL = 0x40000
7374

7475
class _Feature:
7576
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
@@ -126,3 +127,7 @@ def __repr__(self):
126127
unicode_literals = _Feature((2, 6, 0, "alpha", 2),
127128
(3, 0, 0, "alpha", 0),
128129
CO_FUTURE_UNICODE_LITERALS)
130+
131+
barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2),
132+
(3, 9, 0, "alpha", 0),
133+
CO_FUTURE_BARRY_AS_BDFL)

Lib/test/test_flufl.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import __future__
2+
import unittest
3+
4+
class FLUFLTests(unittest.TestCase):
5+
6+
def test_barry_as_bdfl(self):
7+
code = "from __future__ import barry_as_FLUFL; 2 {0} 3"
8+
compile(code.format('<>'), '<BDFL test>', 'exec',
9+
__future__.CO_FUTURE_BARRY_AS_BDFL)
10+
self.assertRaises(SyntaxError, compile, code.format('!='),
11+
'<FLUFL test>', 'exec',
12+
__future__.CO_FUTURE_BARRY_AS_BDFL)
13+
14+
def test_guido_as_bdfl(self):
15+
code = '2 {0} 3'
16+
compile(code.format('!='), '<BDFL test>', 'exec')
17+
self.assertRaises(SyntaxError, compile, code.format('<>'),
18+
'<FLUFL test>', 'exec')
19+
20+
21+
def test_main():
22+
from test.support import run_unittest
23+
run_unittest(FLUFLTests)
24+
25+
26+
if __name__ == '__main__':
27+
test_main()

Parser/parser.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,15 @@ classify(parser_state *ps, int type, char *str)
149149
strcmp(l->lb_str, s) != 0)
150150
continue;
151151
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
152+
#if 0
152153
/* Leaving this in as an example */
153154
if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) {
154155
if (s[0] == 'w' && strcmp(s, "with") == 0)
155156
break; /* not a keyword yet */
156157
else if (s[0] == 'a' && strcmp(s, "as") == 0)
157158
break; /* not a keyword yet */
158159
}
160+
#endif
159161
#endif
160162
D(printf("It's a keyword\n"));
161163
return n - i;
@@ -178,6 +180,7 @@ classify(parser_state *ps, int type, char *str)
178180
}
179181

180182
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
183+
#if 0
181184
/* Leaving this in as an example */
182185
static void
183186
future_hack(parser_state *ps)
@@ -218,6 +221,7 @@ future_hack(parser_state *ps)
218221
}
219222
}
220223
}
224+
#endif
221225
#endif /* future keyword */
222226

223227
int
@@ -278,10 +282,12 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
278282
d->d_name,
279283
ps->p_stack.s_top->s_state));
280284
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
285+
#if 0
281286
if (d->d_name[0] == 'i' &&
282287
strcmp(d->d_name,
283288
"import_stmt") == 0)
284289
future_hack(ps);
290+
#endif
285291
#endif
286292
s_pop(&ps->p_stack);
287293
if (s_empty(&ps->p_stack)) {
@@ -296,9 +302,11 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
296302

297303
if (s->s_accept) {
298304
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
305+
#if 0
299306
if (d->d_name[0] == 'i' &&
300307
strcmp(d->d_name, "import_stmt") == 0)
301308
future_hack(ps);
309+
#endif
302310
#endif
303311
/* Pop this dfa and try again */
304312
s_pop(&ps->p_stack);

Parser/parsetok.c

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
100100
}
101101

102102
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
103+
#if 0
103104
static char with_msg[] =
104105
"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
105106

@@ -114,6 +115,7 @@ warn(const char *msg, const char *filename, int lineno)
114115
PySys_WriteStderr(msg, filename, lineno);
115116
}
116117
#endif
118+
#endif
117119

118120
/* Parse input coming from the given tokenizer structure.
119121
Return error code. */
@@ -133,8 +135,8 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
133135
return NULL;
134136
}
135137
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
136-
if (*flags & PyPARSE_WITH_IS_KEYWORD)
137-
ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
138+
if (*flags & PyPARSE_BARRY_AS_BDFL)
139+
ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
138140
#endif
139141

140142
for (;;) {
@@ -177,26 +179,20 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
177179
str[len] = '\0';
178180

179181
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
180-
/* This is only necessary to support the "as" warning, but
181-
we don't want to warn about "as" in import statements. */
182-
if (type == NAME &&
183-
len == 6 && str[0] == 'i' && strcmp(str, "import") == 0)
184-
handling_import = 1;
185-
186-
/* Warn about with as NAME */
187-
if (type == NAME &&
188-
!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) {
189-
if (len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
190-
warn(with_msg, err_ret->filename, tok->lineno);
191-
else if (!(handling_import || handling_with) &&
192-
len == 2 && str[0] == 'a' &&
193-
strcmp(str, "as") == 0)
194-
warn(as_msg, err_ret->filename, tok->lineno);
182+
if (type == NOTEQUAL) {
183+
if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
184+
strcmp(str, "!=")) {
185+
err_ret->error = E_SYNTAX;
186+
break;
187+
}
188+
else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
189+
strcmp(str, "<>")) {
190+
err_ret->text = "with Barry as BDFL, use '<>' "
191+
"instead of '!='";
192+
err_ret->error = E_SYNTAX;
193+
break;
194+
}
195195
}
196-
else if (type == NAME &&
197-
(ps->p_flags & CO_FUTURE_WITH_STATEMENT) &&
198-
len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
199-
handling_with = 1;
200196
#endif
201197
if (a >= tok->line_start)
202198
col_offset = a - tok->line_start;

Parser/tokenizer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,7 @@ PyToken_TwoChars(int c1, int c2)
10401040
break;
10411041
case '<':
10421042
switch (c2) {
1043+
case '>': return NOTEQUAL;
10431044
case '=': return LESSEQUAL;
10441045
case '<': return LEFTSHIFT;
10451046
}

Python/future.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
3939
continue;
4040
} else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
4141
continue;
42+
} else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) {
43+
ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL;
4244
} else if (strcmp(feature, "braces") == 0) {
4345
PyErr_SetString(PyExc_SyntaxError,
4446
"not a chance");

0 commit comments

Comments
 (0)
0