Merged revisions 55328-55341 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/p3yk

........
  r55329 | brett.cannon | 2007-05-14 16:36:56 -0700 (Mon, 14 May 2007) | 3 lines

  Implement the removal of tuple parameter unpacking (PEP 3113).
  Thanks, Tony Lownds for the patch.
........
  r55331 | neal.norwitz | 2007-05-14 16:40:30 -0700 (Mon, 14 May 2007) | 1 line

  Update to use Python 3.0
........
  r55332 | brett.cannon | 2007-05-14 16:47:18 -0700 (Mon, 14 May 2007) | 2 lines

  Mention PEP 3113.  And thanks to Tony Lownds for the PEP 3113 patch.
........
  r55333 | neal.norwitz | 2007-05-14 16:57:06 -0700 (Mon, 14 May 2007) | 1 line

  Fix exception printing (no more exceptions module)
........
  r55334 | neal.norwitz | 2007-05-14 17:11:10 -0700 (Mon, 14 May 2007) | 1 line

  Remove popen* functions from os
........
  r55335 | neal.norwitz | 2007-05-14 18:03:38 -0700 (Mon, 14 May 2007) | 1 line

  Get rid of most of popen.  There are still some uses I need to cleanup.
........
  r55336 | neal.norwitz | 2007-05-14 21:11:34 -0700 (Mon, 14 May 2007) | 1 line

  Remove a few more remnants of the compiler package
........
  r55337 | neal.norwitz | 2007-05-14 22:28:27 -0700 (Mon, 14 May 2007) | 1 line

  Get test_[cx]pickle working on 64-bit platforms (avoid overflow int/long)
........
This commit is contained in:
Guido van Rossum 2007-05-15 18:46:22 +00:00
parent 360e4b8fb1
commit 1bc535dc78
64 changed files with 1614 additions and 2842 deletions

View File

@ -270,7 +270,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
lib/libimaplib.tex \ lib/libimaplib.tex \
lib/libpoplib.tex \ lib/libpoplib.tex \
lib/libcalendar.tex \ lib/libcalendar.tex \
lib/libpopen2.tex \
lib/libbisect.tex \ lib/libbisect.tex \
lib/libcollections.tex \ lib/libcollections.tex \
lib/libheapq.tex \ lib/libheapq.tex \

View File

@ -280,7 +280,6 @@ and how to embed it in other applications.
\input{libsubprocess} \input{libsubprocess}
\input{libsocket} \input{libsocket}
\input{libsignal} \input{libsignal}
\input{libpopen2}
\input{libasyncore} \input{libasyncore}
\input{libasynchat} \input{libasynchat}

View File

@ -459,7 +459,7 @@ Mark
# is differencing with a range so that consecutive numbers all appear in # is differencing with a range so that consecutive numbers all appear in
# same group. # same group.
>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):
... print map(operator.itemgetter(1), g) ... print map(operator.itemgetter(1), g)
... ...
[1] [1]

View File

@ -378,68 +378,6 @@ deleted once there are no file descriptors for the file.
Availability: Macintosh, \UNIX, Windows. Availability: Macintosh, \UNIX, Windows.
\end{funcdesc} \end{funcdesc}
There are a number of different \function{popen*()} functions that
provide slightly different ways to create subprocesses.
\deprecated{2.6}{All of the \function{popen*()} functions are obsolete.
Use the \module{subprocess} module.}
For each of the \function{popen*()} variants, if \var{bufsize} is
specified, it specifies the buffer size for the I/O pipes.
\var{mode}, if provided, should be the string \code{'b'} or
\code{'t'}; on Windows this is needed to determine whether the file
objects should be opened in binary or text mode. The default value
for \var{mode} is \code{'t'}.
Also, for each of these variants, on \UNIX, \var{cmd} may be a sequence, in
which case arguments will be passed directly to the program without shell
intervention (as with \function{os.spawnv()}). If \var{cmd} is a string it will
be passed to the shell (as with \function{os.system()}).
These methods do not make it possible to retrieve the exit status from
the child processes. The only way to control the input and output
streams and also retrieve the return codes is to use the
\refmodule{subprocess} module; these are only available on \UNIX.
For a discussion of possible deadlock conditions related to the use
of these functions, see ``\ulink{Flow Control
Issues}{popen2-flow-control.html}''
(section~\ref{popen2-flow-control}).
\begin{funcdesc}{popen2}{cmd\optional{, mode\optional{, bufsize}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdin}, \var{child_stdout})}.
\deprecated{2.6}{All of the \function{popen*()} functions are obsolete.
Use the \module{subprocess} module.}
Availability: Macintosh, \UNIX, Windows.
\versionadded{2.0}
\end{funcdesc}
\begin{funcdesc}{popen3}{cmd\optional{, mode\optional{, bufsize}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdin}, \var{child_stdout}, \var{child_stderr})}.
\deprecated{2.6}{All of the \function{popen*()} functions are obsolete.
Use the \module{subprocess} module.}
Availability: Macintosh, \UNIX, Windows.
\versionadded{2.0}
\end{funcdesc}
\begin{funcdesc}{popen4}{cmd\optional{, mode\optional{, bufsize}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdin}, \var{child_stdout_and_stderr})}.
\deprecated{2.6}{All of the \function{popen*()} functions are obsolete.
Use the \module{subprocess} module.}
Availability: Macintosh, \UNIX, Windows.
\versionadded{2.0}
\end{funcdesc}
(Note that \code{\var{child_stdin}, \var{child_stdout}, and
\var{child_stderr}} are named from the point of view of the child
process, so \var{child_stdin} is the child's standard input.)
This functionality is also available in the \refmodule{popen2} module
using functions of the same names, but the return values of those
functions have a different order.
\subsection{File Descriptor Operations \label{os-fd-ops}} \subsection{File Descriptor Operations \label{os-fd-ops}}
@ -1575,9 +1513,6 @@ Availability: Macintosh, \UNIX.
\end{funcdesc} \end{funcdesc}
\begin{funcdescni}{popen}{\unspecified} \begin{funcdescni}{popen}{\unspecified}
\funclineni{popen2}{\unspecified}
\funclineni{popen3}{\unspecified}
\funclineni{popen4}{\unspecified}
Run child processes, returning opened pipes for communications. These Run child processes, returning opened pipes for communications. These
functions are described in section \ref{os-newstreams}. functions are described in section \ref{os-newstreams}.
\end{funcdescni} \end{funcdescni}

View File

@ -1,190 +0,0 @@
\section{\module{popen2} ---
Subprocesses with accessible I/O streams}
\declaremodule{standard}{popen2}
\modulesynopsis{Subprocesses with accessible standard I/O streams.}
\sectionauthor{Drew Csillag}{drew_csillag@geocities.com}
\deprecated{2.6}{This module is obsolete. Use the \module{subprocess} module.}
This module allows you to spawn processes and connect to their
input/output/error pipes and obtain their return codes under
\UNIX{} and Windows.
The \module{subprocess} module provides more powerful facilities for
spawning new processes and retrieving their results. Using the
\module{subprocess} module is preferable to using the \module{popen2}
module.
The primary interface offered by this module is a trio of factory
functions. For each of these, if \var{bufsize} is specified,
it specifies the buffer size for the I/O pipes. \var{mode}, if
provided, should be the string \code{'b'} or \code{'t'}; on Windows
this is needed to determine whether the file objects should be opened
in binary or text mode. The default value for \var{mode} is
\code{'t'}.
On \UNIX, \var{cmd} may be a sequence, in which case arguments will be passed
directly to the program without shell intervention (as with
\function{os.spawnv()}). If \var{cmd} is a string it will be passed to the
shell (as with \function{os.system()}).
The only way to retrieve the return codes for the child processes is
by using the \method{poll()} or \method{wait()} methods on the
\class{Popen3} and \class{Popen4} classes; these are only available on
\UNIX. This information is not available when using the
\function{popen2()}, \function{popen3()}, and \function{popen4()}
functions, or the equivalent functions in the \refmodule{os} module.
(Note that the tuples returned by the \refmodule{os} module's functions
are in a different order from the ones returned by the \module{popen2}
module.)
\begin{funcdesc}{popen2}{cmd\optional{, bufsize\optional{, mode}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdout}, \var{child_stdin})}.
\end{funcdesc}
\begin{funcdesc}{popen3}{cmd\optional{, bufsize\optional{, mode}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdout}, \var{child_stdin}, \var{child_stderr})}.
\end{funcdesc}
\begin{funcdesc}{popen4}{cmd\optional{, bufsize\optional{, mode}}}
Executes \var{cmd} as a sub-process. Returns the file objects
\code{(\var{child_stdout_and_stderr}, \var{child_stdin})}.
\versionadded{2.0}
\end{funcdesc}
On \UNIX, a class defining the objects returned by the factory
functions is also available. These are not used for the Windows
implementation, and are not available on that platform.
\begin{classdesc}{Popen3}{cmd\optional{, capturestderr\optional{, bufsize}}}
This class represents a child process. Normally, \class{Popen3}
instances are created using the \function{popen2()} and
\function{popen3()} factory functions described above.
If not using one of the helper functions to create \class{Popen3}
objects, the parameter \var{cmd} is the shell command to execute in a
sub-process. The \var{capturestderr} flag, if true, specifies that
the object should capture standard error output of the child process.
The default is false. If the \var{bufsize} parameter is specified, it
specifies the size of the I/O buffers to/from the child process.
\end{classdesc}
\begin{classdesc}{Popen4}{cmd\optional{, bufsize}}
Similar to \class{Popen3}, but always captures standard error into the
same file object as standard output. These are typically created
using \function{popen4()}.
\versionadded{2.0}
\end{classdesc}
\subsection{Popen3 and Popen4 Objects \label{popen3-objects}}
Instances of the \class{Popen3} and \class{Popen4} classes have the
following methods:
\begin{methoddesc}[Popen3]{poll}{}
Returns \code{-1} if child process hasn't completed yet, or its return
code otherwise.
\end{methoddesc}
\begin{methoddesc}[Popen3]{wait}{}
Waits for and returns the status code of the child process. The
status code encodes both the return code of the process and
information about whether it exited using the \cfunction{exit()}
system call or died due to a signal. Functions to help interpret the
status code are defined in the \refmodule{os} module; see section
\ref{os-process} for the \function{W\var{*}()} family of functions.
\end{methoddesc}
The following attributes are also available:
\begin{memberdesc}[Popen3]{fromchild}
A file object that provides output from the child process. For
\class{Popen4} instances, this will provide both the standard output
and standard error streams.
\end{memberdesc}
\begin{memberdesc}[Popen3]{tochild}
A file object that provides input to the child process.
\end{memberdesc}
\begin{memberdesc}[Popen3]{childerr}
A file object that provides error output from the child process, if
\var{capturestderr} was true for the constructor, otherwise
\code{None}. This will always be \code{None} for \class{Popen4}
instances.
\end{memberdesc}
\begin{memberdesc}[Popen3]{pid}
The process ID of the child process.
\end{memberdesc}
\subsection{Flow Control Issues \label{popen2-flow-control}}
Any time you are working with any form of inter-process communication,
control flow needs to be carefully thought out. This remains the case
with the file objects provided by this module (or the \refmodule{os}
module equivalents).
% Example explanation and suggested work-arounds substantially stolen
% from Martin von Löwis:
% http://mail.python.org/pipermail/python-dev/2000-September/009460.html
When reading output from a child process that writes a lot of data to
standard error while the parent is reading from the child's standard
output, a deadlock can occur. A similar situation can occur with other
combinations of reads and writes. The essential factors are that more
than \constant{_PC_PIPE_BUF} bytes are being written by one process in
a blocking fashion, while the other process is reading from the other
process, also in a blocking fashion.
There are several ways to deal with this situation.
The simplest application change, in many cases, will be to follow this
model in the parent process:
\begin{verbatim}
import popen2
r, w, e = popen2.popen3('python slave.py')
e.readlines()
r.readlines()
r.close()
e.close()
w.close()
\end{verbatim}
with code like this in the child:
\begin{verbatim}
import os
import sys
# note that each of these print statements
# writes a single long string
print >>sys.stderr, 400 * 'this is a test\n'
os.close(sys.stderr.fileno())
print >>sys.stdout, 400 * 'this is another test\n'
\end{verbatim}
In particular, note that \code{sys.stderr} must be closed after
writing all data, or \method{readlines()} won't return. Also note
that \function{os.close()} must be used, as \code{sys.stderr.close()}
won't close \code{stderr} (otherwise assigning to \code{sys.stderr}
will silently close it, so no further errors can be printed).
Applications which need to support a more general approach should
integrate I/O over pipes with their \function{select()} loops, or use
separate threads to read each of the individual files provided by
whichever \function{popen*()} function or \class{Popen*} class was
used.
\begin{seealso}
\seemodule{subprocess}{Module for spawning and managing subprocesses.}
\end{seealso}

View File

@ -15,8 +15,6 @@ and functions, such as:
\begin{verbatim} \begin{verbatim}
os.system os.system
os.spawn* os.spawn*
os.popen*
popen2.*
commands.* commands.*
\end{verbatim} \end{verbatim}
@ -335,68 +333,3 @@ pipe = os.popen(cmd, mode='w', bufsize)
==> ==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
\end{verbatim} \end{verbatim}
\begin{verbatim}
(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
\end{verbatim}
\begin{verbatim}
(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)
\end{verbatim}
\begin{verbatim}
(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)
\end{verbatim}
\subsubsection{Replacing popen2.*}
\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.}
\begin{verbatim}
(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)
\end{verbatim}
\begin{verbatim}
(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)
\end{verbatim}
The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen,
except that:
\begin{itemize}
\item subprocess.Popen raises an exception if the execution fails
\item the \var{capturestderr} argument is replaced with the \var{stderr}
argument.
\item stdin=PIPE and stdout=PIPE must be specified.
\item popen2 closes all file descriptors by default, but you have to
specify close_fds=True with subprocess.Popen.
\end{itemize}

View File

