Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5215225

Browse files
committed
Apply SF patch #101135, adding 'import module as m' and 'from module import
name as n'. By doing some twists and turns, "as" is not a reserved word. There is a slight change in semantics for 'from module import name' (it will now honour the 'global' keyword) but only in cases that are explicitly undocumented.
1 parent 1d75a79 commit 5215225

12 files changed

Lines changed: 895 additions & 743 deletions

File tree

Doc/lib/libdis.tex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ \subsection{Python Byte Code Instructions}
301301
Returns with TOS to the caller of the function.
302302
\end{opcodedesc}
303303

304+
\begin{opcodedesc}{IMPORT_STAR}{}
305+
Loads all symbols not starting with '_' directly from the module TOS
306+
to the local namespace. The module is popped after loading all names.
307+
This opcode implements 'from module import *'.
308+
\begin{opcodedesc}
309+
304310
\begin{opcodedesc}{EXEC_STMT}{}
305311
Implements \code{exec TOS2,TOS1,TOS}. The compiler fills
306312
missing optional parameters with None.
@@ -411,8 +417,9 @@ \subsection{Python Byte Code Instructions}
411417
\end{opcodedesc}
412418

413419
\begin{opcodedesc}{IMPORT_FROM}{namei}
414-
Imports the attribute \code{co_names[\var{namei}]}. The module to import
415-
from is found in TOS and left there.
420+
Loads the attribute \code{co_names[\var{namei}]} from the module found in
421+
TOS. The resulting object is pushed onto the stack, to be subsequently
422+
stored by a \code{STORE_FAST} instruction.
416423
\end{opcodedesc}
417424

418425
\begin{opcodedesc}{JUMP_FORWARD}{delta}

Doc/ref/ref6.tex

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,9 @@ \section{The \keyword{import} statement \label{import}}
443443
\stindex{import}
444444

445445
\begin{verbatim}
446-
import_stmt: "import" module ("," module)*
447-
| "from" module "import" identifier ("," identifier)*
446+
import_stmt: "import" module ["as" name] ("," module ["as" name] )*
447+
| "from" module "import" identifier ["as" name]
448+
("," identifier ["as" name] )*
448449
| "from" module "import" "*"
449450
module: (identifier ".")* identifier
450451
\end{verbatim}
@@ -496,13 +497,16 @@ \section{The \keyword{import} statement \label{import}}
496497

497498
The first form of \keyword{import} statement binds the module name in the
498499
local namespace to the module object, and then goes on to import the
499-
next identifier, if any. The \keyword{from} form does not bind the
500-
module name: it goes through the list of identifiers, looks each one
501-
of them up in the module found in step (1), and binds the name in the
502-
local namespace to the object thus found. If a name is not found,
500+
next identifier, if any. If the module name is followed by \keyword{as},
501+
the name following \keyword{as} is used as the local name for the module.
502+
The \keyword{from} form does not bind the module name: it goes through the
503+
list of identifiers, looks each one of them up in the module found in step
504+
(1), and binds the name in the local namespace to the object thus found.
505+
Like with the first form of \keyword{import}, an alternate local name can be
506+
supplied by specifying "\keyword{as} localname". If a name is not found,
503507
\exception{ImportError} is raised. If the list of identifiers is replaced
504-
by a star (\samp{*}), all names defined in the module are bound,
505-
except those beginning with an underscore (\character{_}).
508+
by a star (\samp{*}), all names defined in the module are bound, except
509+
those beginning with an underscore (\character{_}).
506510
\indexii{name}{binding}
507511
\exindex{ImportError}
508512

Grammar/Grammar

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ break_stmt: 'break'
4141
continue_stmt: 'continue'
4242
return_stmt: 'return' [testlist]
4343
raise_stmt: 'raise' [test [',' test [',' test]]]
44-
import_stmt: 'import' dotted_name (',' dotted_name)* | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
44+
import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
45+
import_as_name: NAME [NAME NAME]
46+
dotted_as_name: dotted_name [NAME NAME]
4547
dotted_name: NAME ('.' NAME)*
4648
global_stmt: 'global' NAME (',' NAME)*
4749
#access_stmt: 'access' ('*' | NAME (',' NAME)*) ':' accesstype (',' accesstype)*

