Skip to content

Commit 52318d6

Browse files
committed
Patch #1550786: ellipsis literal.
1 parent 7cae87c commit 52318d6

File tree

19 files changed

+140
-141
lines changed

19 files changed

+140
-141
lines changed

Doc/lib/libconsts.tex

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ \section{Built-in Constants}
2626
\end{datadesc}
2727

2828
\begin{datadesc}{Ellipsis}
29-
Special value used in conjunction with extended slicing syntax.
29+
The same as \code{...}.
30+
Special value used mostly in conjunction with extended slicing syntax
31+
for user-defined container data types.
3032
% XXX Someone who understands extended slicing should fill in here.
3133
\end{datadesc}

Doc/lib/libstdtypes.tex

+2-2
Original file line numberDiff line numberDiff line change
@@ -2004,12 +2004,12 @@ \subsection{The Null Object \label{bltin-null-object}}
20042004

20052005
\subsection{The Ellipsis Object \label{bltin-ellipsis-object}}
20062006

2007-
This object is used by extended slice notation (see the
2007+
This object is mostly used by extended slice notation (see the
20082008
\citetitle[../ref/ref.html]{Python Reference Manual}). It supports no
20092009
special operations. There is exactly one ellipsis object, named
20102010
\constant{Ellipsis} (a built-in name).
20112011

2012-
It is written as \code{Ellipsis}.
2012+
It is written as \code{Ellipsis} or \code{...}.
20132013

20142014
\subsection{Boolean Values}
20152015

Doc/ref/ref3.tex

+2-3
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,8 @@ \section{The standard type hierarchy\label{types}}
148148

149149
\item[Ellipsis]
150150
This type has a single value. There is a single object with this value.
151-
This object is accessed through the built-in name \code{Ellipsis}.
152-
It is used to indicate the presence of the \samp{...} syntax in a
153-
slice. Its truth value is true.
151+
This object is accessed through the literal \code{...} or the
152+
built-in name \code{Ellipsis}. Its truth value is true.
154153
\obindex{Ellipsis}
155154

156155
\item[Numbers]

Doc/ref/ref5.tex

+1-2
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,7 @@ \subsection{Slicings\label{slicings}}
411411
contains at least one comma, the key is a tuple containing the
412412
conversion of the slice items; otherwise, the conversion of the lone
413413
slice item is the key. The conversion of a slice item that is an
414-
expression is that expression. The conversion of an ellipsis slice
415-
item is the built-in \code{Ellipsis} object. The conversion of a
414+
expression is that expression. The conversion of a
416415
proper slice is a slice object (see section \ref{types}) whose
417416
\member{start}, \member{stop} and \member{step} attributes are the
418417
values of the expressions given as lower bound, upper bound and

Grammar/Grammar

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ power: atom trailer* ['**' factor]
101101
atom: ('(' [yield_expr|testlist_gexp] ')' |
102102
'[' [listmaker] ']' |
103103
'{' [dictsetmaker] '}' |
104-
NAME | NUMBER | STRING+)
104+
NAME | NUMBER | STRING+ | '.' '.' '.')
105105
listmaker: test ( list_for | (',' test)* [','] )
106106
testlist_gexp: test ( gen_for | (',' test)* [','] )
107107
lambdef: 'lambda' [varargslist] ':' test
108108
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
109109
subscriptlist: subscript (',' subscript)* [',']
110-
subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
110+
subscript: test | [test] ':' [test] [sliceop]
111111
sliceop: ':' [test]
112112
exprlist: expr (',' expr)* [',']
113113
testlist: test (',' test)* [',']

Include/Python-ast.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ struct _stmt {
180180
enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
181181
IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8,
182182
GeneratorExp_kind=9, Yield_kind=10, Compare_kind=11,
183-
Call_kind=12, Num_kind=13, Str_kind=14, Attribute_kind=15,
184-
Subscript_kind=16, Name_kind=17, List_kind=18, Tuple_kind=19};
183+
Call_kind=12, Num_kind=13, Str_kind=14, Ellipsis_kind=15,
184+
Attribute_kind=16, Subscript_kind=17, Name_kind=18,
185+
List_kind=19, Tuple_kind=20};
185186
struct _expr {
186187
enum _expr_kind kind;
187188
union {
@@ -289,7 +290,7 @@ struct _expr {
289290
int col_offset;
290291
};
291292

292-
enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4};
293+
enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3};
293294
struct _slice {
294295
enum _slice_kind kind;
295296
union {
@@ -408,6 +409,7 @@ expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
408409
*arena);
409410
expr_ty Num(object n, int lineno, int col_offset, PyArena *arena);
410411
expr_ty Str(string s, int lineno, int col_offset, PyArena *arena);
412+
expr_ty Ellipsis(int lineno, int col_offset, PyArena *arena);
411413
expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
412414
lineno, int col_offset, PyArena *arena);
413415
expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
@@ -418,7 +420,6 @@ expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset,
418420
PyArena *arena);
419421
expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset,
420422
PyArena *arena);
421-
slice_ty Ellipsis(PyArena *arena);
422423
slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
423424
slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
424425
slice_ty Index(expr_ty value, PyArena *arena);

