Merged revisions 73196,73278-73280,73299,73308,73312-73313,73317-73318,73321,73324,73331,73335,73340,73363 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r73196 | benjamin.peterson | 2009-06-03 20:40:29 -0500 (Wed, 03 Jun 2009) | 1 line use the offical api ........ r73278 | benjamin.peterson | 2009-06-07 17:33:11 -0500 (Sun, 07 Jun 2009) | 1 line inherit from object ........ r73279 | benjamin.peterson | 2009-06-07 17:35:00 -0500 (Sun, 07 Jun 2009) | 1 line always inherit from an appropiate base class ........ r73280 | benjamin.peterson | 2009-06-07 17:54:35 -0500 (Sun, 07 Jun 2009) | 1 line use booleans for flags ........ r73299 | georg.brandl | 2009-06-08 13:41:36 -0500 (Mon, 08 Jun 2009) | 1 line Typo fix. ........ r73308 | benjamin.peterson | 2009-06-08 17:18:32 -0500 (Mon, 08 Jun 2009) | 1 line remove useless assertion ........ r73312 | benjamin.peterson | 2009-06-08 18:44:13 -0500 (Mon, 08 Jun 2009) | 1 line remove error checks already done in set_context() ........ r73313 | r.david.murray | 2009-06-08 19:44:22 -0500 (Mon, 08 Jun 2009) | 4 lines Issue 2947: document how return code handling translates from os.popen to subprocess. Also fixes reference link in the os.spawn documentation. ........ r73317 | benjamin.peterson | 2009-06-09 12:24:26 -0500 (Tue, 09 Jun 2009) | 1 line make ast.c depend on the grammar ........ r73318 | benjamin.peterson | 2009-06-09 12:29:51 -0500 (Tue, 09 Jun 2009) | 1 line explain why keyword names are not just NAME ........ r73321 | benjamin.peterson | 2009-06-09 16:13:43 -0500 (Tue, 09 Jun 2009) | 1 line update symbol.py from with statement changes ........ r73324 | amaury.forgeotdarc | 2009-06-09 17:53:16 -0500 (Tue, 09 Jun 2009) | 2 lines Avoid invoking the parser/compiler just to test the presence of a function. ........ r73331 | benjamin.peterson | 2009-06-10 08:45:31 -0500 (Wed, 10 Jun 2009) | 1 line fix spelling ........ r73335 | raymond.hettinger | 2009-06-10 11:15:40 -0500 (Wed, 10 Jun 2009) | 1 line Fix signed/unsigned compiler warning. ........ r73340 | amaury.forgeotdarc | 2009-06-10 15:30:19 -0500 (Wed, 10 Jun 2009) | 2 lines Fix a typo spotted by Nick Coghlan. ........ r73363 | benjamin.peterson | 2009-06-11 12:51:17 -0500 (Thu, 11 Jun 2009) | 1 line use multi-with syntax ........
This commit is contained in:
parent
6520b685fd
commit
87c8d87b91
|
@ -1470,8 +1470,8 @@ written in Python, such as a mail server's external command delivery program.
|
|||
|
||||
(Note that the :mod:`subprocess` module provides more powerful facilities for
|
||||
spawning new processes and retrieving their results; using that module is
|
||||
preferable to using these functions. Check specially the *Replacing Older
|
||||
Functions with the subprocess Module* section in that documentation page.)
|
||||
preferable to using these functions. Check especially the
|
||||
:ref:`subprocess-replacements` section.)
|
||||
|
||||
If *mode* is :const:`P_NOWAIT`, this function returns the process id of the new
|
||||
process; if *mode* is :const:`P_WAIT`, returns the process's exit code if it
|
||||
|
|
|
@ -412,8 +412,8 @@ Replacing shell pipeline
|
|||
output = p2.communicate()[0]
|
||||
|
||||
|
||||
Replacing os.system()
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Replacing :func:`os.system`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
|
@ -440,8 +440,8 @@ A more realistic example would look like this::
|
|||
print("Execution failed:", e, file=sys.stderr)
|
||||
|
||||
|
||||
Replacing the os.spawn family
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Replacing the :func:`os.spawn <os.spawnl>` family
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
P_NOWAIT example::
|
||||
|
||||
|
@ -468,17 +468,85 @@ Environment example::
|
|||
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
|
||||
|
||||
|
||||
Replacing os.popen
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Replacing :func:`os.popen`, :func:`os.popen2`, :func:`os.popen3`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
pipe = os.popen(cmd, 'r', bufsize)
|
||||
(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
|
||||
==>
|
||||
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
|
||||
p = Popen(cmd, shell=True, bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, close_fds=True)
|
||||
(child_stdin, child_stdout) = (p.stdin, p.stdout)
|
||||
|
||||
::
|
||||
|
||||
pipe = os.popen(cmd, 'w', bufsize)
|
||||
(child_stdin,
|
||||
child_stdout,
|
||||
child_stderr) = os.popen3(cmd, mode, bufsize)
|
||||
==>
|
||||
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
|
||||
p = Popen(cmd, shell=True, bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
|
||||
(child_stdin,
|
||||
child_stdout,
|
||||
child_stderr) = (p.stdin, p.stdout, p.stderr)
|
||||
|
||||
::
|
||||
|
||||
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
|
||||
==>
|
||||
p = Popen(cmd, shell=True, bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
|
||||
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
|
||||
|
||||
Return code handling translates as follows::
|
||||
|
||||
pipe = os.popen(cmd, 'w')
|
||||
...
|
||||
rc = pipe.close()
|
||||
if rc != None and rc % 256:
|
||||
print "There were some errors"
|
||||
==>
|
||||
process = Popen(cmd, 'w', stdin=PIPE)
|
||||
...
|
||||
process.stdin.close()
|
||||
if process.wait() != 0:
|
||||
print "There were some errors"
|
||||
|
||||
|
||||
Replacing functions from the :mod:`popen2` module
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
|
||||
If the cmd argument to popen2 functions is a string, the command is executed
|
||||
through /bin/sh. If it is a list, the command is directly executed.
|
||||
|
||||
::
|
||||
|
||||
(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
|
||||
==>
|
||||
p = Popen(["somestring"], shell=True, bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, close_fds=True)
|
||||
(child_stdout, child_stdin) = (p.stdout, p.stdin)
|
||||
|
||||
::
|
||||
|
||||
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
|
||||
==>
|
||||
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
|
||||
stdin=PIPE, stdout=PIPE, close_fds=True)
|
||||
(child_stdout, child_stdin) = (p.stdout, p.stdin)
|
||||
|
||||
:class:`popen2.Popen3` and :class:`popen2.Popen4` basically work as
|
||||
:class:`subprocess.Popen`, except that:
|
||||
|
||||
* :class:`Popen` raises an exception if the execution fails.
|
||||
|
||||
* the *capturestderr* argument is replaced with the *stderr* argument.
|
||||
|
||||
* ``stdin=PIPE`` and ``stdout=PIPE`` must be specified.
|
||||
|
||||
* popen2 closes all file descriptors by default, but you have to specify
|
||||
``close_fds=True`` with :class:`Popen`.
|
||||
|
|
|
@ -663,7 +663,11 @@ Porting to Python 2.7
|
|||
This section lists previously described changes and other bugfixes
|
||||
that may require changes to your code:
|
||||
|
||||
To be written.
|
||||
* Because of an optimization for the :keyword:`with` statement, the special
|
||||
methods :meth:`__enter__` and :meth:`__exit__` must belong to the object's
|
||||
type, and cannot be directly attached to the object's instance. This
|
||||
affects new-style classes (derived from :class:`object`) and C extension
|
||||
types. (:issue:`6101`.)
|
||||
|
||||
.. ======================================================================
|
||||
|
||||
|
|
|
@ -116,8 +116,9 @@ classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
|
|||
arglist: (argument ',')* (argument [',']
|
||||
|'*' test (',' argument)* [',' '**' test]
|
||||
|'**' test)
|
||||
# The reason that keywords are test nodes instead of NAME is that using NAME
|
||||
# results in an ambiguity. ast.c makes sure it's a NAME.
|
||||
argument: test [comp_for] | test '=' test # Really [keyword '='] test
|
||||
|
||||
comp_iter: comp_for | comp_if
|
||||
comp_for: 'for' exprlist 'in' or_test [comp_iter]
|
||||
comp_if: 'if' test_nocond [comp_iter]
|
||||
|
|
|
@ -109,7 +109,7 @@ class Queue(object):
|
|||
self._rlock.release()
|
||||
|
||||
def qsize(self):
|
||||
# Raises NotImplementError on Mac OSX because of broken sem_getvalue()
|
||||
# Raises NotImplementedError on Mac OSX because of broken sem_getvalue()
|
||||
return self._maxsize - self._sem._semlock._get_value()
|
||||
|
||||
def empty(self):
|
||||
|
|
|
@ -437,11 +437,7 @@ def getenv(key, default=None):
|
|||
__all__.append("getenv")
|
||||
|
||||
def _exists(name):
|
||||
try:
|
||||
eval(name)
|
||||
return True
|
||||
except NameError:
|
||||
return False
|
||||
return name in globals()
|
||||
|
||||
# Supply spawn*() (probably only for Unix)
|
||||
if _exists("fork") and not _exists("spawnv") and _exists("execv"):
|
||||
|
|
|
@ -52,7 +52,7 @@ while_stmt = 294
|
|||
for_stmt = 295
|
||||
try_stmt = 296
|
||||
with_stmt = 297
|
||||
with_var = 298
|
||||
with_item = 298
|
||||
except_clause = 299
|
||||
suite = 300
|
||||
test = 301
|
||||
|
|
|
@ -1584,7 +1584,7 @@ SyntaxError: can't assign to yield expression
|
|||
>>> def f(): (yield bar) += y
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: augmented assignment to yield expression not possible
|
||||
SyntaxError: can't assign to yield expression
|
||||
|
||||
|
||||
Now check some throw() conditions:
|
||||
|
|
|
@ -142,7 +142,7 @@ Verify that syntax error's are raised for genexps used as lvalues
|
|||
>>> (y for y in (1,2)) += 10
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: augmented assignment to generator expression not possible
|
||||
SyntaxError: can't assign to generator expression
|
||||
|
||||
|
||||
########### Tests borrowed from or inspired by test_generators.py ############
|
||||
|
|
|
@ -222,17 +222,17 @@ Traceback (most recent call last):
|
|||
SyntaxError: keyword can't be an expression
|
||||
|
||||
|
||||
From ast_for_expr_stmt():
|
||||
More set_context():
|
||||
|
||||
>>> (x for x in x) += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: augmented assignment to generator expression not possible
|
||||
SyntaxError: can't assign to generator expression
|
||||
>>> None += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: assignment to keyword
|
||||
>>> f() += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: illegal expression for augmented assignment
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
|
||||
Test continue in finally in weird combinations.
|
||||
|
|
|
@ -562,7 +562,7 @@ $(AST_H): $(AST_ASDL) $(ASDLGEN_FILES)
|
|||
$(AST_C): $(AST_ASDL) $(ASDLGEN_FILES)
|
||||
$(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL)
|
||||
|
||||
Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H)
|
||||
Python/compile.o Python/symtable.o Python/ast.o: $(GRAMMAR_H) $(AST_H)
|
||||
|
||||
Python/getplatform.o: $(srcdir)/Python/getplatform.c
|
||||
$(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
|
||||
|
|
|
@ -717,7 +717,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
|
|||
/* We can arrive here with a NULL tstate during initialization:
|
||||
try running "python -Wi" for an example related to string
|
||||
interning. Let's just hope that no exception occurs then... */
|
||||
tstate = _PyThreadState_Current;
|
||||
tstate = PyThreadState_GET();
|
||||
if (tstate != NULL && tstate->curexc_type != NULL) {
|
||||
/* preserve the existing exception */
|
||||
PyObject *err_type, *err_value, *err_tb;
|
||||
|
|
|
@ -20,7 +20,7 @@ def output(string):
|
|||
sys.stdout.write(string + "\n")
|
||||
|
||||
|
||||
class Token:
|
||||
class Token(object):
|
||||
# spark seems to dispatch in the parser based on a token's
|
||||
# type attribute
|
||||
def __init__(self, type, lineno):
|
||||
|
@ -221,20 +221,20 @@ class ASDLParser(spark.GenericParser, object):
|
|||
def p_field_2(self, info):
|
||||
" field ::= Id * Id "
|
||||
type, _, name = info
|
||||
return Field(type, name, seq=1)
|
||||
return Field(type, name, seq=True)
|
||||
|
||||
def p_field_3(self, info):
|
||||
" field ::= Id ? Id "
|
||||
type, _, name = info
|
||||
return Field(type, name, opt=1)
|
||||
return Field(type, name, opt=True)
|
||||
|
||||
def p_field_4(self, type_):
|
||||
" field ::= Id * "
|
||||
return Field(type_[0], seq=1)
|
||||
return Field(type_[0], seq=True)
|
||||
|
||||
def p_field_5(self, type_):
|
||||
" field ::= Id ? "
|
||||
return Field(type[0], opt=1)
|
||||
return Field(type[0], opt=True)
|
||||
|
||||
builtin_types = ("identifier", "string", "int", "bool", "object")
|
||||
|
||||
|
@ -242,7 +242,7 @@ builtin_types = ("identifier", "string", "int", "bool", "object")
|
|||
# not sure if any of the methods are useful yet, but I'm adding them
|
||||
# piecemeal as they seem helpful
|
||||
|
||||
class AST:
|
||||
class AST(object):
|
||||
pass # a marker class
|
||||
|
||||
class Module(AST):
|
||||
|
@ -274,7 +274,7 @@ class Constructor(AST):
|
|||
return "Constructor(%s, %s)" % (self.name, self.fields)
|
||||
|
||||
class Field(AST):
|
||||
def __init__(self, type, name=None, seq=0, opt=0):
|
||||
def __init__(self, type, name=None, seq=False, opt=False):
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.seq = seq
|
||||
|
@ -282,9 +282,9 @@ class Field(AST):
|
|||
|
||||
def __repr__(self):
|
||||
if self.seq:
|
||||
extra = ", seq=1"
|
||||
extra = ", seq=True"
|
||||
elif self.opt:
|
||||
extra = ", opt=1"
|
||||
extra = ", opt=True"
|
||||
else:
|
||||
extra = ""
|
||||
if self.name is None:
|
||||
|
@ -312,7 +312,7 @@ class Product(AST):
|
|||
|
||||
class VisitorBase(object):
|
||||
|
||||
def __init__(self, skip=0):
|
||||
def __init__(self, skip=False):
|
||||
self.cache = {}
|
||||
self.skip = skip
|
||||
|
||||
|
@ -347,7 +347,7 @@ class VisitorBase(object):
|
|||
class Check(VisitorBase):
|
||||
|
||||
def __init__(self):
|
||||
super(Check, self).__init__(skip=1)
|
||||
super(Check, self).__init__(skip=True)
|
||||
self.cons = {}
|
||||
self.errors = 0
|
||||
self.types = {}
|
||||
|
|
|
@ -86,7 +86,7 @@ class EmitVisitor(asdl.VisitorBase):
|
|||
self.file = file
|
||||
super(EmitVisitor, self).__init__()
|
||||
|
||||
def emit(self, s, depth, reflow=1):
|
||||
def emit(self, s, depth, reflow=True):
|
||||
# XXX reflow long lines?
|
||||
if reflow:
|
||||
lines = reflow_lines(s, depth)
|
||||
|
@ -255,7 +255,7 @@ class PrototypeVisitor(EmitVisitor):
|
|||
ctype = get_c_type(type)
|
||||
self.emit_function(cons.name, ctype, args, attrs)
|
||||
|
||||
def emit_function(self, name, ctype, args, attrs, union=1):
|
||||
def emit_function(self, name, ctype, args, attrs, union=True):
|
||||
args = args + attrs
|
||||
if args:
|
||||
argstr = ", ".join(["%s %s" % (atype, aname)
|
||||
|
@ -267,19 +267,19 @@ class PrototypeVisitor(EmitVisitor):
|
|||
for i in range(1, len(args)+1):
|
||||
margs += ", a%d" % i
|
||||
self.emit("#define %s(%s) _Py_%s(%s)" % (name, margs, name, margs), 0,
|
||||
reflow = 0)
|
||||
self.emit("%s _Py_%s(%s);" % (ctype, name, argstr), 0)
|
||||
reflow=False)
|
||||
self.emit("%s _Py_%s(%s);" % (ctype, name, argstr), False)
|
||||
|
||||
def visitProduct(self, prod, name):
|
||||
self.emit_function(name, get_c_type(name),
|
||||
self.get_args(prod.fields), [], union=0)
|
||||
self.get_args(prod.fields), [], union=False)
|
||||
|
||||
|
||||
class FunctionVisitor(PrototypeVisitor):
|
||||
"""Visitor to generate constructor functions for AST."""
|
||||
|
||||
def emit_function(self, name, ctype, args, attrs, union=1):
|
||||
def emit(s, depth=0, reflow=1):
|
||||
def emit_function(self, name, ctype, args, attrs, union=True):
|
||||
def emit(s, depth=0, reflow=True):
|
||||
self.emit(s, depth, reflow)
|
||||
argstr = ", ".join(["%s %s" % (atype, aname)
|
||||
for atype, aname, opt in args + attrs])
|
||||
|
@ -297,7 +297,7 @@ class FunctionVisitor(PrototypeVisitor):
|
|||
emit("PyErr_SetString(PyExc_ValueError,", 2)
|
||||
msg = "field %s is required for %s" % (argname, name)
|
||||
emit(' "%s");' % msg,
|
||||
2, reflow=0)
|
||||
2, reflow=False)
|
||||
emit('return NULL;', 2)
|
||||
emit('}', 1)
|
||||
|
||||
|
@ -313,7 +313,7 @@ class FunctionVisitor(PrototypeVisitor):
|
|||
emit("")
|
||||
|
||||
def emit_body_union(self, name, args, attrs):
|
||||
def emit(s, depth=0, reflow=1):
|
||||
def emit(s, depth=0, reflow=True):
|
||||
self.emit(s, depth, reflow)
|
||||
emit("p->kind = %s_kind;" % name, 1)
|
||||
for argtype, argname, opt in args:
|
||||
|
@ -322,7 +322,7 @@ class FunctionVisitor(PrototypeVisitor):
|
|||
emit("p->%s = %s;" % (argname, argname), 1)
|
||||
|
||||
def emit_body_struct(self, name, args, attrs):
|
||||
def emit(s, depth=0, reflow=1):
|
||||
def emit(s, depth=0, reflow=True):
|
||||
self.emit(s, depth, reflow)
|
||||
for argtype, argname, opt in args:
|
||||
emit("p->%s = %s;" % (argname, argname), 1)
|
||||
|
|
24
Python/ast.c
24
Python/ast.c
|
@ -2103,29 +2103,6 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
|||
expr1 = ast_for_testlist(c, ch);
|
||||
if (!expr1)
|
||||
return NULL;
|
||||
/* TODO(nas): Remove duplicated error checks (set_context does it) */
|
||||
switch (expr1->kind) {
|
||||
case GeneratorExp_kind:
|
||||
ast_error(ch, "augmented assignment to generator "
|
||||
"expression not possible");
|
||||
return NULL;
|
||||
case Yield_kind:
|
||||
ast_error(ch, "augmented assignment to yield "
|
||||
"expression not possible");
|
||||
return NULL;
|
||||
case Name_kind: {
|
||||
if (forbidden_name(expr1, ch))
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
case Attribute_kind:
|
||||
case Subscript_kind:
|
||||
break;
|
||||
default:
|
||||
ast_error(ch, "illegal expression for augmented "
|
||||
"assignment");
|
||||
return NULL;
|
||||
}
|
||||
if(!set_context(c, expr1, Store, ch))
|
||||
return NULL;
|
||||
|
||||
|
@ -3086,7 +3063,6 @@ ast_for_stmt(struct compiling *c, const node *n)
|
|||
n = CHILD(n, 0);
|
||||
}
|
||||
if (TYPE(n) == small_stmt) {
|
||||
REQ(n, small_stmt);
|
||||
n = CHILD(n, 0);
|
||||
/* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt
|
||||
| import_stmt | global_stmt | nonlocal_stmt | assert_stmt
|
||||
|
|
Loading…
Reference in New Issue