Skip to content

Commit 7f5a0b3

Browse files
Merge python#3
3: Add warnings for numbers r=vext01 a=nanjekyejoannah This has several changes, after git playing games with me, I managed to split the commits instead of committing one long one, as I had done before. *First commit*: Adds warnings for when the suffix "L" is used with numbers but also adds a custom Exception for our work suggested in the review of python#2 , called `Py3xWarning`. I should have committed the exception separately though. *Second commit*: Add warnings for octal literals. I fixed a test too Co-authored-by: Joannah Nanjekye <[email protected]>
2 parents 2f90d9c + 508cbd5 commit 7f5a0b3

File tree

12 files changed

+75
-5
lines changed

12 files changed

+75
-5
lines changed

Doc/c-api/exceptions.rst

+3
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ the variables:
690690
single: PyExc_SyntaxWarning
691691
single: PyExc_UnicodeWarning
692692
single: PyExc_UserWarning
693+
single: PyExc_Py3xWarning
693694
694695
+------------------------------------------+---------------------------------+----------+
695696
| C Name | Python Name | Notes |
@@ -714,6 +715,8 @@ the variables:
714715
+------------------------------------------+---------------------------------+----------+
715716
| :c:data:`PyExc_UserWarning` | :exc:`UserWarning` | |
716717
+------------------------------------------+---------------------------------+----------+
718+
| :c:data:`PyExc_3xWarning` | :exc:`Py3xWarning` | |
719+
+------------------------------------------+---------------------------------+----------+
717720
718721
Notes:
719722

Doc/library/exceptions.rst

+4
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,10 @@ module for more information.
530530

531531
.. versionadded:: 2.6
532532

533+
.. exception:: Py3xWarning
534+
535+
Base class for warnings about 3.x compatibility.
536+
533537

534538
Exception hierarchy
535539
-------------------

Doc/library/warnings.rst

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ following warnings category classes are currently defined:
9494
| :exc:`BytesWarning` | Base category for warnings related to |
9595
| | bytes and bytearray. |
9696
+----------------------------------+-----------------------------------------------+
97+
| :exc:`Py3xWarning` | Base class for warnings about 3.x |
98+
| compatibility | |
99+
+----------------------------------+-----------------------------------------------+
97100

98101
While these are technically built-in exceptions, they are documented here,
99102
because conceptually they belong to the warnings mechanism.

Include/pyerrors.h

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ PyAPI_DATA(PyObject *) PyExc_FutureWarning;
177177
PyAPI_DATA(PyObject *) PyExc_ImportWarning;
178178
PyAPI_DATA(PyObject *) PyExc_UnicodeWarning;
179179
PyAPI_DATA(PyObject *) PyExc_BytesWarning;
180+
PyAPI_DATA(PyObject *) PyExc_Py3xWarning;
180181

181182

182183
/* Convenience functions */

Lib/test/exception_hierarchy.txt

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ BaseException
4545
+-- SyntaxWarning
4646
+-- UserWarning
4747
+-- FutureWarning
48+
+-- Py3xWarning
4849
+-- ImportWarning
4950
+-- UnicodeWarning
5051
+-- BytesWarning

Lib/test/test_grammar.py

+9
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ def test_plain_integers(self):
6565
else:
6666
self.fail('Weird maxint value %r' % maxint)
6767

68+
if sys.py3kwarning:
69+
with warnings.catch_warnings():
70+
warnings.filterwarnings('error', category=Py3xWarning)
71+
with self.assertRaises(Py3xWarning) as oct:
72+
compile('032', '<test string>', 'eval')
73+
self.assertIn("octal literals are not supported in 3.x;\n"
74+
"drop the leading 0",
75+
str(oct.exception))
76+
6877
def test_long_integers(self):
6978
x = 0L
7079
x = 0l

Lib/test/test_optparse.py

+11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
BadOptionError, OptionValueError, Values
2424
from optparse import _match_abbrev
2525
from optparse import _parse_num
26+
from test.test_support import run_unittest, check_py3k_warnings
2627

2728
retype = type(re.compile(''))
2829

@@ -1654,6 +1655,16 @@ def test_numeric_options(self):
16541655
self.assertParseFail(["-l", "0x12x"],
16551656
"option -l: invalid long integer value: '0x12x'")
16561657

1658+
def test_parse_num_3k_warnings(self):
1659+
expected = 'the L suffix is not supported in 3.x; simply drop the suffix, \
1660+
or accept the auto fixer modifications'
1661+
with check_py3k_warnings((expected, Py3xWarning)):
1662+
x = 10L
1663+
y = 8L
1664+
z = x + y
1665+
a = x * y
1666+
b = x - y
1667+
16571668

16581669
def test_main():
16591670
test_support.run_unittest(__name__)

Misc/Vim/python.vim

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ if exists("python_highlight_exceptions")
9292
syn keyword pythonException ReferenceError RuntimeError RuntimeWarning
9393
syn keyword pythonException StandardError StopIteration SyntaxError
9494
syn keyword pythonException SyntaxWarning SystemError SystemExit TabError
95+
syn keyword pythonException Py3xWarning SystemError SystemExit Warning
9596
syn keyword pythonException TypeError UnboundLocalError UnicodeDecodeError
9697
syn keyword pythonException UnicodeEncodeError UnicodeError
9798
syn keyword pythonException UnicodeTranslateError UnicodeWarning

Objects/exceptions.c

+9
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,13 @@ SimpleExtendsException(PyExc_Warning, SyntaxWarning,
19811981
"Base class for warnings about dubious syntax.");
19821982

