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:
parent
360e4b8fb1
commit
1bc535dc78
|
@ -270,7 +270,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
|||
lib/libimaplib.tex \
|
||||
lib/libpoplib.tex \
|
||||
lib/libcalendar.tex \
|
||||
lib/libpopen2.tex \
|
||||
lib/libbisect.tex \
|
||||
lib/libcollections.tex \
|
||||
lib/libheapq.tex \
|
||||
|
|
|
@ -280,7 +280,6 @@ and how to embed it in other applications.
|
|||
\input{libsubprocess}
|
||||
\input{libsocket}
|
||||
\input{libsignal}
|
||||
\input{libpopen2}
|
||||
\input{libasyncore}
|
||||
\input{libasynchat}
|
||||
|
||||
|
|
|
@ -459,7 +459,7 @@ Mark
|
|||
# is differencing with a range so that consecutive numbers all appear in
|
||||
# same group.
|
||||
>>> 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)
|
||||
...
|
||||
[1]
|
||||
|
|
|
@ -378,68 +378,6 @@ deleted once there are no file descriptors for the file.
|
|||
Availability: Macintosh, \UNIX, Windows.
|
||||
\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}}
|
||||
|
||||
|
@ -1575,9 +1513,6 @@ Availability: Macintosh, \UNIX.
|
|||
\end{funcdesc}
|
||||
|
||||
\begin{funcdescni}{popen}{\unspecified}
|
||||
\funclineni{popen2}{\unspecified}
|
||||
\funclineni{popen3}{\unspecified}
|
||||
\funclineni{popen4}{\unspecified}
|
||||
Run child processes, returning opened pipes for communications. These
|
||||
functions are described in section \ref{os-newstreams}.
|
||||
\end{funcdescni}
|
||||
|
|
|
@ -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}
|
|
@ -15,8 +15,6 @@ and functions, such as:
|
|||
\begin{verbatim}
|
||||
os.system
|
||||
os.spawn*
|
||||
os.popen*
|
||||
popen2.*
|
||||
commands.*
|
||||
\end{verbatim}
|
||||
|
||||
|
@ -335,68 +333,3 @@ pipe = os.popen(cmd, mode='w', bufsize)
|
|||
==>
|
||||
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
|
||||
\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}
|
||||
|
|
|
@ -498,8 +498,9 @@ Special attributes:
|
|||
\lineiii{__closure__}{\code{None} or a tuple of cells that contain
|
||||
bindings for the function's free variables.}{Read-only}
|
||||
|
||||
\lineiii{__annotations__}{A dict containing annotations of parameters.}
|
||||
{Writable}
|
||||
\lineiii{__annotations__}{A dict containing annotations of parameters.
|
||||
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
|
||||
parameters.}{Writable}
|
||||
|
|
|
@ -668,11 +668,7 @@ raised.
|
|||
|
||||
Formal parameters using the syntax \samp{*identifier} or
|
||||
\samp{**identifier} cannot be used as positional argument slots or
|
||||
as keyword argument names. Formal parameters using the syntax
|
||||
\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.
|
||||
as keyword argument names.
|
||||
|
||||
A call always returns some value, possibly \code{None}, unless it
|
||||
raises an exception. How this value is computed depends on the type
|
||||
|
@ -1177,7 +1173,8 @@ def name(arguments):
|
|||
\end{verbatim}
|
||||
|
||||
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}
|
||||
|
||||
\section{Expression lists\label{exprlists}}
|
||||
|
|
|
@ -381,6 +381,7 @@ section~\ref{types}):
|
|||
\begin{productionlist}
|
||||
\production{funcdef}
|
||||
{[\token{decorators}] "def" \token{funcname} "(" [\token{parameter_list}] ")"
|
||||
["->" \token{expression}]?
|
||||
":" \token{suite}}
|
||||
\production{decorators}
|
||||
{\token{decorator}+}
|
||||
|
@ -390,15 +391,14 @@ section~\ref{types}):
|
|||
{\token{identifier} ("." \token{identifier})*}
|
||||
\production{parameter_list}
|
||||
{(\token{defparameter} ",")*}
|
||||
\productioncont{(~~"*" \token{identifier} [, "**" \token{identifier}]}
|
||||
\productioncont{ | "**" \token{identifier}}
|
||||
\productioncont{(~~"*" [\token{parameter}] ("," \token{defparameter})*}
|
||||
\productioncont{ [, "**" \token{parameter}]}
|
||||
\productioncont{ | "**" \token{parameter}}
|
||||
\productioncont{ | \token{defparameter} [","] )}
|
||||
\production{parameter}
|
||||
{\token{identifier} [":" \token{expression}]}
|
||||
\production{defparameter}
|
||||
{\token{parameter} ["=" \token{expression}]}
|
||||
\production{sublist}
|
||||
{\token{parameter} ("," \token{parameter})* [","]}
|
||||
\production{parameter}
|
||||
{\token{identifier} | "(" \token{sublist} ")"}
|
||||
\production{funcname}
|
||||
{\token{identifier}}
|
||||
\end{productionlist}
|
||||
|
@ -435,14 +435,14 @@ def func(): pass
|
|||
func = f1(arg)(f2(func))
|
||||
\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
|
||||
parameter values.'' For a parameter with a
|
||||
default value, the corresponding argument may be omitted from a call,
|
||||
in which case the parameter's default value is substituted. If a
|
||||
parameter has a default value, all following parameters must also have
|
||||
a default value --- this is a syntactic restriction that is not
|
||||
expressed by the grammar.
|
||||
parameter has a default value, all following parameters up until the
|
||||
``\code{*}'' must also have a default value --- this is a syntactic
|
||||
restriction that is not expressed by the grammar.
|
||||
\indexiii{default}{parameter}{value}
|
||||
|
||||
\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
|
||||
``\code{**identifier}'' is present, it is initialized to a new
|
||||
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
|
||||
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
|
||||
assigned to another name just like a function defined by a lambda
|
||||
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}
|
||||
|
||||
\strong{Programmer's note:} Functions are first-class objects. A
|
||||
|
|
|
@ -184,12 +184,12 @@ your local Python guru or system administrator. (E.g.,
|
|||
\file{/usr/local/python} is a popular alternative location.)
|
||||
|
||||
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,
|
||||
you can type the following command into the command prompt in a DOS box:
|
||||
|
||||
\begin{verbatim}
|
||||
set path=%path%;C:\python26
|
||||
set path=%path%;C:\python30
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
@ -3539,7 +3539,7 @@ as desired.
|
|||
... print 'x =', x
|
||||
... print 'y =', y
|
||||
...
|
||||
<type 'exceptions.Exception'>
|
||||
<type 'Exception'>
|
||||
('spam', 'eggs')
|
||||
('spam', 'eggs')
|
||||
x = spam
|
||||
|
@ -4638,7 +4638,7 @@ operating system:
|
|||
>>> os.system('time 0:02')
|
||||
0
|
||||
>>> os.getcwd() # Return the current working directory
|
||||
'C:\\Python26'
|
||||
'C:\\Python30'
|
||||
>>> os.chdir('/server/accesslogs')
|
||||
\end{verbatim}
|
||||
|
||||
|
@ -5243,7 +5243,7 @@ applications include caching objects that are expensive to create:
|
|||
Traceback (most recent call last):
|
||||
File "<pyshell#108>", line 1, in -toplevel-
|
||||
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]()
|
||||
KeyError: 'primary'
|
||||
\end{verbatim}
|
||||
|
|
|
@ -24,17 +24,13 @@ decorators: decorator+
|
|||
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
|
||||
parameters: '(' [typedargslist] ')'
|
||||
typedargslist: ((tfpdef ['=' test] ',')*
|
||||
('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
|
||||
('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
|
||||
| tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
|
||||
tname: NAME [':' test]
|
||||
tfpdef: tname | '(' tfplist ')'
|
||||
tfplist: tfpdef (',' tfpdef)* [',']
|
||||
tfpdef: NAME [':' test]
|
||||
varargslist: ((vfpdef ['=' test] ',')*
|
||||
('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
|
||||
('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
|
||||
| vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
|
||||
vname: NAME
|
||||
vfpdef: vname | '(' vfplist ')'
|
||||
vfplist: vfpdef (',' vfpdef)* [',']
|
||||
vfpdef: NAME
|
||||
|
||||
stmt: simple_stmt | compound_stmt
|
||||
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
|
||||
|
|
|
@ -355,20 +355,9 @@ struct _arguments {
|
|||
asdl_seq *kw_defaults;
|
||||
};
|
||||
|
||||
enum _arg_kind {SimpleArg_kind=1, NestedArgs_kind=2};
|
||||
struct _arg {
|
||||
enum _arg_kind kind;
|
||||
union {
|
||||
struct {
|
||||
identifier arg;
|
||||
expr_ty annotation;
|
||||
} SimpleArg;
|
||||
|
||||
struct {
|
||||
asdl_seq *args;
|
||||
} NestedArgs;
|
||||
|
||||
} v;
|
||||
};
|
||||
|
||||
struct _keyword {
|
||||
|
@ -535,10 +524,8 @@ arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, expr_ty
|
|||
varargannotation, asdl_seq * kwonlyargs, identifier
|
||||
kwarg, expr_ty kwargannotation, asdl_seq * defaults,
|
||||
asdl_seq * kw_defaults, PyArena *arena);
|
||||
#define SimpleArg(a0, a1, a2) _Py_SimpleArg(a0, a1, a2)
|
||||
arg_ty _Py_SimpleArg(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 arg(a0, a1, a2) _Py_arg(a0, a1, a2)
|
||||
arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena);
|
||||
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
|
||||
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
|
||||
#define alias(a0, a1, a2) _Py_alias(a0, a1, a2)
|
||||
|
|
|
@ -6,79 +6,75 @@
|
|||
#define funcdef 261
|
||||
#define parameters 262
|
||||
#define typedargslist 263
|
||||
#define tname 264
|
||||
#define tfpdef 265
|
||||
#define tfplist 266
|
||||
#define varargslist 267
|
||||
#define vname 268
|
||||
#define vfpdef 269
|
||||
#define vfplist 270
|
||||
#define stmt 271
|
||||
#define simple_stmt 272
|
||||
#define small_stmt 273
|
||||
#define expr_stmt 274
|
||||
#define augassign 275
|
||||
#define del_stmt 276
|
||||
#define pass_stmt 277
|
||||
#define flow_stmt 278
|
||||
#define break_stmt 279
|
||||
#define continue_stmt 280
|
||||
#define return_stmt 281
|
||||
#define yield_stmt 282
|
||||
#define raise_stmt 283
|
||||
#define import_stmt 284
|
||||
#define import_name 285
|
||||
#define import_from 286
|
||||
#define import_as_name 287
|
||||
#define dotted_as_name 288
|
||||
#define import_as_names 289
|
||||
#define dotted_as_names 290
|
||||
#define dotted_name 291
|
||||
#define global_stmt 292
|
||||
#define nonlocal_stmt 293
|
||||
#define assert_stmt 294
|
||||
#define compound_stmt 295
|
||||
#define if_stmt 296
|
||||
#define while_stmt 297
|
||||
#define for_stmt 298
|
||||
#define try_stmt 299
|
||||
#define with_stmt 300
|
||||
#define with_var 301
|
||||
#define except_clause 302
|
||||
#define suite 303
|
||||
#define test 304
|
||||
#define test_nocond 305
|
||||
#define lambdef 306
|
||||
#define lambdef_nocond 307
|
||||
#define or_test 308
|
||||
#define and_test 309
|
||||
#define not_test 310
|
||||
#define comparison 311
|
||||
#define comp_op 312
|
||||
#define star_expr 313
|
||||
#define expr 314
|
||||
#define xor_expr 315
|
||||
#define and_expr 316
|
||||
#define shift_expr 317
|
||||
#define arith_expr 318
|
||||
#define term 319
|
||||
#define factor 320
|
||||
#define power 321
|
||||
#define atom 322
|
||||
#define testlist_comp 323
|
||||
#define trailer 324
|
||||
#define subscriptlist 325
|
||||
#define subscript 326
|
||||
#define sliceop 327
|
||||
#define exprlist 328
|
||||
#define testlist 329
|
||||
#define dictorsetmaker 330
|
||||
#define classdef 331
|
||||
#define arglist 332
|
||||
#define argument 333
|
||||
#define comp_iter 334
|
||||
#define comp_for 335
|
||||
#define comp_if 336
|
||||
#define testlist1 337
|
||||
#define encoding_decl 338
|
||||
#define yield_expr 339
|
||||
#define tfpdef 264
|
||||
#define varargslist 265
|
||||
#define vfpdef 266
|
||||
#define stmt 267
|
||||
#define simple_stmt 268
|
||||
#define small_stmt 269
|
||||
#define expr_stmt 270
|
||||
#define augassign 271
|
||||
#define del_stmt 272
|
||||
#define pass_stmt 273
|
||||
#define flow_stmt 274
|
||||
#define break_stmt 275
|
||||
#define continue_stmt 276
|
||||
#define return_stmt 277
|
||||
#define yield_stmt 278
|
||||
#define raise_stmt 279
|
||||
#define import_stmt 280
|
||||
#define import_name 281
|
||||
#define import_from 282
|
||||
#define import_as_name 283
|
||||
#define dotted_as_name 284
|
||||
#define import_as_names 285
|
||||
#define dotted_as_names 286
|
||||
#define dotted_name 287
|
||||
#define global_stmt 288
|
||||
#define nonlocal_stmt 289
|
||||
#define assert_stmt 290
|
||||
#define compound_stmt 291
|
||||
#define if_stmt 292
|
||||
#define while_stmt 293
|
||||
#define for_stmt 294
|
||||
#define try_stmt 295
|
||||
#define with_stmt 296
|
||||
#define with_var 297
|
||||
#define except_clause 298
|
||||
#define suite 299
|
||||
#define test 300
|
||||
#define test_nocond 301
|
||||
#define lambdef 302
|
||||
#define lambdef_nocond 303
|
||||
#define or_test 304
|
||||
#define and_test 305
|
||||
#define not_test 306
|
||||
#define comparison 307
|
||||
#define comp_op 308
|
||||
#define star_expr 309
|
||||
#define expr 310
|
||||
#define xor_expr 311
|
||||
#define and_expr 312
|
||||
#define shift_expr 313
|
||||
#define arith_expr 314
|
||||
#define term 315
|
||||
#define factor 316
|
||||
#define power 317
|
||||
#define atom 318
|
||||
#define testlist_comp 319
|
||||
#define trailer 320
|
||||
#define subscriptlist 321
|
||||
#define subscript 322
|
||||
#define sliceop 323
|
||||
#define exprlist 324
|
||||
#define testlist 325
|
||||
#define dictorsetmaker 326
|
||||
#define classdef 327
|
||||
#define arglist 328
|
||||
#define argument 329
|
||||
#define comp_iter 330
|
||||
#define comp_for 331
|
||||
#define comp_if 332
|
||||
#define testlist1 333
|
||||
#define encoding_decl 334
|
||||
#define yield_expr 335
|
||||
|
|
|
@ -665,7 +665,8 @@ class Aifc_write:
|
|||
## raise Error, 'cannot change parameters after starting to write'
|
||||
## 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:
|
||||
raise Error, 'cannot change parameters after starting to write'
|
||||
if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
|
||||
|
|
|
@ -151,7 +151,7 @@ class Bdb:
|
|||
"""This method is called when a return trap is set here."""
|
||||
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,
|
||||
but only if we are to stop at or just below this level."""
|
||||
pass
|
||||
|
|
|
@ -170,7 +170,8 @@ class _Rlecoderengine:
|
|||
del self.ofp
|
||||
|
||||
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(''):
|
||||
ofname = ofp
|
||||
ofp = open(ofname, 'w')
|
||||
|
|
|
@ -94,10 +94,11 @@ def scanvars(reader, frame, locals):
|
|||
lasttoken = token
|
||||
return vars
|
||||
|
||||
def html((etype, evalue, etb), context=5):
|
||||
def html(einfo, context=5):
|
||||
"""Return a nice HTML document describing a given traceback."""
|
||||
import os, types, time, traceback, linecache, inspect, pydoc
|
||||
|
||||
etype, evalue, etb = einfo
|
||||
if type(etype) is types.ClassType:
|
||||
etype = etype.__name__
|
||||
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))
|
||||
|
||||
def text((etype, evalue, etb), context=5):
|
||||
def text(einfo, context=5):
|
||||
"""Return a plain text document describing a given traceback."""
|
||||
import os, types, time, traceback, linecache, inspect, pydoc
|
||||
|
||||
etype, evalue, etb = einfo
|
||||
if type(etype) is types.ClassType:
|
||||
etype = etype.__name__
|
||||
pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
|
||||
|
|
|
@ -228,7 +228,8 @@ class AbstractFormatter:
|
|||
self.align = 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:
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
|
|
|
@ -183,7 +183,6 @@ if __name__=='__main__':
|
|||
def t4(*args): "(...)"
|
||||
def t5(a, *args): "(a, ...)"
|
||||
def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)"
|
||||
def t7((a, b), c, (d, e)): "(<tuple>, c, <tuple>)"
|
||||
|
||||
class TC(object):
|
||||
"(ai=None, ...)"
|
||||
|
@ -194,7 +193,6 @@ if __name__=='__main__':
|
|||
def t4(self, *args): "(...)"
|
||||
def t5(self, ai, *args): "(ai, ...)"
|
||||
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):
|
||||
ct = CallTips()
|
||||
|
@ -215,7 +213,7 @@ if __name__=='__main__':
|
|||
print("%d of %d tests failed" % (len(failed), len(tests)))
|
||||
|
||||
tc = TC()
|
||||
tests = (t1, t2, t3, t4, t5, t6, t7,
|
||||
TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6, tc.t7)
|
||||
tests = (t1, t2, t3, t4, t5, t6,
|
||||
TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6)
|
||||
|
||||
test(tests)
|
||||
|
|
|
@ -253,7 +253,8 @@ class Debugger:
|
|||
if self.vsource.get():
|
||||
self.sync_source_line()
|
||||
|
||||
def show_frame(self, (frame, lineno)):
|
||||
def show_frame(self, stackitem):
|
||||
frame, lineno = stackitem
|
||||
self.frame = frame
|
||||
self.show_variables()
|
||||
|
||||
|
|
|
@ -278,7 +278,10 @@ class Importer:
|
|||
setattr(parent, modname, 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)
|
||||
is_module = isinstance(code, _ModuleType)
|
||||
|
||||
|
|
|
@ -366,8 +366,8 @@ def getfile(object):
|
|||
def getmoduleinfo(path):
|
||||
"""Get the module name, suffix, mode, and module type for a given file."""
|
||||
filename = os.path.basename(path)
|
||||
suffixes = map(lambda (suffix, mode, mtype):
|
||||
(-len(suffix), suffix, mode, mtype), imp.get_suffixes())
|
||||
suffixes = [(-len(suffix), suffix, mode, mtype)
|
||||
for suffix, mode, mtype in imp.get_suffixes()]
|
||||
suffixes.sort() # try longest suffixes first, in case they overlap
|
||||
for neglen, suffix, mode, mtype in suffixes:
|
||||
if filename[neglen:] == suffix:
|
||||
|
@ -568,7 +568,7 @@ class BlockFinder:
|
|||
self.passline = False
|
||||
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:
|
||||
# look for the first "def", "class" or "lambda"
|
||||
if token in ("def", "class", "lambda"):
|
||||
|
@ -578,7 +578,7 @@ class BlockFinder:
|
|||
self.passline = True # skip to the end of the line
|
||||
elif type == tokenize.NEWLINE:
|
||||
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
|
||||
raise EndOfBlock
|
||||
elif self.passline:
|
||||
|
@ -698,40 +698,6 @@ def _getfullargs(co):
|
|||
kwonlyargs = list(names[nargs:nargs+nkwargs])
|
||||
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
|
||||
varargs = None
|
||||
if co.co_flags & CO_VARARGS:
|
||||
|
|
|
@ -279,7 +279,8 @@ class ModuleFinder:
|
|||
self.msgout(3, "import_module ->", 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)
|
||||
if type == imp.PKG_DIRECTORY:
|
||||
m = self.load_package(fqname, pathname)
|
||||
|
|
62
Lib/os.py
62
Lib/os.py
|
@ -653,68 +653,6 @@ otherwise return -SIG, where SIG is the signal that killed it. """
|
|||
|
||||
__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
|
||||
|
||||
def _make_stat_result(tup, dict):
|
||||
|
|
|
@ -180,13 +180,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
|||
print('--Return--', file=self.stdout)
|
||||
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,
|
||||
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
|
||||
if type(exc_type) == type(''):
|
||||
exc_type_name = exc_type
|
||||
else: exc_type_name = exc_type.__name__
|
||||
exc_type_name = exc_type.__name__
|
||||
print(exc_type_name + ':', _saferepr(exc_value), file=self.stdout)
|
||||
self.interaction(frame, exc_traceback)
|
||||
|
||||
|
|
|
@ -326,7 +326,8 @@ def _parse_object(file):
|
|||
#
|
||||
# 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)
|
||||
exec('inst.'+fdata.Name+' = form\n')
|
||||
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
|
||||
# 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')
|
||||
if odatalist[0].Class != FL.BOX:
|
||||
raise error, 'merge_full_form() expects FL.BOX as first obj'
|
||||
|
|
|
@ -296,8 +296,9 @@ def location(object, pos=None):
|
|||
return _getlocation(object_alias)
|
||||
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."""
|
||||
x, y = location
|
||||
finder = _getfinder()
|
||||
args = {}
|
||||
attrs = {}
|
||||
|
@ -438,8 +439,9 @@ def windowsize(folder, size=None):
|
|||
return _getwindowsize(folder_alias)
|
||||
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)"""
|
||||
w, h = size
|
||||
finder = _getfinder()
|
||||
args = {}
|
||||
attrs = {}
|
||||
|
@ -489,8 +491,9 @@ def windowposition(folder, pos=None):
|
|||
pos = (pos.h, pos.v)
|
||||
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)."""
|
||||
x, y = position
|
||||
finder = _getfinder()
|
||||
args = {}
|
||||
attrs = {}
|
||||
|
|
205
Lib/popen2.py
205
Lib/popen2.py
|
@ -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"])
|
|
@ -249,7 +249,10 @@ def _safe_repr(object, context, maxlevels, level):
|
|||
try:
|
||||
items = sorted(items)
|
||||
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:
|
||||
krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
|
||||
vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
|
||||
|
|
34
Lib/pydoc.py
34
Lib/pydoc.py
|
@ -171,11 +171,12 @@ def visiblename(name, all=None):
|
|||
|
||||
def classify_class_attrs(object):
|
||||
"""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):
|
||||
kind = 'data descriptor'
|
||||
return name, kind, cls, value
|
||||
return map(fixup, inspect.classify_class_attrs(object))
|
||||
results.append((name, kind, cls, value))
|
||||
return results
|
||||
|
||||
# ----------------------------------------------------- module manipulation
|
||||
|
||||
|
@ -228,11 +229,9 @@ def synopsis(filename, cache={}):
|
|||
|
||||
class ErrorDuringImport(Exception):
|
||||
"""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.exc = exc
|
||||
self.value = value
|
||||
self.tb = tb
|
||||
self.exc, self.value, self.tb = exc_info
|
||||
|
||||
def __str__(self):
|
||||
exc = self.exc
|
||||
|
@ -502,8 +501,9 @@ class HTMLDoc(Doc):
|
|||
"""Make a link for a module."""
|
||||
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."""
|
||||
name, path, ispackage, shadowed = modpkginfo
|
||||
if shadowed:
|
||||
return self.grey(name)
|
||||
if path:
|
||||
|
@ -662,12 +662,12 @@ class HTMLDoc(Doc):
|
|||
'Package Contents', '#ffffff', '#aa55cc', contents)
|
||||
elif modules:
|
||||
contents = self.multicolumn(
|
||||
modules, lambda (key, value), s=self: s.modulelink(value))
|
||||
modules, lambda t: self.modulelink(t[1]))
|
||||
result = result + self.bigsection(
|
||||
'Modules', '#fffff', '#aa55cc', contents)
|
||||
|
||||
if classes:
|
||||
classlist = map(lambda (key, value): value, classes)
|
||||
classlist = [value for (key, value) in classes]
|
||||
contents = [
|
||||
self.formattree(inspect.getclasstree(classlist, 1), name)]
|
||||
for key, value in classes:
|
||||
|
@ -768,8 +768,10 @@ class HTMLDoc(Doc):
|
|||
push('\n')
|
||||
return attrs
|
||||
|
||||
attrs = filter(lambda (name, kind, cls, value): visiblename(name),
|
||||
classify_class_attrs(object))
|
||||
attrs = [(name, kind, cls, value)
|
||||
for name, kind, cls, value in classify_class_attrs(object)
|
||||
if visiblename(name)]
|
||||
|
||||
mdict = {}
|
||||
for key, kind, homecls, value in attrs:
|
||||
mdict[key] = anchor = '#' + name + '-' + key
|
||||
|
@ -1071,7 +1073,7 @@ class TextDoc(Doc):
|
|||
'PACKAGE CONTENTS', '\n'.join(modpkgs))
|
||||
|
||||
if classes:
|
||||
classlist = map(lambda (key, value): value, classes)
|
||||
classlist = [value for key, value in classes]
|
||||
contents = [self.formattree(
|
||||
inspect.getclasstree(classlist, 1), name)]
|
||||
for key, value in classes:
|
||||
|
@ -1175,8 +1177,10 @@ class TextDoc(Doc):
|
|||
name, mod, maxlen=70, doc=doc) + '\n')
|
||||
return attrs
|
||||
|
||||
attrs = filter(lambda (name, kind, cls, value): visiblename(name),
|
||||
classify_class_attrs(object))
|
||||
attrs = [(name, kind, cls, value)
|
||||
for name, kind, cls, value in classify_class_attrs(object)
|
||||
if visiblename(name)]
|
||||
|
||||
while attrs:
|
||||
if mro:
|
||||
thisclass = mro.popleft()
|
||||
|
|
|
@ -364,7 +364,8 @@ class Au_write:
|
|||
else:
|
||||
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.setsampwidth(sampwidth)
|
||||
self.setframerate(framerate)
|
||||
|
|
|
@ -5,7 +5,7 @@ import sys, inspect
|
|||
# line 5
|
||||
|
||||
# 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)
|
||||
|
||||
# line 11
|
||||
|
|
|
@ -60,8 +60,8 @@ def with_comment(): # hello
|
|||
|
||||
# line 61
|
||||
multiline_sig = [
|
||||
lambda (x,
|
||||
y): x+y,
|
||||
lambda x, \
|
||||
y: x+y,
|
||||
None,
|
||||
]
|
||||
|
||||
|
|
|
@ -887,7 +887,6 @@ _expectations = {
|
|||
test_ossaudiodev
|
||||
test_poll
|
||||
test_popen
|
||||
test_popen2
|
||||
test_posix
|
||||
test_pty
|
||||
test_pwd
|
||||
|
@ -986,7 +985,6 @@ _expectations = {
|
|||
test_ntpath
|
||||
test_openpty
|
||||
test_poll
|
||||
test_popen2
|
||||
test_pty
|
||||
test_pwd
|
||||
test_strop
|
||||
|
@ -1062,7 +1060,6 @@ _expectations = {
|
|||
test_mmap
|
||||
test_nis
|
||||
test_poll
|
||||
test_popen2
|
||||
test_resource
|
||||
test_sqlite
|
||||
test_startfile
|
||||
|
|
|
@ -7,8 +7,6 @@ warnings.filterwarnings("ignore",
|
|||
"the gopherlib module is deprecated",
|
||||
DeprecationWarning,
|
||||
"<string>")
|
||||
warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*",
|
||||
DeprecationWarning)
|
||||
|
||||
class AllTest(unittest.TestCase):
|
||||
|
||||
|
@ -112,7 +110,6 @@ class AllTest(unittest.TestCase):
|
|||
self.check_all("pickle")
|
||||
self.check_all("pickletools")
|
||||
self.check_all("pipes")
|
||||
self.check_all("popen2")
|
||||
self.check_all("poplib")
|
||||
self.check_all("posixpath")
|
||||
self.check_all("pprint")
|
||||
|
|
|
@ -124,29 +124,9 @@ def f(x):
|
|||
exec(code, g)
|
||||
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):
|
||||
try:
|
||||
exec('def f(a=1, (b, c)): pass')
|
||||
exec('def f(a=1, b): pass')
|
||||
self.fail("non-default args after default")
|
||||
except SyntaxError:
|
||||
pass
|
||||
|
@ -394,16 +374,16 @@ if 1:
|
|||
self.assertEqual((Ellipsis, Ellipsis) in d, False)
|
||||
|
||||
def test_annotation_limit(self):
|
||||
# 16 bits are available for # of annotations, and the
|
||||
# tuple of annotations names is counted, hence 65534
|
||||
# 16 bits are available for # of annotations, but only 8 bits are
|
||||
# available for the parameter count, hence 255
|
||||
# is the max. Ensure the result of too many annotations is a
|
||||
# SyntaxError.
|
||||
s = "def f((%s)): pass"
|
||||
s %= ', '.join('a%d:%d' % (i,i) for i in range(65535))
|
||||
s = "def f(%s): pass"
|
||||
s %= ', '.join('a%d:%d' % (i,i) for i in range(256))
|
||||
self.assertRaises(SyntaxError, compile, s, '?', 'exec')
|
||||
# Test that the max # of annotations compiles.
|
||||
s = "def f((%s)): pass"
|
||||
s %= ', '.join('a%d:%d' % (i,i) for i in range(65534))
|
||||
s = "def f(%s): pass"
|
||||
s %= ', '.join('a%d:%d' % (i,i) for i in range(255))
|
||||
compile(s, '?', 'exec')
|
||||
|
||||
def test_mangling(self):
|
||||
|
|
|
@ -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()
|
|
@ -144,51 +144,32 @@ class GrammarTests(unittest.TestCase):
|
|||
### decorators: decorator+
|
||||
### parameters: '(' [typedargslist] ')'
|
||||
### typedargslist: ((tfpdef ['=' test] ',')*
|
||||
### ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
|
||||
### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
|
||||
### | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
|
||||
### tname: NAME [':' test]
|
||||
### tfpdef: tname | '(' tfplist ')'
|
||||
### tfplist: tfpdef (',' tfpdef)* [',']
|
||||
### tfpdef: NAME [':' test]
|
||||
### varargslist: ((vfpdef ['=' test] ',')*
|
||||
### ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname)
|
||||
### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
|
||||
### | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
|
||||
### vname: NAME
|
||||
### vfpdef: vname | '(' vfplist ')'
|
||||
### vfplist: vfpdef (',' vfpdef)* [',']
|
||||
### vfpdef: NAME
|
||||
def f1(): pass
|
||||
f1()
|
||||
f1(*())
|
||||
f1(*(), **{})
|
||||
def f2(one_argument): 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(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 a2(two, args,): pass
|
||||
def v0(*rest): pass
|
||||
def v1(a, *rest): pass
|
||||
def v2(a, b, *rest): pass
|
||||
def v3(a, (b, c), *rest): return a, b, c, rest
|
||||
|
||||
f1()
|
||||
f2(1)
|
||||
f2(1,)
|
||||
f3(1, 2)
|
||||
f3(1, 2,)
|
||||
f4(1, (2, (3, 4)))
|
||||
v0()
|
||||
v0(1)
|
||||
v0(1,)
|
||||
|
@ -203,17 +184,7 @@ class GrammarTests(unittest.TestCase):
|
|||
v2(1,2,3)
|
||||
v2(1,2,3,4)
|
||||
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
|
||||
d01()
|
||||
d01(1)
|
||||
|
@ -286,10 +257,6 @@ class GrammarTests(unittest.TestCase):
|
|||
d22v(*(1, 2, 3, 4))
|
||||
d22v(1, 2, *(3, 4, 5))
|
||||
d22v(1, *(2, 3), **{'d': 4})
|
||||
def d31v((x)): pass
|
||||
d31v(1)
|
||||
def d32v((x,)): pass
|
||||
d32v((1,))
|
||||
# keyword only argument tests
|
||||
def pos0key1(*, key): return key
|
||||
pos0key1(key=100)
|
||||
|
@ -312,12 +279,12 @@ class GrammarTests(unittest.TestCase):
|
|||
self.assertEquals(f.__annotations__, {'x': float})
|
||||
def f(x, y:1+2): pass
|
||||
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})
|
||||
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__,
|
||||
{'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
|
||||
self.assertEquals(f.__annotations__,
|
||||
{'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
|
||||
|
|
|
@ -116,11 +116,11 @@ class TestInterpreterStack(IsTestBase):
|
|||
|
||||
def test_previous_frame(self):
|
||||
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(varkw, 'h')
|
||||
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):
|
||||
# Subclasses must override.
|
||||
|
@ -321,9 +321,9 @@ class TestClassesAndFunctions(unittest.TestCase):
|
|||
self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
|
||||
|
||||
self.assertArgSpecEquals(mod.spam,
|
||||
['a', 'b', 'c', 'd', ['e', ['f']]],
|
||||
'g', 'h', (3, (4, (5,))),
|
||||
'(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
|
||||
['a', 'b', 'c', 'd', 'e', 'f'],
|
||||
'g', 'h', (3, 4, 5),
|
||||
'(a, b, c, d=3, e=4, f=5, *g, **h)')
|
||||
|
||||
def test_getargspec_method(self):
|
||||
class A(object):
|
||||
|
@ -331,13 +331,6 @@ class TestClassesAndFunctions(unittest.TestCase):
|
|||
pass
|
||||
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):
|
||||
class A(object):
|
||||
|
||||
|
|
|
@ -859,7 +859,7 @@ Samuele
|
|||
# is differencing with a range so that consecutive numbers all appear in
|
||||
# same group.
|
||||
>>> 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))
|
||||
...
|
||||
[1]
|
||||
|
|
|
@ -105,10 +105,11 @@ class MathTests(unittest.TestCase):
|
|||
def testFrexp(self):
|
||||
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:
|
||||
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(0)', math.frexp(0), (0, 0))
|
||||
|
@ -145,10 +146,11 @@ class MathTests(unittest.TestCase):
|
|||
def testModf(self):
|
||||
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):
|
||||
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))
|
||||
|
|
|
@ -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()
|
|
@ -323,13 +323,6 @@ else:
|
|||
|
||||
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):
|
||||
# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ class TestDecorateSortUndecorate(unittest.TestCase):
|
|||
def test_stability(self):
|
||||
data = [(random.randrange(100), i) for i in range(200)]
|
||||
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
|
||||
self.assertEqual(data, copy) # should get the same result
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ process_pid = os.getpid()
|
|||
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)
|
||||
usr2 = signal.signal(signal.SIGUSR2, for_usr2)
|
||||
alrm = signal.signal(signal.SIGALRM, for_alrm)
|
||||
|
@ -74,11 +74,11 @@ def test_main():
|
|||
signal.SIGUSR2 : {'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:
|
||||
run_unittest(ThreadSignals)
|
||||
finally:
|
||||
registerSignals(oldsigs)
|
||||
registerSignals(*oldsigs)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_main()
|
||||
|
|
|
@ -128,10 +128,9 @@ class _RLock(_Verbose):
|
|||
|
||||
# Internal methods used by condition variables
|
||||
|
||||
def _acquire_restore(self, (count, owner)):
|
||||
def _acquire_restore(self, state):
|
||||
self.__block.acquire()
|
||||
self.__count = count
|
||||
self.__owner = owner
|
||||
self.__count, self.__owner = state
|
||||
if __debug__:
|
||||
self._note("%s._acquire_restore()", self)
|
||||
|
||||
|
|
|
@ -131,7 +131,8 @@ class TokenError(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" % \
|
||||
(srow, scol, erow, ecol, tok_name[type], repr(token)))
|
||||
|
||||
|
|
|
@ -220,16 +220,18 @@ def urlsplit(url, scheme='', allow_fragments=True):
|
|||
_parse_cache[key] = 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
|
||||
slightly different, but equivalent URL, if the URL that was parsed
|
||||
originally had redundant delimiters, e.g. a ? with an empty query
|
||||
(the draft states that these are equivalent)."""
|
||||
scheme, netloc, url, params, query, fragment = components
|
||||
if params:
|
||||
url = "%s;%s" % (url, params)
|
||||
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 url and url[:1] != '/': url = '/' + url
|
||||
url = '//' + (netloc or '') + url
|
||||
|
|
|
@ -384,7 +384,8 @@ class Wave_write:
|
|||
def getcompname(self):
|
||||
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:
|
||||
raise Error, 'cannot change parameters after starting to write'
|
||||
self.setnchannels(nchannels)
|
||||
|
|
|
@ -714,7 +714,7 @@ PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \
|
|||
PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
|
||||
LIBSUBDIRS= lib-tk site-packages test test/output test/data \
|
||||
test/decimaltestdata \
|
||||
encodings compiler hotshot \
|
||||
encodings hotshot \
|
||||
email email/mime email/test email/test/data \
|
||||
sqlite3 sqlite3/test \
|
||||
logging bsddb bsddb/test csv wsgiref \
|
||||
|
|
|
@ -26,6 +26,8 @@ TO DO
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Remove tuple parameter unpacking (PEP 3113).
|
||||
|
||||
- Remove the f_restricted attribute from frames. This naturally leads to teh
|
||||
removal of PyEval_GetRestricted() and PyFrame_IsRestricted().
|
||||
|
||||
|
@ -178,8 +180,10 @@ Extension Modules
|
|||
Library
|
||||
-------
|
||||
|
||||
- Remove the compiler package. Use of the _ast module and (an eventual) AST ->
|
||||
bytecode mechanism.
|
||||
- Remove popen2 module and os.popen* functions.
|
||||
|
||||
- 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.
|
||||
|
||||
|
|
|
@ -1919,7 +1919,6 @@ pickle Pickling (save and restore) of Python objects (a faster
|
|||
Cimplementation exists in built-in module: cPickle).
|
||||
pipes Conversion pipeline templates.
|
||||
pkgunil Utilities for working with Python packages.
|
||||
popen2 variations on pipe open.
|
||||
poplib A POP3 client class. Based on the J. Myers POP3 draft.
|
||||
posixfile Extended (posix) file operations.
|
||||
posixpath Common operations on POSIX pathnames.
|
||||
|
|
|
@ -1031,7 +1031,7 @@ save_long(Picklerobject *self, PyObject *args)
|
|||
Py_ssize_t size;
|
||||
int res = -1;
|
||||
PyObject *repr = NULL;
|
||||
int val = PyInt_AsLong(args);
|
||||
long val = PyInt_AsLong(args);
|
||||
static char l = LONG;
|
||||
|
||||
if (val == -1 && PyErr_Occurred()) {
|
||||
|
|
|
@ -854,7 +854,7 @@ VALIDATER(node); VALIDATER(small_stmt);
|
|||
VALIDATER(class); VALIDATER(node);
|
||||
VALIDATER(parameters); VALIDATER(suite);
|
||||
VALIDATER(testlist); VALIDATER(varargslist);
|
||||
VALIDATER(vfpdef); VALIDATER(vfplist);
|
||||
VALIDATER(vfpdef);
|
||||
VALIDATER(stmt); VALIDATER(simple_stmt);
|
||||
VALIDATER(expr_stmt); VALIDATER(power);
|
||||
VALIDATER(del_stmt);
|
||||
|
@ -862,7 +862,7 @@ VALIDATER(return_stmt); VALIDATER(raise_stmt);
|
|||
VALIDATER(import_stmt); VALIDATER(import_stmt);
|
||||
VALIDATER(import_name); VALIDATER(yield_stmt);
|
||||
VALIDATER(global_stmt); VALIDATER(assert_stmt);
|
||||
VALIDATER(compound_stmt); VALIDATER(vname);
|
||||
VALIDATER(compound_stmt);
|
||||
VALIDATER(while); VALIDATER(for);
|
||||
VALIDATER(try); VALIDATER(except_clause);
|
||||
VALIDATER(test); VALIDATER(and_test);
|
||||
|
@ -1111,18 +1111,18 @@ validate_testlist1(node *tree)
|
|||
}
|
||||
|
||||
|
||||
/* validate either vname or tname.
|
||||
* vname: NAME
|
||||
* tname: NAME [':' test]
|
||||
/* validate either vfpdef or tfpdef.
|
||||
* vfpdef: NAME
|
||||
* tfpdef: NAME [':' test]
|
||||
*/
|
||||
static int
|
||||
validate_vname(node *tree)
|
||||
validate_vfpdef(node *tree)
|
||||
{
|
||||
int nch = NCH(tree);
|
||||
if (TYPE(tree) == vname) {
|
||||
if (TYPE(tree) == vfpdef) {
|
||||
return nch == 1 && validate_name(CHILD(tree, 0), NULL);
|
||||
}
|
||||
else if (TYPE(tree) == tname) {
|
||||
else if (TYPE(tree) == tfpdef) {
|
||||
if (nch == 1) {
|
||||
return validate_name(CHILD(tree, 0), NULL);
|
||||
}
|
||||
|
@ -1135,8 +1135,8 @@ validate_vname(node *tree)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* '*' vname (',' vname ['=' test])* [',' '**' vname] | '**' vname
|
||||
* ..or tname in place of vname. vname: NAME; tname: NAME [':' test]
|
||||
/* '*' vfpdef (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef
|
||||
* ..or tfpdef in place of vfpdef. vfpdef: NAME; tfpdef: NAME [':' test]
|
||||
*/
|
||||
static int
|
||||
validate_varargslist_trailer(node *tree, int start)
|
||||
|
@ -1152,27 +1152,27 @@ validate_varargslist_trailer(node *tree, int start)
|
|||
sym = TYPE(CHILD(tree, start));
|
||||
if (sym == STAR) {
|
||||
/*
|
||||
* '*' vname (',' vname ['=' test])* [',' '**' vname] | '**' vname
|
||||
* '*' vfpdef (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef
|
||||
*/
|
||||
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)
|
||||
res = (validate_vname(CHILD(tree, start+1))
|
||||
res = (validate_vfpdef(CHILD(tree, start+1))
|
||||
&& validate_comma(CHILD(tree, start+2))
|
||||
&& validate_doublestar(CHILD(tree, start+3))
|
||||
&& validate_vname(CHILD(tree, start+4)));
|
||||
&& validate_vfpdef(CHILD(tree, start+4)));
|
||||
else {
|
||||
/* skip over vname (',' vname ['=' test])* */
|
||||
/* skip over vfpdef (',' vfpdef ['=' test])* */
|
||||
i = start + 1;
|
||||
if (TYPE(CHILD(tree, i)) == vname ||
|
||||
TYPE(CHILD(tree, i)) == tname) { /* skip over vname or tname */
|
||||
if (TYPE(CHILD(tree, i)) == vfpdef ||
|
||||
TYPE(CHILD(tree, i)) == tfpdef) { /* skip over vfpdef or tfpdef */
|
||||
i += 1;
|
||||
}
|
||||
while (res && i+1 < nch) { /* validate (',' vname ['=' test])* */
|
||||
while (res && i+1 < nch) { /* validate (',' vfpdef ['=' test])* */
|
||||
res = validate_comma(CHILD(tree, i));
|
||||
if (TYPE(CHILD(tree, i+1)) == DOUBLESTAR)
|
||||
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) {
|
||||
res = res && (i+3 < nch)
|
||||
&& validate_test(CHILD(tree, i+3));
|
||||
|
@ -1182,9 +1182,9 @@ validate_varargslist_trailer(node *tree, int start)
|
|||
i += 2;
|
||||
}
|
||||
}
|
||||
/* [',' '**' vname] */
|
||||
/* [',' '**' vfpdef] */
|
||||
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
|
||||
*/
|
||||
if (nch-start == 2)
|
||||
res = validate_vname(CHILD(tree, start+1));
|
||||
res = validate_vfpdef(CHILD(tree, start+1));
|
||||
}
|
||||
if (!res)
|
||||
err_string("illegal variable argument trailer for varargslist");
|
||||
|
@ -1206,19 +1206,15 @@ validate_varargslist_trailer(node *tree, int start)
|
|||
* Validate typedargslist or varargslist.
|
||||
*
|
||||
* typedargslist: ((tfpdef ['=' test] ',')*
|
||||
* ('*' [tname] (',' tname ['=' test])* [',' '**' tname] |
|
||||
* '**' tname)
|
||||
* ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] |
|
||||
* '**' tfpdef)
|
||||
* | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
|
||||
* tname: NAME [':' test]
|
||||
* tfpdef: tname | '(' tfplist ')'
|
||||
* tfplist: tfpdef (',' tfpdef)* [',']
|
||||
* tfpdef: NAME [':' test]
|
||||
* varargslist: ((vfpdef ['=' test] ',')*
|
||||
* ('*' [vname] (',' vname ['=' test])* [',' '**' vname] |
|
||||
* '**' vname)
|
||||
* ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] |
|
||||
* '**' vfpdef)
|
||||
* | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
|
||||
* vname: NAME
|
||||
* vfpdef: vname | '(' vfplist ')'
|
||||
* vfplist: vfpdef (',' vfpdef)* [',']
|
||||
* vfpdef: NAME
|
||||
*
|
||||
*/
|
||||
static int
|
||||
|
@ -1229,33 +1225,23 @@ validate_varargslist(node *tree)
|
|||
TYPE(tree) == typedargslist) &&
|
||||
(nch != 0);
|
||||
int sym;
|
||||
node *ch;
|
||||
int i = 0;
|
||||
|
||||
if (!res)
|
||||
return 0;
|
||||
if (nch < 1) {
|
||||
err_string("varargslist missing child nodes");
|
||||
return 0;
|
||||
}
|
||||
sym = TYPE(CHILD(tree, 0));
|
||||
if (sym == STAR || sym == DOUBLESTAR)
|
||||
/* whole thing matches:
|
||||
* '*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME
|
||||
*/
|
||||
res = validate_varargslist_trailer(tree, 0);
|
||||
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));
|
||||
while (i < nch) {
|
||||
ch = CHILD(tree, i);
|
||||
sym = TYPE(ch);
|
||||
if (sym == vfpdef || sym == tfpdef) {
|
||||
/* validate (vfpdef ['=' test] ',')+ */
|
||||
res = validate_vfpdef(ch);
|
||||
++i;
|
||||
if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
|
||||
if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
|
||||
res = (validate_equal(CHILD(tree, i))
|
||||
&& validate_test(CHILD(tree, i+1)));
|
||||
if (res)
|
||||
|
@ -1264,59 +1250,15 @@ validate_varargslist(node *tree)
|
|||
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)
|
||||
} else if (sym == DOUBLESTAR || sym == STAR) {
|
||||
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;
|
||||
if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
|
||||
res = (validate_equal(CHILD(tree, i))
|
||||
&& validate_test(CHILD(tree, i+1)));
|
||||
i += 2;
|
||||
}
|
||||
/*
|
||||
* ... (',' vfpdef ['=' test])*
|
||||
* 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) {
|
||||
break;
|
||||
} else {
|
||||
res = 0;
|
||||
err_string("illegal formation for varargslist");
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -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\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\email\*.*; DestDir: {app}\Lib\email; 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]
|
||||
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\*.pyo; Type: files
|
||||
Name: {app}\Lib\distutils\command; Type: dirifempty
|
||||
|
|
|
@ -110,8 +110,7 @@ module Python version "$Revision$"
|
|||
arg* kwonlyargs, identifier? kwarg,
|
||||
expr? kwargannotation, expr* defaults,
|
||||
expr* kw_defaults)
|
||||
arg = SimpleArg(identifier arg, expr? annotation)
|
||||
| NestedArgs(arg* args)
|
||||
arg = (identifier arg, expr? annotation)
|
||||
|
||||
-- keyword arguments supplied to call
|
||||
keyword = (identifier arg, expr value)
|
||||
|
|
|
@ -115,49 +115,54 @@ class ASDLParser(spark.GenericParser, object):
|
|||
def error(self, 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, name, version, _0, _1 = info
|
||||
if module.value != "module":
|
||||
raise ASDLSyntaxError(module.lineno,
|
||||
msg="expected 'module', found %s" % module)
|
||||
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, name, version, _0, definitions, _1 = info
|
||||
if module.value != "module":
|
||||
raise ASDLSyntaxError(module.lineno,
|
||||
msg="expected 'module', found %s" % module)
|
||||
return Module(name, definitions, version)
|
||||
|
||||
def p_version(self, (version, V)):
|
||||
def p_version(self, info):
|
||||
"version ::= Id String"
|
||||
version, V = info
|
||||
if version.value != "version":
|
||||
raise ASDLSyntaxError(version.lineno,
|
||||
msg="expected 'version', found %" % version)
|
||||
return V
|
||||
|
||||
def p_definition_0(self, (definition,)):
|
||||
def p_definition_0(self, definition):
|
||||
" definitions ::= definition "
|
||||
return definition
|
||||
return definition[0]
|
||||
|
||||
def p_definition_1(self, (definitions, definition)):
|
||||
def p_definition_1(self, 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 "
|
||||
id, _, type = info
|
||||
return [Type(id, type)]
|
||||
|
||||
def p_type_0(self, (product,)):
|
||||
def p_type_0(self, product):
|
||||
" type ::= product "
|
||||
return product
|
||||
return product[0]
|
||||
|
||||
def p_type_1(self, (sum,)):
|
||||
def p_type_1(self, 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 ) "
|
||||
sum, id, _0, attributes, _1 = info
|
||||
if id.value != "attributes":
|
||||
raise ASDLSyntaxError(id.lineno,
|
||||
msg="expected attributes, found %s" % id)
|
||||
|
@ -165,65 +170,73 @@ class ASDLParser(spark.GenericParser, object):
|
|||
attributes.reverse()
|
||||
return Sum(sum, attributes)
|
||||
|
||||
def p_product(self, (_0, fields, _1)):
|
||||
def p_product(self, info):
|
||||
" product ::= ( fields ) "
|
||||
_0, fields, _1 = info
|
||||
# XXX can't I just construct things in the right order?
|
||||
fields.reverse()
|
||||
return Product(fields)
|
||||
|
||||
def p_sum_0(self, (constructor,)):
|
||||
def p_sum_0(self, constructor):
|
||||
" sum ::= constructor """
|
||||
return [constructor]
|
||||
return [constructor[0]]
|
||||
|
||||
def p_sum_1(self, (constructor, _, sum)):
|
||||
def p_sum_1(self, ):
|
||||
" sum ::= constructor | sum "
|
||||
constructor, _, sum = info
|
||||
return [constructor] + sum
|
||||
|
||||
def p_sum_2(self, (constructor, _, sum)):
|
||||
def p_sum_2(self, info):
|
||||
" sum ::= constructor | sum "
|
||||
constructor, _, sum = info
|
||||
return [constructor] + sum
|
||||
|
||||
def p_constructor_0(self, (id,)):
|
||||
def p_constructor_0(self, 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 ) "
|
||||
id, _0, fields, _1 = info
|
||||
# XXX can't I just construct things in the right order?
|
||||
fields.reverse()
|
||||
return Constructor(id, fields)
|
||||
|
||||
def p_fields_0(self, (field,)):
|
||||
def p_fields_0(self, field):
|
||||
" fields ::= field "
|
||||
return [field]
|
||||
return [field[0]]
|
||||
|
||||
def p_fields_1(self, (field, _, fields)):
|
||||
def p_fields_1(self, info):
|
||||
" fields ::= field , fields "
|
||||
field, _, fields = info
|
||||
return fields + [field]
|
||||
|
||||
def p_field_0(self, (type,)):
|
||||
def p_field_0(self, type_):
|
||||
" 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 "
|
||||
type, name = info
|
||||
return Field(type, name)
|
||||
|
||||
def p_field_2(self, (type, _, name)):
|
||||
def p_field_2(self, info):
|
||||
" field ::= Id * Id "
|
||||
type, _, name = info
|
||||
return Field(type, name, seq=1)
|
||||
|
||||
def p_field_3(self, (type, _, name)):
|
||||
def p_field_3(self, info):
|
||||
" field ::= Id ? Id "
|
||||
type, _, name = info
|
||||
return Field(type, name, opt=1)
|
||||
|
||||
def p_field_4(self, (type, _)):
|
||||
def p_field_4(self, type_):
|
||||
" 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 ? "
|
||||
return Field(type, opt=1)
|
||||
return Field(type[0], opt=1)
|
||||
|
||||
builtin_types = ("identifier", "string", "int", "bool", "object")
|
||||
|
||||
|
|
|
@ -353,10 +353,10 @@ class GenericParser:
|
|||
#
|
||||
return self._NULLABLE == sym[0:len(self._NULLABLE)]
|
||||
|
||||
def skip(self, (lhs, rhs), pos=0):
|
||||
n = len(rhs)
|
||||
def skip(self, hs, pos=0):
|
||||
n = len(hs[1])
|
||||
while pos < n:
|
||||
if not self.isnullable(rhs[pos]):
|
||||
if not self.isnullable(hs[1][pos]):
|
||||
break
|
||||
pos = pos + 1
|
||||
return pos
|
||||
|
@ -671,7 +671,7 @@ class GenericParser:
|
|||
sortlist.append((len(rhs), name))
|
||||
name2index[name] = i
|
||||
sortlist.sort()
|
||||
list = map(lambda (a,b): b, sortlist)
|
||||
list = [b for a, b in sortlist]
|
||||
return rules[name2index[self.resolve(list)]]
|
||||
|
||||
def resolve(self, list):
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
/*
|
||||
__version__ 54835.
|
||||
__version__ 55270.
|
||||
|
||||
This module must be committed separately after each AST grammar change;
|
||||
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 PyObject* ast2obj_arg(void*);
|
||||
static PyTypeObject *SimpleArg_type;
|
||||
static char *SimpleArg_fields[]={
|
||||
static char *arg_fields[]={
|
||||
"arg",
|
||||
"annotation",
|
||||
};
|
||||
static PyTypeObject *NestedArgs_type;
|
||||
static char *NestedArgs_fields[]={
|
||||
"args",
|
||||
};
|
||||
static PyTypeObject *keyword_type;
|
||||
static PyObject* ast2obj_keyword(void*);
|
||||
static char *keyword_fields[]={
|
||||
|
@ -752,14 +747,8 @@ static int init_types(void)
|
|||
if (!excepthandler_type) return 0;
|
||||
arguments_type = make_type("arguments", AST_type, arguments_fields, 8);
|
||||
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 (!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);
|
||||
if (!keyword_type) return 0;
|
||||
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
|
||||
SimpleArg(identifier arg, expr_ty annotation, PyArena *arena)
|
||||
arg(identifier arg, expr_ty annotation, PyArena *arena)
|
||||
{
|
||||
arg_ty p;
|
||||
if (!arg) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field arg is required for SimpleArg");
|
||||
"field arg is required for arg");
|
||||
return NULL;
|
||||
}
|
||||
p = (arg_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = SimpleArg_kind;
|
||||
p->v.SimpleArg.arg = arg;
|
||||
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;
|
||||
p->arg = arg;
|
||||
p->annotation = annotation;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -3048,31 +3024,18 @@ ast2obj_arg(void* _o)
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
switch (o->kind) {
|
||||
case SimpleArg_kind:
|
||||
result = PyType_GenericNew(SimpleArg_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_identifier(o->v.SimpleArg.arg);
|
||||
result = PyType_GenericNew(arg_type, NULL, NULL);
|
||||
if (!result) return NULL;
|
||||
value = ast2obj_identifier(o->arg);
|
||||
if (!value) goto failed;
|
||||
if (PyObject_SetAttrString(result, "arg", value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_expr(o->v.SimpleArg.annotation);
|
||||
value = ast2obj_expr(o->annotation);
|
||||
if (!value) goto failed;
|
||||
if (PyObject_SetAttrString(result, "annotation", value) == -1)
|
||||
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;
|
||||
failed:
|
||||
Py_XDECREF(value);
|
||||
|
@ -3150,7 +3113,7 @@ init_ast(void)
|
|||
if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
|
||||
if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
|
||||
return;
|
||||
if (PyModule_AddStringConstant(m, "__version__", "54835") < 0)
|
||||
if (PyModule_AddStringConstant(m, "__version__", "55270") < 0)
|
||||
return;
|
||||
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
|
||||
if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
|
||||
|
@ -3295,10 +3258,6 @@ init_ast(void)
|
|||
if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_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)
|
||||
return;
|
||||
if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;
|
||||
|
|
105
Python/ast.c
105
Python/ast.c
|
@ -566,13 +566,13 @@ seq_for_testlist(struct compiling *c, const node *n)
|
|||
}
|
||||
|
||||
static arg_ty
|
||||
compiler_simple_arg(struct compiling *c, const node *n)
|
||||
compiler_arg(struct compiling *c, const node *n)
|
||||
{
|
||||
identifier name;
|
||||
expr_ty annotation = NULL;
|
||||
node *ch;
|
||||
|
||||
assert(TYPE(n) == tname || TYPE(n) == vname);
|
||||
assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef);
|
||||
ch = CHILD(n, 0);
|
||||
if (!strcmp(STR(ch), "None")) {
|
||||
ast_error(ch, "assignment to None");
|
||||
|
@ -588,51 +588,12 @@ compiler_simple_arg(struct compiling *c, const node *n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return SimpleArg(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);
|
||||
return arg(name, annotation, c->c_arena);
|
||||
}
|
||||
|
||||
/* returns -1 if failed to handle keyword only arguments
|
||||
returns new position to keep processing if successful
|
||||
(',' tname ['=' test])*
|
||||
(',' tfpdef ['=' test])*
|
||||
^^^
|
||||
start pointing here
|
||||
*/
|
||||
|
@ -650,8 +611,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
|
|||
while (i < NCH(n)) {
|
||||
ch = CHILD(n, i);
|
||||
switch (TYPE(ch)) {
|
||||
case vname:
|
||||
case tname:
|
||||
case vfpdef:
|
||||
case tfpdef:
|
||||
if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
|
||||
expression = ast_for_expr(c, CHILD(n, i + 2));
|
||||
if (!expression) {
|
||||
|
@ -680,7 +641,7 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
|
|||
ast_error(ch, "assignment to None");
|
||||
goto error;
|
||||
}
|
||||
arg = SimpleArg(NEW_IDENTIFIER(ch), annotation, c->c_arena);
|
||||
arg = arg(NEW_IDENTIFIER(ch), annotation, c->c_arena);
|
||||
if (!arg) {
|
||||
ast_error(ch, "expecting name");
|
||||
goto error;
|
||||
|
@ -710,13 +671,15 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
|
||||
parameters: '(' [typedargslist] ')'
|
||||
typedargslist: ((tfpdef ['=' test] ',')*
|
||||
('*' [tname] (',' tname ['=' test])* [',' '**' tname]
|
||||
| '**' tname)
|
||||
('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef]
|
||||
| '**' tfpdef)
|
||||
| tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
|
||||
tfpdef: NAME [':' test]
|
||||
varargslist: ((vfpdef ['=' test] ',')*
|
||||
('*' [vname] (',' vname ['=' test])* [',' '**' vname]
|
||||
| '**' vname)
|
||||
('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef]
|
||||
| '**' vfpdef)
|
||||
| vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
|
||||
vfpdef: NAME
|
||||
*/
|
||||
int i, j, k, nposargs = 0, nkwonlyargs = 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++) {
|
||||
ch = CHILD(n, i);
|
||||
if (TYPE(ch) == STAR) {
|
||||
if (TYPE(CHILD(n, i+1)) == tname
|
||||
|| TYPE(CHILD(n, i+1)) == vname) {
|
||||
/* skip NAME of vararg */
|
||||
/* so that following can count only keyword only args */
|
||||
i += 2;
|
||||
}
|
||||
else {
|
||||
/* skip star and possible argument */
|
||||
i++;
|
||||
}
|
||||
i += (TYPE(CHILD(n, i)) == tfpdef
|
||||
|| TYPE(CHILD(n, i)) == vfpdef);
|
||||
break;
|
||||
}
|
||||
if (TYPE(ch) == DOUBLESTAR) break;
|
||||
if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++;
|
||||
if (TYPE(ch) == EQUAL) nposdefaults++;
|
||||
}
|
||||
|
@ -757,9 +716,8 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
for ( ; i < NCH(n); ++i) {
|
||||
ch = CHILD(n, i);
|
||||
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);
|
||||
if (!posargs && nposargs)
|
||||
goto error;
|
||||
|
@ -784,12 +742,8 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* tname: NAME [':' test]
|
||||
tfpdef: tname | '(' tfplist ')'
|
||||
tfplist: tfpdef (',' tfpdef)* [',']
|
||||
vname: NAME
|
||||
vfpdef: NAME | '(' vfplist ')'
|
||||
vfplist: vfpdef (',' vfpdef)* [',']
|
||||
/* tfpdef: NAME [':' test]
|
||||
vfpdef: NAME
|
||||
*/
|
||||
i = 0;
|
||||
j = 0; /* index for defaults */
|
||||
|
@ -816,14 +770,7 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
"non-default argument follows default argument");
|
||||
goto error;
|
||||
}
|
||||
/* def foo((x)): is not complex, special case. */
|
||||
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));
|
||||
arg = compiler_arg(c, ch);
|
||||
if (!arg)
|
||||
goto error;
|
||||
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");
|
||||
goto error;
|
||||
}
|
||||
ch = CHILD(n, i+1); /* tname or COMMA */
|
||||
ch = CHILD(n, i+1); /* tfpdef or COMMA */
|
||||
if (TYPE(ch) == COMMA) {
|
||||
int res = 0;
|
||||
i += 2; /* now follows keyword only arguments */
|
||||
|
@ -855,8 +802,8 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
varargannotation = ast_for_expr(c, CHILD(ch, 2));
|
||||
}
|
||||
i += 3;
|
||||
if (i < NCH(n) && (TYPE(CHILD(n, i)) == tname
|
||||
|| TYPE(CHILD(n, i)) == vname)) {
|
||||
if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef
|
||||
|| TYPE(CHILD(n, i)) == vfpdef)) {
|
||||
int res = 0;
|
||||
res = handle_keywordonly_args(c, n, i,
|
||||
kwonlyargs, kwdefaults);
|
||||
|
@ -866,8 +813,8 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
}
|
||||
break;
|
||||
case DOUBLESTAR:
|
||||
ch = CHILD(n, i+1); /* tname */
|
||||
assert(TYPE(ch) == tname || TYPE(ch) == vname);
|
||||
ch = CHILD(n, i+1); /* tfpdef */
|
||||
assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef);
|
||||
if (!strcmp(STR(CHILD(ch, 0)), "None")) {
|
||||
ast_error(CHILD(ch, 0), "assignment to None");
|
||||
goto error;
|
||||
|
|
|
@ -1282,54 +1282,6 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
|
|||
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
|
||||
compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
|
||||
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);
|
||||
expr_ty default_ = asdl_seq_GET(kw_defaults, i);
|
||||
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_)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1368,16 +1320,10 @@ compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
|
|||
int i, error;
|
||||
for (i = 0; i < asdl_seq_LEN(args); i++) {
|
||||
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
|
||||
if (arg->kind == NestedArgs_kind)
|
||||
error = compiler_visit_argannotations(
|
||||
c,
|
||||
arg->v.NestedArgs.args,
|
||||
names);
|
||||
else
|
||||
error = compiler_visit_argannotation(
|
||||
c,
|
||||
arg->v.SimpleArg.arg,
|
||||
arg->v.SimpleArg.annotation,
|
||||
arg->arg,
|
||||
arg->annotation,
|
||||
names);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1498,9 +1444,6 @@ compiler_function(struct compiler *c, stmt_ty s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* unpack nested arguments */
|
||||
compiler_arguments(c, args);
|
||||
|
||||
c->u->u_argcount = asdl_seq_LEN(args->args);
|
||||
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
|
||||
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))
|
||||
return 0;
|
||||
|
||||
/* unpack nested arguments */
|
||||
compiler_arguments(c, args);
|
||||
|
||||
c->u->u_argcount = asdl_seq_LEN(args->args);
|
||||
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
|
||||
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
|
||||
|
|
2500
Python/graminit.c
2500
Python/graminit.c
File diff suppressed because it is too large
Load Diff
|
@ -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_keyword(struct symtable *st, keyword_ty);
|
||||
static int symtable_visit_slice(struct symtable *st, slice_ty);
|
||||
static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top,
|
||||
int annotations);
|
||||
static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args,
|
||||
int annotations);
|
||||
static int symtable_visit_params(struct symtable *st, asdl_seq *args);
|
||||
static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);
|
||||
static int symtable_implicit_arg(struct symtable *st, int pos);
|
||||
static int symtable_visit_annotations(struct symtable *st, stmt_ty s);
|
||||
|
||||
|
@ -1328,44 +1326,16 @@ symtable_implicit_arg(struct symtable *st, int pos)
|
|||
}
|
||||
|
||||
static int
|
||||
symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel,
|
||||
int annotations)
|
||||
symtable_visit_params(struct symtable *st, asdl_seq *args)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
/* go through all the toplevel arguments first */
|
||||
for (i = 0; i < asdl_seq_LEN(args); i++) {
|
||||
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
|
||||
if (arg->kind == SimpleArg_kind) {
|
||||
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))
|
||||
if (!symtable_add_def(st, arg->arg, DEF_PARAM))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1373,34 +1343,34 @@ symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel,
|
|||
}
|
||||
|
||||
static int
|
||||
symtable_visit_params_nested(struct symtable *st, asdl_seq *args,
|
||||
int annotations)
|
||||
symtable_visit_argannotations(struct symtable *st, asdl_seq *args)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < asdl_seq_LEN(args); i++) {
|
||||
arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
|
||||
if (arg->kind == NestedArgs_kind &&
|
||||
!symtable_visit_params(st, arg->v.NestedArgs.args, 0,
|
||||
annotations))
|
||||
return 0;
|
||||
if (arg->annotation)
|
||||
VISIT(st, expr, arg->annotation);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
symtable_visit_annotations(struct symtable *st, stmt_ty s)
|
||||
{
|
||||
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;
|
||||
if (a->varargannotation)
|
||||
VISIT(st, expr, a->varargannotation);
|
||||
if (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;
|
||||
if (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
|
||||
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;
|
||||
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs, 1, 0))
|
||||
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))
|
||||
return 0;
|
||||
if (a->vararg) {
|
||||
if (!symtable_add_def(st, a->vararg, DEF_PARAM))
|
||||
|
@ -1427,8 +1397,6 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
|
|||
return 0;
|
||||
st->st_cur->ste_varkeywords = 1;
|
||||
}
|
||||
if (a->args && !symtable_visit_params_nested(st, a->args, 0))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ class Reindenter:
|
|||
return line
|
||||
|
||||
# Line-eater for tokenize.
|
||||
def tokeneater(self, type, token, (sline, scol), end, line,
|
||||
def tokeneater(self, type, token, slinecol, end, line,
|
||||
INDENT=tokenize.INDENT,
|
||||
DEDENT=tokenize.DEDENT,
|
||||
NEWLINE=tokenize.NEWLINE,
|
||||
|
@ -267,7 +267,7 @@ class Reindenter:
|
|||
|
||||
elif type == COMMENT:
|
||||
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
|
||||
# find_stmt alone
|
||||
|
||||
|
@ -280,7 +280,7 @@ class Reindenter:
|
|||
# ENDMARKER.
|
||||
self.find_stmt = 0
|
||||
if line: # not endmarker
|
||||
self.stats.append((sline, self.level))
|
||||
self.stats.append((slinecol[0], self.level))
|
||||
|
||||
# Count number of leading blanks.
|
||||
def getlspace(line):
|
||||
|
|
Loading…
Reference in New Issue