Lib/compiler/ast.py

-13
Original file line numberDiff line numberDiff line change
@@ -427,19 +427,6 @@ def getChildNodes(self):
427427
def __repr__(self):
428428
return "Div((%s, %s))" % (repr(self.left), repr(self.right))
429429

430-
class Ellipsis(Node):
431-
def __init__(self, lineno=None):
432-
self.lineno = lineno
433-
434-
def getChildren(self):
435-
return ()
436-
437-
def getChildNodes(self):
438-
return ()
439-
440-
def __repr__(self):
441-
return "Ellipsis()"
442-
443430
class FloorDiv(Node):
444431
def __init__(self, (left, right), lineno=None):
445432
self.left = left

Lib/compiler/pycodegen.py

-3
Original file line numberDiff line numberDiff line change
@@ -1214,9 +1214,6 @@ def visitBitxor(self, node):
12141214

12151215
# object constructors
12161216

1217-
def visitEllipsis(self, node):
1218-
self.emit('LOAD_CONST', Ellipsis)
1219-
12201217
def visitTuple(self, node):
12211218
self.set_lineno(node)
12221219
for elt in node.nodes:

Lib/compiler/transformer.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ def __init__(self):
113113
token.LBRACE: self.atom_lbrace,
114114
token.NUMBER: self.atom_number,
115115
token.STRING: self.atom_string,
116+
token.DOT: self.atom_ellipsis,
116117
token.NAME: self.atom_name,
117118
}
118119
self.encoding = None
@@ -747,6 +748,9 @@ def atom_string(self, nodelist):
747748
k += self.decode_literal(node[1])
748749
return Const(k, lineno=nodelist[0][2])
749750

751+
def atom_ellipsis(self, nodelist):
752+
return Const(Ellipsis, lineno=nodelist[0][2])
753+
750754
def atom_name(self, nodelist):
751755
return Name(nodelist[0][1], lineno=nodelist[0][2])
752756

@@ -1276,11 +1280,9 @@ def com_subscriptlist(self, primary, nodelist, assigning):
12761280
lineno=extractLineNo(nodelist))
12771281

12781282
def com_subscript(self, node):
1279-
# slice_item: expression | proper_slice | ellipsis
1283+
# slice_item: expression | proper_slice
12801284
ch = node[1]
12811285
t = ch[0]
1282-
if t == token.DOT and node[2][0] == token.DOT:
1283-
return Ellipsis()
12841286
if t == token.COLON or len(node) > 2:
12851287
return self.com_sliceobj(node)
12861288
return self.com_node(ch)

Lib/test/output/test_grammar

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test_grammar
77
1.1.2.2 Long integers
88
1.1.2.3 Floating point
99
1.1.3 String literals
10+
1.1.4 Ellipsis literal
1011
1.2 Grammar
1112
single_input
1213
file_input

Lib/test/test_grammar.py

+6
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@
125125
'; verify(x == y)
126126

127127

128+
print '1.1.4 Ellipsis literal'
129+
130+
x = ...
131+
verify(x == Ellipsis)
132+
133+
128134
print '1.2 Grammar'
129135

130136
print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE

Modules/parsermodule.c

+5
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,11 @@ validate_atom(node *tree)
23852385
for (pos = 1; res && (pos < nch); ++pos)
23862386
res = validate_ntype(CHILD(tree, pos), STRING);
23872387
break;
2388+
case DOT:
2389+
res = (nch == 3 &&
2390+
validate_ntype(CHILD(tree, 1), DOT) &&
2391+
validate_ntype(CHILD(tree, 2), DOT));
2392+
break;
23882393
default:
23892394
res = 0;
23902395
break;

Parser/Python.asdl

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ module Python version "$Revision$"
6363
expr? starargs, expr? kwargs)
6464
| Num(object n) -- a number as a PyObject.
6565
| Str(string s) -- need to specify raw, unicode, etc?
66+
| Ellipsis
6667
-- other literals? bools?
6768

6869
-- the following expression can appear in assignment context
@@ -77,7 +78,7 @@ module Python version "$Revision$"
7778

7879
expr_context = Load | Store | Del | AugLoad | AugStore | Param
7980

80-
slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step)
81+
slice = Slice(expr? lower, expr? upper, expr? step)
8182
| ExtSlice(slice* dims)
8283
| Index(expr value)
8384

Python/Python-ast.c

