Skip to content

Commit

Permalink
Merge python#3
Browse files Browse the repository at this point in the history
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 <jnanjekye@python.org>
  • Loading branch information
bors[bot] and nanjekyejoannah authored Mar 30, 2022
2 parents 2f90d9c + 508cbd5 commit 7f5a0b3
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 5 deletions.
3 changes: 3 additions & 0 deletions Doc/c-api/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,7 @@ the variables:
single: PyExc_SyntaxWarning
single: PyExc_UnicodeWarning
single: PyExc_UserWarning
single: PyExc_Py3xWarning
+------------------------------------------+---------------------------------+----------+
| C Name | Python Name | Notes |
Expand All @@ -714,6 +715,8 @@ the variables:
+------------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_UserWarning` | :exc:`UserWarning` | |
+------------------------------------------+---------------------------------+----------+
| :c:data:`PyExc_3xWarning` | :exc:`Py3xWarning` | |
+------------------------------------------+---------------------------------+----------+
Notes:
Expand Down
4 changes: 4 additions & 0 deletions Doc/library/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ module for more information.

.. versionadded:: 2.6

.. exception:: Py3xWarning

Base class for warnings about 3.x compatibility.


Exception hierarchy
-------------------
Expand Down
3 changes: 3 additions & 0 deletions Doc/library/warnings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ following warnings category classes are currently defined:
| :exc:`BytesWarning` | Base category for warnings related to |
| | bytes and bytearray. |
+----------------------------------+-----------------------------------------------+
| :exc:`Py3xWarning` | Base class for warnings about 3.x |
| compatibility | |
+----------------------------------+-----------------------------------------------+

While these are technically built-in exceptions, they are documented here,
because conceptually they belong to the warnings mechanism.
Expand Down
1 change: 1 addition & 0 deletions Include/pyerrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ PyAPI_DATA(PyObject *) PyExc_FutureWarning;
PyAPI_DATA(PyObject *) PyExc_ImportWarning;
PyAPI_DATA(PyObject *) PyExc_UnicodeWarning;
PyAPI_DATA(PyObject *) PyExc_BytesWarning;
PyAPI_DATA(PyObject *) PyExc_Py3xWarning;


/* Convenience functions */
Expand Down
1 change: 1 addition & 0 deletions Lib/test/exception_hierarchy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ BaseException
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- Py3xWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
9 changes: 9 additions & 0 deletions Lib/test/test_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ def test_plain_integers(self):
else:
self.fail('Weird maxint value %r' % maxint)

if sys.py3kwarning:
with warnings.catch_warnings():
warnings.filterwarnings('error', category=Py3xWarning)
with self.assertRaises(Py3xWarning) as oct:
compile('032', '<test string>', 'eval')
self.assertIn("octal literals are not supported in 3.x;\n"
"drop the leading 0",
str(oct.exception))

def test_long_integers(self):
x = 0L
x = 0l
Expand Down
11 changes: 11 additions & 0 deletions Lib/test/test_optparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
BadOptionError, OptionValueError, Values
from optparse import _match_abbrev
from optparse import _parse_num
from test.test_support import run_unittest, check_py3k_warnings

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

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

def test_parse_num_3k_warnings(self):
expected = 'the L suffix is not supported in 3.x; simply drop the suffix, \
or accept the auto fixer modifications'
with check_py3k_warnings((expected, Py3xWarning)):
x = 10L
y = 8L
z = x + y
a = x * y
b = x - y


def test_main():
test_support.run_unittest(__name__)
Expand Down
1 change: 1 addition & 0 deletions Misc/Vim/python.vim
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ if exists("python_highlight_exceptions")
syn keyword pythonException ReferenceError RuntimeError RuntimeWarning
syn keyword pythonException StandardError StopIteration SyntaxError
syn keyword pythonException SyntaxWarning SystemError SystemExit TabError
syn keyword pythonException Py3xWarning SystemError SystemExit Warning
syn keyword pythonException TypeError UnboundLocalError UnicodeDecodeError
syn keyword pythonException UnicodeEncodeError UnicodeError
syn keyword pythonException UnicodeTranslateError UnicodeWarning
Expand Down
9 changes: 9 additions & 0 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,13 @@ SimpleExtendsException(PyExc_Warning, SyntaxWarning,
"Base class for warnings about dubious syntax.");


/*
* 3xWarning extends Warning
*/
SimpleExtendsException(PyExc_Warning, Py3xWarning,
"Base class for warnings about 3.x compatibility.");


/*
* RuntimeWarning extends Warning
*/
Expand Down Expand Up @@ -2104,6 +2111,7 @@ _PyExc_Init(void)
PRE_INIT(ImportWarning)
PRE_INIT(UnicodeWarning)
PRE_INIT(BytesWarning)
PRE_INIT(Py3xWarning)

m = Py_InitModule4("exceptions", functions, exceptions_doc,
(PyObject *)NULL, PYTHON_API_VERSION);
Expand Down Expand Up @@ -2173,6 +2181,7 @@ _PyExc_Init(void)
POST_INIT(ImportWarning)
POST_INIT(UnicodeWarning)
POST_INIT(BytesWarning)
POST_INIT(Py3xWarning)

PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
if (!PyExc_MemoryErrorInst)
Expand Down
1 change: 1 addition & 0 deletions PC/os2emx/python27.def
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ EXPORTS
"PyExc_DeprecationWarning"
"PyExc_PendingDeprecationWarning"
"PyExc_SyntaxWarning"
"PyExc_Py3xWarning"
"PyExc_RuntimeWarning"
"PyExc_FutureWarning"
"PyExc_ImportWarning"
Expand Down
8 changes: 8 additions & 0 deletions Parser/tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,14 @@ tok_get(register struct tok_state *tok, char **p_start, char **p_end)
/* Number */
if (isdigit(c)) {
if (c == '0') {
if (Py_Py3kWarningFlag) {
if (PyErr_WarnExplicit(PyExc_Py3xWarning,
"octal literals are not supported in 3.x;\n"
"drop the leading 0",
tok->filename, tok->lineno, NULL, NULL)) {
return NULL;
}
}
/* Hex, octal or binary -- maybe. */
c = tok_nextc(tok);
if (c == '.')
Expand Down
29 changes: 24 additions & 5 deletions Python/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static expr_ty ast_for_testlist_comp(struct compiling *, const node *);
/* Note different signature for ast_for_call */
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);

static PyObject *parsenumber(struct compiling *, const char *);
static PyObject *parsenumber(struct compiling *, const node *n, const char *);
static PyObject *parsestr(struct compiling *, const node *n, const char *);
static PyObject *parsestrplus(struct compiling *, const node *n);

Expand Down Expand Up @@ -130,6 +130,19 @@ ast_warn(struct compiling *c, const node *n, char *msg)
return 1;
}

static int
ast_3x_warn(struct compiling *c, const node *n, char *msg)
{
if (PyErr_WarnExplicit(PyExc_Py3xWarning, msg, c->c_filename, LINENO(n),
NULL, NULL) < 0) {
/* if -Werr, change it to a SyntaxError */
if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_Py3xWarning))
ast_error(n, msg);
return 0;
}
return 1;
}

static int
forbidden_check(struct compiling *c, const node *n, const char *x)
{
Expand Down Expand Up @@ -1403,7 +1416,7 @@ ast_for_atom(struct compiling *c, const node *n)
return Str(str, LINENO(n), n->n_col_offset, c->c_arena);
}
case NUMBER: {
PyObject *pynum = parsenumber(c, STR(ch));
PyObject *pynum = parsenumber(c, n, STR(ch));
if (!pynum)
return NULL;

Expand Down Expand Up @@ -1751,7 +1764,7 @@ ast_for_factor(struct compiling *c, const node *n)
return NULL;
s[0] = '-';
strcpy(s + 1, STR(pnum));
pynum = parsenumber(c, s);
pynum = parsenumber(c, n, s);
PyObject_FREE(s);
if (!pynum)
return NULL;
Expand Down Expand Up @@ -3324,7 +3337,7 @@ ast_for_stmt(struct compiling *c, const node *n)
}

static PyObject *
parsenumber(struct compiling *c, const char *s)
parsenumber(struct compiling *c, const node *n, const char *s)
{
const char *end;
long x;
Expand All @@ -3340,8 +3353,14 @@ parsenumber(struct compiling *c, const char *s)
#ifndef WITHOUT_COMPLEX
imflag = *end == 'j' || *end == 'J';
#endif
if (*end == 'l' || *end == 'L')
if (*end == 'l' || *end == 'L') {
if (Py_Py3kWarningFlag &&
!ast_3x_warn(c, n, "the L suffix is not supported in 3.x; simply drop the suffix, \n"
"or accept the auto fixer modifications")) {
return NULL;
}
return PyLong_FromString((char *)s, (char **)0, 0);
}
x = PyOS_strtol((char *)s, (char **)&end, 0);
if (*end == '\0') {
if (errno != 0)
Expand Down

0 comments on commit 7f5a0b3

Please sign in to comment.