Include/graminit.h

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,45 @@
1919
#define return_stmt 274
2020
#define raise_stmt 275
2121
#define import_stmt 276
22-
#define dotted_name 277
23-
#define global_stmt 278
24-
#define exec_stmt 279
25-
#define assert_stmt 280
26-
#define compound_stmt 281
27-
#define if_stmt 282
28-
#define while_stmt 283
29-
#define for_stmt 284
30-
#define try_stmt 285
31-
#define except_clause 286
32-
#define suite 287
33-
#define test 288
34-
#define and_test 289
35-
#define not_test 290
36-
#define comparison 291
37-
#define comp_op 292
38-
#define expr 293
39-
#define xor_expr 294
40-
#define and_expr 295
41-
#define shift_expr 296
42-
#define arith_expr 297
43-
#define term 298
44-
#define factor 299
45-
#define power 300
46-
#define atom 301
47-
#define listmaker 302
48-
#define lambdef 303
49-
#define trailer 304
50-
#define subscriptlist 305
51-
#define subscript 306
52-
#define sliceop 307
53-
#define exprlist 308
54-
#define testlist 309
55-
#define dictmaker 310
56-
#define classdef 311
57-
#define arglist 312
58-
#define argument 313
59-
#define list_iter 314
60-
#define list_for 315
61-
#define list_if 316
22+
#define import_as_name 277
23+
#define dotted_as_name 278
24+
#define dotted_name 279
25+
#define global_stmt 280
26+
#define exec_stmt 281
27+
#define assert_stmt 282
28+
#define compound_stmt 283
29+
#define if_stmt 284
30+
#define while_stmt 285
31+
#define for_stmt 286
32+
#define try_stmt 287
33+
#define except_clause 288
34+
#define suite 289
35+
#define test 290
36+
#define and_test 291
37+
#define not_test 292
38+
#define comparison 293
39+
#define comp_op 294
40+
#define expr 295
41+
#define xor_expr 296
42+
#define and_expr 297
43+
#define shift_expr 298
44+
#define arith_expr 299
45+
#define term 300
46+
#define factor 301
47+
#define power 302
48+
#define atom 303
49+
#define listmaker 304
50+
#define lambdef 305
51+
#define trailer 306
52+
#define subscriptlist 307
53+
#define subscript 308
54+
#define sliceop 309
55+
#define exprlist 310
56+
#define testlist 311
57+
#define dictmaker 312
58+
#define classdef 313
59+
#define arglist 314
60+
#define argument 315
61+
#define list_iter 316
62+
#define list_for 317
63+
#define list_if 318

Include/opcode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
6565

6666
#define LOAD_LOCALS 82
6767
#define RETURN_VALUE 83
68-
68+
#define IMPORT_STAR 84
6969
#define EXEC_STMT 85
7070

7171
#define POP_BLOCK 87

Lib/dis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def jabs_op(name, op):
195195

196196
def_op('LOAD_LOCALS', 82)
197197
def_op('RETURN_VALUE', 83)
198-
198+
def_op('IMPORT_STAR', 84)
199199
def_op('EXEC_STMT', 85)
200200

201201
def_op('POP_BLOCK', 87)

Lib/test/output/test_pkg

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ t6.ham loading
3636
t6.eggs loading
3737
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__path__', 'eggs', 'ham', 'spam']
3838
['eggs', 'ham', 'spam', 't6']
39+
running test t7
40+
t7 loading
41+
['__builtins__', '__doc__', '__file__', '__name__', '__path__']
42+
['__builtins__', '__doc__', '__file__', '__name__', '__path__']
43+
t7.sub.subsub loading
44+
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'spam']
45+
t7.sub.subsub.spam = 1