19831983

1984+
/*
1985+
* 3xWarning extends Warning
1986+
*/
1987+
SimpleExtendsException(PyExc_Warning, Py3xWarning,
1988+
"Base class for warnings about 3.x compatibility.");
1989+
1990+
19841991
/*
19851992
* RuntimeWarning extends Warning
19861993
*/
@@ -2104,6 +2111,7 @@ _PyExc_Init(void)
21042111
PRE_INIT(ImportWarning)
21052112
PRE_INIT(UnicodeWarning)
21062113
PRE_INIT(BytesWarning)
2114+
PRE_INIT(Py3xWarning)
21072115

21082116
m = Py_InitModule4("exceptions", functions, exceptions_doc,
21092117
(PyObject *)NULL, PYTHON_API_VERSION);
@@ -2173,6 +2181,7 @@ _PyExc_Init(void)
21732181
POST_INIT(ImportWarning)
21742182
POST_INIT(UnicodeWarning)
21752183
POST_INIT(BytesWarning)
2184+
POST_INIT(Py3xWarning)
21762185

21772186
PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
21782187
if (!PyExc_MemoryErrorInst)

PC/os2emx/python27.def

+1
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ EXPORTS
819819
"PyExc_DeprecationWarning"
820820
"PyExc_PendingDeprecationWarning"
821821
"PyExc_SyntaxWarning"
822+
"PyExc_Py3xWarning"
822823
"PyExc_RuntimeWarning"
823824
"PyExc_FutureWarning"
824825
"PyExc_ImportWarning"

Parser/tokenizer.c

+8
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,14 @@ tok_get(register struct tok_state *tok, char **p_start, char **p_end)
14331433
/* Number */
14341434
if (isdigit(c)) {
14351435
if (c == '0') {
1436+
if (Py_Py3kWarningFlag) {
1437+
if (PyErr_WarnExplicit(PyExc_Py3xWarning,
1438+
"octal literals are not supported in 3.x;\n"
1439+
"drop the leading 0",
1440+
tok->filename, tok->lineno, NULL, NULL)) {
1441+
return NULL;
1442+
}
1443+
}
14361444
/* Hex, octal or binary -- maybe. */
14371445
c = tok_nextc(tok);
14381446
if (c == '.')

Python/ast.c

+24-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static expr_ty ast_for_testlist_comp(struct compiling *, const node *);
3636
/* Note different signature for ast_for_call */
3737
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
3838

39-
static PyObject *parsenumber(struct compiling *, const char *);
39+
static PyObject *parsenumber(struct compiling *, const node *n, const char *);
4040
static PyObject *parsestr(struct compiling *, const node *n, const char *);
4141
static PyObject *parsestrplus(struct compiling *, const node *n);
4242

@@ -130,6 +130,19 @@ ast_warn(struct compiling *c, const node *n, char *msg)
130130
return 1;
131131
}
132132

133+
static int
134+
ast_3x_warn(struct compiling *c, const node *n, char *msg)
135+
{
136+
if (PyErr_WarnExplicit(PyExc_Py3xWarning, msg, c->c_filename, LINENO(n),
137+
NULL, NULL) < 0) {
138+
/* if -Werr, change it to a SyntaxError */
139+
if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_Py3xWarning))
140+
ast_error(n, msg);
141+
return 0;
142+
}
143+
return 1;
144+
}
145+
133146
static int
134147
forbidden_check(struct compiling *c, const node *n, const char *x)
135148
{
@@ -1403,7 +1416,7 @@ ast_for_atom(struct compiling *c, const node *n)
14031416
return Str(str, LINENO(n), n->n_col_offset, c->c_arena);
14041417
}
14051418
case NUMBER: {
1406-
PyObject *pynum = parsenumber(c, STR(ch));
1419+
PyObject *pynum = parsenumber(c, n, STR(ch));
14071420
if (!pynum)
14081421
return NULL;
14091422

@@ -1751,7 +1764,7 @@ ast_for_factor(struct compiling *c, const node *n)
17511764
return NULL;
17521765
s[0] = '-';
17531766
strcpy(s + 1, STR(pnum));
1754-
pynum = parsenumber(c, s);
1767+
pynum = parsenumber(c, n, s);
17551768
PyObject_FREE(s);
17561769
if (!pynum)
17571770
return NULL;
@@ -3324,7 +3337,7 @@ ast_for_stmt(struct compiling *c, const node *n)
33243337
}
33253338

33263339
static PyObject *
3327-
parsenumber(struct compiling *c, const char *s)
3340+
parsenumber(struct compiling *c, const node *n, const char *s)
33283341
{
33293342
const char *end;
33303343
long x;
@@ -3340,8 +3353,14 @@ parsenumber(struct compiling *c, const char *s)
33403353
#ifndef WITHOUT_COMPLEX
33413354
imflag = *end == 'j' || *end == 'J';
33423355
#endif
3343-
if (*end == 'l' || *end == 'L')
3356+
if (*end == 'l' || *end == 'L') {
3357+
if (Py_Py3kWarningFlag &&
3358+
!ast_3x_warn(c, n, "the L suffix is not supported in 3.x; simply drop the suffix, \n"
3359+
"or accept the auto fixer modifications")) {
3360+
return NULL;
3361+
}
33443362
return PyLong_FromString((char *)s, (char **)0, 0);
3363+
}
33453364
x = PyOS_strtol((char *)s, (char **)&end, 0);
33463365
if (*end == '\0') {
33473366
if (errno != 0)

0 commit comments

Comments
 (0)