@ -498,8 +498,9 @@ Special attributes:
\lineiii{__closure__}{\code{None} or a tuple of cells that contain \lineiii{__closure__}{\code{None} or a tuple of cells that contain
bindings for the function's free variables.}{Read-only} bindings for the function's free variables.}{Read-only}
\lineiii{__annotations__}{A dict containing annotations of parameters.} \lineiii{__annotations__}{A dict containing annotations of parameters.
{Writable} The keys of the dict are the parameter names, or \code{'return'}
for the return annotation, if provided.}{Writable}
\lineiii{__kwdefaults__}{A dict containing defaults for keyword-only \lineiii{__kwdefaults__}{A dict containing defaults for keyword-only
parameters.}{Writable} parameters.}{Writable}

View File

@ -668,11 +668,7 @@ raised.
Formal parameters using the syntax \samp{*identifier} or Formal parameters using the syntax \samp{*identifier} or
\samp{**identifier} cannot be used as positional argument slots or \samp{**identifier} cannot be used as positional argument slots or
as keyword argument names. Formal parameters using the syntax as keyword argument names.
\samp{(sublist)} cannot be used as keyword argument names; the
outermost sublist corresponds to a single unnamed argument slot, and
the argument value is assigned to the sublist using the usual tuple
assignment rules after all other parameter processing is done.
A call always returns some value, possibly \code{None}, unless it A call always returns some value, possibly \code{None}, unless it
raises an exception. How this value is computed depends on the type raises an exception. How this value is computed depends on the type
@ -1177,7 +1173,8 @@ def name(arguments):
\end{verbatim} \end{verbatim}
See section \ref{function} for the syntax of parameter lists. Note See section \ref{function} for the syntax of parameter lists. Note
that functions created with lambda forms cannot contain statements. that functions created with lambda forms cannot contain statements
or annotations.
\label{lambda} \label{lambda}
\section{Expression lists\label{exprlists}} \section{Expression lists\label{exprlists}}

View File

@ -381,6 +381,7 @@ section~\ref{types}):
\begin{productionlist} \begin{productionlist}
\production{funcdef} \production{funcdef}
{[\token{decorators}] "def" \token{funcname} "(" [\token{parameter_list}] ")" {[\token{decorators}] "def" \token{funcname} "(" [\token{parameter_list}] ")"
["->" \token{expression}]?
":" \token{suite}} ":" \token{suite}}
\production{decorators} \production{decorators}
{\token{decorator}+} {\token{decorator}+}
@ -390,15 +391,14 @@ section~\ref{types}):
{\token{identifier} ("." \token{identifier})*} {\token{identifier} ("." \token{identifier})*}
\production{parameter_list} \production{parameter_list}
{(\token{defparameter} ",")*} {(\token{defparameter} ",")*}
\productioncont{(~~"*" \token{identifier} [, "**" \token{identifier}]} \productioncont{(~~"*" [\token{parameter}] ("," \token{defparameter})*}
\productioncont{ | "**" \token{identifier}} \productioncont{ [, "**" \token{parameter}]}
\productioncont{ | "**" \token{parameter}}
\productioncont{ | \token{defparameter} [","] )} \productioncont{ | \token{defparameter} [","] )}
\production{parameter}
{\token{identifier} [":" \token{expression}]}
\production{defparameter} \production{defparameter}
{\token{parameter} ["=" \token{expression}]} {\token{parameter} ["=" \token{expression}]}
\production{sublist}
{\token{parameter} ("," \token{parameter})* [","]}
\production{parameter}
{\token{identifier} | "(" \token{sublist} ")"}
\production{funcname} \production{funcname}
{\token{identifier}} {\token{identifier}}
\end{productionlist} \end{productionlist}
@ -435,14 +435,14 @@ def func(): pass
func = f1(arg)(f2(func)) func = f1(arg)(f2(func))
\end{verbatim} \end{verbatim}
When one or more top-level parameters have the form \var{parameter} When one or more parameters have the form \var{parameter}
\code{=} \var{expression}, the function is said to have ``default \code{=} \var{expression}, the function is said to have ``default
parameter values.'' For a parameter with a parameter values.'' For a parameter with a
default value, the corresponding argument may be omitted from a call, default value, the corresponding argument may be omitted from a call,
in which case the parameter's default value is substituted. If a in which case the parameter's default value is substituted. If a
parameter has a default value, all following parameters must also have parameter has a default value, all following parameters up until the
a default value --- this is a syntactic restriction that is not ``\code{*}'' must also have a default value --- this is a syntactic
expressed by the grammar. restriction that is not expressed by the grammar.
\indexiii{default}{parameter}{value} \indexiii{default}{parameter}{value}
\strong{Default parameter values are evaluated when the function \strong{Default parameter values are evaluated when the function
@ -473,7 +473,21 @@ is present, it is initialized to a tuple receiving any excess
positional parameters, defaulting to the empty tuple. If the form positional parameters, defaulting to the empty tuple. If the form
``\code{**identifier}'' is present, it is initialized to a new ``\code{**identifier}'' is present, it is initialized to a new
dictionary receiving any excess keyword arguments, defaulting to a dictionary receiving any excess keyword arguments, defaulting to a
new empty dictionary. new empty dictionary. Parameters after ``\code{*}'' or ``\code{*identifier}''
are keyword-only parameters and may only be passed used keyword arguments.
Parameters may have annotations of the form ``\code{: expression}''
following the parameter name. Any parameter may have an annotation even
those of the form \code{*identifier} or \code{**identifier}.
Functions may have ``return'' annotation of the form ``\code{-> expression}''
after the parameter list. These annotations can be any valid Python
expression and are evaluated when the function definition is executed.
Annotations may be evaluated in a different order than they appear in the
source code. The presence of annotations does not change the semantics of a
function. The annotation values are available as values of a dictionary
keyed by the parameters' names in the \member{__annotations__}
attribute of the function object.
\indexii{function}{annotations}
It is also possible to create anonymous functions (functions not bound It is also possible to create anonymous functions (functions not bound
to a name), for immediate use in expressions. This uses lambda forms, to a name), for immediate use in expressions. This uses lambda forms,
@ -482,7 +496,7 @@ merely a shorthand for a simplified function definition; a function
defined in a ``\keyword{def}'' statement can be passed around or defined in a ``\keyword{def}'' statement can be passed around or
assigned to another name just like a function defined by a lambda assigned to another name just like a function defined by a lambda
form. The ``\keyword{def}'' form is actually more powerful since it form. The ``\keyword{def}'' form is actually more powerful since it
allows the execution of multiple statements. allows the execution of multiple statements and annotations.
\indexii{lambda}{form} \indexii{lambda}{form}
\strong{Programmer's note:} Functions are first-class objects. A \strong{Programmer's note:} Functions are first-class objects. A

View File

@ -184,12 +184,12 @@ your local Python guru or system administrator. (E.g.,
\file{/usr/local/python} is a popular alternative location.) \file{/usr/local/python} is a popular alternative location.)
On Windows machines, the Python installation is usually placed in On Windows machines, the Python installation is usually placed in
\file{C:\e Python26}, though you can change this when you're running \file{C:\e Python30}, though you can change this when you're running
the installer. To add this directory to your path, the installer. To add this directory to your path,
you can type the following command into the command prompt in a DOS box: you can type the following command into the command prompt in a DOS box:
\begin{verbatim} \begin{verbatim}
set path=%path%;C:\python26 set path=%path%;C:\python30
\end{verbatim} \end{verbatim}
@ -3539,7 +3539,7 @@ as desired.
... print 'x =', x ... print 'x =', x
... print 'y =', y ... print 'y =', y
... ...
<type 'exceptions.Exception'> <type 'Exception'>
('spam', 'eggs') ('spam', 'eggs')
('spam', 'eggs') ('spam', 'eggs')
x = spam x = spam
@ -4638,7 +4638,7 @@ operating system:
>>> os.system('time 0:02') >>> os.system('time 0:02')
0 0
>>> os.getcwd() # Return the current working directory >>> os.getcwd() # Return the current working directory
'C:\\Python26' 'C:\\Python30'
>>> os.chdir('/server/accesslogs') >>> os.chdir('/server/accesslogs')
\end{verbatim} \end{verbatim}
@ -5243,7 +5243,7 @@ applications include caching objects that are expensive to create:
Traceback (most recent call last): Traceback (most recent call last):
File "<pyshell#108>", line 1, in -toplevel- File "<pyshell#108>", line 1, in -toplevel-
d['primary'] # entry was automatically removed d['primary'] # entry was automatically removed
File "C:/python26/lib/weakref.py", line 46, in __getitem__ File "C:/python30/lib/weakref.py", line 46, in __getitem__
o = self.data[key]() o = self.data[key]()
KeyError: 'primary' KeyError: 'primary'
\end{verbatim} \end{verbatim}

View File

@ -24,17 +24,13 @@ decorators: decorator+
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')' parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')* typedargslist: ((tfpdef ['=' test] ',')*
('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
| tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tname: NAME [':' test] tfpdef: NAME [':' test]
tfpdef: tname | '(' tfplist ')'
tfplist: tfpdef (',' tfpdef)* [',']
varargslist: ((vfpdef ['=' test] ',')* varargslist: ((vfpdef ['=' test] ',')*
('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
| vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
vname: NAME vfpdef: NAME
vfpdef: vname | '(' vfplist ')'
vfplist: vfpdef (',' vfpdef)* [',']
stmt: simple_stmt | compound_stmt stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE

View File

@ -355,20 +355,9 @@ struct _arguments {
asdl_seq *kw_defaults; asdl_seq *kw_defaults;
}; };
enum _arg_kind {SimpleArg_kind=1, NestedArgs_kind=2};
struct _arg { struct _arg {
enum _arg_kind kind; identifier arg;
union { expr_ty annotation;
struct {
identifier arg;
expr_ty annotation;
} SimpleArg;
struct {
asdl_seq *args;
} NestedArgs;
} v;
}; };
struct _keyword { struct _keyword {
@ -535,10 +524,8 @@ arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, expr_ty
varargannotation, asdl_seq * kwonlyargs, identifier varargannotation, asdl_seq * kwonlyargs, identifier
kwarg, expr_ty kwargannotation, asdl_seq * defaults, kwarg, expr_ty kwargannotation, asdl_seq * defaults,
asdl_seq * kw_defaults, PyArena *arena); asdl_seq * kw_defaults, PyArena *arena);
#define SimpleArg(a0, a1, a2) _Py_SimpleArg(a0, a1, a2) #define arg(a0, a1, a2) _Py_arg(a0, a1, a2)
arg_ty _Py_SimpleArg(identifier arg, expr_ty annotation, PyArena *arena); arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena);
#define NestedArgs(a0, a1) _Py_NestedArgs(a0, a1)
arg_ty _Py_NestedArgs(asdl_seq * args, PyArena *arena);
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) #define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) #define alias(a0, a1, a2) _Py_alias(a0, a1, a2)

View File

@ -6,79 +6,75 @@
#define funcdef 261 #define funcdef 261
#define parameters 262 #define parameters 262
#define typedargslist 263 #define typedargslist 263
#define tname 264 #define tfpdef 264
#define tfpdef 265 #define varargslist 265
#define tfplist 266 #define vfpdef 266
#define varargslist 267 #define stmt 267
#define vname 268 #define simple_stmt 268
#define vfpdef 269 #define small_stmt 269
#define vfplist 270 #define expr_stmt 270
#define stmt 271 #define augassign 271
#define simple_stmt 272 #define del_stmt 272
#define small_stmt 273 #define pass_stmt 273
#define expr_stmt 274 #define flow_stmt 274
#define augassign 275 #define break_stmt 275
#define del_stmt 276 #define continue_stmt 276
#define pass_stmt 277 #define return_stmt 277
#define flow_stmt 278 #define yield_stmt 278
#define break_stmt 279 #define raise_stmt 279
#define continue_stmt 280 #define import_stmt 280
#define return_stmt 281 #define import_name 281
#define yield_stmt 282 #define import_from 282
#define raise_stmt 283 #define import_as_name 283
#define import_stmt 284 #define dotted_as_name 284
#define import_name 285 #define import_as_names 285
#define import_from 286 #define dotted_as_names 286
#define import_as_name 287 #define dotted_name 287
#define dotted_as_name 288 #define global_stmt 288
#define import_as_names 289 #define nonlocal_stmt 289
#define dotted_as_names 290 #define assert_stmt 290
#define dotted_name 291 #define compound_stmt 291
#define global_stmt 292 #define if_stmt 292
#define nonlocal_stmt 293 #define while_stmt 293
#define assert_stmt 294 #define for_stmt 294
#define compound_stmt 295 #define try_stmt 295
#define if_stmt 296 #define with_stmt 296
#define while_stmt 297 #define with_var 297
#define for_stmt 298 #define except_clause 298
#define try_stmt 299 #define suite 299
#define with_stmt 300 #define test 300
#define with_var 301 #define test_nocond 301
#define except_clause 302 #define lambdef 302
#define suite 303 #define lambdef_nocond 303
#define test 304 #define or_test 304
#define test_nocond 305 #define and_test 305
#define lambdef 306 #define not_test 306
#define lambdef_nocond 307 #define comparison 307
#define or_test 308 #define comp_op 308
#define and_test 309 #define star_expr 309
#define not_test 310 #define expr 310
#define comparison 311 #define xor_expr 311
#define comp_op 312 #define and_expr 312
#define star_expr 313 #define shift_expr 313
#define expr 314 #define arith_expr 314
#define xor_expr 315 #define term 315
#define and_expr 316 #define factor 316
#define shift_expr 317 #define power 317
#define arith_expr 318 #define atom 318
#define term 319 #define testlist_comp 319
#define factor 320 #define trailer 320
#define power 321 #define subscriptlist 321
#define atom 322 #define subscript 322
#define testlist_comp 323 #define sliceop 323
#define trailer 324 #define exprlist 324
#define subscriptlist 325 #define testlist 325
#define subscript 326 #define dictorsetmaker 326
#define sliceop 327 #define classdef 327
#define exprlist 328 #define arglist 328
#define testlist 329 #define argument 329
#define dictorsetmaker 330 #define comp_iter 330
#define classdef 331 #define comp_for 331
#define arglist 332 #define comp_if 332
#define argument 333 #define testlist1 333
#define comp_iter 334 #define encoding_decl 334
#define comp_for 335 #define yield_expr 335
#define comp_if 336
#define testlist1 337
#define encoding_decl 338
#define yield_expr 339

View File

@ -665,7 +665,8 @@ class Aifc_write:
## raise Error, 'cannot change parameters after starting to write' ## raise Error, 'cannot change parameters after starting to write'
## self._version = version ## self._version = version
def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)): def setparams(self, params):
nchannels, sampwidth, framerate, nframes, comptype, compname = params
if self._nframeswritten: if self._nframeswritten:
raise Error, 'cannot change parameters after starting to write' raise Error, 'cannot change parameters after starting to write'
if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'): if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):

View File

@ -151,7 +151,7 @@ class Bdb:
"""This method is called when a return trap is set here.""" """This method is called when a return trap is set here."""
pass pass
def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): def user_exception(self, frame, exc_info):
"""This method is called if an exception occurs, """This method is called if an exception occurs,
but only if we are to stop at or just below this level.""" but only if we are to stop at or just below this level."""
pass pass

View File

@ -170,7 +170,8 @@ class _Rlecoderengine:
del self.ofp del self.ofp
class BinHex: class BinHex:
def __init__(self, (name, finfo, dlen, rlen), ofp): def __init__(self, name_finfo_dlen_rlen, ofp):
name, finfo, dlen, rlen = name_finfo_dlen_rlen
if type(ofp) == type(''): if type(ofp) == type(''):
ofname = ofp ofname = ofp
ofp = open(ofname, 'w') ofp = open(ofname, 'w')

View File