+24-22
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static PyTypeObject *Str_type;
212212
static char *Str_fields[]={
213213
"s",
214214
};
215+
static PyTypeObject *Ellipsis_type;
215216
static PyTypeObject *Attribute_type;
216217
static char *Attribute_fields[]={
217218
"value",
@@ -251,7 +252,6 @@ static PyTypeObject *AugStore_type;
251252
static PyTypeObject *Param_type;
252253
static PyTypeObject *slice_type;
253254
static PyObject* ast2obj_slice(void*);
254-
static PyTypeObject *Ellipsis_type;
255255
static PyTypeObject *Slice_type;
256256
static char *Slice_fields[]={
257257
"lower",
@@ -530,6 +530,8 @@ static int init_types(void)
530530
if (!Num_type) return 0;
531531
Str_type = make_type("Str", expr_type, Str_fields, 1);
532532
if (!Str_type) return 0;
533+
Ellipsis_type = make_type("Ellipsis", expr_type, NULL, 0);
534+
if (!Ellipsis_type) return 0;
533535
Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
534536
if (!Attribute_type) return 0;
535537
Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
@@ -570,8 +572,6 @@ static int init_types(void)
570572
slice_type = make_type("slice", AST_type, NULL, 0);
571573
if (!slice_type) return 0;
572574
if (!add_attributes(slice_type, NULL, 0)) return 0;
573-
Ellipsis_type = make_type("Ellipsis", slice_type, NULL, 0);
574-
if (!Ellipsis_type) return 0;
575575
Slice_type = make_type("Slice", slice_type, Slice_fields, 3);
576576
if (!Slice_type) return 0;
577577
ExtSlice_type = make_type("ExtSlice", slice_type, ExtSlice_fields, 1);
@@ -1578,6 +1578,21 @@ Str(string s, int lineno, int col_offset, PyArena *arena)
15781578
return p;
15791579
}
15801580

1581+
expr_ty
1582+
Ellipsis(int lineno, int col_offset, PyArena *arena)
1583+
{
1584+
expr_ty p;
1585+
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
1586+
if (!p) {
1587+
PyErr_NoMemory();
1588+
return NULL;
1589+
}
1590+
p->kind = Ellipsis_kind;
1591+
p->lineno = lineno;
1592+
p->col_offset = col_offset;
1593+
return p;
1594+
}
1595+
15811596
expr_ty
15821597
Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
15831598
col_offset, PyArena *arena)
@@ -1720,19 +1735,6 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
17201735
return p;
17211736
}
17221737

1723-
slice_ty
1724-
Ellipsis(PyArena *arena)
1725-
{
1726-
slice_ty p;
1727-
p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
1728-
if (!p) {
1729-
PyErr_NoMemory();
1730-
return NULL;
1731-
}
1732-
p->kind = Ellipsis_kind;
1733-
return p;
1734-
}
1735-
17361738
slice_ty
17371739
Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
17381740
{
@@ -2515,6 +2517,10 @@ ast2obj_expr(void* _o)
25152517
goto failed;
25162518
Py_DECREF(value);
25172519
break;
2520+
case Ellipsis_kind:
2521+
result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
2522+
if (!result) goto failed;
2523+
break;
25182524
case Attribute_kind:
25192525
result = PyType_GenericNew(Attribute_type, NULL, NULL);
25202526
if (!result) goto failed;
@@ -2648,10 +2654,6 @@ ast2obj_slice(void* _o)
26482654
}
26492655

26502656
switch (o->kind) {
2651-
case Ellipsis_kind:
2652-
result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
2653-
if (!result) goto failed;
2654-
break;
26552657
case Slice_kind:
26562658
result = PyType_GenericNew(Slice_type, NULL, NULL);
26572659
if (!result) goto failed;
@@ -3059,6 +3061,8 @@ init_ast(void)
30593061
if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return;
30603062
if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
30613063
if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
3064+
if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
3065+
return;
30623066
if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
30633067
0) return;
30643068
if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <
@@ -3077,8 +3081,6 @@ init_ast(void)
30773081
return;
30783082
if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return;
30793083
if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return;
3080-
if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
3081-
return;
30823084
if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return;
30833085
if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0)
30843086
return;

Python/ast.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
399399
case Str_kind:
400400
expr_name = "literal";
401401
break;
402+
case Ellipsis_kind:
403+
expr_name = "Ellipsis";
404+
break;
402405
case Compare_kind:
403406
expr_name = "comparison";
404407
break;
@@ -1213,6 +1216,9 @@ ast_for_atom(struct compiling *c, const node *n)
12131216
PyArena_AddPyObject(c->c_arena, pynum);
12141217
return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);
12151218
}
1219+
case DOT:
1220+
/* Ellipsis */
1221+
return Ellipsis(LINENO(n), n->n_col_offset, c->c_arena);
12161222
case LPAR: /* some parenthesized expressions */
12171223
ch = CHILD(n, 1);
12181224

@@ -1308,13 +1314,10 @@ ast_for_slice(struct compiling *c, const node *n)
13081314
REQ(n, subscript);
13091315

13101316
/*
1311-
subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
1317+
subscript: test | [test] ':' [test] [sliceop]
13121318
sliceop: ':' [test]
13131319
*/
13141320
ch = CHILD(n, 0);
1315-
if (TYPE(ch) == DOT)
1316-
return Ellipsis(c->c_arena);
1317-
13181321
if (NCH(n) == 1 && TYPE(ch) == test) {
13191322
/* 'step' variable hold no significance in terms of being used over
13201323
other vars */

0 commit comments

Comments
 (0)