Lib/test/test_pkg.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,33 @@ def runtest(hier, code):
164164
from t6 import *
165165
print dir(t6)
166166
print dir()
167+
"""),
168+
169+
("t7", [
170+
("t7.py", "print 'Importing t7.py'"),
171+
("t7", None),
172+
("t7 __init__.py", "print __name__, 'loading'"),
173+
("t7 sub.py", "print 'THIS SHOULD NOT BE PRINTED (sub.py)'"),
174+
("t7 sub", None),
175+
("t7 sub __init__.py", ""),
176+
("t7 sub subsub.py", "print 'THIS SHOULD NOT BE PRINTED (subsub.py)'"),
177+
("t7 sub subsub", None),
178+
("t7 sub subsub __init__.py", "print __name__, 'loading'; spam = 1"),
179+
],
180+
"""
181+
t7, sub, subsub = None, None, None
182+
import t7 as tas
183+
print dir(tas)
184+
assert not t7
185+
from t7 import sub as subpar
186+
print dir(subpar)
187+
assert not t7 and not sub
188+
from t7.sub import subsub as subsubsub
189+
print dir(subsubsub)
190+
assert not t7 and not sub and not subsub
191+
from t7.sub.subsub import spam as ham
192+
print "t7.sub.subsub.spam =", ham
193+
assert not t7 and not sub and not subsub
167194
"""),
168195

169196
]

Python/ceval.c

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
6666
static int assign_slice(PyObject *, PyObject *,
6767
PyObject *, PyObject *);
6868
static PyObject *cmp_outcome(int, PyObject *, PyObject *);
69-
static int import_from(PyObject *, PyObject *, PyObject *);
69+
static PyObject *import_from(PyObject *, PyObject *);
70+
static int import_all_from(PyObject *, PyObject *);
7071
static PyObject *build_class(PyObject *, PyObject *, PyObject *);
7172
static int exec_statement(PyFrameObject *,
7273
PyObject *, PyObject *, PyObject *);
@@ -1414,20 +1415,28 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
14141415
if (x != NULL) continue;
14151416
break;
14161417

1417-
case IMPORT_FROM:
1418-
w = GETNAMEV(oparg);
1419-
v = TOP();
1418+
case IMPORT_STAR:
1419+
v = POP();
14201420
PyFrame_FastToLocals(f);
14211421
if ((x = f->f_locals) == NULL) {
14221422
PyErr_SetString(PyExc_SystemError,
14231423
"no locals");
14241424
break;
14251425
}
1426-
err = import_from(x, v, w);
1426+
err = import_all_from(x, v);
14271427
PyFrame_LocalsToFast(f, 0);
1428+
Py_DECREF(v);
14281429
if (err == 0) continue;
14291430
break;
14301431

1432+
case IMPORT_FROM:
1433+
w = GETNAMEV(oparg);
1434+
v = TOP();
1435+
x = import_from(v, w);
1436+
PUSH(x);
1437+
if (x != NULL) continue;
1438+
break;
1439+
14311440
case JUMP_FORWARD:
14321441
JUMPBY(oparg);
14331442
continue;
@@ -2647,43 +2656,51 @@ cmp_outcome(int op, register PyObject *v, register PyObject *w)
26472656
return v;
26482657
}
26492658

2650-
static int
2651-
import_from(PyObject *locals, PyObject *v, PyObject *name)
2659+
static PyObject *
2660+
import_from(PyObject *v, PyObject *name)
26522661
{
26532662
PyObject *w, *x;
2663+
if (!PyModule_Check(v)) {
2664+
PyErr_SetString(PyExc_TypeError,
2665+
"import-from requires module object");
2666+
return NULL;
2667+
}
2668+
w = PyModule_GetDict(v); /* TDB: can this not fail ? */
2669+
x = PyDict_GetItem(w, name);
2670+
if (x == NULL) {
2671+
PyErr_Format(PyExc_ImportError,
2672+
"cannot import name %.230s",
2673+
PyString_AsString(name));
2674+
} else
2675+
Py_INCREF(x);
2676+
return x;
2677+
}
2678+
2679+
static int
2680+
import_all_from(PyObject *locals, PyObject *v)
2681+
{
2682+
int pos = 0, err;
2683+
PyObject *name, *value;
2684+
PyObject *w;
2685+
26542686
if (!PyModule_Check(v)) {
26552687
PyErr_SetString(PyExc_TypeError,
26562688
"import-from requires module object");
26572689
return -1;
26582690
}
2659-
w = PyModule_GetDict(v);
2660-
if (PyString_AsString(name)[0] == '*') {
2661-
int pos, err;
2662-
PyObject *name, *value;
2663-
pos = 0;
2664-
while (PyDict_Next(w, &pos, &name, &value)) {
2665-
if (!PyString_Check(name) ||
2666-
PyString_AsString(name)[0] == '_')
2691+
w = PyModule_GetDict(v); /* TBD: can this not fail ? */
2692+
2693+
while (PyDict_Next(w, &pos, &name, &value)) {
2694+
if (!PyString_Check(name) ||
2695+
PyString_AsString(name)[0] == '_')
26672696
continue;
2668-
Py_INCREF(value);
2669-
err = PyDict_SetItem(locals, name, value);
2670-
Py_DECREF(value);
2671-
if (err != 0)
2672-
return -1;
2673-
}
2674-
return 0;
2675-
}
2676-
else {
2677-
x = PyDict_GetItem(w, name);
2678-
if (x == NULL) {
2679-
PyErr_Format(PyExc_ImportError,
2680-
"cannot import name %.230s",
2681-
PyString_AsString(name));
2697+
Py_INCREF(value);
2698+
err = PyDict_SetItem(locals, name, value);
2699+
Py_DECREF(value);
2700+
if (err != 0)
26822701
return -1;
2683-
}
2684-
else
2685-
return PyDict_SetItem(locals, name, x);
26862702
}
2703+
return 0;
26872704
}
26882705

26892706
static PyObject *
@@ -2825,26 +2842,36 @@ find_from_args(PyFrameObject *f, int nexti)
28252842
next_instr += nexti;
28262843

28272844
opcode = (*next_instr++);
2828-
if (opcode != IMPORT_FROM) {
2845+
if (opcode != IMPORT_FROM && opcode != IMPORT_STAR) {
28292846
Py_INCREF(Py_None);
28302847
return Py_None;
28312848
}
28322849

28332850
list = PyList_New(0);
28342851
if (list == NULL)
28352852
return NULL;
2836-
2837-
do {
2838-
oparg = (next_instr[1]<<8) + next_instr[0];
2839-
next_instr += 2;
2840-
name = Getnamev(f, oparg);
2841-
if (PyList_Append(list, name) < 0) {
2853+
2854+
if (opcode == IMPORT_STAR) {
2855+
name = PyString_FromString("*");
2856+
if (!name)
28422857
Py_DECREF(list);
2843-
break;
2858+
else {
2859+
if (PyList_Append(list, name) < 0)
2860+
Py_DECREF(list);
2861+
Py_DECREF(name);
28442862
}
2845-
opcode = (*next_instr++);
2846-
} while (opcode == IMPORT_FROM);
2847-
2863+
} else {
2864+
do {
2865+
oparg = (next_instr[1]<<8) + next_instr[0];
2866+
next_instr += 2;
2867+
name = Getnamev(f, oparg);
2868+
if (PyList_Append(list, name) < 0) {
2869+
Py_DECREF(list);
2870+
break;
2871+
}
2872+
opcode = (*next_instr++);
2873+
} while (opcode == IMPORT_FROM);
2874+
}
28482875
return list;
28492876
}
28502877

0 commit comments

Comments
 (0)