@ -94,10 +94,11 @@ def scanvars(reader, frame, locals):
lasttoken = token lasttoken = token
return vars return vars
def html((etype, evalue, etb), context=5): def html(einfo, context=5):
"""Return a nice HTML document describing a given traceback.""" """Return a nice HTML document describing a given traceback."""
import os, types, time, traceback, linecache, inspect, pydoc import os, types, time, traceback, linecache, inspect, pydoc
etype, evalue, etb = einfo
if type(etype) is types.ClassType: if type(etype) is types.ClassType:
etype = etype.__name__ etype = etype.__name__
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
@ -184,10 +185,11 @@ function calls leading up to the error, in the order they occurred.</p>'''
--> -->
''' % ''.join(traceback.format_exception(etype, evalue, etb)) ''' % ''.join(traceback.format_exception(etype, evalue, etb))
def text((etype, evalue, etb), context=5): def text(einfo, context=5):
"""Return a plain text document describing a given traceback.""" """Return a plain text document describing a given traceback."""
import os, types, time, traceback, linecache, inspect, pydoc import os, types, time, traceback, linecache, inspect, pydoc
etype, evalue, etb = einfo
if type(etype) is types.ClassType: if type(etype) is types.ClassType:
etype = etype.__name__ etype = etype.__name__
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable

View File

@ -228,7 +228,8 @@ class AbstractFormatter:
self.align = None self.align = None
self.writer.new_alignment(None) self.writer.new_alignment(None)
def push_font(self, (size, i, b, tt)): def push_font(self, font):
size, i, b, tt = font
if self.softspace: if self.softspace:
self.hard_break = self.para_end = self.softspace = 0 self.hard_break = self.para_end = self.softspace = 0
self.nospace = 1 self.nospace = 1

View File

@ -183,7 +183,6 @@ if __name__=='__main__':
def t4(*args): "(...)" def t4(*args): "(...)"
def t5(a, *args): "(a, ...)" def t5(a, *args): "(a, ...)"
def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)" def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)"
def t7((a, b), c, (d, e)): "(<tuple>, c, <tuple>)"
class TC(object): class TC(object):
"(ai=None, ...)" "(ai=None, ...)"
@ -194,7 +193,6 @@ if __name__=='__main__':
def t4(self, *args): "(...)" def t4(self, *args): "(...)"
def t5(self, ai, *args): "(ai, ...)" def t5(self, ai, *args): "(ai, ...)"
def t6(self, ai, b=None, *args, **kw): "(ai, b=None, ..., ***)" def t6(self, ai, b=None, *args, **kw): "(ai, b=None, ..., ***)"
def t7(self, (ai, b), c, (d, e)): "(<tuple>, c, <tuple>)"
def test(tests): def test(tests):
ct = CallTips() ct = CallTips()
@ -215,7 +213,7 @@ if __name__=='__main__':
print("%d of %d tests failed" % (len(failed), len(tests))) print("%d of %d tests failed" % (len(failed), len(tests)))
tc = TC() tc = TC()
tests = (t1, t2, t3, t4, t5, t6, t7, tests = (t1, t2, t3, t4, t5, t6,
TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6, tc.t7) TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6)
test(tests) test(tests)

View File

@ -253,7 +253,8 @@ class Debugger:
if self.vsource.get(): if self.vsource.get():
self.sync_source_line() self.sync_source_line()
def show_frame(self, (frame, lineno)): def show_frame(self, stackitem):
frame, lineno = stackitem
self.frame = frame self.frame = frame
self.show_variables() self.show_variables()

View File

@ -278,7 +278,10 @@ class Importer:
setattr(parent, modname, module) setattr(parent, modname, module)
return module return module
def _process_result(self, (ispkg, code, values), fqname): def _process_result(self, result, fqname):
# unpack result
ispkg, code, values = result
# did get_code() return an actual module? (rather than a code object) # did get_code() return an actual module? (rather than a code object)
is_module = isinstance(code, _ModuleType) is_module = isinstance(code, _ModuleType)

View File

@ -366,8 +366,8 @@ def getfile(object):
def getmoduleinfo(path): def getmoduleinfo(path):
"""Get the module name, suffix, mode, and module type for a given file.""" """Get the module name, suffix, mode, and module type for a given file."""
filename = os.path.basename(path) filename = os.path.basename(path)
suffixes = map(lambda (suffix, mode, mtype): suffixes = [(-len(suffix), suffix, mode, mtype)
(-len(suffix), suffix, mode, mtype), imp.get_suffixes()) for suffix, mode, mtype in imp.get_suffixes()]
suffixes.sort() # try longest suffixes first, in case they overlap suffixes.sort() # try longest suffixes first, in case they overlap
for neglen, suffix, mode, mtype in suffixes: for neglen, suffix, mode, mtype in suffixes:
if filename[neglen:] == suffix: if filename[neglen:] == suffix:
@ -568,7 +568,7 @@ class BlockFinder:
self.passline = False self.passline = False
self.last = 1 self.last = 1
def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): def tokeneater(self, type, token, srowcol, erowcol, line):
if not self.started: if not self.started:
# look for the first "def", "class" or "lambda" # look for the first "def", "class" or "lambda"
if token in ("def", "class", "lambda"): if token in ("def", "class", "lambda"):
@ -578,7 +578,7 @@ class BlockFinder:
self.passline = True # skip to the end of the line self.passline = True # skip to the end of the line
elif type == tokenize.NEWLINE: elif type == tokenize.NEWLINE:
self.passline = False # stop skipping when a NEWLINE is seen self.passline = False # stop skipping when a NEWLINE is seen
self.last = srow self.last = srowcol[0]
if self.islambda: # lambdas always end at the first NEWLINE if self.islambda: # lambdas always end at the first NEWLINE
raise EndOfBlock raise EndOfBlock
elif self.passline: elif self.passline:
@ -698,40 +698,6 @@ def _getfullargs(co):
kwonlyargs = list(names[nargs:nargs+nkwargs]) kwonlyargs = list(names[nargs:nargs+nkwargs])
step = 0 step = 0
# The following acrobatics are for anonymous (tuple) arguments.
for i in range(nargs):
if args[i][:1] in ('', '.'):
stack, remain, count = [], [], []
while step < len(code):
op = ord(code[step])
step = step + 1
if op >= dis.HAVE_ARGUMENT:
opname = dis.opname[op]
value = ord(code[step]) + ord(code[step+1])*256
step = step + 2
if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
remain.append(value)
count.append(value)
elif opname == 'STORE_FAST':
stack.append(names[value])
# Special case for sublists of length 1: def foo((bar))
# doesn't generate the UNPACK_TUPLE bytecode, so if
# `remain` is empty here, we have such a sublist.
if not remain:
stack[0] = [stack[0]]
break
else:
remain[-1] = remain[-1] - 1
while remain[-1] == 0:
remain.pop()
size = count.pop()
stack[-size:] = [stack[-size:]]
if not remain: break
remain[-1] = remain[-1] - 1
if not remain: break
args[i] = stack[0]
nargs += nkwargs nargs += nkwargs
varargs = None varargs = None
if co.co_flags & CO_VARARGS: if co.co_flags & CO_VARARGS:

View File

@ -279,7 +279,8 @@ class ModuleFinder:
self.msgout(3, "import_module ->", m) self.msgout(3, "import_module ->", m)
return m return m
def load_module(self, fqname, fp, pathname, (suffix, mode, type)): def load_module(self, fqname, fp, pathname, file_info):
suffix, mode, type = file_info
self.msgin(2, "load_module", fqname, fp and "fp", pathname) self.msgin(2, "load_module", fqname, fp and "fp", pathname)
if type == imp.PKG_DIRECTORY: if type == imp.PKG_DIRECTORY:
m = self.load_package(fqname, pathname) m = self.load_package(fqname, pathname)

View File

@ -653,68 +653,6 @@ otherwise return -SIG, where SIG is the signal that killed it. """
__all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",]) __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
# Supply popen2 etc. (for Unix)
if _exists("fork"):
if not _exists("popen2"):
def popen2(cmd, mode="t", bufsize=-1):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
may be a sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()). If 'cmd'
is a string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdin, child_stdout) are returned."""
import warnings
msg = "os.popen2 is deprecated. Use the subprocess module."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
import subprocess
PIPE = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
return p.stdin, p.stdout
__all__.append("popen2")
if not _exists("popen3"):
def popen3(cmd, mode="t", bufsize=-1):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
may be a sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()). If 'cmd'
is a string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdin, child_stdout, child_stderr) are returned."""
import warnings
msg = "os.popen3 is deprecated. Use the subprocess module."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
import subprocess
PIPE = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE,
close_fds=True)
return p.stdin, p.stdout, p.stderr
__all__.append("popen3")
if not _exists("popen4"):
def popen4(cmd, mode="t", bufsize=-1):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
may be a sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()). If 'cmd'
is a string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdin, child_stdout_stderr) are returned."""
import warnings
msg = "os.popen4 is deprecated. Use the subprocess module."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
import subprocess
PIPE = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE,
stderr=subprocess.STDOUT, close_fds=True)
return p.stdin, p.stdout
__all__.append("popen4")
import copy_reg as _copy_reg import copy_reg as _copy_reg
def _make_stat_result(tup, dict): def _make_stat_result(tup, dict):

View File

@ -180,13 +180,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
print('--Return--', file=self.stdout) print('--Return--', file=self.stdout)
self.interaction(frame, None) self.interaction(frame, None)
def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): def user_exception(self, frame, exc_info):
"""This function is called if an exception occurs, """This function is called if an exception occurs,
but only if we are to stop at or just below this level.""" but only if we are to stop at or just below this level."""
exc_type, exc_value, exc_traceback = exc_info
frame.f_locals['__exception__'] = exc_type, exc_value frame.f_locals['__exception__'] = exc_type, exc_value
if type(exc_type) == type(''): exc_type_name = exc_type.__name__
exc_type_name = exc_type
else: exc_type_name = exc_type.__name__
print(exc_type_name + ':', _saferepr(exc_value), file=self.stdout) print(exc_type_name + ':', _saferepr(exc_value), file=self.stdout)
self.interaction(frame, exc_traceback) self.interaction(frame, exc_traceback)

View File

@ -326,7 +326,8 @@ def _parse_object(file):
# #
# External - Create a form an link to an instance variable. # External - Create a form an link to an instance variable.
# #
def create_full_form(inst, (fdata, odatalist)): def create_full_form(inst, formdata):
fdata, odatalist = formdata
form = create_form(fdata) form = create_form(fdata)
exec('inst.'+fdata.Name+' = form\n') exec('inst.'+fdata.Name+' = form\n')
for odata in odatalist: for odata in odatalist:
@ -336,7 +337,8 @@ def create_full_form(inst, (fdata, odatalist)):
# External - Merge a form into an existing form in an instance # External - Merge a form into an existing form in an instance
# variable. # variable.
# #
def merge_full_form(inst, form, (fdata, odatalist)): def merge_full_form(inst, form, formdata):
fdata, odatalist = formdata
exec('inst.'+fdata.Name+' = form\n') exec('inst.'+fdata.Name+' = form\n')
if odatalist[0].Class != FL.BOX: if odatalist[0].Class != FL.BOX:
raise error, 'merge_full_form() expects FL.BOX as first obj' raise error, 'merge_full_form() expects FL.BOX as first obj'

View File

@ -296,8 +296,9 @@ def location(object, pos=None):
return _getlocation(object_alias) return _getlocation(object_alias)
return _setlocation(object_alias, pos) return _setlocation(object_alias, pos)
def _setlocation(object_alias, (x, y)): def _setlocation(object_alias, location):
"""_setlocation: Set the location of the icon for the object.""" """_setlocation: Set the location of the icon for the object."""
x, y = location
finder = _getfinder() finder = _getfinder()
args = {} args = {}
attrs = {} attrs = {}
@ -438,8 +439,9 @@ def windowsize(folder, size=None):
return _getwindowsize(folder_alias) return _getwindowsize(folder_alias)
return _setwindowsize(folder_alias, size) return _setwindowsize(folder_alias, size)
def _setwindowsize(folder_alias, (w, h)): def _setwindowsize(folder_alias, size):
"""Set the size of a Finder window for folder to (w, h)""" """Set the size of a Finder window for folder to (w, h)"""
w, h = size
finder = _getfinder() finder = _getfinder()
args = {} args = {}
attrs = {} attrs = {}
@ -489,8 +491,9 @@ def windowposition(folder, pos=None):
pos = (pos.h, pos.v) pos = (pos.h, pos.v)
return _setwindowposition(folder_alias, pos) return _setwindowposition(folder_alias, pos)
def _setwindowposition(folder_alias, (x, y)): def _setwindowposition(folder_alias, position):
"""Set the size of a Finder window for folder to (w, h).""" """Set the size of a Finder window for folder to (w, h)."""
x, y = position
finder = _getfinder() finder = _getfinder()
args = {} args = {}
attrs = {} attrs = {}

View File

@ -1,205 +0,0 @@
"""Spawn a command with pipes to its stdin, stdout, and optionally stderr.
The normal os.popen(cmd, mode) call spawns a shell command and provides a
file interface to just the input or output of the process depending on
whether mode is 'r' or 'w'. This module provides the functions popen2(cmd)
and popen3(cmd) which return two or three pipes to the spawned command.
"""
import os
import sys
import warnings
warnings.warn("The popen2 module is deprecated. Use the subprocess module.",
DeprecationWarning, stacklevel=2)
__all__ = ["popen2", "popen3", "popen4"]
try:
MAXFD = os.sysconf('SC_OPEN_MAX')
except (AttributeError, ValueError):
MAXFD = 256
_active = []
def _cleanup():
for inst in _active[:]:
if inst.poll(_deadstate=sys.maxint) >= 0:
try:
_active.remove(inst)
except ValueError:
# This can happen if two threads create a new Popen instance.
# It's harmless that it was already removed, so ignore.
pass
class Popen3:
"""Class representing a child process. Normally instances are created
by the factory functions popen2() and popen3()."""
sts = -1 # Child not completed yet
def __init__(self, cmd, capturestderr=False, bufsize=-1):
"""The parameter 'cmd' is the shell command to execute in a
sub-process. On UNIX, 'cmd' may be a sequence, in which case arguments
will be passed directly to the program without shell intervention (as
with os.spawnv()). If 'cmd' is a string it will be passed to the shell
(as with os.system()). The 'capturestderr' flag, if true, specifies
that the object should capture standard error output of the child
process. The default is false. If the 'bufsize' parameter is
specified, it specifies the size of the I/O buffers to/from the child
process."""
_cleanup()
self.cmd = cmd
p2cread, p2cwrite = os.pipe()
c2pread, c2pwrite = os.pipe()
if capturestderr:
errout, errin = os.pipe()
self.pid = os.fork()
if self.pid == 0:
# Child
os.dup2(p2cread, 0)
os.dup2(c2pwrite, 1)
if capturestderr:
os.dup2(errin, 2)
self._run_child(cmd)
os.close(p2cread)
self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
os.close(c2pwrite)
self.fromchild = os.fdopen(c2pread, 'r', bufsize)
if capturestderr:
os.close(errin)
self.childerr = os.fdopen(errout, 'r', bufsize)
else:
self.childerr = None
def __del__(self):
# In case the child hasn't been waited on, check if it's done.
self.poll(_deadstate=sys.maxint)
if self.sts < 0:
if _active is not None:
# Child is still running, keep us alive until we can wait on it.
_active.append(self)
def _run_child(self, cmd):
if isinstance(cmd, basestring):
cmd = ['/bin/sh', '-c', cmd]
for i in range(3, MAXFD):
try:
os.close(i)
except OSError:
pass
try:
os.execvp(cmd[0], cmd)
finally:
os._exit(1)
def poll(self, _deadstate=None):
"""Return the exit status of the child process if it has finished,
or -1 if it hasn't finished yet."""
if self.sts < 0:
try:
pid, sts = os.waitpid(self.pid, os.WNOHANG)
# pid will be 0 if self.pid hasn't terminated
if pid == self.pid:
self.sts = sts
except os.error:
if _deadstate is not None:
self.sts = _deadstate
return self.sts
def wait(self):
"""Wait for and return the exit status of the child process."""
if self.sts < 0:
pid, sts = os.waitpid(self.pid, 0)
# This used to be a test, but it is believed to be
# always true, so I changed it to an assertion - mvl
assert pid == self.pid
self.sts = sts
return self.sts
class Popen4(Popen3):
childerr = None
def __init__(self, cmd, bufsize=-1):
_cleanup()
self.cmd = cmd
p2cread, p2cwrite = os.pipe()
c2pread, c2pwrite = os.pipe()
self.pid = os.fork()
if self.pid == 0:
# Child
os.dup2(p2cread, 0)
os.dup2(c2pwrite, 1)
os.dup2(c2pwrite, 2)
self._run_child(cmd)
os.close(p2cread)
self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
os.close(c2pwrite)
self.fromchild = os.fdopen(c2pread, 'r', bufsize)
if sys.platform[:3] == "win" or sys.platform == "os2emx":
# Some things don't make sense on non-Unix platforms.
del Popen3, Popen4
def popen2(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout, child_stdin) are returned."""
w, r = os.popen2(cmd, mode, bufsize)
return r, w
def popen3(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout, child_stdin, child_stderr) are returned."""
w, r, e = os.popen3(cmd, mode, bufsize)
return r, w, e
def popen4(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout_stderr, child_stdin) are returned."""
w, r = os.popen4(cmd, mode, bufsize)
return r, w
else:
def popen2(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout, child_stdin) are returned."""
inst = Popen3(cmd, False, bufsize)
return inst.fromchild, inst.tochild
def popen3(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout, child_stdin, child_stderr) are returned."""
inst = Popen3(cmd, True, bufsize)
return inst.fromchild, inst.tochild, inst.childerr
def popen4(cmd, bufsize=-1, mode='t'):
"""Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
be a sequence, in which case arguments will be passed directly to the
program without shell intervention (as with os.spawnv()). If 'cmd' is a
string it will be passed to the shell (as with os.system()). If
'bufsize' is specified, it sets the buffer size for the I/O pipes. The
file objects (child_stdout_stderr, child_stdin) are returned."""
inst = Popen4(cmd, bufsize)
return inst.fromchild, inst.tochild
__all__.extend(["Popen3", "Popen4"])

View File

@ -249,7 +249,10 @@ def _safe_repr(object, context, maxlevels, level):
try: try:
items = sorted(items) items = sorted(items)
except TypeError: except TypeError:
items = sorted(items, key=lambda (k, v): (str(type(k)), k, v)) def sortkey(item):
key, value = item
return str(type(key)), key, value
items = sorted(items, key=sortkey)
for k, v in items: for k, v in items:
krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level) vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)

View File

@ -171,11 +171,12 @@ def visiblename(name, all=None):
def classify_class_attrs(object): def classify_class_attrs(object):
"""Wrap inspect.classify_class_attrs, with fixup for data descriptors.""" """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
def fixup((name, kind, cls, value)): results = []
for (name, kind, cls, value) in inspect.classify_class_attrs(object):
if inspect.isdatadescriptor(value): if inspect.isdatadescriptor(value):
kind = 'data descriptor' kind = 'data descriptor'
return name, kind, cls, value results.append((name, kind, cls, value))
return map(fixup, inspect.classify_class_attrs(object)) return results
# ----------------------------------------------------- module manipulation # ----------------------------------------------------- module manipulation
@ -228,11 +229,9 @@ def synopsis(filename, cache={}):
class ErrorDuringImport(Exception): class ErrorDuringImport(Exception):
"""Errors that occurred while trying to import something to document it.""" """Errors that occurred while trying to import something to document it."""
def __init__(self, filename, (exc, value, tb)): def __init__(self, filename, exc_info):
self.filename = filename self.filename = filename
self.exc = exc self.exc, self.value, self.tb = exc_info
self.value = value
self.tb = tb
def __str__(self): def __str__(self):
exc = self.exc exc = self.exc
@ -502,8 +501,9 @@ class HTMLDoc(Doc):
"""Make a link for a module.""" """Make a link for a module."""
return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__) return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
def modpkglink(self, (name, path, ispackage, shadowed)): def modpkglink(self, modpkginfo):
"""Make a link for a module or package to display in an index.""" """Make a link for a module or package to display in an index."""
name, path, ispackage, shadowed = modpkginfo
if shadowed: if shadowed:
return self.grey(name) return self.grey(name)
if path: if path:
@ -662,12 +662,12 @@ class HTMLDoc(Doc):
'Package Contents', '#ffffff', '#aa55cc', contents) 'Package Contents', '#ffffff', '#aa55cc', contents)
elif modules: elif modules:
contents = self.multicolumn( contents = self.multicolumn(
modules, lambda (key, value), s=self: s.modulelink(value)) modules, lambda t: self.modulelink(t[1]))
result = result + self.bigsection( result = result + self.bigsection(
'Modules', '#fffff', '#aa55cc', contents) 'Modules', '#fffff', '#aa55cc', contents)
if classes: if classes:
classlist = map(lambda (key, value): value, classes) classlist = [value for (key, value) in classes]
contents = [ contents = [
self.formattree(inspect.getclasstree(classlist, 1), name)] self.formattree(inspect.getclasstree(classlist, 1), name)]
for key, value in classes: for key, value in classes:
@ -768,8 +768,10 @@ class HTMLDoc(Doc):
push('\n') push('\n')
return attrs return attrs
attrs = filter(lambda (name, kind, cls, value): visiblename(name), attrs = [(name, kind, cls, value)
classify_class_attrs(object)) for name, kind, cls, value in classify_class_attrs(object)
if visiblename(name)]
mdict = {} mdict = {}
for key, kind, homecls, value in attrs: for key, kind, homecls, value in attrs:
mdict[key] = anchor = '#' + name + '-' + key mdict[key] = anchor = '#' + name + '-' + key
@ -1071,7 +1073,7 @@ class TextDoc(Doc):
'PACKAGE CONTENTS', '\n'.join(modpkgs)) 'PACKAGE CONTENTS', '\n'.join(modpkgs))
if classes: if classes:
classlist = map(lambda (key, value): value, classes) classlist = [value for key, value in classes]
contents = [self.formattree( contents = [self.formattree(
inspect.getclasstree(classlist, 1), name)] inspect.getclasstree(classlist, 1), name)]
for key, value in classes: for key, value in classes:
@ -1175,8 +1177,10 @@ class TextDoc(Doc):
name, mod, maxlen=70, doc=doc) + '\n') name, mod, maxlen=70, doc=doc) + '\n')
return attrs return attrs
attrs = filter(lambda (name, kind, cls, value): visiblename(name), attrs = [(name, kind, cls, value)
classify_class_attrs(object)) for name, kind, cls, value in classify_class_attrs(object)
if visiblename(name)]
while attrs: while attrs:
if mro: if mro:
thisclass = mro.popleft() thisclass = mro.popleft()

View File

@ -364,7 +364,8 @@ class Au_write:
else: else:
return 'not compressed' return 'not compressed'
def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)): def setparams(self, params):
nchannels, sampwidth, framerate, nframes, comptype, compname = params
self.setnchannels(nchannels) self.setnchannels(nchannels)
self.setsampwidth(sampwidth) self.setsampwidth(sampwidth)
self.setframerate(framerate) self.setframerate(framerate)

View File

@ -5,7 +5,7 @@ import sys, inspect
# line 5 # line 5
# line 7 # line 7
def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h): def spam(a, b, c, d=3, e=4, f=5, *g, **h):
eggs(b + d, c + f) eggs(b + d, c + f)
# line 11 # line 11

View File

@ -60,8 +60,8 @@ def with_comment(): # hello
# line 61 # line 61
multiline_sig = [ multiline_sig = [
lambda (x, lambda x, \
y): x+y, y: x+y,
None, None,
] ]

View File

@ -887,7 +887,6 @@ _expectations = {
test_ossaudiodev test_ossaudiodev
test_poll test_poll
test_popen test_popen
test_popen2
test_posix test_posix
test_pty test_pty
test_pwd test_pwd
@ -986,7 +985,6 @@ _expectations = {
test_ntpath test_ntpath
test_openpty test_openpty
test_poll test_poll
test_popen2
test_pty test_pty
test_pwd test_pwd
test_strop test_strop
@ -1062,7 +1060,6 @@ _expectations = {
test_mmap test_mmap
test_nis test_nis
test_poll test_poll
test_popen2
test_resource test_resource
test_sqlite test_sqlite
test_startfile test_startfile

View File

@ -7,8 +7,6 @@ warnings.filterwarnings("ignore",
"the gopherlib module is deprecated", "the gopherlib module is deprecated",
DeprecationWarning, DeprecationWarning,
"<string>") "<string>")
warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*",
DeprecationWarning)
class AllTest(unittest.TestCase): class AllTest(unittest.TestCase):
@ -112,7 +110,6 @@ class AllTest(unittest.TestCase):
self.check_all("pickle") self.check_all("pickle")
self.check_all("pickletools") self.check_all("pickletools")
self.check_all("pipes") self.check_all("pipes")
self.check_all("popen2")
self.check_all("poplib") self.check_all("poplib")
self.check_all("posixpath") self.check_all("posixpath")
self.check_all("pprint") self.check_all("pprint")

View File

@ -124,29 +124,9 @@ def f(x):
exec(code, g) exec(code, g)
self.assertEqual(g['f'](5), 0) self.assertEqual(g['f'](5), 0)
def test_complex_args(self):
def comp_args((a, b)):
return a,b
self.assertEqual(comp_args((1, 2)), (1, 2))
def comp_args((a, b)=(3, 4)):
return a, b
self.assertEqual(comp_args((1, 2)), (1, 2))
self.assertEqual(comp_args(), (3, 4))
def comp_args(a, (b, c)):
return a, b, c
self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
def comp_args(a=2, (b, c)=(3, 4)):
return a, b, c
self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
self.assertEqual(comp_args(), (2, 3, 4))
def test_argument_order(self): def test_argument_order(self):
try: try:
exec('def f(a=1, (b, c)): pass') exec('def f(a=1, b): pass')
self.fail("non-default args after default") self.fail("non-default args after default")
except SyntaxError: except SyntaxError:
pass pass
@ -394,16 +374,16 @@ if 1:
self.assertEqual((Ellipsis, Ellipsis) in d, False) self.assertEqual((Ellipsis, Ellipsis) in d, False)
def test_annotation_limit(self): def test_annotation_limit(self):
# 16 bits are available for # of annotations, and the # 16 bits are available for # of annotations, but only 8 bits are
# tuple of annotations names is counted, hence 65534 # available for the parameter count, hence 255
# is the max. Ensure the result of too many annotations is a # is the max. Ensure the result of too many annotations is a
# SyntaxError. # SyntaxError.
s = "def f((%s)): pass" s = "def f(%s): pass"
s %= ', '.join('a%d:%d' % (i,i) for i in range(65535)) s %= ', '.join('a%d:%d' % (i,i) for i in range(256))
self.assertRaises(SyntaxError, compile, s, '?', 'exec') self.assertRaises(SyntaxError, compile, s, '?', 'exec')
# Test that the max # of annotations compiles. # Test that the max # of annotations compiles.
s = "def f((%s)): pass" s = "def f(%s): pass"
s %= ', '.join('a%d:%d' % (i,i) for i in range(65534)) s %= ', '.join('a%d:%d' % (i,i) for i in range(255))
compile(s, '?', 'exec') compile(s, '?', 'exec')
def test_mangling(self): def test_mangling(self):

View File

@ -1,91 +0,0 @@
import unittest
from test import test_support
class ComplexArgsTestCase(unittest.TestCase):
def check(self, func, expected, *args):
self.assertEqual(func(*args), expected)
# These functions are tested below as lambdas too. If you add a function test,
# also add a similar lambda test.
def test_func_parens_no_unpacking(self):
def f(((((x))))): return x
self.check(f, 1, 1)
# Inner parens are elided, same as: f(x,)
def f(((x)),): return x
self.check(f, 2, 2)
def test_func_1(self):
def f(((((x),)))): return x
self.check(f, 3, (3,))
def f(((((x)),))): return x
self.check(f, 4, (4,))
def f(((((x))),)): return x
self.check(f, 5, (5,))
def f(((x),)): return x
self.check(f, 6, (6,))
def test_func_2(self):
def f(((((x)),),)): return x
self.check(f, 2, ((2,),))
def test_func_3(self):
def f((((((x)),),),)): return x
self.check(f, 3, (((3,),),))
def test_func_complex(self):
def f((((((x)),),),), a, b, c): return x, a, b, c
self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
def f(((((((x)),)),),), a, b, c): return x, a, b, c
self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
def f(a, b, c, ((((((x)),)),),)): return a, b, c, x
self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
# Duplicate the tests above, but for lambda. If you add a lambda test,
# also add a similar function test above.
def test_lambda_parens_no_unpacking(self):
f = lambda (((((x))))): x
self.check(f, 1, 1)
# Inner parens are elided, same as: f(x,)
f = lambda ((x)),: x
self.check(f, 2, 2)
def test_lambda_1(self):
f = lambda (((((x),)))): x
self.check(f, 3, (3,))
f = lambda (((((x)),))): x
self.check(f, 4, (4,))
f = lambda (((((x))),)): x
self.check(f, 5, (5,))
f = lambda (((x),)): x
self.check(f, 6, (6,))
def test_lambda_2(self):
f = lambda (((((x)),),)): x
self.check(f, 2, ((2,),))
def test_lambda_3(self):
f = lambda ((((((x)),),),)): x
self.check(f, 3, (((3,),),))
def test_lambda_complex(self):
f = lambda (((((x)),),),), a, b, c: (x, a, b, c)
self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
f = lambda ((((((x)),)),),), a, b, c: (x, a, b, c)
self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
f = lambda a, b, c, ((((((x)),)),),): (a, b, c, x)
self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
def test_main():
test_support.run_unittest(ComplexArgsTestCase)
if __name__ == "__main__":
test_main()

View File

@ -144,51 +144,32 @@ class GrammarTests(unittest.TestCase):
### decorators: decorator+ ### decorators: decorator+
### parameters: '(' [typedargslist] ')' ### parameters: '(' [typedargslist] ')'
### typedargslist: ((tfpdef ['=' test] ',')* ### typedargslist: ((tfpdef ['=' test] ',')*
### ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
### tname: NAME [':' test] ### tfpdef: NAME [':' test]
### tfpdef: tname | '(' tfplist ')'
### tfplist: tfpdef (',' tfpdef)* [',']
### varargslist: ((vfpdef ['=' test] ',')* ### varargslist: ((vfpdef ['=' test] ',')*
### ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
### vname: NAME ### vfpdef: NAME
### vfpdef: vname | '(' vfplist ')'
### vfplist: vfpdef (',' vfpdef)* [',']
def f1(): pass def f1(): pass
f1() f1()
f1(*()) f1(*())
f1(*(), **{}) f1(*(), **{})
def f2(one_argument): pass def f2(one_argument): pass
def f3(two, arguments): pass def f3(two, arguments): pass
def f4(two, (compound, (argument, list))): pass
def f5((compound, first), two): pass
self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) self.assertEquals(f2.__code__.co_varnames, ('one_argument',))
self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments'))
if sys.platform.startswith('java'):
self.assertEquals(f4.__code__.co_varnames,
('two', '(compound, (argument, list))', 'compound', 'argument',
'list',))
self.assertEquals(f5.__code__.co_varnames,
('(compound, first)', 'two', 'compound', 'first'))
else:
self.assertEquals(f4.__code__.co_varnames,
('two', '.1', 'compound', 'argument', 'list'))
self.assertEquals(f5.__code__.co_varnames,
('.0', 'two', 'compound', 'first'))
def a1(one_arg,): pass def a1(one_arg,): pass
def a2(two, args,): pass def a2(two, args,): pass
def v0(*rest): pass def v0(*rest): pass
def v1(a, *rest): pass def v1(a, *rest): pass
def v2(a, b, *rest): pass def v2(a, b, *rest): pass
def v3(a, (b, c), *rest): return a, b, c, rest
f1() f1()
f2(1) f2(1)
f2(1,) f2(1,)
f3(1, 2) f3(1, 2)
f3(1, 2,) f3(1, 2,)
f4(1, (2, (3, 4)))
v0() v0()
v0(1) v0(1)
v0(1,) v0(1,)
@ -203,17 +184,7 @@ class GrammarTests(unittest.TestCase):
v2(1,2,3) v2(1,2,3)
v2(1,2,3,4) v2(1,2,3,4)
v2(1,2,3,4,5,6,7,8,9,0) v2(1,2,3,4,5,6,7,8,9,0)
v3(1,(2,3))
v3(1,(2,3),4)
v3(1,(2,3),4,5,6,7,8,9,0)
# ceval unpacks the formal arguments into the first argcount names;
# thus, the names nested inside tuples must appear after these names.
if sys.platform.startswith('java'):
self.assertEquals(v3.__code__.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
else:
self.assertEquals(v3.__code__.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
def d01(a=1): pass def d01(a=1): pass
d01() d01()
d01(1) d01(1)
@ -286,10 +257,6 @@ class GrammarTests(unittest.TestCase):
d22v(*(1, 2, 3, 4)) d22v(*(1, 2, 3, 4))
d22v(1, 2, *(3, 4, 5)) d22v(1, 2, *(3, 4, 5))
d22v(1, *(2, 3), **{'d': 4}) d22v(1, *(2, 3), **{'d': 4})
def d31v((x)): pass
d31v(1)
def d32v((x,)): pass
d32v((1,))
# keyword only argument tests # keyword only argument tests
def pos0key1(*, key): return key def pos0key1(*, key): return key
pos0key1(key=100) pos0key1(key=100)
@ -312,12 +279,12 @@ class GrammarTests(unittest.TestCase):
self.assertEquals(f.__annotations__, {'x': float}) self.assertEquals(f.__annotations__, {'x': float})
def f(x, y:1+2): pass def f(x, y:1+2): pass
self.assertEquals(f.__annotations__, {'y': 3}) self.assertEquals(f.__annotations__, {'y': 3})
def f(a, (b:1, c:2, d)): pass def f(a, b:1, c:2, d): pass
self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) self.assertEquals(f.__annotations__, {'b': 1, 'c': 2})
def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass
self.assertEquals(f.__annotations__, self.assertEquals(f.__annotations__,
{'b': 1, 'c': 2, 'e': 3, 'g': 6}) {'b': 1, 'c': 2, 'e': 3, 'g': 6})
def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6, h:7, i=8, j:9=10, def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10,
**k:11) -> 12: pass **k:11) -> 12: pass
self.assertEquals(f.__annotations__, self.assertEquals(f.__annotations__,
{'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,

View File

@ -116,11 +116,11 @@ class TestInterpreterStack(IsTestBase):
def test_previous_frame(self): def test_previous_frame(self):
args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]]) self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
self.assertEqual(varargs, 'g') self.assertEqual(varargs, 'g')
self.assertEqual(varkw, 'h') self.assertEqual(varkw, 'h')
self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals), self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
'(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})') '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
class GetSourceBase(unittest.TestCase): class GetSourceBase(unittest.TestCase):
# Subclasses must override. # Subclasses must override.
@ -321,9 +321,9 @@ class TestClassesAndFunctions(unittest.TestCase):
self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)') self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
self.assertArgSpecEquals(mod.spam, self.assertArgSpecEquals(mod.spam,
['a', 'b', 'c', 'd', ['e', ['f']]], ['a', 'b', 'c', 'd', 'e', 'f'],
'g', 'h', (3, (4, (5,))), 'g', 'h', (3, 4, 5),
'(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)') '(a, b, c, d=3, e=4, f=5, *g, **h)')
def test_getargspec_method(self): def test_getargspec_method(self):
class A(object): class A(object):
@ -331,13 +331,6 @@ class TestClassesAndFunctions(unittest.TestCase):
pass pass
self.assertArgSpecEquals(A.m, ['self']) self.assertArgSpecEquals(A.m, ['self'])
def test_getargspec_sublistofone(self):
def sublistOfOne((foo,)): return 1
self.assertArgSpecEquals(sublistOfOne, [['foo']])
def fakeSublistOfOne((foo)): return 1
self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
def test_classify_newstyle(self): def test_classify_newstyle(self):
class A(object): class A(object):

View File

@ -859,7 +859,7 @@ Samuele
# is differencing with a range so that consecutive numbers all appear in # is differencing with a range so that consecutive numbers all appear in
# same group. # same group.
>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):
... print(map(operator.itemgetter(1), g)) ... print(map(operator.itemgetter(1), g))
... ...
[1] [1]

View File

@ -105,10 +105,11 @@ class MathTests(unittest.TestCase):
def testFrexp(self): def testFrexp(self):
self.assertRaises(TypeError, math.frexp) self.assertRaises(TypeError, math.frexp)
def testfrexp(name, (mant, exp), (emant, eexp)): def testfrexp(name, result, expected):
(mant, exp), (emant, eexp) = result, expected
if abs(mant-emant) > eps or exp != eexp: if abs(mant-emant) > eps or exp != eexp:
self.fail('%s returned %r, expected %r'%\ self.fail('%s returned %r, expected %r'%\
(name, (mant, exp), (emant,eexp))) (name, result, expected))
testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1)) testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
testfrexp('frexp(0)', math.frexp(0), (0, 0)) testfrexp('frexp(0)', math.frexp(0), (0, 0))
@ -145,10 +146,11 @@ class MathTests(unittest.TestCase):
def testModf(self): def testModf(self):
self.assertRaises(TypeError, math.modf) self.assertRaises(TypeError, math.modf)
def testmodf(name, (v1, v2), (e1, e2)): def testmodf(name, result, expected):
(v1, v2), (e1, e2) = result, expected
if abs(v1-e1) > eps or abs(v2-e2): if abs(v1-e1) > eps or abs(v2-e2):
self.fail('%s returned %r, expected %r'%\ self.fail('%s returned %r, expected %r'%\
(name, (v1,v2), (e1,e2))) (name, result, expected))
testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0)) testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0)) testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))

View File

@ -1,98 +0,0 @@
#! /usr/bin/env python
"""Test script for popen2.py"""
import warnings
warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*",
DeprecationWarning)
warnings.filterwarnings("ignore", "os\.popen. is deprecated.*",
DeprecationWarning)
import os
import sys
import unittest
import popen2
from test.test_support import TestSkipped, run_unittest, reap_children
if sys.platform[:4] == 'beos' or sys.platform[:6] == 'atheos':
# Locks get messed up or something. Generally we're supposed
# to avoid mixing "posix" fork & exec with native threads, and
# they may be right about that after all.
raise TestSkipped("popen2() doesn't work on " + sys.platform)
# if we don't have os.popen, check that
# we have os.fork. if not, skip the test
# (by raising an ImportError)
try:
from os import popen
del popen
except ImportError:
from os import fork
del fork
class Popen2Test(unittest.TestCase):
cmd = "cat"
if os.name == "nt":
cmd = "more"
teststr = "ab cd\n"
# "more" doesn't act the same way across Windows flavors,
# sometimes adding an extra newline at the start or the
# end. So we strip whitespace off both ends for comparison.
expected = teststr.strip()
def setUp(self):
popen2._cleanup()
# When the test runs, there shouldn't be any open pipes
self.assertFalse(popen2._active, "Active pipes when test starts" +
repr([c.cmd for c in popen2._active]))
def tearDown(self):
for inst in popen2._active:
inst.wait()
popen2._cleanup()
self.assertFalse(popen2._active, "_active not empty")
reap_children()
def validate_output(self, teststr, expected_out, r, w, e=None):
w.write(teststr)
w.close()
got = r.read()
self.assertEquals(expected_out, got.strip(), "wrote %r read %r" %
(teststr, got))
if e is not None:
got = e.read()
self.assertFalse(got, "unexpected %r on stderr" % got)
def test_popen2(self):
r, w = popen2.popen2(self.cmd)
self.validate_output(self.teststr, self.expected, r, w)
def test_popen3(self):
if os.name == 'posix':
r, w, e = popen2.popen3([self.cmd])
self.validate_output(self.teststr, self.expected, r, w, e)
r, w, e = popen2.popen3(self.cmd)
self.validate_output(self.teststr, self.expected, r, w, e)
def test_os_popen2(self):
# same test as test_popen2(), but using the os.popen*() API
w, r = os.popen2(self.cmd)
self.validate_output(self.teststr, self.expected, r, w)
def test_os_popen3(self):
# same test as test_popen3(), but using the os.popen*() API
if os.name == 'posix':
w, r, e = os.popen3([self.cmd])
self.validate_output(self.teststr, self.expected, r, w, e)
w, r, e = os.popen3(self.cmd)
self.validate_output(self.teststr, self.expected, r, w, e)
def test_main():
run_unittest(Popen2Test)
if __name__ == "__main__":
test_main()

View File

@ -323,13 +323,6 @@ else:
self.assertEqual(makeReturner2(a=11)()['a'], 11) self.assertEqual(makeReturner2(a=11)()['a'], 11)
def makeAddPair((a, b)):
def addPair((c, d)):
return (a + c, b + d)
return addPair
self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202))
def testScopeOfGlobalStmt(self): def testScopeOfGlobalStmt(self):
# Examples posted by Samuele Pedroni to python-dev on 3/1/2001 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001

View File

@ -184,7 +184,7 @@ class TestDecorateSortUndecorate(unittest.TestCase):
def test_stability(self): def test_stability(self):
data = [(random.randrange(100), i) for i in range(200)] data = [(random.randrange(100), i) for i in range(200)]
copy = data[:] copy = data[:]
data.sort(key=lambda (x,y): x) # sort on the random first field data.sort(key=lambda t: t[0]) # sort on the random first field
copy.sort() # sort using both fields copy.sort() # sort using both fields
self.assertEqual(data, copy) # should get the same result self.assertEqual(data, copy) # should get the same result

View File

@ -14,7 +14,7 @@ process_pid = os.getpid()
signalled_all=thread.allocate_lock() signalled_all=thread.allocate_lock()
def registerSignals((for_usr1, for_usr2, for_alrm)): def registerSignals(for_usr1, for_usr2, for_alrm):
usr1 = signal.signal(signal.SIGUSR1, for_usr1) usr1 = signal.signal(signal.SIGUSR1, for_usr1)
usr2 = signal.signal(signal.SIGUSR2, for_usr2) usr2 = signal.signal(signal.SIGUSR2, for_usr2)
alrm = signal.signal(signal.SIGALRM, for_alrm) alrm = signal.signal(signal.SIGALRM, for_alrm)
@ -74,11 +74,11 @@ def test_main():
signal.SIGUSR2 : {'tripped': 0, 'tripped_by': 0 }, signal.SIGUSR2 : {'tripped': 0, 'tripped_by': 0 },
signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } } signal.SIGALRM : {'tripped': 0, 'tripped_by': 0 } }
oldsigs = registerSignals((handle_signals, handle_signals, handle_signals)) oldsigs = registerSignals(handle_signals, handle_signals, handle_signals)
try: try:
run_unittest(ThreadSignals) run_unittest(ThreadSignals)
finally: finally:
registerSignals(oldsigs) registerSignals(*oldsigs)
if __name__ == '__main__': if __name__ == '__main__':
test_main() test_main()

View File

@ -128,10 +128,9 @@ class _RLock(_Verbose):
# Internal methods used by condition variables # Internal methods used by condition variables
def _acquire_restore(self, (count, owner)): def _acquire_restore(self, state):
self.__block.acquire() self.__block.acquire()
self.__count = count self.__count, self.__owner = state
self.__owner = owner
if __debug__: if __debug__:
self._note("%s._acquire_restore()", self) self._note("%s._acquire_restore()", self)

View File

@ -131,7 +131,8 @@ class TokenError(Exception): pass
class StopTokenizing(Exception): pass class StopTokenizing(Exception): pass
def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing def printtoken(type, token, startrowcol, endrowcol, line): # for testing
(srow, scol), (erow, ecol) = startrowcol, endrowcol
print("%d,%d-%d,%d:\t%s\t%s" % \ print("%d,%d-%d,%d:\t%s\t%s" % \
(srow, scol, erow, ecol, tok_name[type], repr(token))) (srow, scol, erow, ecol, tok_name[type], repr(token)))

View File

@ -220,16 +220,18 @@ def urlsplit(url, scheme='', allow_fragments=True):
_parse_cache[key] = v _parse_cache[key] = v
return v return v
def urlunparse((scheme, netloc, url, params, query, fragment)): def urlunparse(components):
"""Put a parsed URL back together again. This may result in a """Put a parsed URL back together again. This may result in a
slightly different, but equivalent URL, if the URL that was parsed slightly different, but equivalent URL, if the URL that was parsed
originally had redundant delimiters, e.g. a ? with an empty query originally had redundant delimiters, e.g. a ? with an empty query
(the draft states that these are equivalent).""" (the draft states that these are equivalent)."""
scheme, netloc, url, params, query, fragment = components
if params: if params:
url = "%s;%s" % (url, params) url = "%s;%s" % (url, params)
return urlunsplit((scheme, netloc, url, query, fragment)) return urlunsplit((scheme, netloc, url, query, fragment))
def urlunsplit((scheme, netloc, url, query, fragment)): def urlunsplit(components):
scheme, netloc, url, query, fragment = components
if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'): if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
if url and url[:1] != '/': url = '/' + url if url and url[:1] != '/': url = '/' + url
url = '//' + (netloc or '') + url url = '//' + (netloc or '') + url

View File

@ -384,7 +384,8 @@ class Wave_write:
def getcompname(self): def getcompname(self):
return self._compname return self._compname
def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)): def setparams(self, params):
nchannels, sampwidth, framerate, nframes, comptype, compname = params
if self._datawritten: if self._datawritten:
raise Error, 'cannot change parameters after starting to write' raise Error, 'cannot change parameters after starting to write'
self.setnchannels(nchannels) self.setnchannels(nchannels)

View File

@ -714,7 +714,7 @@ PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \
PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
LIBSUBDIRS= lib-tk site-packages test test/output test/data \ LIBSUBDIRS= lib-tk site-packages test test/output test/data \
test/decimaltestdata \ test/decimaltestdata \
encodings compiler hotshot \ encodings hotshot \
email email/mime email/test email/test/data \ email email/mime email/test email/test/data \
sqlite3 sqlite3/test \ sqlite3 sqlite3/test \
logging bsddb bsddb/test csv wsgiref \ logging bsddb bsddb/test csv wsgiref \

View File

@ -26,6 +26,8 @@ TO DO
Core and Builtins Core and Builtins
----------------- -----------------
- Remove tuple parameter unpacking (PEP 3113).
- Remove the f_restricted attribute from frames. This naturally leads to teh - Remove the f_restricted attribute from frames. This naturally leads to teh
removal of PyEval_GetRestricted() and PyFrame_IsRestricted(). removal of PyEval_GetRestricted() and PyFrame_IsRestricted().
@ -178,8 +180,10 @@ Extension Modules
Library Library
------- -------
- Remove the compiler package. Use of the _ast module and (an eventual) AST -> - Remove popen2 module and os.popen* functions.
bytecode mechanism.
- Remove the compiler package. Use of the _ast module and (an eventual)
AST -> bytecode mechanism.
- Remove md5 and sha. Both have been deprecated since Python 2.5. - Remove md5 and sha. Both have been deprecated since Python 2.5.

View File

@ -1919,7 +1919,6 @@ pickle Pickling (save and restore) of Python objects (a faster
Cimplementation exists in built-in module: cPickle). Cimplementation exists in built-in module: cPickle).
pipes Conversion pipeline templates. pipes Conversion pipeline templates.
pkgunil Utilities for working with Python packages. pkgunil Utilities for working with Python packages.
popen2 variations on pipe open.
poplib A POP3 client class. Based on the J. Myers POP3 draft. poplib A POP3 client class. Based on the J. Myers POP3 draft.
posixfile Extended (posix) file operations. posixfile Extended (posix) file operations.
posixpath Common operations on POSIX pathnames. posixpath Common operations on POSIX pathnames.

View File

@ -1031,7 +1031,7 @@ save_long(Picklerobject *self, PyObject *args)
Py_ssize_t size; Py_ssize_t size;
int res = -1; int res = -1;
PyObject *repr = NULL; PyObject *repr = NULL;
int val = PyInt_AsLong(args); long val = PyInt_AsLong(args);
static char l = LONG; static char l = LONG;
if (val == -1 && PyErr_Occurred()) { if (val == -1 && PyErr_Occurred()) {

View File

@ -854,7 +854,7 @@ VALIDATER(node); VALIDATER(small_stmt);
VALIDATER(class); VALIDATER(node); VALIDATER(class); VALIDATER(node);
VALIDATER(parameters); VALIDATER(suite); VALIDATER(parameters); VALIDATER(suite);
VALIDATER(testlist); VALIDATER(varargslist); VALIDATER(testlist); VALIDATER(varargslist);
VALIDATER(vfpdef); VALIDATER(vfplist); VALIDATER(vfpdef);
VALIDATER(stmt); VALIDATER(simple_stmt); VALIDATER(stmt); VALIDATER(simple_stmt);
VALIDATER(expr_stmt); VALIDATER(power); VALIDATER(expr_stmt); VALIDATER(power);
VALIDATER(del_stmt); VALIDATER(del_stmt);
@ -862,7 +862,7 @@ VALIDATER(return_stmt); VALIDATER(raise_stmt);
VALIDATER(import_stmt); VALIDATER(import_stmt); VALIDATER(import_stmt); VALIDATER(import_stmt);
VALIDATER(import_name); VALIDATER(yield_stmt); VALIDATER(import_name); VALIDATER(yield_stmt);
VALIDATER(global_stmt); VALIDATER(assert_stmt); VALIDATER(global_stmt); VALIDATER(assert_stmt);
VALIDATER(compound_stmt); VALIDATER(vname); VALIDATER(compound_stmt);
VALIDATER(while); VALIDATER(for); VALIDATER(while); VALIDATER(for);
VALIDATER(try); VALIDATER(except_clause); VALIDATER(try); VALIDATER(except_clause);
VALIDATER(test); VALIDATER(and_test); VALIDATER(test); VALIDATER(and_test);
@ -1111,18 +1111,18 @@ validate_testlist1(node *tree)
} }
/* validate either vname or tname. /* validate either vfpdef or tfpdef.
* vname: NAME * vfpdef: NAME
* tname: NAME [':' test] * tfpdef: NAME [':' test]
*/ */
static int static int
validate_vname(node *tree) validate_vfpdef(node *tree)
{ {
int nch = NCH(tree); int nch = NCH(tree);
if (TYPE(tree) == vname) { if (TYPE(tree) == vfpdef) {
return nch == 1 && validate_name(CHILD(tree, 0), NULL); return nch == 1 && validate_name(CHILD(tree, 0), NULL);
} }
else if (TYPE(tree) == tname) { else if (TYPE(tree) == tfpdef) {
if (nch == 1) { if (nch == 1) {
return validate_name(CHILD(tree, 0), NULL); return validate_name(CHILD(tree, 0), NULL);
} }
@ -1135,8 +1135,8 @@ validate_vname(node *tree)
return 0; return 0;
} }
/* '*' vname (',' vname ['=' test])* [',' '**' vname] | '**' vname /* '*' vfpdef (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef
* ..or tname in place of vname. vname: NAME; tname: NAME [':' test] * ..or tfpdef in place of vfpdef. vfpdef: NAME; tfpdef: NAME [':' test]
*/ */
static int static int
validate_varargslist_trailer(node *tree, int start) validate_varargslist_trailer(node *tree, int start)
@ -1152,27 +1152,27 @@ validate_varargslist_trailer(node *tree, int start)
sym = TYPE(CHILD(tree, start)); sym = TYPE(CHILD(tree, start));
if (sym == STAR) { if (sym == STAR) {
/* /*
* '*' vname (',' vname ['=' test])* [',' '**' vname] | '**' vname * '*' vfpdef (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef
*/ */
if (nch-start == 2) if (nch-start == 2)
res = validate_vname(CHILD(tree, start+1)); res = validate_vfpdef(CHILD(tree, start+1));
else if (nch-start == 5 && TYPE(CHILD(tree, start+2)) == COMMA) else if (nch-start == 5 && TYPE(CHILD(tree, start+2)) == COMMA)
res = (validate_vname(CHILD(tree, start+1)) res = (validate_vfpdef(CHILD(tree, start+1))
&& validate_comma(CHILD(tree, start+2)) && validate_comma(CHILD(tree, start+2))
&& validate_doublestar(CHILD(tree, start+3)) && validate_doublestar(CHILD(tree, start+3))
&& validate_vname(CHILD(tree, start+4))); && validate_vfpdef(CHILD(tree, start+4)));
else { else {
/* skip over vname (',' vname ['=' test])* */ /* skip over vfpdef (',' vfpdef ['=' test])* */
i = start + 1; i = start + 1;
if (TYPE(CHILD(tree, i)) == vname || if (TYPE(CHILD(tree, i)) == vfpdef ||
TYPE(CHILD(tree, i)) == tname) { /* skip over vname or tname */ TYPE(CHILD(tree, i)) == tfpdef) { /* skip over vfpdef or tfpdef */
i += 1; i += 1;
} }
while (res && i+1 < nch) { /* validate (',' vname ['=' test])* */ while (res && i+1 < nch) { /* validate (',' vfpdef ['=' test])* */
res = validate_comma(CHILD(tree, i)); res = validate_comma(CHILD(tree, i));
if (TYPE(CHILD(tree, i+1)) == DOUBLESTAR) if (TYPE(CHILD(tree, i+1)) == DOUBLESTAR)
break; break;
res = res && validate_vname(CHILD(tree, i+1)); res = res && validate_vfpdef(CHILD(tree, i+1));
if (res && i+2 < nch && TYPE(CHILD(tree, i+2)) == EQUAL) { if (res && i+2 < nch && TYPE(CHILD(tree, i+2)) == EQUAL) {
res = res && (i+3 < nch) res = res && (i+3 < nch)
&& validate_test(CHILD(tree, i+3)); && validate_test(CHILD(tree, i+3));
@ -1182,9 +1182,9 @@ validate_varargslist_trailer(node *tree, int start)
i += 2; i += 2;
} }
} }
/* [',' '**' vname] */ /* [',' '**' vfpdef] */
if (res && i+1 < nch && TYPE(CHILD(tree, i+1)) == DOUBLESTAR) { if (res && i+1 < nch && TYPE(CHILD(tree, i+1)) == DOUBLESTAR) {
res = validate_vname(CHILD(tree, i+2)); res = validate_vfpdef(CHILD(tree, i+2));
} }
} }
} }
@ -1193,7 +1193,7 @@ validate_varargslist_trailer(node *tree, int start)
* '**' NAME * '**' NAME
*/ */
if (nch-start == 2) if (nch-start == 2)
res = validate_vname(CHILD(tree, start+1)); res = validate_vfpdef(CHILD(tree, start+1));
} }
if (!res) if (!res)
err_string("illegal variable argument trailer for varargslist"); err_string("illegal variable argument trailer for varargslist");
@ -1206,19 +1206,15 @@ validate_varargslist_trailer(node *tree, int start)
* Validate typedargslist or varargslist. * Validate typedargslist or varargslist.
* *
* typedargslist: ((tfpdef ['=' test] ',')* * typedargslist: ((tfpdef ['=' test] ',')*
* ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | * ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] |
* '**' tname) * '**' tfpdef)
* | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) * | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
* tname: NAME [':' test] * tfpdef: NAME [':' test]
* tfpdef: tname | '(' tfplist ')'
* tfplist: tfpdef (',' tfpdef)* [',']
* varargslist: ((vfpdef ['=' test] ',')* * varargslist: ((vfpdef ['=' test] ',')*
* ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | * ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] |
* '**' vname) * '**' vfpdef)
* | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) * | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
* vname: NAME * vfpdef: NAME
* vfpdef: vname | '(' vfplist ')'
* vfplist: vfpdef (',' vfpdef)* [',']
* *
*/ */
static int static int
@ -1229,92 +1225,38 @@ validate_varargslist(node *tree)
TYPE(tree) == typedargslist) && TYPE(tree) == typedargslist) &&
(nch != 0); (nch != 0);
int sym; int sym;
node *ch;
int i = 0;
if (!res) if (!res)
return 0; return 0;
if (nch < 1) { if (nch < 1) {
err_string("varargslist missing child nodes"); err_string("varargslist missing child nodes");
return 0; return 0;
} }
sym = TYPE(CHILD(tree, 0)); while (i < nch) {
if (sym == STAR || sym == DOUBLESTAR) ch = CHILD(tree, i);
/* whole thing matches: sym = TYPE(ch);
* '*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME if (sym == vfpdef || sym == tfpdef) {
*/ /* validate (vfpdef ['=' test] ',')+ */
res = validate_varargslist_trailer(tree, 0); res = validate_vfpdef(ch);
else if (sym == vfpdef || sym == tfpdef) {
int i = 0;
sym = TYPE(CHILD(tree, nch-1));
if (sym == vname || sym == tname) {
/*
* (vfpdef ['=' test] ',')+
* ('*' vname [',' '**' vname]
* | '**' vname)
*/
/* skip over (vfpdef ['=' test] ',')+ */
while (res && (i+2 <= nch)) {
res = validate_vfpdef(CHILD(tree, i));
++i;
if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
res = (validate_equal(CHILD(tree, i))
&& validate_test(CHILD(tree, i+1)));
if (res)
i += 2;
}
if (res && i < nch) {
res = validate_comma(CHILD(tree, i));
++i;
if (res && i < nch
&& (TYPE(CHILD(tree, i)) == DOUBLESTAR
|| TYPE(CHILD(tree, i)) == STAR))
break;
}
}
/* .. ('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME)
* i --^^^
*/
if (res)
res = validate_varargslist_trailer(tree, i);
}
else {
/*
* vfpdef ['=' test] (',' vfpdef ['=' test])* [',']
*/
/* strip trailing comma node */
if (sym == COMMA) {
res = validate_comma(CHILD(tree, nch-1));
if (!res)
return 0;
--nch;
}
/*
* vfpdef ['=' test] (',' vfpdef ['=' test])*
*/
res = validate_vfpdef(CHILD(tree, 0));
++i; ++i;
if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) { if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
res = (validate_equal(CHILD(tree, i)) res = (validate_equal(CHILD(tree, i))
&& validate_test(CHILD(tree, i+1))); && validate_test(CHILD(tree, i+1)));
i += 2; if (res)
i += 2;
} }
/* if (res && i < nch) {
* ... (',' vfpdef ['=' test])* res = validate_comma(CHILD(tree, i));
* i ---^^^ ++i;
*/
while (res && (nch - i) >= 2) {
res = (validate_comma(CHILD(tree, i))
&& validate_vfpdef(CHILD(tree, i+1)));
i += 2;
if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
res = (validate_equal(CHILD(tree, i))
&& validate_test(CHILD(tree, i+1)));
i += 2;
}
}
if (res && nch - i != 0) {
res = 0;
err_string("illegal formation for varargslist");
} }
} else if (sym == DOUBLESTAR || sym == STAR) {
res = validate_varargslist_trailer(tree, i);
break;
} else {
res = 0;
err_string("illegal formation for varargslist");
} }
} }
return res; return res;
@ -1379,48 +1321,6 @@ validate_comp_if(node *tree)
} }
/* validate_vfpdef()
*
* Validate vfpdef or tfpdef.
*
* vname: NAME
* vfpdef: vname | '(' vfplist ')'
* vfplist: vfpdef (',' vfpdef)* [',']
*
* tname: NAME [':' test]
* tfpdef: tname | '(' tfplist ')'
* tfplist: tfpdef (',' tfpdef)* [',']
*
*/
static int
validate_vfpdef(node *tree)
{
int nch = NCH(tree);
int typ = TYPE(tree);
int res = typ == vfpdef || typ == tfpdef;
if (res) {
if (nch == 1)
res = validate_vname(CHILD(tree, 0));
else if (nch == 3)
res = (validate_lparen(CHILD(tree, 0))
&& validate_vfplist(CHILD(tree, 1))
&& validate_rparen(CHILD(tree, 2)));
else
res = validate_numnodes(tree, 1, "fpdef");
}
return (res);
}
static int
validate_vfplist(node *tree)
{
return (validate_repeating_list(tree, vfplist,
validate_vfpdef, "vfplist"));
}
/* simple_stmt | compound_stmt /* simple_stmt | compound_stmt
* *
*/ */

View File

@ -171,7 +171,6 @@ Source: DLLs\expat.dll; DestDir: {app}\DLLs; CopyMode: alwaysoverwrite; Componen
Source: Lib\*.py; DestDir: {app}\Lib; CopyMode: alwaysoverwrite; Components: main Source: Lib\*.py; DestDir: {app}\Lib; CopyMode: alwaysoverwrite; Components: main
Source: Lib\compiler\*.*; DestDir: {app}\Lib\compiler; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
Source: Lib\distutils\*.*; DestDir: {app}\Lib\distutils; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs Source: Lib\distutils\*.*; DestDir: {app}\Lib\distutils; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
Source: Lib\email\*.*; DestDir: {app}\Lib\email; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs Source: Lib\email\*.*; DestDir: {app}\Lib\email; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
Source: Lib\encodings\*.*; DestDir: {app}\Lib\encodings; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs Source: Lib\encodings\*.*; DestDir: {app}\Lib\encodings; CopyMode: alwaysoverwrite; Components: main; Flags: recursesubdirs
@ -270,9 +269,6 @@ end.
[UninstallDelete] [UninstallDelete]
Name: {app}\Lib\compiler\*.pyc; Type: files
Name: {app}\Lib\compiler\*.pyo; Type: files
Name: {app}\Lib\compiler; Type: dirifempty
Name: {app}\Lib\distutils\command\*.pyc; Type: files Name: {app}\Lib\distutils\command\*.pyc; Type: files
Name: {app}\Lib\distutils\command\*.pyo; Type: files Name: {app}\Lib\distutils\command\*.pyo; Type: files
Name: {app}\Lib\distutils\command; Type: dirifempty Name: {app}\Lib\distutils\command; Type: dirifempty

View File

@ -110,8 +110,7 @@ module Python version "$Revision$"
arg* kwonlyargs, identifier? kwarg, arg* kwonlyargs, identifier? kwarg,
expr? kwargannotation, expr* defaults, expr? kwargannotation, expr* defaults,
expr* kw_defaults) expr* kw_defaults)
arg = SimpleArg(identifier arg, expr? annotation) arg = (identifier arg, expr? annotation)
| NestedArgs(arg* args)
-- keyword arguments supplied to call -- keyword arguments supplied to call
keyword = (identifier arg, expr value) keyword = (identifier arg, expr value)

View File

@ -115,49 +115,54 @@ class ASDLParser(spark.GenericParser, object):
def error(self, tok): def error(self, tok):
raise ASDLSyntaxError(tok.lineno, tok) raise ASDLSyntaxError(tok.lineno, tok)
def p_module_0(self, (module, name, version, _0, _1)): def p_module_0(self, info):
" module ::= Id Id version { } " " module ::= Id Id version { } "
module, name, version, _0, _1 = info
if module.value != "module": if module.value != "module":
raise ASDLSyntaxError(module.lineno, raise ASDLSyntaxError(module.lineno,
msg="expected 'module', found %s" % module) msg="expected 'module', found %s" % module)
return Module(name, None, version) return Module(name, None, version)
def p_module(self, (module, name, version, _0, definitions, _1)): def p_module(self, info):
" module ::= Id Id version { definitions } " " module ::= Id Id version { definitions } "
module, name, version, _0, definitions, _1 = info
if module.value != "module": if module.value != "module":
raise ASDLSyntaxError(module.lineno, raise ASDLSyntaxError(module.lineno,
msg="expected 'module', found %s" % module) msg="expected 'module', found %s" % module)
return Module(name, definitions, version) return Module(name, definitions, version)
def p_version(self, (version, V)): def p_version(self, info):
"version ::= Id String" "version ::= Id String"
version, V = info
if version.value != "version": if version.value != "version":
raise ASDLSyntaxError(version.lineno, raise ASDLSyntaxError(version.lineno,
msg="expected 'version', found %" % version) msg="expected 'version', found %" % version)
return V return V
def p_definition_0(self, (definition,)): def p_definition_0(self, definition):
" definitions ::= definition " " definitions ::= definition "
return definition return definition[0]
def p_definition_1(self, (definitions, definition)): def p_definition_1(self, definitions):
" definitions ::= definition definitions " " definitions ::= definition definitions "
return definitions + definition return definitions[0] + definitions[1]
def p_definition(self, (id, _, type)): def p_definition(self, info):
" definition ::= Id = type " " definition ::= Id = type "
id, _, type = info
return [Type(id, type)] return [Type(id, type)]
def p_type_0(self, (product,)): def p_type_0(self, product):
" type ::= product " " type ::= product "
return product return product[0]
def p_type_1(self, (sum,)): def p_type_1(self, sum):
" type ::= sum " " type ::= sum "
return Sum(sum) return Sum(sum[0])
def p_type_2(self, (sum, id, _0, attributes, _1)): def p_type_2(self, info):
" type ::= sum Id ( fields ) " " type ::= sum Id ( fields ) "
sum, id, _0, attributes, _1 = info
if id.value != "attributes": if id.value != "attributes":
raise ASDLSyntaxError(id.lineno, raise ASDLSyntaxError(id.lineno,
msg="expected attributes, found %s" % id) msg="expected attributes, found %s" % id)
@ -165,65 +170,73 @@ class ASDLParser(spark.GenericParser, object):
attributes.reverse() attributes.reverse()
return Sum(sum, attributes) return Sum(sum, attributes)
def p_product(self, (_0, fields, _1)): def p_product(self, info):
" product ::= ( fields ) " " product ::= ( fields ) "
_0, fields, _1 = info
# XXX can't I just construct things in the right order? # XXX can't I just construct things in the right order?
fields.reverse() fields.reverse()
return Product(fields) return Product(fields)
def p_sum_0(self, (constructor,)): def p_sum_0(self, constructor):
" sum ::= constructor """ " sum ::= constructor """
return [constructor] return [constructor[0]]
def p_sum_1(self, (constructor, _, sum)): def p_sum_1(self, ):
" sum ::= constructor | sum " " sum ::= constructor | sum "
constructor, _, sum = info
return [constructor] + sum return [constructor] + sum
def p_sum_2(self, (constructor, _, sum)): def p_sum_2(self, info):
" sum ::= constructor | sum " " sum ::= constructor | sum "
constructor, _, sum = info
return [constructor] + sum return [constructor] + sum
def p_constructor_0(self, (id,)): def p_constructor_0(self, id):
" constructor ::= Id " " constructor ::= Id "
return Constructor(id) return Constructor(id[0])
def p_constructor_1(self, (id, _0, fields, _1)): def p_constructor_1(self, info):
" constructor ::= Id ( fields ) " " constructor ::= Id ( fields ) "
id, _0, fields, _1 = info
# XXX can't I just construct things in the right order? # XXX can't I just construct things in the right order?
fields.reverse() fields.reverse()
return Constructor(id, fields) return Constructor(id, fields)
def p_fields_0(self, (field,)): def p_fields_0(self, field):
" fields ::= field " " fields ::= field "
return [field] return [field[0]]
def p_fields_1(self, (field, _, fields)): def p_fields_1(self, info):
" fields ::= field , fields " " fields ::= field , fields "
field, _, fields = info
return fields + [field] return fields + [field]
def p_field_0(self, (type,)): def p_field_0(self, type_):
" field ::= Id " " field ::= Id "
return Field(type) return Field(type_[0])
def p_field_1(self, (type, name)): def p_field_1(self, info):
" field ::= Id Id " " field ::= Id Id "
type, name = info
return Field(type, name) return Field(type, name)
def p_field_2(self, (type, _, name)): def p_field_2(self, info):
" field ::= Id * Id " " field ::= Id * Id "
type, _, name = info
return Field(type, name, seq=1) return Field(type, name, seq=1)
def p_field_3(self, (type, _, name)): def p_field_3(self, info):
" field ::= Id ? Id " " field ::= Id ? Id "
type, _, name = info
return Field(type, name, opt=1) return Field(type, name, opt=1)
def p_field_4(self, (type, _)): def p_field_4(self, type_):
" field ::= Id * " " field ::= Id * "
return Field(type, seq=1) return Field(type_[0], seq=1)
def p_field_5(self, (type, _)): def p_field_5(self, type_):
" field ::= Id ? " " field ::= Id ? "
return Field(type, opt=1) return Field(type[0], opt=1)
builtin_types = ("identifier", "string", "int", "bool", "object") builtin_types = ("identifier", "string", "int", "bool", "object")

View File

@ -353,10 +353,10 @@ class GenericParser:
# #
return self._NULLABLE == sym[0:len(self._NULLABLE)] return self._NULLABLE == sym[0:len(self._NULLABLE)]
def skip(self, (lhs, rhs), pos=0): def skip(self, hs, pos=0):
n = len(rhs) n = len(hs[1])
while pos < n: while pos < n:
if not self.isnullable(rhs[pos]): if not self.isnullable(hs[1][pos]):
break break
pos = pos + 1 pos = pos + 1
return pos return pos
@ -671,7 +671,7 @@ class GenericParser:
sortlist.append((len(rhs), name)) sortlist.append((len(rhs), name))
name2index[name] = i name2index[name] = i
sortlist.sort() sortlist.sort()
list = map(lambda (a,b): b, sortlist) list = [b for a, b in sortlist]
return rules[name2index[self.resolve(list)]] return rules[name2index[self.resolve(list)]]
def resolve(self, list): def resolve(self, list):

View File

@ -2,7 +2,7 @@
/* /*
__version__ 54835. __version__ 55270.
This module must be committed separately after each AST grammar change; This module must be committed separately after each AST grammar change;
The __version__ number is set to the revision number of the commit The __version__ number is set to the revision number of the commit
@ -367,15 +367,10 @@ static char *arguments_fields[]={
}; };
static PyTypeObject *arg_type; static PyTypeObject *arg_type;
static PyObject* ast2obj_arg(void*); static PyObject* ast2obj_arg(void*);
static PyTypeObject *SimpleArg_type; static char *arg_fields[]={
static char *SimpleArg_fields[]={
"arg", "arg",
"annotation", "annotation",
}; };
static PyTypeObject *NestedArgs_type;
static char *NestedArgs_fields[]={
"args",
};
static PyTypeObject *keyword_type; static PyTypeObject *keyword_type;
static PyObject* ast2obj_keyword(void*); static PyObject* ast2obj_keyword(void*);
static char *keyword_fields[]={ static char *keyword_fields[]={
@ -752,14 +747,8 @@ static int init_types(void)
if (!excepthandler_type) return 0; if (!excepthandler_type) return 0;
arguments_type = make_type("arguments", AST_type, arguments_fields, 8); arguments_type = make_type("arguments", AST_type, arguments_fields, 8);
if (!arguments_type) return 0; if (!arguments_type) return 0;
arg_type = make_type("arg", AST_type, NULL, 0); arg_type = make_type("arg", AST_type, arg_fields, 2);
if (!arg_type) return 0; if (!arg_type) return 0;
if (!add_attributes(arg_type, NULL, 0)) return 0;
SimpleArg_type = make_type("SimpleArg", arg_type, SimpleArg_fields, 2);
if (!SimpleArg_type) return 0;
NestedArgs_type = make_type("NestedArgs", arg_type, NestedArgs_fields,
1);
if (!NestedArgs_type) return 0;
keyword_type = make_type("keyword", AST_type, keyword_fields, 2); keyword_type = make_type("keyword", AST_type, keyword_fields, 2);
if (!keyword_type) return 0; if (!keyword_type) return 0;
alias_type = make_type("alias", AST_type, alias_fields, 2); alias_type = make_type("alias", AST_type, alias_fields, 2);
@ -1865,32 +1854,19 @@ arguments(asdl_seq * args, identifier vararg, expr_ty varargannotation,
} }
arg_ty arg_ty
SimpleArg(identifier arg, expr_ty annotation, PyArena *arena) arg(identifier arg, expr_ty annotation, PyArena *arena)
{ {
arg_ty p; arg_ty p;
if (!arg) { if (!arg) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"field arg is required for SimpleArg"); "field arg is required for arg");
return NULL; return NULL;
} }
p = (arg_ty)PyArena_Malloc(arena, sizeof(*p)); p = (arg_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p) if (!p)
return NULL; return NULL;
p->kind = SimpleArg_kind; p->arg = arg;
p->v.SimpleArg.arg = arg; p->annotation = annotation;
p->v.SimpleArg.annotation = annotation;
return p;
}
arg_ty
NestedArgs(asdl_seq * args, PyArena *arena)
{
arg_ty p;
p = (arg_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->kind = NestedArgs_kind;
p->v.NestedArgs.args = args;
return p; return p;
} }
@ -3048,31 +3024,18 @@ ast2obj_arg(void* _o)
return Py_None; return Py_None;
} }
switch (o->kind) { result = PyType_GenericNew(arg_type, NULL, NULL);
case SimpleArg_kind: if (!result) return NULL;
result = PyType_GenericNew(SimpleArg_type, NULL, NULL); value = ast2obj_identifier(o->arg);
if (!result) goto failed; if (!value) goto failed;
value = ast2obj_identifier(o->v.SimpleArg.arg); if (PyObject_SetAttrString(result, "arg", value) == -1)
if (!value) goto failed; goto failed;
if (PyObject_SetAttrString(result, "arg", value) == -1) Py_DECREF(value);
goto failed; value = ast2obj_expr(o->annotation);
Py_DECREF(value); if (!value) goto failed;
value = ast2obj_expr(o->v.SimpleArg.annotation); if (PyObject_SetAttrString(result, "annotation", value) == -1)
if (!value) goto failed; goto failed;
if (PyObject_SetAttrString(result, "annotation", value) == -1) Py_DECREF(value);
goto failed;
Py_DECREF(value);
break;
case NestedArgs_kind:
result = PyType_GenericNew(NestedArgs_type, NULL, NULL);
if (!result) goto failed;
value = ast2obj_list(o->v.NestedArgs.args, ast2obj_arg);
if (!value) goto failed;
if (PyObject_SetAttrString(result, "args", value) == -1)
goto failed;
Py_DECREF(value);
break;
}
return result; return result;
failed: failed:
Py_XDECREF(value); Py_XDECREF(value);
@ -3150,7 +3113,7 @@ init_ast(void)
if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return; if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
return; return;
if (PyModule_AddStringConstant(m, "__version__", "54835") < 0) if (PyModule_AddStringConstant(m, "__version__", "55270") < 0)
return; return;
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
@ -3295,10 +3258,6 @@ init_ast(void)
if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) < if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
0) return; 0) return;
if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return; if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return;
if (PyDict_SetItemString(d, "SimpleArg", (PyObject*)SimpleArg_type) <
0) return;
if (PyDict_SetItemString(d, "NestedArgs", (PyObject*)NestedArgs_type) <
0) return;
if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0) if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0)
return; return;
if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return; if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;

View File

@ -566,13 +566,13 @@ seq_for_testlist(struct compiling *c, const node *n)
} }
static arg_ty static arg_ty
compiler_simple_arg(struct compiling *c, const node *n) compiler_arg(struct compiling *c, const node *n)
{ {
identifier name; identifier name;
expr_ty annotation = NULL; expr_ty annotation = NULL;
node *ch; node *ch;
assert(TYPE(n) == tname || TYPE(n) == vname); assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef);
ch = CHILD(n, 0); ch = CHILD(n, 0);
if (!strcmp(STR(ch), "None")) { if (!strcmp(STR(ch), "None")) {
ast_error(ch, "assignment to None"); ast_error(ch, "assignment to None");
@ -588,51 +588,12 @@ compiler_simple_arg(struct compiling *c, const node *n)
return NULL; return NULL;
} }
return SimpleArg(name, annotation, c->c_arena); return arg(name, annotation, c->c_arena);
}
static arg_ty
compiler_complex_args(struct compiling *c, const node *n)
{
int i, len = (NCH(n) + 1) / 2;
arg_ty arg;
asdl_seq *args = asdl_seq_new(len, c->c_arena);
if (!args)
return NULL;
assert(TYPE(n) == tfplist || TYPE(n) == vfplist);
for (i = 0; i < len; i++) {
const node *child = CHILD(n, 2*i);
/* def foo(((x), y)): -- x is not nested complex, special case. */
while (NCH(child) == 3 && NCH(CHILD(child, 1)) == 1)
child = CHILD(CHILD(child, 1), 0);
/* child either holds a tname or '(', a tfplist, ')' */
switch (TYPE(CHILD(child, 0))) {
case tname:
case vname:
arg = compiler_simple_arg(c, CHILD(child, 0));
break;
case LPAR:
arg = compiler_complex_args(c, CHILD(child, 1));
break;
default:
PyErr_Format(PyExc_SystemError,
"unexpected node in args: %d @ %d",
TYPE(CHILD(child, 0)), i);
arg = NULL;
}
if (!arg)
return NULL;
asdl_seq_SET(args, i, arg);
}
return NestedArgs(args, c->c_arena);
} }
/* returns -1 if failed to handle keyword only arguments /* returns -1 if failed to handle keyword only arguments
returns new position to keep processing if successful returns new position to keep processing if successful
(',' tname ['=' test])* (',' tfpdef ['=' test])*
^^^ ^^^
start pointing here start pointing here
*/ */
@ -650,8 +611,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
while (i < NCH(n)) { while (i < NCH(n)) {
ch = CHILD(n, i); ch = CHILD(n, i);
switch (TYPE(ch)) { switch (TYPE(ch)) {
case vname: case vfpdef:
case tname: case tfpdef:
if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
expression = ast_for_expr(c, CHILD(n, i + 2)); expression = ast_for_expr(c, CHILD(n, i + 2));
if (!expression) { if (!expression) {
@ -680,7 +641,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
ast_error(ch, "assignment to None"); ast_error(ch, "assignment to None");
goto error; goto error;
} }
arg = SimpleArg(NEW_IDENTIFIER(ch), annotation, c->c_arena); arg = arg(NEW_IDENTIFIER(ch), annotation, c->c_arena);
if (!arg) { if (!arg) {
ast_error(ch, "expecting name"); ast_error(ch, "expecting name");
goto error; goto error;
@ -710,13 +671,15 @@ ast_for_arguments(struct compiling *c, const node *n)
parameters: '(' [typedargslist] ')' parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')* typedargslist: ((tfpdef ['=' test] ',')*
('*' [tname] (',' tname ['=' test])* [',' '**' tname] ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef]
| '**' tname) | '**' tfpdef)
| tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
tfpdef: NAME [':' test]
varargslist: ((vfpdef ['=' test] ',')* varargslist: ((vfpdef ['=' test] ',')*
('*' [vname] (',' vname ['=' test])* [',' '**' vname] ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef]
| '**' vname) | '**' vfpdef)
| vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
vfpdef: NAME
*/ */
int i, j, k, nposargs = 0, nkwonlyargs = 0; int i, j, k, nposargs = 0, nkwonlyargs = 0;
int nposdefaults = 0, found_default = 0; int nposdefaults = 0, found_default = 0;
@ -738,17 +701,13 @@ ast_for_arguments(struct compiling *c, const node *n)
for (i = 0; i < NCH(n); i++) { for (i = 0; i < NCH(n); i++) {
ch = CHILD(n, i); ch = CHILD(n, i);
if (TYPE(ch) == STAR) { if (TYPE(ch) == STAR) {
if (TYPE(CHILD(n, i+1)) == tname /* skip star and possible argument */
|| TYPE(CHILD(n, i+1)) == vname) { i++;
/* skip NAME of vararg */ i += (TYPE(CHILD(n, i)) == tfpdef
/* so that following can count only keyword only args */ || TYPE(CHILD(n, i)) == vfpdef);
i += 2;
}
else {
i++;
}
break; break;
} }
if (TYPE(ch) == DOUBLESTAR) break;
if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++;
if (TYPE(ch) == EQUAL) nposdefaults++; if (TYPE(ch) == EQUAL) nposdefaults++;
} }
@ -757,9 +716,8 @@ ast_for_arguments(struct compiling *c, const node *n)
for ( ; i < NCH(n); ++i) { for ( ; i < NCH(n); ++i) {
ch = CHILD(n, i); ch = CHILD(n, i);
if (TYPE(ch) == DOUBLESTAR) break; if (TYPE(ch) == DOUBLESTAR) break;
if (TYPE(ch) == tname || TYPE(ch) == vname) nkwonlyargs++; if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++;
} }
posargs = (nposargs ? asdl_seq_new(nposargs, c->c_arena) : NULL); posargs = (nposargs ? asdl_seq_new(nposargs, c->c_arena) : NULL);
if (!posargs && nposargs) if (!posargs && nposargs)
goto error; goto error;
@ -784,12 +742,8 @@ ast_for_arguments(struct compiling *c, const node *n)
return NULL; return NULL;
} }
/* tname: NAME [':' test] /* tfpdef: NAME [':' test]
tfpdef: tname | '(' tfplist ')' vfpdef: NAME
tfplist: tfpdef (',' tfpdef)* [',']
vname: NAME
vfpdef: NAME | '(' vfplist ')'
vfplist: vfpdef (',' vfpdef)* [',']
*/ */
i = 0; i = 0;
j = 0; /* index for defaults */ j = 0; /* index for defaults */
@ -816,14 +770,7 @@ ast_for_arguments(struct compiling *c, const node *n)
"non-default argument follows default argument"); "non-default argument follows default argument");
goto error; goto error;
} }
/* def foo((x)): is not complex, special case. */ arg = compiler_arg(c, ch);
while (NCH(ch) == 3 && NCH(CHILD(ch, 1)) == 1)
ch = CHILD(CHILD(ch, 1), 0);
if (NCH(ch) != 1)
arg = compiler_complex_args(c, CHILD(ch, 1));
else
arg = compiler_simple_arg(c, CHILD(ch, 0));
if (!arg) if (!arg)
goto error; goto error;
asdl_seq_SET(posargs, k++, arg); asdl_seq_SET(posargs, k++, arg);
@ -835,7 +782,7 @@ ast_for_arguments(struct compiling *c, const node *n)
ast_error(CHILD(n, i), "no name for vararg"); ast_error(CHILD(n, i), "no name for vararg");
goto error; goto error;
} }
ch = CHILD(n, i+1); /* tname or COMMA */ ch = CHILD(n, i+1); /* tfpdef or COMMA */
if (TYPE(ch) == COMMA) { if (TYPE(ch) == COMMA) {
int res = 0; int res = 0;
i += 2; /* now follows keyword only arguments */ i += 2; /* now follows keyword only arguments */
@ -851,12 +798,12 @@ ast_for_arguments(struct compiling *c, const node *n)
else { else {
vararg = NEW_IDENTIFIER(CHILD(ch, 0)); vararg = NEW_IDENTIFIER(CHILD(ch, 0));
if (NCH(ch) > 1) { if (NCH(ch) > 1) {
/* there is an annotation on the vararg */ /* there is an annotation on the vararg */
varargannotation = ast_for_expr(c, CHILD(ch, 2)); varargannotation = ast_for_expr(c, CHILD(ch, 2));
} }
i += 3; i += 3;
if (i < NCH(n) && (TYPE(CHILD(n, i)) == tname if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef
|| TYPE(CHILD(n, i)) == vname)) { || TYPE(CHILD(n, i)) == vfpdef)) {
int res = 0; int res = 0;
res = handle_keywordonly_args(c, n, i, res = handle_keywordonly_args(c, n, i,
kwonlyargs, kwdefaults); kwonlyargs, kwdefaults);
@ -866,8 +813,8 @@ ast_for_arguments(struct compiling *c, const node *n)
} }
break; break;
case DOUBLESTAR: case DOUBLESTAR:
ch = CHILD(n, i+1); /* tname */ ch = CHILD(n, i+1); /* tfpdef */
assert(TYPE(ch) == tname || TYPE(ch) == vname); assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef);
if (!strcmp(STR(CHILD(ch, 0)), "None")) { if (!strcmp(STR(CHILD(ch, 0)), "None")) {
ast_error(CHILD(ch, 0), "assignment to None"); ast_error(CHILD(ch, 0), "assignment to None");
goto error; goto error;

View File

@ -1282,54 +1282,6 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
return 1; return 1;
} }
static int
compiler_unpack_nested(struct compiler *c, asdl_seq *args) {
int i, len;
len = asdl_seq_LEN(args);
ADDOP_I(c, UNPACK_SEQUENCE, len);
for (i = 0; i < len; i++) {
arg_ty elt = (arg_ty)asdl_seq_GET(args, i);
switch (elt->kind) {
case SimpleArg_kind:
if (!compiler_nameop(c, elt->v.SimpleArg.arg, Store))
return 0;
break;
case NestedArgs_kind:
if (!compiler_unpack_nested(c, elt->v.NestedArgs.args))
return 0;
break;
default:
return 0;
}
}
return 1;
}
static int
compiler_arguments(struct compiler *c, arguments_ty args)
{
int i;
int n = asdl_seq_LEN(args->args);
for (i = 0; i < n; i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args->args, i);
if (arg->kind == NestedArgs_kind) {
PyObject *id = PyString_FromFormat(".%d", i);
if (id == NULL) {
return 0;
}
if (!compiler_nameop(c, id, Load)) {
Py_DECREF(id);
return 0;
}
Py_DECREF(id);
if (!compiler_unpack_nested(c, arg->v.NestedArgs.args))
return 0;
}
}
return 1;
}
static int static int
compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
asdl_seq *kw_defaults) asdl_seq *kw_defaults)
@ -1339,7 +1291,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
arg_ty arg = asdl_seq_GET(kwonlyargs, i); arg_ty arg = asdl_seq_GET(kwonlyargs, i);
expr_ty default_ = asdl_seq_GET(kw_defaults, i); expr_ty default_ = asdl_seq_GET(kw_defaults, i);
if (default_) { if (default_) {
ADDOP_O(c, LOAD_CONST, arg->v.SimpleArg.arg, consts); ADDOP_O(c, LOAD_CONST, arg->arg, consts);
if (!compiler_visit_expr(c, default_)) { if (!compiler_visit_expr(c, default_)) {
return -1; return -1;
} }
@ -1368,17 +1320,11 @@ compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
int i, error; int i, error;
for (i = 0; i < asdl_seq_LEN(args); i++) { for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i); arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
if (arg->kind == NestedArgs_kind) error = compiler_visit_argannotation(
error = compiler_visit_argannotations( c,
c, arg->arg,
arg->v.NestedArgs.args, arg->annotation,
names); names);
else
error = compiler_visit_argannotation(
c,
arg->v.SimpleArg.arg,
arg->v.SimpleArg.annotation,
names);
if (error) if (error)
return error; return error;
} }
@ -1498,9 +1444,6 @@ compiler_function(struct compiler *c, stmt_ty s)
return 0; return 0;
} }
/* unpack nested arguments */
compiler_arguments(c, args);
c->u->u_argcount = asdl_seq_LEN(args->args); c->u->u_argcount = asdl_seq_LEN(args->args);
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
n = asdl_seq_LEN(s->v.FunctionDef.body); n = asdl_seq_LEN(s->v.FunctionDef.body);
@ -1690,9 +1633,6 @@ compiler_lambda(struct compiler *c, expr_ty e)
if (!compiler_enter_scope(c, name, (void *)e, e->lineno)) if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
return 0; return 0;
/* unpack nested arguments */
compiler_arguments(c, args);
c->u->u_argcount = asdl_seq_LEN(args->args); c->u->u_argcount = asdl_seq_LEN(args->args);
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);

File diff suppressed because it is too large Load Diff

View File

@ -180,10 +180,8 @@ static int symtable_visit_alias(struct symtable *st, alias_ty);
static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
static int symtable_visit_keyword(struct symtable *st, keyword_ty); static int symtable_visit_keyword(struct symtable *st, keyword_ty);
static int symtable_visit_slice(struct symtable *st, slice_ty); static int symtable_visit_slice(struct symtable *st, slice_ty);
static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top, static int symtable_visit_params(struct symtable *st, asdl_seq *args);
int annotations); static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args,
int annotations);
static int symtable_implicit_arg(struct symtable *st, int pos); static int symtable_implicit_arg(struct symtable *st, int pos);
static int symtable_visit_annotations(struct symtable *st, stmt_ty s); static int symtable_visit_annotations(struct symtable *st, stmt_ty s);
@ -1328,79 +1326,51 @@ symtable_implicit_arg(struct symtable *st, int pos)
} }
static int static int
symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel, symtable_visit_params(struct symtable *st, asdl_seq *args)
int annotations)
{ {
int i; int i;
if (!args) if (!args)
return -1; return -1;
/* go through all the toplevel arguments first */
for (i = 0; i < asdl_seq_LEN(args); i++) { for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i); arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
if (arg->kind == SimpleArg_kind) { if (!symtable_add_def(st, arg->arg, DEF_PARAM))
if (!annotations) {
if (!symtable_add_def(st,
arg->v.SimpleArg.arg,
DEF_PARAM))
return 0;
}
else if (arg->v.SimpleArg.annotation)
VISIT(st, expr, arg->v.SimpleArg.annotation);
}
else if (arg->kind == NestedArgs_kind) {
if (toplevel && !annotations) {
if (!symtable_implicit_arg(st, i))
return 0;
}
}
else {
PyErr_SetString(PyExc_SyntaxError,
"invalid expression in parameter list");
PyErr_SyntaxLocation(st->st_filename,
st->st_cur->ste_lineno);
return 0;
}
}
if (!toplevel) {
if (!symtable_visit_params_nested(st, args, annotations))
return 0; return 0;
} }
return 1; return 1;
} }
static int static int
symtable_visit_params_nested(struct symtable *st, asdl_seq *args, symtable_visit_argannotations(struct symtable *st, asdl_seq *args)
int annotations)
{ {
int i; int i;
if (!args)
return -1;
for (i = 0; i < asdl_seq_LEN(args); i++) { for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = (arg_ty)asdl_seq_GET(args, i); arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
if (arg->kind == NestedArgs_kind && if (arg->annotation)
!symtable_visit_params(st, arg->v.NestedArgs.args, 0, VISIT(st, expr, arg->annotation);
annotations))
return 0;
} }
return 1; return 1;
} }
static int static int
symtable_visit_annotations(struct symtable *st, stmt_ty s) symtable_visit_annotations(struct symtable *st, stmt_ty s)
{ {
arguments_ty a = s->v.FunctionDef.args; arguments_ty a = s->v.FunctionDef.args;
if (a->args && !symtable_visit_params(st, a->args, 1, 1)) if (a->args && !symtable_visit_argannotations(st, a->args))
return 0; return 0;
if (a->varargannotation) if (a->varargannotation)
VISIT(st, expr, a->varargannotation); VISIT(st, expr, a->varargannotation);
if (a->kwargannotation) if (a->kwargannotation)
VISIT(st, expr, a->kwargannotation); VISIT(st, expr, a->kwargannotation);
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs, 1, 1)) if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs))
return 0; return 0;
if (s->v.FunctionDef.returns) if (s->v.FunctionDef.returns)
VISIT(st, expr, s->v.FunctionDef.returns); VISIT(st, expr, s->v.FunctionDef.returns);
@ -1413,9 +1383,9 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
/* skip default arguments inside function block /* skip default arguments inside function block
XXX should ast be different? XXX should ast be different?
*/ */
if (a->args && !symtable_visit_params(st, a->args, 1, 0)) if (a->args && !symtable_visit_params(st, a->args))
return 0; return 0;
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs, 1, 0)) if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))
return 0; return 0;
if (a->vararg) { if (a->vararg) {
if (!symtable_add_def(st, a->vararg, DEF_PARAM)) if (!symtable_add_def(st, a->vararg, DEF_PARAM))
@ -1427,8 +1397,6 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
return 0; return 0;
st->st_cur->ste_varkeywords = 1; st->st_cur->ste_varkeywords = 1;
} }
if (a->args && !symtable_visit_params_nested(st, a->args, 0))
return 0;
return 1; return 1;
} }

View File

@ -244,7 +244,7 @@ class Reindenter:
return line return line
# Line-eater for tokenize. # Line-eater for tokenize.
def tokeneater(self, type, token, (sline, scol), end, line, def tokeneater(self, type, token, slinecol, end, line,
INDENT=tokenize.INDENT, INDENT=tokenize.INDENT,
DEDENT=tokenize.DEDENT, DEDENT=tokenize.DEDENT,
NEWLINE=tokenize.NEWLINE, NEWLINE=tokenize.NEWLINE,
@ -267,7 +267,7 @@ class Reindenter:
elif type == COMMENT: elif type == COMMENT:
if self.find_stmt: if self.find_stmt:
self.stats.append((sline, -1)) self.stats.append((slinecol[0], -1))
# but we're still looking for a new stmt, so leave # but we're still looking for a new stmt, so leave
# find_stmt alone # find_stmt alone
@ -280,7 +280,7 @@ class Reindenter:
# ENDMARKER. # ENDMARKER.
self.find_stmt = 0 self.find_stmt = 0
if line: # not endmarker if line: # not endmarker
self.stats.append((sline, self.level)) self.stats.append((slinecol[0], self.level))
# Count number of leading blanks. # Count number of leading blanks.
def getlspace(line): def getlspace(line):