]> granicus.if.org Git - python/commitdiff
Merged revisions 73196,73278-73280,73299,73308,73312-73313,73317-73318,73321,73324...
authorBenjamin Peterson <benjamin@python.org>
Thu, 11 Jun 2009 22:54:11 +0000 (22:54 +0000)
committerBenjamin Peterson <benjamin@python.org>
Thu, 11 Jun 2009 22:54:11 +0000 (22:54 +0000)
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
........

15 files changed:
Doc/library/os.rst
Doc/library/subprocess.rst
Doc/whatsnew/2.7.rst
Grammar/Grammar
Lib/multiprocessing/queues.py
Lib/os.py
Lib/symbol.py
Lib/test/test_generators.py
Lib/test/test_genexps.py
Lib/test/test_syntax.py
Makefile.pre.in
Objects/dictobject.c
Parser/asdl.py
Parser/asdl_c.py
Python/ast.c

index 9bb2fc627b552461e65128c0479f71175c9f153d..90e59ef5c244f1b067609242bed9b0b881018465 100644 (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
index 3318d430ec1ea2837ce4d4ab7a118030f1d71fec..d0e655d1e29e5f665aa6ecee7ab821a0cd75c7d6 100644 (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)
+   ==>
+   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"
    ==>
-   pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
+   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`.
index 9182c45349d7d38f40116d593d853b48b92b2704..f5f7d19839846fc25a387867d1be74ba076c955f 100644 (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`.)
 
 .. ======================================================================
 
index 1b196e5318293424a66f27e51c17f242494be65d..1f226b80b1f7df804b6f4a1622a0d53972e1060b 100644 (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]
index a3393d4585419539ad48dd8ac52d0ccd4142d5cd..bbaf6d5550fc9aeb051c636fe47aad5203cd8e97 100644 (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):
index 65f88ba1892b2142f920bcdefaff462b7ee52c5a..5dce0c1f24d6fa6d6886d674e37810b1f26fbe29 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -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"):
index 1b773d05de54f455ab247f5da8ccee8d2508d5a1..4b4c2198632d9a6299205f80daed783ca3ad6dae 100755 (executable)
@@ -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
index 9b4e3428affa6a02f72c4869b7924a17fdda54b0..84028e85386cd293c24d16f7588b852c51938564 100644 (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:
index 61e9fe5e70a195f46cfae1a425e3f5b9430a04da..1f46af13e3431b9c09d0bdf24a0bf65b3cf9562b 100644 (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 ############
index c82787e548601ef80dc216b6c6204ef0a138025c..c55171a7210b7df40b3dd0cba48794775639b3a6 100644 (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.
index 2f5ccccf30e9f2e6c8b5ecc352e4b383015d347e..41fc51eddc62eb6cb1b3a02205a8807f8d55502f 100644 (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
index f21cea24c3d6a8b1beb9ad640870e937727147e5..ce6760fdbd6820cfa86e9e17361958249e3ba565 100644 (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;
index ce9d0d37f5e9e3ef2ceba676918b740e079d8e61..28a7138797895d61389bcc011bf1b9ab346c84c1 100644 (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 = {}
index af0b349b495c85d08c2ad49888f0ce86a1c327b3..8ccb3ea0458a2373b4bc8a8601d960dd4badb928 100755 (executable)
@@ -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)
index ff412b3d98389b34826ed328e3263aa84501dc66..83572ee882150e97e1190a14ce4f26847ce04708 100644 (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