Python-checkins
Threads by month
- ----- 2025 -----
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
September 2018
- 3 participants
- 560 discussions

[3.7] bpo-34762: Update PyContext* refs to PyObject* in asyncio and decimal (GH-9610)
by Yury Selivanov Sept. 27, 2018
by Yury Selivanov Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/24cb7de15d3a5979425b281ab4f600f7c2…
commit: 24cb7de15d3a5979425b281ab4f600f7c2b401f2
branch: 3.7
author: Yury Selivanov <yury(a)magic.io>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T15:33:23-04:00
summary:
[3.7] bpo-34762: Update PyContext* refs to PyObject* in asyncio and decimal (GH-9610)
files:
M Modules/_asynciomodule.c
M Modules/_decimal/_decimal.c
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index …
[View More]ebda10404eb5..0c161fb2bc7d 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -59,7 +59,7 @@ typedef enum {
PyObject_HEAD \
PyObject *prefix##_loop; \
PyObject *prefix##_callback0; \
- PyContext *prefix##_context0; \
+ PyObject *prefix##_context0; \
PyObject *prefix##_callbacks; \
PyObject *prefix##_exception; \
PyObject *prefix##_result; \
@@ -78,7 +78,7 @@ typedef struct {
FutureObj_HEAD(task)
PyObject *task_fut_waiter;
PyObject *task_coro;
- PyContext *task_context;
+ PyObject *task_context;
int task_must_cancel;
int task_log_destroy_pending;
} TaskObj;
@@ -337,7 +337,7 @@ get_event_loop(void)
static int
-call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyContext *ctx)
+call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx)
{
PyObject *handle;
PyObject *stack[3];
@@ -448,7 +448,7 @@ future_schedule_callbacks(FutureObj *fut)
PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0);
PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1);
- if (call_soon(fut->fut_loop, cb, (PyObject *)fut, (PyContext *)ctx)) {
+ if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) {
/* If an error occurs in pure-Python implementation,
all callbacks are cleared. */
Py_CLEAR(fut->fut_callbacks);
@@ -616,7 +616,7 @@ future_get_result(FutureObj *fut, PyObject **result)
}
static PyObject *
-future_add_done_callback(FutureObj *fut, PyObject *arg, PyContext *ctx)
+future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx)
{
if (!future_is_alive(fut)) {
PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
@@ -903,16 +903,15 @@ _asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn,
/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/
{
if (context == NULL) {
- context = (PyObject *)PyContext_CopyCurrent();
+ context = PyContext_CopyCurrent();
if (context == NULL) {
return NULL;
}
- PyObject *res = future_add_done_callback(
- self, fn, (PyContext *)context);
+ PyObject *res = future_add_done_callback(self, fn, context);
Py_DECREF(context);
return res;
}
- return future_add_done_callback(self, fn, (PyContext *)context);
+ return future_add_done_callback(self, fn, context);
}
/*[clinic input]
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 5bce780cb7fb..1e58d3d5b779 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -122,7 +122,7 @@ incr_false(void)
}
-static PyContextVar *current_context_var;
+static PyObject *current_context_var;
/* Template for creating new thread contexts, calling Context() without
* arguments and initializing the module_context on first access. */
@@ -1500,7 +1500,7 @@ init_current_context(void)
}
CTX(tl_context)->status = 0;
- PyContextToken *tok = PyContextVar_Set(current_context_var, tl_context);
+ PyObject *tok = PyContextVar_Set(current_context_var, tl_context);
if (tok == NULL) {
Py_DECREF(tl_context);
return NULL;
@@ -1561,7 +1561,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
Py_INCREF(v);
}
- PyContextToken *tok = PyContextVar_Set(current_context_var, v);
+ PyObject *tok = PyContextVar_Set(current_context_var, v);
Py_DECREF(v);
if (tok == NULL) {
return NULL;
[View Less]
1
0

bpo-34762: Update PyContext* to PyObject* in asyncio and decimal (GH-9609)
by Yury Selivanov Sept. 27, 2018
by Yury Selivanov Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/994269ccee5574f03cda6b018399347fc5…
commit: 994269ccee5574f03cda6b018399347fc52bf330
branch: master
author: Yury Selivanov <yury(a)magic.io>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T14:55:55-04:00
summary:
bpo-34762: Update PyContext* to PyObject* in asyncio and decimal (GH-9609)
This fixes various compiler warnings.
files:
M Modules/_asynciomodule.c
M Modules/_decimal/_decimal.c
diff --git a/Modules/_asynciomodule.c b/…
[View More]Modules/_asynciomodule.c
index fc91ebd854d0..6bf0fd6b0c94 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -61,7 +61,7 @@ typedef enum {
PyObject_HEAD \
PyObject *prefix##_loop; \
PyObject *prefix##_callback0; \
- PyContext *prefix##_context0; \
+ PyObject *prefix##_context0; \
PyObject *prefix##_callbacks; \
PyObject *prefix##_exception; \
PyObject *prefix##_result; \
@@ -81,7 +81,7 @@ typedef struct {
PyObject *task_fut_waiter;
PyObject *task_coro;
PyObject *task_name;
- PyContext *task_context;
+ PyObject *task_context;
int task_must_cancel;
int task_log_destroy_pending;
} TaskObj;
@@ -340,7 +340,7 @@ get_event_loop(void)
static int
-call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyContext *ctx)
+call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx)
{
PyObject *handle;
PyObject *stack[3];
@@ -451,7 +451,7 @@ future_schedule_callbacks(FutureObj *fut)
PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0);
PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1);
- if (call_soon(fut->fut_loop, cb, (PyObject *)fut, (PyContext *)ctx)) {
+ if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) {
/* If an error occurs in pure-Python implementation,
all callbacks are cleared. */
Py_CLEAR(fut->fut_callbacks);
@@ -619,7 +619,7 @@ future_get_result(FutureObj *fut, PyObject **result)
}
static PyObject *
-future_add_done_callback(FutureObj *fut, PyObject *arg, PyContext *ctx)
+future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx)
{
if (!future_is_alive(fut)) {
PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
@@ -906,16 +906,15 @@ _asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn,
/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/
{
if (context == NULL) {
- context = (PyObject *)PyContext_CopyCurrent();
+ context = PyContext_CopyCurrent();
if (context == NULL) {
return NULL;
}
- PyObject *res = future_add_done_callback(
- self, fn, (PyContext *)context);
+ PyObject *res = future_add_done_callback(self, fn, context);
Py_DECREF(context);
return res;
}
- return future_add_done_callback(self, fn, (PyContext *)context);
+ return future_add_done_callback(self, fn, context);
}
/*[clinic input]
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 5bce780cb7fb..1e58d3d5b779 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -122,7 +122,7 @@ incr_false(void)
}
-static PyContextVar *current_context_var;
+static PyObject *current_context_var;
/* Template for creating new thread contexts, calling Context() without
* arguments and initializing the module_context on first access. */
@@ -1500,7 +1500,7 @@ init_current_context(void)
}
CTX(tl_context)->status = 0;
- PyContextToken *tok = PyContextVar_Set(current_context_var, tl_context);
+ PyObject *tok = PyContextVar_Set(current_context_var, tl_context);
if (tok == NULL) {
Py_DECREF(tl_context);
return NULL;
@@ -1561,7 +1561,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
Py_INCREF(v);
}
- PyContextToken *tok = PyContextVar_Set(current_context_var, v);
+ PyObject *tok = PyContextVar_Set(current_context_var, v);
Py_DECREF(v);
if (tok == NULL) {
return NULL;
[View Less]
1
0
https://github.com/python/cpython/commit/273fc220b25933e443c82af6888eb1871d…
commit: 273fc220b25933e443c82af6888eb1871d032fb8
branch: 3.7
author: Andrés Delfino <adelfino(a)gmail.com>
committer: Ned Deily <nad(a)python.org>
date: 2018-09-27T11:25:47-04:00
summary:
Fix markup for xml.sax entry in 3.7.1 notes (GH-9602)
files:
M Doc/whatsnew/3.7.rst
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 534b9a07a081..87a3ddbf1ecf 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/…
[View More]whatsnew/3.7.rst
@@ -2521,5 +2521,5 @@ In 3.7.1 the C API for Context Variables
:ref:`was updated <contextvarsobjects_pointertype_change>` to use
:c:type:`PyObject` pointers. See also :issue:`34762`.
-:mod:`xml.dom.minidom` and mod:`xml.sax` modules no longer process
+:mod:`xml.dom.minidom` and :mod:`xml.sax` modules no longer process
external entities by default. See also :issue:`17239`.
[View Less]
1
0

bpo-32892: Use ast.Constant instead of specific constant AST types. (GH-9445)
by Serhiy Storchaka Sept. 27, 2018
by Serhiy Storchaka Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/3f22811fef73aec848d961593d95fa877f…
commit: 3f22811fef73aec848d961593d95fa877f77ecbf
branch: master
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T17:42:37+03:00
summary:
bpo-32892: Use ast.Constant instead of specific constant AST types. (GH-9445)
files:
A Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
M Doc/library/ast.rst
M Doc/whatsnew/3.8.rst
M Include/…
[View More]Python-ast.h
M Lib/ast.py
M Lib/inspect.py
M Lib/test/test_ast.py
M Lib/test/test_fstring.py
M Lib/test/test_future.py
M Lib/test/test_pyclbr.py
M Parser/Python.asdl
M Parser/asdl_c.py
M Python/Python-ast.c
M Python/ast.c
M Python/ast_opt.c
M Python/ast_unparse.c
M Python/compile.c
M Python/symtable.c
M Tools/clinic/clinic.py
M Tools/parser/unparse.py
diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 9ff422cdf503..97ce2f5281b5 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -78,8 +78,8 @@ Node classes
node = ast.UnaryOp()
node.op = ast.USub()
- node.operand = ast.Num()
- node.operand.n = 5
+ node.operand = ast.Constant()
+ node.operand.value = 5
node.operand.lineno = 0
node.operand.col_offset = 0
node.lineno = 0
@@ -87,9 +87,16 @@ Node classes
or the more compact ::
- node = ast.UnaryOp(ast.USub(), ast.Num(5, lineno=0, col_offset=0),
+ node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0),
lineno=0, col_offset=0)
+.. deprecated:: 3.8
+
+ Class :class:`ast.Constant` is now used for all constants. Old classes
+ :class:`ast.Num`, :class:`ast.Str`, :class:`ast.Bytes`,
+ :class:`ast.NameConstant` and :class:`ast.Ellipsis` are still available,
+ but they will be removed in future Python releases.
+
.. _abstract-grammar:
@@ -239,7 +246,7 @@ and classes for traversing abstract syntax trees:
def visit_Name(self, node):
return copy_location(Subscript(
value=Name(id='data', ctx=Load()),
- slice=Index(value=Str(s=node.id)),
+ slice=Index(value=Constant(value=node.id)),
ctx=node.ctx
), node)
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 7fbe98105d12..a146249178f4 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -262,6 +262,11 @@ Deprecated
(Contributed by Berker Peksag in :issue:`9372`.)
+* :mod:`ast` classes ``Num``, ``Str``, ``Bytes``, ``NameConstant`` and
+ ``Ellipsis`` are considered deprecated and will be removed in future Python
+ versions. :class:`~ast.Constant` should be used instead.
+ (Contributed by Serhiy Storchaka in :issue:`32892`.)
+
Removed
=======
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
index 8e0f750a8250..2913d1d2d0a9 100644
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -208,11 +208,10 @@ enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8,
SetComp_kind=9, DictComp_kind=10, GeneratorExp_kind=11,
Await_kind=12, Yield_kind=13, YieldFrom_kind=14,
- Compare_kind=15, Call_kind=16, Num_kind=17, Str_kind=18,
- FormattedValue_kind=19, JoinedStr_kind=20, Bytes_kind=21,
- NameConstant_kind=22, Ellipsis_kind=23, Constant_kind=24,
- Attribute_kind=25, Subscript_kind=26, Starred_kind=27,
- Name_kind=28, List_kind=29, Tuple_kind=30};
+ Compare_kind=15, Call_kind=16, FormattedValue_kind=17,
+ JoinedStr_kind=18, Constant_kind=19, Attribute_kind=20,
+ Subscript_kind=21, Starred_kind=22, Name_kind=23,
+ List_kind=24, Tuple_kind=25};
struct _expr {
enum _expr_kind kind;
union {
@@ -297,14 +296,6 @@ struct _expr {
asdl_seq *keywords;
} Call;
- struct {
- object n;
- } Num;
-
- struct {
- string s;
- } Str;
-
struct {
expr_ty value;
int conversion;
@@ -315,14 +306,6 @@ struct _expr {
asdl_seq *values;
} JoinedStr;
- struct {
- bytes s;
- } Bytes;
-
- struct {
- singleton value;
- } NameConstant;
-
struct {
constant value;
} Constant;
@@ -566,23 +549,12 @@ expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
#define Call(a0, a1, a2, a3, a4, a5) _Py_Call(a0, a1, a2, a3, a4, a5)
expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int
lineno, int col_offset, PyArena *arena);
-#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3)
-expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena);
-#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3)
-expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena);
#define FormattedValue(a0, a1, a2, a3, a4, a5) _Py_FormattedValue(a0, a1, a2, a3, a4, a5)
expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec,
int lineno, int col_offset, PyArena *arena);
#define JoinedStr(a0, a1, a2, a3) _Py_JoinedStr(a0, a1, a2, a3)
expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, PyArena
*arena);
-#define Bytes(a0, a1, a2, a3) _Py_Bytes(a0, a1, a2, a3)
-expr_ty _Py_Bytes(bytes s, int lineno, int col_offset, PyArena *arena);
-#define NameConstant(a0, a1, a2, a3) _Py_NameConstant(a0, a1, a2, a3)
-expr_ty _Py_NameConstant(singleton value, int lineno, int col_offset, PyArena
- *arena);
-#define Ellipsis(a0, a1, a2) _Py_Ellipsis(a0, a1, a2)
-expr_ty _Py_Ellipsis(int lineno, int col_offset, PyArena *arena);
#define Constant(a0, a1, a2, a3) _Py_Constant(a0, a1, a2, a3)
expr_ty _Py_Constant(constant value, int lineno, int col_offset, PyArena
*arena);
diff --git a/Lib/ast.py b/Lib/ast.py
index bfe346bba8e3..de3df1473e5e 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -48,10 +48,8 @@ def literal_eval(node_or_string):
node_or_string = node_or_string.body
def _convert_num(node):
if isinstance(node, Constant):
- if isinstance(node.value, (int, float, complex)):
+ if type(node.value) in (int, float, complex):
return node.value
- elif isinstance(node, Num):
- return node.n
raise ValueError('malformed node or string: ' + repr(node))
def _convert_signed_num(node):
if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
@@ -64,10 +62,6 @@ def _convert_signed_num(node):
def _convert(node):
if isinstance(node, Constant):
return node.value
- elif isinstance(node, (Str, Bytes)):
- return node.s
- elif isinstance(node, Num):
- return node.n
elif isinstance(node, Tuple):
return tuple(map(_convert, node.elts))
elif isinstance(node, List):
@@ -77,8 +71,6 @@ def _convert(node):
elif isinstance(node, Dict):
return dict(zip(map(_convert, node.keys),
map(_convert, node.values)))
- elif isinstance(node, NameConstant):
- return node.value
elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
left = _convert_signed_num(node.left)
right = _convert_num(node.right)
@@ -329,3 +321,66 @@ def generic_visit(self, node):
else:
setattr(node, field, new_node)
return node
+
+
+# The following code is for backward compatibility.
+# It will be removed in future.
+
+def _getter(self):
+ return self.value
+
+def _setter(self, value):
+ self.value = value
+
+Constant.n = property(_getter, _setter)
+Constant.s = property(_getter, _setter)
+
+class _ABC(type):
+
+ def __instancecheck__(cls, inst):
+ if not isinstance(inst, Constant):
+ return False
+ if cls in _const_types:
+ try:
+ value = inst.value
+ except AttributeError:
+ return False
+ else:
+ return type(value) in _const_types[cls]
+ return type.__instancecheck__(cls, inst)
+
+def _new(cls, *args, **kwargs):
+ if cls in _const_types:
+ return Constant(*args, **kwargs)
+ return Constant.__new__(cls, *args, **kwargs)
+
+class Num(Constant, metaclass=_ABC):
+ _fields = ('n',)
+ __new__ = _new
+
+class Str(Constant, metaclass=_ABC):
+ _fields = ('s',)
+ __new__ = _new
+
+class Bytes(Constant, metaclass=_ABC):
+ _fields = ('s',)
+ __new__ = _new
+
+class NameConstant(Constant, metaclass=_ABC):
+ __new__ = _new
+
+class Ellipsis(Constant, metaclass=_ABC):
+ _fields = ()
+
+ def __new__(cls, *args, **kwargs):
+ if cls is Ellipsis:
+ return Constant(..., *args, **kwargs)
+ return Constant.__new__(cls, *args, **kwargs)
+
+_const_types = {
+ Num: (int, float, complex),
+ Str: (str,),
+ Bytes: (bytes,),
+ NameConstant: (type(None), bool),
+ Ellipsis: (type(...),),
+}
diff --git a/Lib/inspect.py b/Lib/inspect.py
index e799a83a7404..5b7f526939b6 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2005,14 +2005,8 @@ def wrap_value(s):
except NameError:
raise RuntimeError()
- if isinstance(value, str):
- return ast.Str(value)
- if isinstance(value, (int, float)):
- return ast.Num(value)
- if isinstance(value, bytes):
- return ast.Bytes(value)
- if value in (True, False, None):
- return ast.NameConstant(value)
+ if isinstance(value, (str, int, float, bytes, bool, type(None))):
+ return ast.Constant(value)
raise RuntimeError()
class RewriteSymbolics(ast.NodeTransformer):
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 72f8467847e8..10be02eee0c0 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -300,12 +300,16 @@ def test_field_attr_writable(self):
def test_classattrs(self):
x = ast.Num()
- self.assertEqual(x._fields, ('n',))
+ self.assertEqual(x._fields, ('value',))
+
+ with self.assertRaises(AttributeError):
+ x.value
with self.assertRaises(AttributeError):
x.n
x = ast.Num(42)
+ self.assertEqual(x.value, 42)
self.assertEqual(x.n, 42)
with self.assertRaises(AttributeError):
@@ -319,12 +323,102 @@ def test_classattrs(self):
x = ast.Num(42, lineno=0)
self.assertEqual(x.lineno, 0)
- self.assertEqual(x._fields, ('n',))
+ self.assertEqual(x._fields, ('value',))
+ self.assertEqual(x.value, 42)
self.assertEqual(x.n, 42)
self.assertRaises(TypeError, ast.Num, 1, 2)
self.assertRaises(TypeError, ast.Num, 1, 2, lineno=0)
+ self.assertEqual(ast.Num(42).n, 42)
+ self.assertEqual(ast.Num(4.25).n, 4.25)
+ self.assertEqual(ast.Num(4.25j).n, 4.25j)
+ self.assertEqual(ast.Str('42').s, '42')
+ self.assertEqual(ast.Bytes(b'42').s, b'42')
+ self.assertIs(ast.NameConstant(True).value, True)
+ self.assertIs(ast.NameConstant(False).value, False)
+ self.assertIs(ast.NameConstant(None).value, None)
+
+ self.assertEqual(ast.Constant(42).value, 42)
+ self.assertEqual(ast.Constant(4.25).value, 4.25)
+ self.assertEqual(ast.Constant(4.25j).value, 4.25j)
+ self.assertEqual(ast.Constant('42').value, '42')
+ self.assertEqual(ast.Constant(b'42').value, b'42')
+ self.assertIs(ast.Constant(True).value, True)
+ self.assertIs(ast.Constant(False).value, False)
+ self.assertIs(ast.Constant(None).value, None)
+ self.assertIs(ast.Constant(...).value, ...)
+
+ def test_realtype(self):
+ self.assertEqual(type(ast.Num(42)), ast.Constant)
+ self.assertEqual(type(ast.Num(4.25)), ast.Constant)
+ self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
+ self.assertEqual(type(ast.Str('42')), ast.Constant)
+ self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
+ self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
+ self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
+ self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
+ self.assertEqual(type(ast.Ellipsis()), ast.Constant)
+
+ def test_isinstance(self):
+ self.assertTrue(isinstance(ast.Num(42), ast.Num))
+ self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
+ self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
+ self.assertTrue(isinstance(ast.Str('42'), ast.Str))
+ self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
+ self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
+ self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
+ self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
+ self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
+
+ self.assertTrue(isinstance(ast.Constant(42), ast.Num))
+ self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
+ self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
+ self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
+ self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
+ self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
+ self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
+ self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
+ self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
+
+ self.assertFalse(isinstance(ast.Str('42'), ast.Num))
+ self.assertFalse(isinstance(ast.Num(42), ast.Str))
+ self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
+ self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
+ self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
+
+ self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
+ self.assertFalse(isinstance(ast.Constant(42), ast.Str))
+ self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
+ self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
+ self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
+
+ self.assertFalse(isinstance(ast.Constant(), ast.Num))
+ self.assertFalse(isinstance(ast.Constant(), ast.Str))
+ self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
+ self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
+ self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
+
+ def test_subclasses(self):
+ class N(ast.Num):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.z = 'spam'
+ class N2(ast.Num):
+ pass
+
+ n = N(42)
+ self.assertEqual(n.n, 42)
+ self.assertEqual(n.z, 'spam')
+ self.assertEqual(type(n), N)
+ self.assertTrue(isinstance(n, N))
+ self.assertTrue(isinstance(n, ast.Num))
+ self.assertFalse(isinstance(n, N2))
+ self.assertFalse(isinstance(ast.Num(42), N))
+ n = N(n=42)
+ self.assertEqual(n.n, 42)
+ self.assertEqual(type(n), N)
+
def test_module(self):
body = [ast.Num(42)]
x = ast.Module(body)
@@ -446,17 +540,17 @@ def test_dump(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(ast.dump(node),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
- "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
+ "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
"keywords=[]))])"
)
self.assertEqual(ast.dump(node, annotate_fields=False),
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
- "Str('and cheese')], []))])"
+ "Constant('and cheese')], []))])"
)
self.assertEqual(ast.dump(node, include_attributes=True),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
- "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
+ "lineno=1, col_offset=5), Constant(value='and cheese', lineno=1, "
"col_offset=11)], keywords=[], "
"lineno=1, col_offset=0), lineno=1, col_offset=0)])"
)
@@ -465,8 +559,8 @@ def test_copy_location(self):
src = ast.parse('1 + 1', mode='eval')
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
self.assertEqual(ast.dump(src, include_attributes=True),
- 'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
- 'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
+ 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0), '
+ 'op=Add(), right=Constant(value=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
@@ -477,11 +571,11 @@ def test_fix_missing_locations(self):
self.assertEqual(src, ast.fix_missing_locations(src))
self.assertEqual(ast.dump(src, include_attributes=True),
"Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
- "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, "
+ "lineno=1, col_offset=0), args=[Constant(value='spam', lineno=1, "
"col_offset=6)], keywords=[], "
"lineno=1, col_offset=0), lineno=1, col_offset=0), "
"Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, "
- "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], "
+ "col_offset=0), args=[Constant(value='eggs', lineno=1, col_offset=0)], "
"keywords=[], lineno=1, "
"col_offset=0), lineno=1, col_offset=0)])"
)
@@ -490,16 +584,16 @@ def test_increment_lineno(self):
src = ast.parse('1 + 1', mode='eval')
self.assertEqual(ast.increment_lineno(src, n=3), src)
self.assertEqual(ast.dump(src, include_attributes=True),
- 'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
- 'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
+ 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0), '
+ 'op=Add(), right=Constant(value=1, lineno=4, col_offset=4), lineno=4, '
'col_offset=0))'
)
# issue10869: do not increment lineno of root twice
src = ast.parse('1 + 1', mode='eval')
self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
self.assertEqual(ast.dump(src, include_attributes=True),
- 'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
- 'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
+ 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0), '
+ 'op=Add(), right=Constant(value=1, lineno=4, col_offset=4), lineno=4, '
'col_offset=0))'
)
@@ -514,10 +608,10 @@ def test_iter_child_nodes(self):
self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
iterator = ast.iter_child_nodes(node.body)
self.assertEqual(next(iterator).id, 'spam')
- self.assertEqual(next(iterator).n, 23)
- self.assertEqual(next(iterator).n, 42)
+ self.assertEqual(next(iterator).value, 23)
+ self.assertEqual(next(iterator).value, 42)
self.assertEqual(ast.dump(next(iterator)),
- "keyword(arg='eggs', value=Str(s='leek'))"
+ "keyword(arg='eggs', value=Constant(value='leek'))"
)
def test_get_docstring(self):
@@ -627,9 +721,11 @@ class ASTValidatorTests(unittest.TestCase):
def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
mod.lineno = mod.col_offset = 0
ast.fix_missing_locations(mod)
- with self.assertRaises(exc) as cm:
+ if msg is None:
compile(mod, "<test>", mode)
- if msg is not None:
+ else:
+ with self.assertRaises(exc) as cm:
+ compile(mod, "<test>", mode)
self.assertIn(msg, str(cm.exception))
def expr(self, node, msg=None, *, exc=ValueError):
@@ -927,9 +1023,9 @@ def test_compare(self):
comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
self.expr(comp, "different number of comparators and operands")
comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
- self.expr(comp, "non-numeric", exc=TypeError)
+ self.expr(comp)
comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
- self.expr(comp, "non-numeric", exc=TypeError)
+ self.expr(comp)
def test_call(self):
func = ast.Name("x", ast.Load())
@@ -950,8 +1046,10 @@ class subfloat(float):
pass
class subcomplex(complex):
pass
- for obj in "0", "hello", subint(), subfloat(), subcomplex():
- self.expr(ast.Num(obj), "non-numeric", exc=TypeError)
+ for obj in "0", "hello":
+ self.expr(ast.Num(obj))
+ for obj in subint(), subfloat(), subcomplex():
+ self.expr(ast.Num(obj), "invalid type", exc=TypeError)
def test_attribute(self):
attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
@@ -993,7 +1091,7 @@ def test_tuple(self):
self._sequence(ast.Tuple)
def test_nameconstant(self):
- self.expr(ast.NameConstant(4), "singleton must be True, False, or None")
+ self.expr(ast.NameConstant(4))
def test_stdlib_validates(self):
stdlib = os.path.dirname(ast.__file__)
@@ -1140,35 +1238,35 @@ def main():
#### EVERYTHING BELOW IS GENERATED #####
exec_results = [
-('Module', [('Expr', (1, 0), ('NameConstant', (1, 0), None))]),
-('Module', [('Expr', (1, 0), ('Str', (1, 0), 'module docstring'))]),
+('Module', [('Expr', (1, 0), ('Constant', (1, 0), None))]),
+('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring'))]),
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None)]),
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Str', (1, 9), 'function docstring'))], [], None)]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring'))], [], None)]),
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, []), [('Pass', (1, 10))], [], None)]),
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Constant', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]),
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]),
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]),
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Str', (1, 58), 'doc for f()'))], [], None)]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Constant', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Constant', (1, 11), 1), ('Constant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()'))], [], None)]),
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])]),
-('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Str', (1, 9), 'docstring for class C'))], [])]),
+('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C'))], [])]),
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])]),
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1))], [], None)]),
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
-('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
-('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]),
+('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1))]),
+('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1))]),
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
-('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)]),
+('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string')], []), None)]),
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]),
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]),
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
('Module', [('Global', (1, 0), ['v'])]),
-('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))]),
+('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1))]),
('Module', [('Pass', (1, 0))]),
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])]),
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])]),
@@ -1181,40 +1279,40 @@ def main():
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))]),
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))]),
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))]),
-('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Str', (2, 1), 'async function')), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None)]),
-('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Num', (2, 19), 1))], [('Expr', (3, 7), ('Num', (3, 7), 2))])], [], None)]),
-('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Num', (2, 20), 1))])], [], None)]),
-('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))]),
-('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))]),
+('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function')), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None)]),
+('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1))], [('Expr', (3, 7), ('Constant', (3, 7), 2))])], [], None)]),
+('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1))])], [], None)]),
+('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2)], [('Dict', (1, 3), [('Constant', (1, 4), 1)], [('Constant', (1, 6), 2)]), ('Constant', (1, 12), 3)]))]),
+('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1), ('Constant', (1, 6), 2)]), ('Load',)), ('Constant', (1, 10), 3)]))]),
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 2), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None)]),
]
single_results = [
-('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
+('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1), ('Add',), ('Constant', (1, 2), 2)))]),
]
eval_results = [
-('Expression', ('NameConstant', (1, 0), None)),
+('Expression', ('Constant', (1, 0), None)),
('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
-('Expression', ('Lambda', (1, 0), ('arguments', [], None, [], [], None, []), ('NameConstant', (1, 7), None))),
-('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])),
+('Expression', ('Lambda', (1, 0), ('arguments', [], None, [], [], None, []), ('Constant', (1, 7), None))),
+('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1)], [('Constant', (1, 4), 2)])),
('Expression', ('Dict', (1, 0), [], [])),
-('Expression', ('Set', (1, 0), [('NameConstant', (1, 1), None)])),
-('Expression', ('Dict', (1, 0), [('Num', (2, 6), 1)], [('Num', (4, 10), 2)])),
+('Expression', ('Set', (1, 0), [('Constant', (1, 1), None)])),
+('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1)], [('Constant', (4, 10), 2)])),
('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
-('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])),
-('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Num', (1, 8), 3)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
-('Expression', ('Num', (1, 0), 10)),
-('Expression', ('Str', (1, 0), 'string')),
+('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2), ('Constant', (1, 8), 3)])),
+('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1), ('Constant', (1, 4), 2), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
+('Expression', ('Constant', (1, 0), 10)),
+('Expression', ('Constant', (1, 0), 'string')),
('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
('Expression', ('Name', (1, 0), 'v', ('Load',))),
-('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))),
+('Expression', ('List', (1, 0), [('Constant', (1, 1), 1), ('Constant', (1, 3), 2), ('Constant', (1, 5), 3)], ('Load',))),
('Expression', ('List', (1, 0), [], ('Load',))),
-('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))),
-('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))),
+('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1), ('Constant', (1, 2), 2), ('Constant', (1, 4), 3)], ('Load',))),
+('Expression', ('Tuple', (1, 1), [('Constant', (1, 1), 1), ('Constant', (1, 3), 2), ('Constant', (1, 5), 3)], ('Load',))),
('Expression', ('Tuple', (1, 0), [], ('Load',))),
-('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [])),
+('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12), 1), ('Constant', (1, 14), 2), None), ('Load',))], [])),
]
main()
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index 5e7efe25e39c..fec72e008e5b 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -116,9 +116,11 @@ def test_ast_line_numbers_multiple_formattedvalues(self):
self.assertEqual(type(t.body[1]), ast.Expr)
self.assertEqual(type(t.body[1].value), ast.JoinedStr)
self.assertEqual(len(t.body[1].value.values), 4)
- self.assertEqual(type(t.body[1].value.values[0]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[0].value), str)
self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
- self.assertEqual(type(t.body[1].value.values[2]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[2].value), str)
self.assertEqual(type(t.body[1].value.values[3]), ast.FormattedValue)
self.assertEqual(t.body[1].lineno, 3)
self.assertEqual(t.body[1].value.lineno, 3)
@@ -183,9 +185,11 @@ def test_ast_line_numbers_nested(self):
self.assertEqual(binop.right.col_offset, 7)
# check the nested call location
self.assertEqual(len(binop.right.values), 3)
- self.assertEqual(type(binop.right.values[0]), ast.Str)
+ self.assertEqual(type(binop.right.values[0]), ast.Constant)
+ self.assertEqual(type(binop.right.values[0].value), str)
self.assertEqual(type(binop.right.values[1]), ast.FormattedValue)
- self.assertEqual(type(binop.right.values[2]), ast.Str)
+ self.assertEqual(type(binop.right.values[2]), ast.Constant)
+ self.assertEqual(type(binop.right.values[2].value), str)
self.assertEqual(binop.right.values[0].lineno, 3)
self.assertEqual(binop.right.values[1].lineno, 3)
self.assertEqual(binop.right.values[2].lineno, 3)
@@ -215,9 +219,11 @@ def test_ast_line_numbers_duplicate_expression(self):
self.assertEqual(type(t.body[1].value), ast.JoinedStr)
self.assertEqual(len(t.body[1].value.values), 5)
self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
- self.assertEqual(type(t.body[1].value.values[1]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[1]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[1].value), str)
self.assertEqual(type(t.body[1].value.values[2]), ast.FormattedValue)
- self.assertEqual(type(t.body[1].value.values[3]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[3]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[3].value), str)
self.assertEqual(type(t.body[1].value.values[4]), ast.FormattedValue)
self.assertEqual(t.body[1].lineno, 3)
self.assertEqual(t.body[1].value.lineno, 3)
@@ -287,9 +293,11 @@ def test_ast_line_numbers_multiline_fstring(self):
self.assertEqual(type(t.body[1]), ast.Expr)
self.assertEqual(type(t.body[1].value), ast.JoinedStr)
self.assertEqual(len(t.body[1].value.values), 3)
- self.assertEqual(type(t.body[1].value.values[0]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[0].value), str)
self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
- self.assertEqual(type(t.body[1].value.values[2]), ast.Str)
+ self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
+ self.assertEqual(type(t.body[1].value.values[2].value), str)
# NOTE: the following invalid behavior is described in bpo-16806.
# - line number should be the *first* line (3), not the *last* (8)
# - column offset should not be -1
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index 660701b4b3d8..904e8a9d5dfc 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -230,7 +230,7 @@ def test_annotations(self):
eq("lukasz.langa.pl")
eq("call.me(maybe)")
eq("1 .real")
- eq("1.0 .real")
+ eq("1.0.real")
eq("....__class__")
eq("list[str]")
eq("dict[str, int]")
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index eaab591f74ef..9e970d9df041 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -144,7 +144,8 @@ def defined_in(item, module):
def test_easy(self):
self.checkModule('pyclbr')
- self.checkModule('ast')
+ # XXX: Metaclasses are not supported
+ # self.checkModule('ast')
self.checkModule('doctest', ignore=("TestResults", "_SpoofOut",
"DocTestCase", '_DocTestSuite'))
self.checkModule('difflib', ignore=("Match",))
diff --git a/Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst b/Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
new file mode 100644
index 000000000000..9be4bf89008d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-20-17-35-05.bpo-32892.TOUBdg.rst
@@ -0,0 +1,4 @@
+The parser now represents all constants as :class:`ast.Constant` instead of
+using specific constant AST types (``Num``, ``Str``, ``Bytes``,
+``NameConstant`` and ``Ellipsis``). These classes are considered deprecated
+and will be removed in future Python versions.
diff --git a/Parser/Python.asdl b/Parser/Python.asdl
index f470ad13b655..eee982be1c95 100644
--- a/Parser/Python.asdl
+++ b/Parser/Python.asdl
@@ -1,8 +1,5 @@
--- ASDL's 7 builtin types are:
--- identifier, int, string, bytes, object, singleton, constant
---
--- singleton: None, True or False
--- constant can be None, whereas None means "no value" for object.
+-- ASDL's 5 builtin types are:
+-- identifier, int, string, object, constant
module Python
{
@@ -75,13 +72,8 @@ module Python
-- x < 4 < 3 and (x < 4) < 3
| Compare(expr left, cmpop* ops, expr* comparators)
| Call(expr func, expr* args, keyword* keywords)
- | Num(object n) -- a number as a PyObject.
- | Str(string s) -- need to specify raw, unicode, etc?
| FormattedValue(expr value, int? conversion, expr? format_spec)
| JoinedStr(expr* values)
- | Bytes(bytes s)
- | NameConstant(singleton value)
- | Ellipsis
| Constant(constant value)
-- the following expression can appear in assignment context
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index 44e3d40c6155..4c280a96c30e 100644
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -855,17 +855,6 @@ def visitModule(self, mod):
/* Conversion Python -> AST */
-static int obj2ast_singleton(PyObject *obj, PyObject** out, PyArena* arena)
-{
- if (obj != Py_None && obj != Py_True && obj != Py_False) {
- PyErr_SetString(PyExc_ValueError,
- "AST singleton must be True, False, or None");
- return 1;
- }
- *out = obj;
- return 0;
-}
-
static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
{
if (obj == Py_None)
@@ -883,13 +872,11 @@ def visitModule(self, mod):
static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena)
{
- if (obj) {
- if (PyArena_AddPyObject(arena, obj) < 0) {
- *out = NULL;
- return -1;
- }
- Py_INCREF(obj);
+ if (PyArena_AddPyObject(arena, obj) < 0) {
+ *out = NULL;
+ return -1;
}
+ Py_INCREF(obj);
*out = obj;
return 0;
}
@@ -903,24 +890,6 @@ def visitModule(self, mod):
return obj2ast_object(obj, out, arena);
}
-static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
-{
- if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
- PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
- return 1;
- }
- return obj2ast_object(obj, out, arena);
-}
-
-static int obj2ast_bytes(PyObject* obj, PyObject** out, PyArena* arena)
-{
- if (!PyBytes_CheckExact(obj)) {
- PyErr_SetString(PyExc_TypeError, "AST bytes must be of type bytes");
- return 1;
- }
- return obj2ast_object(obj, out, arena);
-}
-
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
{
int i;
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 6a2f28e0e712..bbe8e69fdd50 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -284,16 +284,6 @@ static char *Call_fields[]={
"args",
"keywords",
};
-static PyTypeObject *Num_type;
-_Py_IDENTIFIER(n);
-static char *Num_fields[]={
- "n",
-};
-static PyTypeObject *Str_type;
-_Py_IDENTIFIER(s);
-static char *Str_fields[]={
- "s",
-};
static PyTypeObject *FormattedValue_type;
_Py_IDENTIFIER(conversion);
_Py_IDENTIFIER(format_spec);
@@ -306,15 +296,6 @@ static PyTypeObject *JoinedStr_type;
static char *JoinedStr_fields[]={
"values",
};
-static PyTypeObject *Bytes_type;
-static char *Bytes_fields[]={
- "s",
-};
-static PyTypeObject *NameConstant_type;
-static char *NameConstant_fields[]={
- "value",
-};
-static PyTypeObject *Ellipsis_type;
static PyTypeObject *Constant_type;
static char *Constant_fields[]={
"value",
@@ -736,17 +717,6 @@ static PyObject* ast2obj_int(long b)
/* Conversion Python -> AST */
-static int obj2ast_singleton(PyObject *obj, PyObject** out, PyArena* arena)
-{
- if (obj != Py_None && obj != Py_True && obj != Py_False) {
- PyErr_SetString(PyExc_ValueError,
- "AST singleton must be True, False, or None");
- return 1;
- }
- *out = obj;
- return 0;
-}
-
static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
{
if (obj == Py_None)
@@ -764,13 +734,11 @@ static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena)
static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena)
{
- if (obj) {
- if (PyArena_AddPyObject(arena, obj) < 0) {
- *out = NULL;
- return -1;
- }
- Py_INCREF(obj);
+ if (PyArena_AddPyObject(arena, obj) < 0) {
+ *out = NULL;
+ return -1;
}
+ Py_INCREF(obj);
*out = obj;
return 0;
}
@@ -784,24 +752,6 @@ static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
return obj2ast_object(obj, out, arena);
}
-static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
-{
- if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
- PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
- return 1;
- }
- return obj2ast_object(obj, out, arena);
-}
-
-static int obj2ast_bytes(PyObject* obj, PyObject** out, PyArena* arena)
-{
- if (!PyBytes_CheckExact(obj)) {
- PyErr_SetString(PyExc_TypeError, "AST bytes must be of type bytes");
- return 1;
- }
- return obj2ast_object(obj, out, arena);
-}
-
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
{
int i;
@@ -943,22 +893,11 @@ static int init_types(void)
if (!Compare_type) return 0;
Call_type = make_type("Call", expr_type, Call_fields, 3);
if (!Call_type) return 0;
- Num_type = make_type("Num", expr_type, Num_fields, 1);
- if (!Num_type) return 0;
- Str_type = make_type("Str", expr_type, Str_fields, 1);
- if (!Str_type) return 0;
FormattedValue_type = make_type("FormattedValue", expr_type,
FormattedValue_fields, 3);
if (!FormattedValue_type) return 0;
JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1);
if (!JoinedStr_type) return 0;
- Bytes_type = make_type("Bytes", expr_type, Bytes_fields, 1);
- if (!Bytes_type) return 0;
- NameConstant_type = make_type("NameConstant", expr_type,
- NameConstant_fields, 1);
- if (!NameConstant_type) return 0;
- Ellipsis_type = make_type("Ellipsis", expr_type, NULL, 0);
- if (!Ellipsis_type) return 0;
Constant_type = make_type("Constant", expr_type, Constant_fields, 1);
if (!Constant_type) return 0;
Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
@@ -2089,44 +2028,6 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int
return p;
}
-expr_ty
-Num(object n, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!n) {
- PyErr_SetString(PyExc_ValueError,
- "field n is required for Num");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = Num_kind;
- p->v.Num.n = n;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Str(string s, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!s) {
- PyErr_SetString(PyExc_ValueError,
- "field s is required for Str");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = Str_kind;
- p->v.Str.s = s;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
expr_ty
FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno,
int col_offset, PyArena *arena)
@@ -2163,57 +2064,6 @@ JoinedStr(asdl_seq * values, int lineno, int col_offset, PyArena *arena)
return p;
}
-expr_ty
-Bytes(bytes s, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!s) {
- PyErr_SetString(PyExc_ValueError,
- "field s is required for Bytes");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = Bytes_kind;
- p->v.Bytes.s = s;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-NameConstant(singleton value, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for NameConstant");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = NameConstant_kind;
- p->v.NameConstant.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Ellipsis(int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p)
- return NULL;
- p->kind = Ellipsis_kind;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
expr_ty
Constant(constant value, int lineno, int col_offset, PyArena *arena)
{
@@ -3289,24 +3139,6 @@ ast2obj_expr(void* _o)
goto failed;
Py_DECREF(value);
break;
- case Num_kind:
- result = PyType_GenericNew(Num_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_object(o->v.Num.n);
- if (!value) goto failed;
- if (_PyObject_SetAttrId(result, &PyId_n, value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Str_kind:
- result = PyType_GenericNew(Str_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_string(o->v.Str.s);
- if (!value) goto failed;
- if (_PyObject_SetAttrId(result, &PyId_s, value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
case FormattedValue_kind:
result = PyType_GenericNew(FormattedValue_type, NULL, NULL);
if (!result) goto failed;
@@ -3335,28 +3167,6 @@ ast2obj_expr(void* _o)
goto failed;
Py_DECREF(value);
break;
- case Bytes_kind:
- result = PyType_GenericNew(Bytes_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_bytes(o->v.Bytes.s);
- if (!value) goto failed;
- if (_PyObject_SetAttrId(result, &PyId_s, value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case NameConstant_kind:
- result = PyType_GenericNew(NameConstant_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_singleton(o->v.NameConstant.value);
- if (!value) goto failed;
- if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Ellipsis_kind:
- result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
- if (!result) goto failed;
- break;
case Constant_kind:
result = PyType_GenericNew(Constant_type, NULL, NULL);
if (!result) goto failed;
@@ -6606,54 +6416,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if (*out == NULL) goto failed;
return 0;
}
- isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
- object n;
-
- if (_PyObject_LookupAttrId(obj, &PyId_n, &tmp) < 0) {
- return 1;
- }
- if (tmp == NULL) {
- PyErr_SetString(PyExc_TypeError, "required field \"n\" missing from Num");
- return 1;
- }
- else {
- int res;
- res = obj2ast_object(tmp, &n, arena);
- if (res != 0) goto failed;
- Py_CLEAR(tmp);
- }
- *out = Num(n, lineno, col_offset, arena);
- if (*out == NULL) goto failed;
- return 0;
- }
- isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
- string s;
-
- if (_PyObject_LookupAttrId(obj, &PyId_s, &tmp) < 0) {
- return 1;
- }
- if (tmp == NULL) {
- PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Str");
- return 1;
- }
- else {
- int res;
- res = obj2ast_string(tmp, &s, arena);
- if (res != 0) goto failed;
- Py_CLEAR(tmp);
- }
- *out = Str(s, lineno, col_offset, arena);
- if (*out == NULL) goto failed;
- return 0;
- }
isinstance = PyObject_IsInstance(obj, (PyObject*)FormattedValue_type);
if (isinstance == -1) {
return 1;
@@ -6748,64 +6510,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
if (*out == NULL) goto failed;
return 0;
}
- isinstance = PyObject_IsInstance(obj, (PyObject*)Bytes_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
- bytes s;
-
- if (_PyObject_LookupAttrId(obj, &PyId_s, &tmp) < 0) {
- return 1;
- }
- if (tmp == NULL) {
- PyErr_SetString(PyExc_TypeError, "required field \"s\" missing from Bytes");
- return 1;
- }
- else {
- int res;
- res = obj2ast_bytes(tmp, &s, arena);
- if (res != 0) goto failed;
- Py_CLEAR(tmp);
- }
- *out = Bytes(s, lineno, col_offset, arena);
- if (*out == NULL) goto failed;
- return 0;
- }
- isinstance = PyObject_IsInstance(obj, (PyObject*)NameConstant_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
- singleton value;
-
- if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) {
- return 1;
- }
- if (tmp == NULL) {
- PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NameConstant");
- return 1;
- }
- else {
- int res;
- res = obj2ast_singleton(tmp, &value, arena);
- if (res != 0) goto failed;
- Py_CLEAR(tmp);
- }
- *out = NameConstant(value, lineno, col_offset, arena);
- if (*out == NULL) goto failed;
- return 0;
- }
- isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type);
- if (isinstance == -1) {
- return 1;
- }
- if (isinstance) {
-
- *out = Ellipsis(lineno, col_offset, arena);
- if (*out == NULL) goto failed;
- return 0;
- }
isinstance = PyObject_IsInstance(obj, (PyObject*)Constant_type);
if (isinstance == -1) {
return 1;
@@ -8244,18 +7948,10 @@ PyInit__ast(void)
if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0) return
NULL;
if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return NULL;
- if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return NULL;
- if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return NULL;
if (PyDict_SetItemString(d, "FormattedValue",
(PyObject*)FormattedValue_type) < 0) return NULL;
if (PyDict_SetItemString(d, "JoinedStr", (PyObject*)JoinedStr_type) < 0)
return NULL;
- if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return
- NULL;
- if (PyDict_SetItemString(d, "NameConstant", (PyObject*)NameConstant_type) <
- 0) return NULL;
- if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
- return NULL;
if (PyDict_SetItemString(d, "Constant", (PyObject*)Constant_type) < 0)
return NULL;
if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) < 0)
diff --git a/Python/ast.c b/Python/ast.c
index b2fcb219752d..587f838f8d8e 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -295,23 +295,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
return 0;
}
return 1;
- case Num_kind: {
- PyObject *n = exp->v.Num.n;
- if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) &&
- !PyComplex_CheckExact(n)) {
- PyErr_SetString(PyExc_TypeError, "non-numeric type in Num");
- return 0;
- }
- return 1;
- }
- case Str_kind: {
- PyObject *s = exp->v.Str.s;
- if (!PyUnicode_CheckExact(s)) {
- PyErr_SetString(PyExc_TypeError, "non-string type in Str");
- return 0;
- }
- return 1;
- }
case JoinedStr_kind:
return validate_exprs(exp->v.JoinedStr.values, Load, 0);
case FormattedValue_kind:
@@ -320,14 +303,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
if (exp->v.FormattedValue.format_spec)
return validate_expr(exp->v.FormattedValue.format_spec, Load);
return 1;
- case Bytes_kind: {
- PyObject *b = exp->v.Bytes.s;
- if (!PyBytes_CheckExact(b)) {
- PyErr_SetString(PyExc_TypeError, "non-bytes type in Bytes");
- return 0;
- }
- return 1;
- }
case Attribute_kind:
return validate_expr(exp->v.Attribute.value, Load);
case Subscript_kind:
@@ -339,10 +314,8 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
return validate_exprs(exp->v.List.elts, ctx, 0);
case Tuple_kind:
return validate_exprs(exp->v.Tuple.elts, ctx, 0);
- /* These last cases don't have any checking. */
+ /* This last case doesn't have any checking. */
case Name_kind:
- case NameConstant_kind:
- case Ellipsis_kind:
return 1;
default:
PyErr_SetString(PyExc_SystemError, "unexpected expression");
@@ -1040,19 +1013,23 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n)
break;
case Dict_kind:
case Set_kind:
- case Num_kind:
- case Str_kind:
- case Bytes_kind:
case JoinedStr_kind:
case FormattedValue_kind:
expr_name = "literal";
break;
- case NameConstant_kind:
- expr_name = "keyword";
- break;
- case Ellipsis_kind:
- expr_name = "Ellipsis";
+ case Constant_kind: {
+ PyObject *value = e->v.Constant.value;
+ if (value == Py_None || value == Py_False || value == Py_True) {
+ expr_name = "keyword";
+ }
+ else if (value == Py_Ellipsis) {
+ expr_name = "Ellipsis";
+ }
+ else {
+ expr_name = "literal";
+ }
break;
+ }
case Compare_kind:
expr_name = "comparison";
break;
@@ -2091,11 +2068,11 @@ ast_for_atom(struct compiling *c, const node *n)
size_t len = strlen(s);
if (len >= 4 && len <= 5) {
if (!strcmp(s, "None"))
- return NameConstant(Py_None, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(Py_None, LINENO(n), n->n_col_offset, c->c_arena);
if (!strcmp(s, "True"))
- return NameConstant(Py_True, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(Py_True, LINENO(n), n->n_col_offset, c->c_arena);
if (!strcmp(s, "False"))
- return NameConstant(Py_False, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(Py_False, LINENO(n), n->n_col_offset, c->c_arena);
}
name = new_identifier(s, c);
if (!name)
@@ -2144,10 +2121,10 @@ ast_for_atom(struct compiling *c, const node *n)
Py_DECREF(pynum);
return NULL;
}
- return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(pynum, LINENO(n), n->n_col_offset, c->c_arena);
}
case ELLIPSIS: /* Ellipsis */
- return Ellipsis(LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(Py_Ellipsis, LINENO(n), n->n_col_offset, c->c_arena);
case LPAR: /* some parenthesized expressions */
ch = CHILD(n, 1);
@@ -4751,7 +4728,7 @@ typedef struct {
expr_ty's, and then after that start dynamically allocating,
doubling the number allocated each time. Note that the f-string
f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one
- Str for the literal 'a'. So you add expr_ty's about twice as
+ Constant for the literal 'a'. So you add expr_ty's about twice as
fast as you add exressions in an f-string. */
Py_ssize_t allocated; /* Number we've allocated. */
@@ -4903,7 +4880,7 @@ FstringParser_Dealloc(FstringParser *state)
ExprList_Dealloc(&state->expr_list);
}
-/* Make a Str node, but decref the PyUnicode object being added. */
+/* Make a Constant node, but decref the PyUnicode object being added. */
static expr_ty
make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
{
@@ -4914,7 +4891,7 @@ make_str_node_and_del(PyObject **str, struct compiling *c, const node* n)
Py_DECREF(s);
return NULL;
}
- return Str(s, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(s, LINENO(n), n->n_col_offset, c->c_arena);
}
/* Add a non-f-string (that is, a regular literal string). str is
@@ -5002,11 +4979,11 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
break;
/* We know we have an expression. Convert any existing string
- to a Str node. */
+ to a Constant node. */
if (!state->last_str) {
/* Do nothing. No previous literal. */
} else {
- /* Convert the existing last_str literal to a Str node. */
+ /* Convert the existing last_str literal to a Constant node. */
expr_ty str = make_str_node_and_del(&state->last_str, c, n);
if (!str || ExprList_Append(&state->expr_list, str) < 0)
return -1;
@@ -5033,7 +5010,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
}
/* Convert the partial state reflected in last_str and expr_list to an
- expr_ty. The expr_ty can be a Str, or a JoinedStr. */
+ expr_ty. The expr_ty can be a Constant, or a JoinedStr. */
static expr_ty
FstringParser_Finish(FstringParser *state, struct compiling *c,
const node *n)
@@ -5055,7 +5032,7 @@ FstringParser_Finish(FstringParser *state, struct compiling *c,
return make_str_node_and_del(&state->last_str, c, n);
}
- /* Create a Str node out of last_str, if needed. It will be the
+ /* Create a Constant node out of last_str, if needed. It will be the
last node in our expression list. */
if (state->last_str) {
expr_ty str = make_str_node_and_del(&state->last_str, c, n);
@@ -5206,9 +5183,9 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
/* Accepts a STRING+ atom, and produces an expr_ty node. Run through
each STRING atom, and process it as needed. For bytes, just
- concatenate them together, and the result will be a Bytes node. For
+ concatenate them together, and the result will be a Constant node. For
normal strings and f-strings, concatenate them together. The result
- will be a Str node if there were no f-strings; a FormattedValue
+ will be a Constant node if there were no f-strings; a FormattedValue
node if there's just an f-string (with no leading or trailing
literals), or a JoinedStr node if there are multiple f-strings or
any literals involved. */
@@ -5279,7 +5256,7 @@ parsestrplus(struct compiling *c, const node *n)
/* Just return the bytes object and we're done. */
if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0)
goto error;
- return Bytes(bytes_str, LINENO(n), n->n_col_offset, c->c_arena);
+ return Constant(bytes_str, LINENO(n), n->n_col_offset, c->c_arena);
}
/* We're not a bytes string, bytes_str should never have been set. */
@@ -5304,9 +5281,6 @@ _PyAST_GetDocString(asdl_seq *body)
return NULL;
}
expr_ty e = st->v.Expr.value;
- if (e->kind == Str_kind) {
- return e->v.Str.s;
- }
if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
return e->v.Constant.value;
}
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 5e57638e3d01..1f9cb773ea7b 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -5,47 +5,6 @@
#include "ast.h"
-/* TODO: is_const and get_const_value are copied from Python/compile.c.
- It should be deduped in the future. Maybe, we can include this file
- from compile.c?
-*/
-static int
-is_const(expr_ty e)
-{
- switch (e->kind) {
- case Constant_kind:
- case Num_kind:
- case Str_kind:
- case Bytes_kind:
- case Ellipsis_kind:
- case NameConstant_kind:
- return 1;
- default:
- return 0;
- }
-}
-
-static PyObject *
-get_const_value(expr_ty e)
-{
- switch (e->kind) {
- case Constant_kind:
- return e->v.Constant.value;
- case Num_kind:
- return e->v.Num.n;
- case Str_kind:
- return e->v.Str.s;
- case Bytes_kind:
- return e->v.Bytes.s;
- case Ellipsis_kind:
- return Py_Ellipsis;
- case NameConstant_kind:
- return e->v.NameConstant.value;
- default:
- Py_UNREACHABLE();
- }
-}
-
static int
make_const(expr_ty node, PyObject *val, PyArena *arena)
{
@@ -81,7 +40,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
{
expr_ty arg = node->v.UnaryOp.operand;
- if (!is_const(arg)) {
+ if (arg->kind != Constant_kind) {
/* Fold not into comparison */
if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
asdl_seq_LEN(arg->v.Compare.ops) == 1) {
@@ -123,7 +82,7 @@ fold_unaryop(expr_ty node, PyArena *arena, int optimize)
[UAdd] = PyNumber_Positive,
[USub] = PyNumber_Negative,
};
- PyObject *newval = ops[node->v.UnaryOp.op](get_const_value(arg));
+ PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
return make_const(node, newval, arena);
}
@@ -259,12 +218,12 @@ fold_binop(expr_ty node, PyArena *arena, int optimize)
expr_ty lhs, rhs;
lhs = node->v.BinOp.left;
rhs = node->v.BinOp.right;
- if (!is_const(lhs) || !is_const(rhs)) {
+ if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) {
return 1;
}
- PyObject *lv = get_const_value(lhs);
- PyObject *rv = get_const_value(rhs);
+ PyObject *lv = lhs->v.Constant.value;
+ PyObject *rv = rhs->v.Constant.value;
PyObject *newval;
switch (node->v.BinOp.op) {
@@ -316,7 +275,7 @@ make_const_tuple(asdl_seq *elts)
{
for (int i = 0; i < asdl_seq_LEN(elts); i++) {
expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
- if (!is_const(e)) {
+ if (e->kind != Constant_kind) {
return NULL;
}
}
@@ -328,7 +287,7 @@ make_const_tuple(asdl_seq *elts)
for (int i = 0; i < asdl_seq_LEN(elts); i++) {
expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
- PyObject *v = get_const_value(e);
+ PyObject *v = e->v.Constant.value;
Py_INCREF(v);
PyTuple_SET_ITEM(newval, i, v);
}
@@ -357,16 +316,16 @@ fold_subscr(expr_ty node, PyArena *arena, int optimize)
arg = node->v.Subscript.value;
slice = node->v.Subscript.slice;
if (node->v.Subscript.ctx != Load ||
- !is_const(arg) ||
+ arg->kind != Constant_kind ||
/* TODO: handle other types of slices */
slice->kind != Index_kind ||
- !is_const(slice->v.Index.value))
+ slice->v.Index.value->kind != Constant_kind)
{
return 1;
}
idx = slice->v.Index.value;
- newval = PyObject_GetItem(get_const_value(arg), get_const_value(idx));
+ newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
return make_const(node, newval, arena);
}
diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c
index 725ce31fe3c0..56ea3c424c5b 100644
--- a/Python/ast_unparse.c
+++ b/Python/ast_unparse.c
@@ -567,8 +567,6 @@ append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
switch (e->kind) {
case Constant_kind:
return append_fstring_unicode(writer, e->v.Constant.value);
- case Str_kind:
- return append_fstring_unicode(writer, e->v.Str.s);
case JoinedStr_kind:
return append_joinedstr(writer, e, is_format_spec);
case FormattedValue_kind:
@@ -690,13 +688,12 @@ static int
append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e)
{
const char *period;
- APPEND_EXPR(e->v.Attribute.value, PR_ATOM);
+ expr_ty v = e->v.Attribute.value;
+ APPEND_EXPR(v, PR_ATOM);
/* Special case: integers require a space for attribute access to be
- unambiguous. Floats and complex numbers don't but work with it, too. */
- if (e->v.Attribute.value->kind == Num_kind ||
- e->v.Attribute.value->kind == Constant_kind)
- {
+ unambiguous. */
+ if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) {
period = " .";
}
else {
@@ -841,21 +838,14 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
case Call_kind:
return append_ast_call(writer, e);
case Constant_kind:
+ if (e->v.Constant.value == Py_Ellipsis) {
+ APPEND_STR_FINISH("...");
+ }
return append_repr(writer, e->v.Constant.value);
- case Num_kind:
- return append_repr(writer, e->v.Num.n);
- case Str_kind:
- return append_repr(writer, e->v.Str.s);
case JoinedStr_kind:
return append_joinedstr(writer, e, false);
case FormattedValue_kind:
return append_formattedvalue(writer, e, false);
- case Bytes_kind:
- return append_repr(writer, e->v.Bytes.s);
- case Ellipsis_kind:
- APPEND_STR_FINISH("...");
- case NameConstant_kind:
- return append_repr(writer, e->v.NameConstant.value);
/* The following exprs can be assignment targets. */
case Attribute_kind:
return append_ast_attribute(writer, e);
diff --git a/Python/compile.c b/Python/compile.c
index 3a45804580ed..096b762f36bb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1398,43 +1398,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
} \
}
-static int
-is_const(expr_ty e)
-{
- switch (e->kind) {
- case Constant_kind:
- case Num_kind:
- case Str_kind:
- case Bytes_kind:
- case Ellipsis_kind:
- case NameConstant_kind:
- return 1;
- default:
- return 0;
- }
-}
-
-static PyObject *
-get_const_value(expr_ty e)
-{
- switch (e->kind) {
- case Constant_kind:
- return e->v.Constant.value;
- case Num_kind:
- return e->v.Num.n;
- case Str_kind:
- return e->v.Str.s;
- case Bytes_kind:
- return e->v.Bytes.s;
- case Ellipsis_kind:
- return Py_Ellipsis;
- case NameConstant_kind:
- return e->v.NameConstant.value;
- default:
- Py_UNREACHABLE();
- }
-}
-
/* Search if variable annotations are present statically in a block. */
static int
@@ -2568,7 +2531,7 @@ static int
compiler_return(struct compiler *c, stmt_ty s)
{
int preserve_tos = ((s->v.Return.value != NULL) &&
- !is_const(s->v.Return.value));
+ (s->v.Return.value->kind != Constant_kind));
if (c->u->u_ste->ste_type != FunctionBlock)
return compiler_error(c, "'return' outside function");
if (s->v.Return.value != NULL &&
@@ -3054,7 +3017,7 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
return 1;
}
- if (is_const(value)) {
+ if (value->kind == Constant_kind) {
/* ignore constant statement */
return 1;
}
@@ -3502,7 +3465,7 @@ are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end)
Py_ssize_t i;
for (i = begin; i < end; i++) {
expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
- if (key == NULL || !is_const(key))
+ if (key == NULL || key->kind != Constant_kind)
return 0;
}
return 1;
@@ -3522,7 +3485,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
return 0;
}
for (i = begin; i < end; i++) {
- key = get_const_value((expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
+ key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
Py_INCREF(key);
PyTuple_SET_ITEM(keys, i - begin, key);
}
@@ -4244,8 +4207,8 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
static int
expr_constant(expr_ty e)
{
- if (is_const(e)) {
- return PyObject_IsTrue(get_const_value(e));
+ if (e->kind == Constant_kind) {
+ return PyObject_IsTrue(e->v.Constant.value);
}
return -1;
}
@@ -4505,25 +4468,10 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
case Constant_kind:
ADDOP_LOAD_CONST(c, e->v.Constant.value);
break;
- case Num_kind:
- ADDOP_LOAD_CONST(c, e->v.Num.n);
- break;
- case Str_kind:
- ADDOP_LOAD_CONST(c, e->v.Str.s);
- break;
case JoinedStr_kind:
return compiler_joined_str(c, e);
case FormattedValue_kind:
return compiler_formatted_value(c, e);
- case Bytes_kind:
- ADDOP_LOAD_CONST(c, e->v.Bytes.s);
- break;
- case Ellipsis_kind:
- ADDOP_LOAD_CONST(c, Py_Ellipsis);
- break;
- case NameConstant_kind:
- ADDOP_LOAD_CONST(c, e->v.NameConstant.value);
- break;
/* The following exprs can be assignment targets. */
case Attribute_kind:
if (e->v.Attribute.ctx != AugStore)
diff --git a/Python/symtable.c b/Python/symtable.c
index e7216147a8a4..16b706b36338 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -1461,11 +1461,6 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_SEQ(st, expr, e->v.JoinedStr.values);
break;
case Constant_kind:
- case Num_kind:
- case Str_kind:
- case Bytes_kind:
- case Ellipsis_kind:
- case NameConstant_kind:
/* Nothing to do here. */
break;
/* The following exprs can be assignment targets. */
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index a6a43d1361d0..ca8096f43a6f 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -3840,9 +3840,6 @@ def bad_node(self, node):
# "starred": "a = [1, 2, 3]; *a"
visit_Starred = bad_node
- # allow ellipsis, for now
- # visit_Ellipsis = bad_node
-
blacklist = DetectBadNodes()
blacklist.visit(module)
bad = blacklist.bad
@@ -3868,10 +3865,15 @@ def bad_node(self, node):
py_default = 'None'
c_default = "NULL"
elif (isinstance(expr, ast.BinOp) or
- (isinstance(expr, ast.UnaryOp) and not isinstance(expr.operand, ast.Num))):
+ (isinstance(expr, ast.UnaryOp) and
+ not (isinstance(expr.operand, ast.Num) or
+ (hasattr(ast, 'Constant') and
+ isinstance(expr.operand, ast.Constant) and
+ type(expr.operand.value) in (int, float, complex)))
+ )):
c_default = kwargs.get("c_default")
if not (isinstance(c_default, str) and c_default):
- fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default.")
+ fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default." + ast.dump(expr))
py_default = default
value = unknown
elif isinstance(expr, ast.Attribute):
@@ -3946,6 +3948,11 @@ def bad_node(self, node):
self.function.parameters[parameter_name] = p
def parse_converter(self, annotation):
+ if (hasattr(ast, 'Constant') and
+ isinstance(annotation, ast.Constant) and
+ type(annotation.value) is str):
+ return annotation.value, True, {}
+
if isinstance(annotation, ast.Str):
return annotation.s, True, {}
diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py
index 7e1cc4ea5db9..82c3c7768072 100644
--- a/Tools/parser/unparse.py
+++ b/Tools/parser/unparse.py
@@ -329,12 +329,6 @@ def _AsyncWith(self, t):
self.leave()
# expr
- def _Bytes(self, t):
- self.write(repr(t.s))
-
- def _Str(self, tree):
- self.write(repr(tree.s))
-
def _JoinedStr(self, t):
self.write("f")
string = io.StringIO()
@@ -352,10 +346,6 @@ def _fstring_JoinedStr(self, t, write):
meth = getattr(self, "_fstring_" + type(value).__name__)
meth(value, write)
- def _fstring_Str(self, t, write):
- value = t.s.replace("{", "{{").replace("}", "}}")
- write(value)
-
def _fstring_Constant(self, t, write):
assert isinstance(t.value, str)
value = t.value.replace("{", "{{").replace("}", "}}")
@@ -384,6 +374,7 @@ def _Name(self, t):
def _write_constant(self, value):
if isinstance(value, (float, complex)):
+ # Substitute overflowing decimal literal for AST infinities.
self.write(repr(value).replace("inf", INFSTR))
else:
self.write(repr(value))
@@ -398,16 +389,11 @@ def _Constant(self, t):
else:
interleave(lambda: self.write(", "), self._write_constant, value)
self.write(")")
+ elif value is ...:
+ self.write("...")
else:
self._write_constant(t.value)
- def _NameConstant(self, t):
- self.write(repr(t.value))
-
- def _Num(self, t):
- # Substitute overflowing decimal literal for AST infinities.
- self.write(repr(t.n).replace("inf", INFSTR))
-
def _List(self, t):
self.write("[")
interleave(lambda: self.write(", "), self.dispatch, t.elts)
@@ -539,8 +525,7 @@ def _Attribute(self,t):
# Special case: 3.__abs__() is a syntax error, so if t.value
# is an integer literal then we need to either parenthesize
# it or add an extra space to get 3 .__abs__().
- if ((isinstance(t.value, ast.Num) and isinstance(t.value.n, int))
- or (isinstance(t.value, ast.Constant) and isinstance(t.value.value, int))):
+ if isinstance(t.value, ast.Constant) and isinstance(t.value.value, int):
self.write(" ")
self.write(".")
self.write(t.attr)
[View Less]
1
0

Sept. 27, 2018
https://github.com/python/cpython/commit/fe48b6df101aac10dc846fa6fd1a41f877…
commit: fe48b6df101aac10dc846fa6fd1a41f877e77025
branch: 3.6
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T06:30:55-07:00
summary:
Fix tests in test_socket to use correctly CMSG_LEN (GH-9594)
After some failures in AMD64 FreeBSD CURRENT Debug 3.x buildbots
regarding tests in test_socket that are using
…
[View More]testFDPassSeparateMinSpace(), FreeBDS revision 337423 was pointed
out to be the reason the test started to fail.
A close examination of the manpage for cmsg_space(3) reveals that
the number of file descriptors needs to be taken into account when
using CMSG_LEN().
This commit fixes tests in test_socket to use correctly CMSG_LEN, taking
into account the number of FDs.
(cherry picked from commit 7291108d88ea31d205da4db19d202d6cbffc6d93)
Co-authored-by: Pablo Galindo <Pablogsal(a)gmail.com>
files:
M Lib/test/test_socket.py
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index f8559ac4eab9..fbbc9f9abfb0 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -2858,10 +2858,11 @@ def _testFDPassSeparate(self):
def testFDPassSeparateMinSpace(self):
# Pass two FDs in two separate arrays, receiving them into the
# minimum space for two arrays.
- self.checkRecvmsgFDs(2,
+ num_fds = 2
+ self.checkRecvmsgFDs(num_fds,
self.doRecvmsg(self.serv_sock, len(MSG),
socket.CMSG_SPACE(SIZEOF_INT) +
- socket.CMSG_LEN(SIZEOF_INT)),
+ socket.CMSG_LEN(SIZEOF_INT * num_fds)),
maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC)
@testFDPassSeparateMinSpace.client_skip
[View Less]
1
0

Sept. 27, 2018
https://github.com/python/cpython/commit/addef07ca7d7b6971d59c062c3229e91a9…
commit: addef07ca7d7b6971d59c062c3229e91a99e5f5e
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T06:30:47-07:00
summary:
Fix tests in test_socket to use correctly CMSG_LEN (GH-9594)
After some failures in AMD64 FreeBSD CURRENT Debug 3.x buildbots
regarding tests in test_socket that are using
…
[View More]testFDPassSeparateMinSpace(), FreeBDS revision 337423 was pointed
out to be the reason the test started to fail.
A close examination of the manpage for cmsg_space(3) reveals that
the number of file descriptors needs to be taken into account when
using CMSG_LEN().
This commit fixes tests in test_socket to use correctly CMSG_LEN, taking
into account the number of FDs.
(cherry picked from commit 7291108d88ea31d205da4db19d202d6cbffc6d93)
Co-authored-by: Pablo Galindo <Pablogsal(a)gmail.com>
files:
M Lib/test/test_socket.py
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index bd4fad1f6380..5f9891de4936 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -3183,10 +3183,11 @@ def _testFDPassSeparate(self):
def testFDPassSeparateMinSpace(self):
# Pass two FDs in two separate arrays, receiving them into the
# minimum space for two arrays.
- self.checkRecvmsgFDs(2,
+ num_fds = 2
+ self.checkRecvmsgFDs(num_fds,
self.doRecvmsg(self.serv_sock, len(MSG),
socket.CMSG_SPACE(SIZEOF_INT) +
- socket.CMSG_LEN(SIZEOF_INT)),
+ socket.CMSG_LEN(SIZEOF_INT * num_fds)),
maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC)
@testFDPassSeparateMinSpace.client_skip
[View Less]
1
0

bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
by Miss Islington (bot) Sept. 27, 2018
by Miss Islington (bot) Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/2b01121fd4200f1c27873422f7f72d02ee…
commit: 2b01121fd4200f1c27873422f7f72d02eec08630
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T04:46:38-07:00
summary:
bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in …
[View More]order to prevent timeouts from deviating when the system clock is adjusted.
This may not be sufficient on all systems. On POSIX for example, the actual waiting (e.g. in ``sem_timedwait``) is specified to rely on the CLOCK_REALTIME clock.
(cherry picked from commit a94ee12c26aa8dd7dce01373779df8055aff765b)
Co-authored-by: orlnub123 <orlnub123(a)gmail.com>
files:
A Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
M Lib/concurrent/futures/_base.py
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index 4f22f7ee0e6d..61c81bb7fe68 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -212,7 +212,7 @@ def as_completed(fs, timeout=None):
before the given timeout.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = set(fs)
total_futures = len(fs)
@@ -231,7 +231,7 @@ def as_completed(fs, timeout=None):
if timeout is None:
wait_timeout = None
else:
- wait_timeout = end_time - time.time()
+ wait_timeout = end_time - time.monotonic()
if wait_timeout < 0:
raise TimeoutError(
'%d (of %d) futures unfinished' % (
@@ -570,7 +570,7 @@ def map(self, fn, *iterables, timeout=None, chunksize=1):
Exception: If fn(*args) raises for any values.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = [self.submit(fn, *args) for args in zip(*iterables)]
@@ -585,7 +585,7 @@ def result_iterator():
if timeout is None:
yield fs.pop().result()
else:
- yield fs.pop().result(end_time - time.time())
+ yield fs.pop().result(end_time - time.monotonic())
finally:
for future in fs:
future.cancel()
diff --git a/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
new file mode 100644
index 000000000000..6bbdea235f03
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
@@ -0,0 +1 @@
+Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in order to prevent timeouts from deviating when the system clock is adjusted.
[View Less]
1
0

bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
by Miss Islington (bot) Sept. 27, 2018
by Miss Islington (bot) Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/3a4aa6ac55e04c42757443d5b5854b6d89…
commit: 3a4aa6ac55e04c42757443d5b5854b6d893e0461
branch: 3.6
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T04:37:33-07:00
summary:
bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in …
[View More]order to prevent timeouts from deviating when the system clock is adjusted.
This may not be sufficient on all systems. On POSIX for example, the actual waiting (e.g. in ``sem_timedwait``) is specified to rely on the CLOCK_REALTIME clock.
(cherry picked from commit a94ee12c26aa8dd7dce01373779df8055aff765b)
Co-authored-by: orlnub123 <orlnub123(a)gmail.com>
files:
A Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
M Lib/concurrent/futures/_base.py
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index 6bace6c74641..4c140508c9ea 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -212,7 +212,7 @@ def as_completed(fs, timeout=None):
before the given timeout.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = set(fs)
total_futures = len(fs)
@@ -231,7 +231,7 @@ def as_completed(fs, timeout=None):
if timeout is None:
wait_timeout = None
else:
- wait_timeout = end_time - time.time()
+ wait_timeout = end_time - time.monotonic()
if wait_timeout < 0:
raise TimeoutError(
'%d (of %d) futures unfinished' % (
@@ -570,7 +570,7 @@ def map(self, fn, *iterables, timeout=None, chunksize=1):
Exception: If fn(*args) raises for any values.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = [self.submit(fn, *args) for args in zip(*iterables)]
@@ -585,7 +585,7 @@ def result_iterator():
if timeout is None:
yield fs.pop().result()
else:
- yield fs.pop().result(end_time - time.time())
+ yield fs.pop().result(end_time - time.monotonic())
finally:
for future in fs:
future.cancel()
diff --git a/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
new file mode 100644
index 000000000000..6bbdea235f03
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
@@ -0,0 +1 @@
+Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in order to prevent timeouts from deviating when the system clock is adjusted.
[View Less]
1
0

bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
by Antoine Pitrou Sept. 27, 2018
by Antoine Pitrou Sept. 27, 2018
Sept. 27, 2018
https://github.com/python/cpython/commit/a94ee12c26aa8dd7dce01373779df8055a…
commit: a94ee12c26aa8dd7dce01373779df8055aff765b
branch: master
author: orlnub123 <orlnub123(a)gmail.com>
committer: Antoine Pitrou <pitrou(a)free.fr>
date: 2018-09-27T13:16:26+02:00
summary:
bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in order to prevent timeouts from …
[View More]deviating when the system clock is adjusted.
This may not be sufficient on all systems. On POSIX for example, the actual waiting (e.g. in ``sem_timedwait``) is specified to rely on the CLOCK_REALTIME clock.
files:
A Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
M Lib/concurrent/futures/_base.py
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index d4416c62450e..8b9dc507138e 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -216,7 +216,7 @@ def as_completed(fs, timeout=None):
before the given timeout.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = set(fs)
total_futures = len(fs)
@@ -235,7 +235,7 @@ def as_completed(fs, timeout=None):
if timeout is None:
wait_timeout = None
else:
- wait_timeout = end_time - time.time()
+ wait_timeout = end_time - time.monotonic()
if wait_timeout < 0:
raise TimeoutError(
'%d (of %d) futures unfinished' % (
@@ -578,7 +578,7 @@ def map(self, fn, *iterables, timeout=None, chunksize=1):
Exception: If fn(*args) raises for any values.
"""
if timeout is not None:
- end_time = timeout + time.time()
+ end_time = timeout + time.monotonic()
fs = [self.submit(fn, *args) for args in zip(*iterables)]
@@ -593,7 +593,7 @@ def result_iterator():
if timeout is None:
yield fs.pop().result()
else:
- yield fs.pop().result(end_time - time.time())
+ yield fs.pop().result(end_time - time.monotonic())
finally:
for future in fs:
future.cancel()
diff --git a/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
new file mode 100644
index 000000000000..6bbdea235f03
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-27-09-45-00.bpo-34819.9ZaFyO.rst
@@ -0,0 +1 @@
+Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in order to prevent timeouts from deviating when the system clock is adjusted.
[View Less]
1
0

Sept. 27, 2018
https://github.com/python/cpython/commit/7291108d88ea31d205da4db19d202d6cbf…
commit: 7291108d88ea31d205da4db19d202d6cbffc6d93
branch: master
author: Pablo Galindo <Pablogsal(a)gmail.com>
committer: GitHub <noreply(a)github.com>
date: 2018-09-27T10:25:03+01:00
summary:
Fix tests in test_socket to use correctly CMSG_LEN (GH-9594)
After some failures in AMD64 FreeBSD CURRENT Debug 3.x buildbots
regarding tests in test_socket that are using
testFDPassSeparateMinSpace(), FreeBDS …
[View More]revision 337423 was pointed
out to be the reason the test started to fail.
A close examination of the manpage for cmsg_space(3) reveals that
the number of file descriptors needs to be taken into account when
using CMSG_LEN().
This commit fixes tests in test_socket to use correctly CMSG_LEN, taking
into account the number of FDs.
files:
M Lib/test/test_socket.py
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index bbbf27b60978..663a018dcfda 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -3223,10 +3223,11 @@ def _testFDPassSeparate(self):
def testFDPassSeparateMinSpace(self):
# Pass two FDs in two separate arrays, receiving them into the
# minimum space for two arrays.
- self.checkRecvmsgFDs(2,
+ num_fds = 2
+ self.checkRecvmsgFDs(num_fds,
self.doRecvmsg(self.serv_sock, len(MSG),
socket.CMSG_SPACE(SIZEOF_INT) +
- socket.CMSG_LEN(SIZEOF_INT)),
+ socket.CMSG_LEN(SIZEOF_INT * num_fds)),
maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC)
@testFDPassSeparateMinSpace.client_skip
[View Less]
1
0