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:
Benjamin Peterson 2009-06-11 22:54:11 +00:00
parent 6520b685fd
commit 87c8d87b91
15 changed files with 118 additions and 73 deletions

View File

@ -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

View File

@ -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`.

View File

@ -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`.)
.. ======================================================================

View File

@ -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]

View File

@ -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):

View File

@ -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"):

View File

@ -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

View File

@ -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:

View File

@ -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 ############

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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 = {}

View File

@ -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)

View File

@ -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