Remove regsub, reconvert, regex, regex_syntax and everything under lib-old.

This commit is contained in:
Neal Norwitz 2006-03-16 06:50:13 +00:00
parent efbeaef1c1
commit 10be10cbe7
69 changed files with 73 additions and 7120 deletions

View File

@ -6,7 +6,7 @@
import sys
import string
import regex
import re
import getopt
import time
@ -35,9 +35,9 @@ def main():
for rev in allrevs:
formatrev(rev, prefix)
parsedateprog = regex.compile(
'^date: \([0-9]+\)/\([0-9]+\)/\([0-9]+\) ' +
'\([0-9]+\):\([0-9]+\):\([0-9]+\); author: \([^ ;]+\)')
parsedateprog = re.compile(
'^date: ([0-9]+)/([0-9]+)/([0-9]+) ' +
'([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)')
authormap = {
'guido': 'Guido van Rossum <guido@cnri.reston.va.us>',
@ -70,7 +70,7 @@ def formatrev(rev, prefix):
print
print
startprog = regex.compile("^Working file: \(.*\)$")
startprog = re.compile("^Working file: (.*)$")
def getnextfile(f):
while 1:

View File

@ -6,12 +6,12 @@
# Python script for bumping up an RCS major revision number.
import sys
import regex
import re
import rcslib
import string
WITHLOCK = 1
majorrev_re = regex.compile('^[0-9]+')
majorrev_re = re.compile('^[0-9]+')
dir = rcslib.RCS()

View File

@ -8,7 +8,7 @@ files and (possibly) corresponding work files.
import fnmatch
import os
import regsub
import re
import string
import tempfile
@ -150,7 +150,7 @@ class RCS:
cmd = 'ci %s%s -t%s %s %s' % \
(lockflag, rev, f.name, otherflags, name)
else:
message = regsub.gsub('\([\\"$`]\)', '\\\\\\1', message)
message = re.sub(r'([\"$`])', r'\\\1', message)
cmd = 'ci %s%s -m"%s" %s %s' % \
(lockflag, rev, message, otherflags, name)
return self._system(cmd)

View File

@ -29,7 +29,7 @@
# into a program for a different change to Python programs...
import sys
import regex
import re
import os
from stat import *
import string
@ -53,7 +53,7 @@ def main():
if fix(arg): bad = 1
sys.exit(bad)
ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
def ispython(name):
return ispythonprog.match(name) >= 0
@ -104,7 +104,7 @@ def fix(filename):
if lineno == 1 and g is None and line[:2] == '#!':
# Check for non-Python scripts
words = string.split(line[2:])
if words and regex.search('[pP]ython', words[0]) < 0:
if words and re.search('[pP]ython', words[0]) < 0:
msg = filename + ': ' + words[0]
msg = msg + ' script; not fixed\n'
err(msg)

View File

@ -13,12 +13,12 @@
import os
import sys
import regex
import re
import string
import getopt
pat = '^\([a-zA-Z0-9 :]*\)!\(.*\)!\(.*\)!\([<>].*\)!\([0-9]+\)!\([0-9]+\)$'
prog = regex.compile(pat)
pat = '^([a-zA-Z0-9 :]*)!(.*)!(.*)!([<>].*)!([0-9]+)!([0-9]+)$'
prog = re.compile(pat)
def main():
maxitems = 25

View File

@ -10,7 +10,7 @@ import time
import os
import stat
import getopt
import regex
import re
def main():
dofile = mmdf
@ -45,7 +45,7 @@ def main():
if sts:
sys.exit(sts)
numeric = regex.compile('[1-9][0-9]*')
numeric = re.compile('[1-9][0-9]*')
def mh(dir):
sts = 0

View File

@ -8,10 +8,10 @@
import os
import sys
import regex
import re
pat = '^\([^: \t\n]+\):\([1-9][0-9]*\):'
prog = regex.compile(pat)
pat = '^([^: \t\n]+):([1-9][0-9]*):'
prog = re.compile(pat)
class FileObj:
def __init__(self, filename):

View File

@ -13,7 +13,6 @@ MYGROUP = '225.0.0.250'
import sys
import time
import struct
import regsub
from socket import *

View File

@ -1,6 +1,6 @@
# Widget to display a man page
import regex
import re
from Tkinter import *
from Tkinter import _tkinter
from ScrolledText import ScrolledText
@ -11,10 +11,10 @@ ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
# XXX Recognizing footers is system dependent
# (This one works for IRIX 5.2 and Solaris 2.2)
footerprog = regex.compile(
footerprog = re.compile(
'^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
emptyprog = regex.compile('^[ \t]*\n')
ulprog = regex.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
emptyprog = re.compile('^[ \t]*\n')
ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
# Basic Man Page class -- does not disable editing
class EditableManPage(ScrolledText):

View File

@ -4,7 +4,7 @@
import os
import sys
import regex
import re
import getopt
import string
import mhlib
@ -157,7 +157,7 @@ def scan_unpost(e):
scanmenu.unpost()
scanmenu.invoke('active')
scanparser = regex.compile('^ *\([0-9]+\)')
scanparser = re.compile('^ *([0-9]+)')
def open_folder(e=None):
global folder, mhf

View File

@ -5,7 +5,7 @@
import sys
import os
import string
import regex
import re
from Tkinter import *
from ManPage import ManPage
@ -208,15 +208,15 @@ class SelectionBox:
print 'Empty search string'
return
if not self.casevar.get():
map = regex.casefold
map = re.IGNORECASE
else:
map = None
try:
if map:
prog = regex.compile(search, map)
prog = re.compile(search, map)
else:
prog = regex.compile(search)
except regex.error, msg:
prog = re.compile(search)
except re.error, msg:
self.frame.bell()
print 'Regex error:', msg
return

View File

@ -33,11 +33,8 @@ This document is available from
The \module{re} module was added in Python 1.5, and provides
Perl-style regular expression patterns. Earlier versions of Python
came with the \module{regex} module, which provides Emacs-style
patterns. Emacs-style patterns are slightly less readable and
don't provide as many features, so there's not much reason to use
the \module{regex} module when writing new code, though you might
encounter old code that uses it.
came with the \module{regex} module, which provided Emacs-style
patterns. \module{regex} module was removed in Python 2.5.
Regular expressions (or REs) are essentially a tiny, highly
specialized programming language embedded inside Python and made
@ -1458,7 +1455,7 @@ Jeffrey Friedl's \citetitle{Mastering Regular Expressions}, published
by O'Reilly. Unfortunately, it exclusively concentrates on Perl and
Java's flavours of regular expressions, and doesn't contain any Python
material at all, so it won't be useful as a reference for programming
in Python. (The first edition covered Python's now-obsolete
in Python. (The first edition covered Python's now-removed
\module{regex} module, which won't help you much.) Consider checking
it out from your library.

View File

@ -87,7 +87,6 @@ and how to embed it in other applications.
\input{libstrings} % String Services
\input{libstring}
\input{libre}
\input{libreconvert}
\input{libstruct} % XXX also/better in File Formats?
\input{libdifflib}
\input{libstringio}
@ -454,8 +453,6 @@ and how to embed it in other applications.
%\input{libcmpcache}
%\input{libcmp}
%\input{libni}
%\input{libregex}
%\input{libregsub}
\chapter{Reporting Bugs}
\input{reportingbugs}

View File

@ -566,9 +566,6 @@ ignored.
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
\end{verbatim}
This function combines and extends the functionality of
the old \function{regsub.split()} and \function{regsub.splitx()}.
\end{funcdesc}
\begin{funcdesc}{findall}{pattern, string\optional{, flags}}
@ -943,7 +940,7 @@ the message \code{maximum recursion limit} exceeded. For example,
>>> re.match('Begin (\w| )*? end', s).end()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/local/lib/python2.3/sre.py", line 132, in match
File "/usr/local/lib/python2.5/re.py", line 132, in match
return _compile(pattern, flags).match(string)
RuntimeError: maximum recursion limit exceeded
\end{verbatim}

View File

@ -1,80 +0,0 @@
\section{\module{reconvert} ---
Convert regular expressions from regex to re form}
\declaremodule{standard}{reconvert}
\moduleauthor{Andrew M. Kuchling}{amk@amk.ca}
\sectionauthor{Skip Montanaro}{skip@pobox.com}
\modulesynopsis{Convert regex-, emacs- or sed-style regular expressions
to re-style syntax.}
This module provides a facility to convert regular expressions from the
syntax used by the deprecated \module{regex} module to those used by the
newer \module{re} module. Because of similarity between the regular
expression syntax of \code{sed(1)} and \code{emacs(1)} and the
\module{regex} module, it is also helpful to convert patterns written for
those tools to \module{re} patterns.
When used as a script, a Python string literal (or any other expression
evaluating to a string) is read from stdin, and the translated expression is
written to stdout as a string literal. Unless stdout is a tty, no trailing
newline is written to stdout. This is done so that it can be used with
Emacs \code{C-U M-|} (shell-command-on-region) which filters the region
through the shell command.
\begin{seealso}
\seetitle{Mastering Regular Expressions}{Book on regular expressions
by Jeffrey Friedl, published by O'Reilly. The second
edition of the book no longer covers Python at all,
but the first edition covered writing good regular expression
patterns in great detail.}
\end{seealso}
\subsection{Module Contents}
\nodename{Contents of Module reconvert}
The module defines two functions and a handful of constants.
\begin{funcdesc}{convert}{pattern\optional{, syntax=None}}
Convert a \var{pattern} representing a \module{regex}-stype regular
expression into a \module{re}-style regular expression. The optional
\var{syntax} parameter is a bitwise-or'd set of flags that control what
constructs are converted. See below for a description of the various
constants.
\end{funcdesc}
\begin{funcdesc}{quote}{s\optional{, quote=None}}
Convert a string object to a quoted string literal.
This is similar to \function{repr} but will return a "raw" string (r'...'
or r"...") when the string contains backslashes, instead of doubling all
backslashes. The resulting string does not always evaluate to the same
string as the original; however it will do just the right thing when passed
into re.compile().
The optional second argument forces the string quote; it must be a single
character which is a valid Python string quote. Note that prior to Python
2.5 this would not accept triple-quoted string delimiters.
\end{funcdesc}
\begin{datadesc}{RE_NO_BK_PARENS}
Suppress paren conversion. This should be omitted when converting
\code{sed}-style or \code{emacs}-style regular expressions.
\end{datadesc}
\begin{datadesc}{RE_NO_BK_VBAR}
Suppress vertical bar conversion. This should be omitted when converting
\code{sed}-style or \code{emacs}-style regular expressions.
\end{datadesc}
\begin{datadesc}{RE_BK_PLUS_QM}
Enable conversion of \code{+} and \code{?} characters. This should be
added to the \var{syntax} arg of \function{convert} when converting
\code{sed}-style regular expressions and omitted when converting
\code{emacs}-style regular expressions.
\end{datadesc}
\begin{datadesc}{RE_NEWLINE_OR}
When set, newline characters are replaced by \code{|}.
\end{datadesc}

View File

@ -1,370 +0,0 @@
\section{\module{regex} ---
Regular expression operations}
\declaremodule{builtin}{regex}
\modulesynopsis{Regular expression search and match operations.
\strong{Obsolete!}}
This module provides regular expression matching operations similar to
those found in Emacs.
\strong{Obsolescence note:}
This module is obsolete as of Python version 1.5; it is still being
maintained because much existing code still uses it. All new code in
need of regular expressions should use the new
\code{re}\refstmodindex{re} module, which supports the more powerful
and regular Perl-style regular expressions. Existing code should be
converted. The standard library module
\code{reconvert}\refstmodindex{reconvert} helps in converting
\code{regex} style regular expressions to \code{re}\refstmodindex{re}
style regular expressions. (For more conversion help, see Andrew
Kuchling's\index{Kuchling, Andrew} ``\module{regex-to-re} HOWTO'' at
\url{http://www.python.org/doc/howto/regex-to-re/}.)
By default the patterns are Emacs-style regular expressions
(with one exception). There is
a way to change the syntax to match that of several well-known
\UNIX{} utilities. The exception is that Emacs' \samp{\e s}
pattern is not supported, since the original implementation references
the Emacs syntax tables.
This module is 8-bit clean: both patterns and strings may contain null
bytes and characters whose high bit is set.
\strong{Please note:} There is a little-known fact about Python string
literals which means that you don't usually have to worry about
doubling backslashes, even though they are used to escape special
characters in string literals as well as in regular expressions. This
is because Python doesn't remove backslashes from string literals if
they are followed by an unrecognized escape character.
\emph{However}, if you want to include a literal \dfn{backslash} in a
regular expression represented as a string literal, you have to
\emph{quadruple} it or enclose it in a singleton character class.
E.g.\ to extract \LaTeX\ \samp{\e section\{\textrm{\ldots}\}} headers
from a document, you can use this pattern:
\code{'[\e ]section\{\e (.*\e )\}'}. \emph{Another exception:}
the escape sequence \samp{\e b} is significant in string literals
(where it means the ASCII bell character) as well as in Emacs regular
expressions (where it stands for a word boundary), so in order to
search for a word boundary, you should use the pattern \code{'\e \e b'}.
Similarly, a backslash followed by a digit 0-7 should be doubled to
avoid interpretation as an octal escape.
\subsection{Regular Expressions}
A regular expression (or RE) specifies a set of strings that matches
it; the functions in this module let you check if a particular string
matches a given regular expression (or if a given regular expression
matches a particular string, which comes down to the same thing).
Regular expressions can be concatenated to form new regular
expressions; if \emph{A} and \emph{B} are both regular expressions,
then \emph{AB} is also an regular expression. If a string \emph{p}
matches A and another string \emph{q} matches B, the string \emph{pq}
will match AB. Thus, complex expressions can easily be constructed
from simpler ones like the primitives described here. For details of
the theory and implementation of regular expressions, consult almost
any textbook about compiler construction.
% XXX The reference could be made more specific, say to
% "Compilers: Principles, Techniques and Tools", by Alfred V. Aho,
% Ravi Sethi, and Jeffrey D. Ullman, or some FA text.
A brief explanation of the format of regular expressions follows.
Regular expressions can contain both special and ordinary characters.
Ordinary characters, like '\code{A}', '\code{a}', or '\code{0}', are
the simplest regular expressions; they simply match themselves. You
can concatenate ordinary characters, so '\code{last}' matches the
characters 'last'. (In the rest of this section, we'll write RE's in
\code{this special font}, usually without quotes, and strings to be
matched 'in single quotes'.)
Special characters either stand for classes of ordinary characters, or
affect how the regular expressions around them are interpreted.
The special characters are:
\begin{itemize}
\item[\code{.}] (Dot.) Matches any character except a newline.
\item[\code{\^}] (Caret.) Matches the start of the string.
\item[\code{\$}] Matches the end of the string.
\code{foo} matches both 'foo' and 'foobar', while the regular
expression '\code{foo\$}' matches only 'foo'.
\item[\code{*}] Causes the resulting RE to
match 0 or more repetitions of the preceding RE. \code{ab*} will
match 'a', 'ab', or 'a' followed by any number of 'b's.
\item[\code{+}] Causes the
resulting RE to match 1 or more repetitions of the preceding RE.
\code{ab+} will match 'a' followed by any non-zero number of 'b's; it
will not match just 'a'.
\item[\code{?}] Causes the resulting RE to
match 0 or 1 repetitions of the preceding RE. \code{ab?} will
match either 'a' or 'ab'.
\item[\code{\e}] Either escapes special characters (permitting you to match
characters like '*?+\&\$'), or signals a special sequence; special
sequences are discussed below. Remember that Python also uses the
backslash as an escape sequence in string literals; if the escape
sequence isn't recognized by Python's parser, the backslash and
subsequent character are included in the resulting string. However,
if Python would recognize the resulting sequence, the backslash should
be repeated twice.
\item[\code{[]}] Used to indicate a set of characters. Characters can
be listed individually, or a range is indicated by giving two
characters and separating them by a '-'. Special characters are
not active inside sets. For example, \code{[akm\$]}
will match any of the characters 'a', 'k', 'm', or '\$'; \code{[a-z]} will
match any lowercase letter.
If you want to include a \code{]} inside a
set, it must be the first character of the set; to include a \code{-},
place it as the first or last character.
Characters \emph{not} within a range can be matched by including a
\code{\^} as the first character of the set; \code{\^} elsewhere will
simply match the '\code{\^}' character.
\end{itemize}
The special sequences consist of '\code{\e}' and a character
from the list below. If the ordinary character is not on the list,
then the resulting RE will match the second character. For example,
\code{\e\$} matches the character '\$'. Ones where the backslash
should be doubled in string literals are indicated.
\begin{itemize}
\item[\code{\e|}]\code{A\e|B}, where A and B can be arbitrary REs,
creates a regular expression that will match either A or B. This can
be used inside groups (see below) as well.
%
\item[\code{\e( \e)}] Indicates the start and end of a group; the
contents of a group can be matched later in the string with the
\code{\e [1-9]} special sequence, described next.
\end{itemize}
\begin{fulllineitems}
\item[\code{\e \e 1, ... \e \e 7, \e 8, \e 9}]
Matches the contents of the group of the same
number. For example, \code{\e (.+\e ) \e \e 1} matches 'the the' or
'55 55', but not 'the end' (note the space after the group). This
special sequence can only be used to match one of the first 9 groups;
groups with higher numbers can be matched using the \code{\e v}
sequence. (\code{\e 8} and \code{\e 9} don't need a double backslash
because they are not octal digits.)
\end{fulllineitems}
\begin{itemize}
\item[\code{\e \e b}] Matches the empty string, but only at the
beginning or end of a word. A word is defined as a sequence of
alphanumeric characters, so the end of a word is indicated by
whitespace or a non-alphanumeric character.
%
\item[\code{\e B}] Matches the empty string, but when it is \emph{not} at the
beginning or end of a word.
%
\item[\code{\e v}] Must be followed by a two digit decimal number, and
matches the contents of the group of the same number. The group
number must be between 1 and 99, inclusive.
%
\item[\code{\e w}]Matches any alphanumeric character; this is
equivalent to the set \code{[a-zA-Z0-9]}.
%
\item[\code{\e W}] Matches any non-alphanumeric character; this is
equivalent to the set \code{[\^a-zA-Z0-9]}.
\item[\code{\e <}] Matches the empty string, but only at the beginning of a
word. A word is defined as a sequence of alphanumeric characters, so
the end of a word is indicated by whitespace or a non-alphanumeric
character.
\item[\code{\e >}] Matches the empty string, but only at the end of a
word.
\item[\code{\e \e \e \e}] Matches a literal backslash.
% In Emacs, the following two are start of buffer/end of buffer. In
% Python they seem to be synonyms for ^$.
\item[\code{\e `}] Like \code{\^}, this only matches at the start of the
string.
\item[\code{\e \e '}] Like \code{\$}, this only matches at the end of
the string.
% end of buffer
\end{itemize}
\subsection{Module Contents}
\nodename{Contents of Module regex}
The module defines these functions, and an exception:
\begin{funcdesc}{match}{pattern, string}
Return how many characters at the beginning of \var{string} match
the regular expression \var{pattern}. Return \code{-1} if the
string does not match the pattern (this is different from a
zero-length match!).
\end{funcdesc}
\begin{funcdesc}{search}{pattern, string}
Return the first position in \var{string} that matches the regular
expression \var{pattern}. Return \code{-1} if no position in the string
matches the pattern (this is different from a zero-length match
anywhere!).
\end{funcdesc}
\begin{funcdesc}{compile}{pattern\optional{, translate}}
Compile a regular expression pattern into a regular expression
object, which can be used for matching using its \code{match()} and
\code{search()} methods, described below. The optional argument
\var{translate}, if present, must be a 256-character string
indicating how characters (both of the pattern and of the strings to
be matched) are translated before comparing them; the \var{i}-th
element of the string gives the translation for the character with
\ASCII{} code \var{i}. This can be used to implement
case-insensitive matching; see the \code{casefold} data item below.
The sequence
\begin{verbatim}
prog = regex.compile(pat)
result = prog.match(str)
\end{verbatim}
%
is equivalent to
\begin{verbatim}
result = regex.match(pat, str)
\end{verbatim}
but the version using \code{compile()} is more efficient when multiple
regular expressions are used concurrently in a single program. (The
compiled version of the last pattern passed to \code{regex.match()} or
\code{regex.search()} is cached, so programs that use only a single
regular expression at a time needn't worry about compiling regular
expressions.)
\end{funcdesc}
\begin{funcdesc}{set_syntax}{flags}
Set the syntax to be used by future calls to \code{compile()},
\code{match()} and \code{search()}. (Already compiled expression
objects are not affected.) The argument is an integer which is the
OR of several flag bits. The return value is the previous value of
the syntax flags. Names for the flags are defined in the standard
module \code{regex_syntax}\refstmodindex{regex_syntax}; read the
file \file{regex_syntax.py} for more information.
\end{funcdesc}
\begin{funcdesc}{get_syntax}{}
Returns the current value of the syntax flags as an integer.
\end{funcdesc}
\begin{funcdesc}{symcomp}{pattern\optional{, translate}}
This is like \code{compile()}, but supports symbolic group names: if a
parenthesis-enclosed group begins with a group name in angular
brackets, e.g. \code{'\e(<id>[a-z][a-z0-9]*\e)'}, the group can
be referenced by its name in arguments to the \code{group()} method of
the resulting compiled regular expression object, like this:
\code{p.group('id')}. Group names may contain alphanumeric characters
and \code{'_'} only.
\end{funcdesc}
\begin{excdesc}{error}
Exception raised when a string passed to one of the functions here
is not a valid regular expression (e.g., unmatched parentheses) or
when some other error occurs during compilation or matching. (It is
never an error if a string contains no match for a pattern.)
\end{excdesc}
\begin{datadesc}{casefold}
A string suitable to pass as the \var{translate} argument to
\code{compile()} to map all upper case characters to their lowercase
equivalents.
\end{datadesc}
\noindent
Compiled regular expression objects support these methods:
\setindexsubitem{(regex method)}
\begin{funcdesc}{match}{string\optional{, pos}}
Return how many characters at the beginning of \var{string} match
the compiled regular expression. Return \code{-1} if the string
does not match the pattern (this is different from a zero-length
match!).
The optional second parameter, \var{pos}, gives an index in the string
where the search is to start; it defaults to \code{0}. This is not
completely equivalent to slicing the string; the \code{'\^'} pattern
character matches at the real beginning of the string and at positions
just after a newline, not necessarily at the index where the search
is to start.
\end{funcdesc}
\begin{funcdesc}{search}{string\optional{, pos}}
Return the first position in \var{string} that matches the regular
expression \code{pattern}. Return \code{-1} if no position in the
string matches the pattern (this is different from a zero-length
match anywhere!).
The optional second parameter has the same meaning as for the
\code{match()} method.
\end{funcdesc}
\begin{funcdesc}{group}{index, index, ...}
This method is only valid when the last call to the \code{match()}
or \code{search()} method found a match. It returns one or more
groups of the match. If there is a single \var{index} argument,
the result is a single string; if there are multiple arguments, the
result is a tuple with one item per argument. If the \var{index} is
zero, the corresponding return value is the entire matching string; if
it is in the inclusive range [1..99], it is the string matching the
corresponding parenthesized group (using the default syntax,
groups are parenthesized using \code{{\e}(} and \code{{\e})}). If no
such group exists, the corresponding result is \code{None}.
If the regular expression was compiled by \code{symcomp()} instead of
\code{compile()}, the \var{index} arguments may also be strings
identifying groups by their group name.
\end{funcdesc}
\noindent
Compiled regular expressions support these data attributes:
\setindexsubitem{(regex attribute)}
\begin{datadesc}{regs}
When the last call to the \code{match()} or \code{search()} method found a
match, this is a tuple of pairs of indexes corresponding to the
beginning and end of all parenthesized groups in the pattern. Indices
are relative to the string argument passed to \code{match()} or
\code{search()}. The 0-th tuple gives the beginning and end or the
whole pattern. When the last match or search failed, this is
\code{None}.
\end{datadesc}
\begin{datadesc}{last}
When the last call to the \code{match()} or \code{search()} method found a
match, this is the string argument passed to that method. When the
last match or search failed, this is \code{None}.
\end{datadesc}
\begin{datadesc}{translate}
This is the value of the \var{translate} argument to
\code{regex.compile()} that created this regular expression object. If
the \var{translate} argument was omitted in the \code{regex.compile()}
call, this is \code{None}.
\end{datadesc}
\begin{datadesc}{givenpat}
The regular expression pattern as passed to \code{compile()} or
\code{symcomp()}.
\end{datadesc}
\begin{datadesc}{realpat}
The regular expression after stripping the group names for regular
expressions compiled with \code{symcomp()}. Same as \code{givenpat}
otherwise.
\end{datadesc}
\begin{datadesc}{groupindex}
A dictionary giving the mapping from symbolic group names to numerical
group indexes for regular expressions compiled with \code{symcomp()}.
\code{None} otherwise.
\end{datadesc}

View File

@ -1,74 +0,0 @@
\section{\module{regsub} ---
String operations using regular expressions}
\declaremodule{standard}{regsub}
\modulesynopsis{Substitution and splitting operations that use
regular expressions. \strong{Obsolete!}}
This module defines a number of functions useful for working with
regular expressions (see built-in module \refmodule{regex}).
Warning: these functions are not thread-safe.
\strong{Obsolescence note:}
This module is obsolete as of Python version 1.5; it is still being
maintained because much existing code still uses it. All new code in
need of regular expressions should use the new \refmodule{re} module, which
supports the more powerful and regular Perl-style regular expressions.
Existing code should be converted. The standard library module
\module{reconvert} helps in converting \refmodule{regex} style regular
expressions to \refmodule{re} style regular expressions. (For more
conversion help, see Andrew Kuchling's\index{Kuchling, Andrew}
``regex-to-re HOWTO'' at
\url{http://www.python.org/doc/howto/regex-to-re/}.)
\begin{funcdesc}{sub}{pat, repl, str}
Replace the first occurrence of pattern \var{pat} in string
\var{str} by replacement \var{repl}. If the pattern isn't found,
the string is returned unchanged. The pattern may be a string or an
already compiled pattern. The replacement may contain references
\samp{\e \var{digit}} to subpatterns and escaped backslashes.
\end{funcdesc}
\begin{funcdesc}{gsub}{pat, repl, str}
Replace all (non-overlapping) occurrences of pattern \var{pat} in
string \var{str} by replacement \var{repl}. The same rules as for
\code{sub()} apply. Empty matches for the pattern are replaced only
when not adjacent to a previous match, so e.g.
\code{gsub('', '-', 'abc')} returns \code{'-a-b-c-'}.
\end{funcdesc}
\begin{funcdesc}{split}{str, pat\optional{, maxsplit}}
Split the string \var{str} in fields separated by delimiters matching
the pattern \var{pat}, and return a list containing the fields. Only
non-empty matches for the pattern are considered, so e.g.
\code{split('a:b', ':*')} returns \code{['a', 'b']} and
\code{split('abc', '')} returns \code{['abc']}. The \var{maxsplit}
defaults to 0. If it is nonzero, only \var{maxsplit} number of splits
occur, and the remainder of the string is returned as the final
element of the list.
\end{funcdesc}
\begin{funcdesc}{splitx}{str, pat\optional{, maxsplit}}
Split the string \var{str} in fields separated by delimiters matching
the pattern \var{pat}, and return a list containing the fields as well
as the separators. For example, \code{splitx('a:::b', ':*')} returns
\code{['a', ':::', 'b']}. Otherwise, this function behaves the same
as \code{split}.
\end{funcdesc}
\begin{funcdesc}{capwords}{s\optional{, pat}}
Capitalize words separated by optional pattern \var{pat}. The default
pattern uses any characters except letters, digits and underscores as
word delimiters. Capitalization is done by changing the first
character of each word to upper case.
\end{funcdesc}
\begin{funcdesc}{clear_cache}{}
The regsub module maintains a cache of compiled regular expressions,
keyed on the regular expression string and the syntax of the regex
module at the time the expression was compiled. This function clears
that cache.
\end{funcdesc}

View File

@ -137,18 +137,6 @@ now just as good).
\item[\module{rand}]
--- Old interface to the random number generator.
\item[\module{regex}]
--- Emacs-style regular expression support; may still be used in some
old code (extension module). Refer to the
\citetitle[http://www.python.org/doc/1.6/lib/module-regex.html]{Python
1.6 Documentation} for documentation.
\item[\module{regsub}]
--- Regular expression based string replacement utilities, for use
with \module{regex} (extension module). Refer to the
\citetitle[http://www.python.org/doc/1.6/lib/module-regsub.html]{Python
1.6 Documentation} for documentation.
\item[\module{statcache}]
--- Caches the results of os.stat(). Using the cache can be fragile
and error-prone, just use \code{os.stat()} directly.

View File

@ -1,343 +0,0 @@
# Text formatting abstractions
# Note -- this module is obsolete, it's too slow anyway
# Oft-used type object
Int = type(0)
# Represent a paragraph. This is a list of words with associated
# font and size information, plus indents and justification for the
# entire paragraph.
# Once the words have been added to a paragraph, it can be laid out
# for different line widths. Once laid out, it can be rendered at
# different screen locations. Once rendered, it can be queried
# for mouse hits, and parts of the text can be highlighted
class Para:
#
def __init__(self):
self.words = [] # The words
self.just = 'l' # Justification: 'l', 'r', 'lr' or 'c'
self.indent_left = self.indent_right = self.indent_hang = 0
# Final lay-out parameters, may change
self.left = self.top = self.right = self.bottom = \
self.width = self.height = self.lines = None
#
# Add a word, computing size information for it.
# Words may also be added manually by appending to self.words
# Each word should be a 7-tuple:
# (font, text, width, space, stretch, ascent, descent)
def addword(self, d, font, text, space, stretch):
if font is not None:
d.setfont(font)
width = d.textwidth(text)
ascent = d.baseline()
descent = d.lineheight() - ascent
spw = d.textwidth(' ')
space = space * spw
stretch = stretch * spw
tuple = (font, text, width, space, stretch, ascent, descent)
self.words.append(tuple)
#
# Hooks to begin and end anchors -- insert numbers in the word list!
def bgn_anchor(self, id):
self.words.append(id)
#
def end_anchor(self, id):
self.words.append(0)
#
# Return the total length (width) of the text added so far, in pixels
def getlength(self):
total = 0
for word in self.words:
if type(word) is not Int:
total = total + word[2] + word[3]
return total
#
# Tab to a given position (relative to the current left indent):
# remove all stretch, add fixed space up to the new indent.
# If the current position is already at the tab stop,
# don't add any new space (but still remove the stretch)
def tabto(self, tab):
total = 0
as, de = 1, 0
for i in range(len(self.words)):
word = self.words[i]
if type(word) is Int: continue
(fo, te, wi, sp, st, as, de) = word
self.words[i] = (fo, te, wi, sp, 0, as, de)
total = total + wi + sp
if total < tab:
self.words.append((None, '', 0, tab-total, 0, as, de))
#
# Make a hanging tag: tab to hang, increment indent_left by hang,
# and reset indent_hang to -hang
def makehangingtag(self, hang):
self.tabto(hang)
self.indent_left = self.indent_left + hang
self.indent_hang = -hang
#
# Decide where the line breaks will be given some screen width
def layout(self, linewidth):
self.width = linewidth
height = 0
self.lines = lines = []
avail1 = self.width - self.indent_left - self.indent_right
avail = avail1 - self.indent_hang
words = self.words
i = 0
n = len(words)
lastfont = None
while i < n:
firstfont = lastfont
charcount = 0
width = 0
stretch = 0
ascent = 0
descent = 0
lsp = 0
j = i
while i < n:
word = words[i]
if type(word) is Int:
if word > 0 and width >= avail:
break
i = i+1
continue
fo, te, wi, sp, st, as, de = word
if width + wi > avail and width > 0 and wi > 0:
break
if fo is not None:
lastfont = fo
if width == 0:
firstfont = fo
charcount = charcount + len(te) + (sp > 0)
width = width + wi + sp
lsp = sp
stretch = stretch + st
lst = st
ascent = max(ascent, as)
descent = max(descent, de)
i = i+1
while i > j and type(words[i-1]) is Int and \
words[i-1] > 0: i = i-1
width = width - lsp
if i < n:
stretch = stretch - lst
else:
stretch = 0
tuple = i-j, firstfont, charcount, width, stretch, \
ascent, descent
lines.append(tuple)
height = height + ascent + descent
avail = avail1
self.height = height
#
# Call a function for all words in a line
def visit(self, wordfunc, anchorfunc):
avail1 = self.width - self.indent_left - self.indent_right
avail = avail1 - self.indent_hang
v = self.top
i = 0
for tuple in self.lines:
wordcount, firstfont, charcount, width, stretch, \
ascent, descent = tuple
h = self.left + self.indent_left
if i == 0: h = h + self.indent_hang
extra = 0
if self.just == 'r': h = h + avail - width
elif self.just == 'c': h = h + (avail - width) / 2
elif self.just == 'lr' and stretch > 0:
extra = avail - width
v2 = v + ascent + descent
for j in range(i, i+wordcount):
word = self.words[j]
if type(word) is Int:
ok = anchorfunc(self, tuple, word, \
h, v)
if ok is not None: return ok
continue
fo, te, wi, sp, st, as, de = word
if extra > 0 and stretch > 0:
ex = extra * st / stretch
extra = extra - ex
stretch = stretch - st
else:
ex = 0
h2 = h + wi + sp + ex
ok = wordfunc(self, tuple, word, h, v, \
h2, v2, (j==i), (j==i+wordcount-1))
if ok is not None: return ok
h = h2
v = v2
i = i + wordcount
avail = avail1
#
# Render a paragraph in "drawing object" d, using the rectangle
# given by (left, top, right) with an unspecified bottom.
# Return the computed bottom of the text.
def render(self, d, left, top, right):
if self.width != right-left:
self.layout(right-left)
self.left = left
self.top = top
self.right = right
self.bottom = self.top + self.height
self.anchorid = 0
try:
self.d = d
self.visit(self.__class__._renderword, \
self.__class__._renderanchor)
finally:
self.d = None
return self.bottom
#
def _renderword(self, tuple, word, h, v, h2, v2, isfirst, islast):
if word[0] is not None: self.d.setfont(word[0])
baseline = v + tuple[5]
self.d.text((h, baseline - word[5]), word[1])
if self.anchorid > 0:
self.d.line((h, baseline+2), (h2, baseline+2))
#
def _renderanchor(self, tuple, word, h, v):
self.anchorid = word
#
# Return which anchor(s) was hit by the mouse
def hitcheck(self, mouseh, mousev):
self.mouseh = mouseh
self.mousev = mousev
self.anchorid = 0
self.hits = []
self.visit(self.__class__._hitcheckword, \
self.__class__._hitcheckanchor)
return self.hits
#
def _hitcheckword(self, tuple, word, h, v, h2, v2, isfirst, islast):
if self.anchorid > 0 and h <= self.mouseh <= h2 and \
v <= self.mousev <= v2:
self.hits.append(self.anchorid)
#
def _hitcheckanchor(self, tuple, word, h, v):
self.anchorid = word
#
# Return whether the given anchor id is present
def hasanchor(self, id):
return id in self.words or -id in self.words
#
# Extract the raw text from the word list, substituting one space
# for non-empty inter-word space, and terminating with '\n'
def extract(self):
text = ''
for w in self.words:
if type(w) is not Int:
word = w[1]
if w[3]: word = word + ' '
text = text + word
return text + '\n'
#
# Return which character position was hit by the mouse, as
# an offset in the entire text as returned by extract().
# Return None if the mouse was not in this paragraph
def whereis(self, d, mouseh, mousev):
if mousev < self.top or mousev > self.bottom:
return None
self.mouseh = mouseh
self.mousev = mousev
self.lastfont = None
self.charcount = 0
try:
self.d = d
return self.visit(self.__class__._whereisword, \
self.__class__._whereisanchor)
finally:
self.d = None
#
def _whereisword(self, tuple, word, h1, v1, h2, v2, isfirst, islast):
fo, te, wi, sp, st, as, de = word
if fo is not None: self.lastfont = fo
h = h1
if isfirst: h1 = 0
if islast: h2 = 999999
if not (v1 <= self.mousev <= v2 and h1 <= self.mouseh <= h2):
self.charcount = self.charcount + len(te) + (sp > 0)
return
if self.lastfont is not None:
self.d.setfont(self.lastfont)
cc = 0
for c in te:
cw = self.d.textwidth(c)
if self.mouseh <= h + cw/2:
return self.charcount + cc
cc = cc+1
h = h+cw
self.charcount = self.charcount + cc
if self.mouseh <= (h+h2) / 2:
return self.charcount
else:
return self.charcount + 1
#
def _whereisanchor(self, tuple, word, h, v):
pass
#
# Return screen position corresponding to position in paragraph.
# Return tuple (h, vtop, vbaseline, vbottom).
# This is more or less the inverse of whereis()
def screenpos(self, d, pos):
if pos < 0:
ascent, descent = self.lines[0][5:7]
return self.left, self.top, self.top + ascent, \
self.top + ascent + descent
self.pos = pos
self.lastfont = None
try:
self.d = d
ok = self.visit(self.__class__._screenposword, \
self.__class__._screenposanchor)
finally:
self.d = None
if ok is None:
ascent, descent = self.lines[-1][5:7]
ok = self.right, self.bottom - ascent - descent, \
self.bottom - descent, self.bottom
return ok
#
def _screenposword(self, tuple, word, h1, v1, h2, v2, isfirst, islast):
fo, te, wi, sp, st, as, de = word
if fo is not None: self.lastfont = fo
cc = len(te) + (sp > 0)
if self.pos > cc:
self.pos = self.pos - cc
return
if self.pos < cc:
self.d.setfont(self.lastfont)
h = h1 + self.d.textwidth(te[:self.pos])
else:
h = h2
ascent, descent = tuple[5:7]
return h, v1, v1+ascent, v2
#
def _screenposanchor(self, tuple, word, h, v):
pass
#
# Invert the stretch of text between pos1 and pos2.
# If pos1 is None, the beginning is implied;
# if pos2 is None, the end is implied.
# Undoes its own effect when called again with the same arguments
def invert(self, d, pos1, pos2):
if pos1 is None:
pos1 = self.left, self.top, self.top, self.top
else:
pos1 = self.screenpos(d, pos1)
if pos2 is None:
pos2 = self.right, self.bottom,self.bottom,self.bottom
else:
pos2 = self.screenpos(d, pos2)
h1, top1, baseline1, bottom1 = pos1
h2, top2, baseline2, bottom2 = pos2
if bottom1 <= top2:
d.invert((h1, top1), (self.right, bottom1))
h1 = self.left
if bottom1 < top2:
d.invert((h1, bottom1), (self.right, top2))
top1, bottom1 = top2, bottom2
d.invert((h1, top1), (h2, bottom2))

View File

@ -1,67 +0,0 @@
# This module provides standard support for "packages".
#
# The idea is that large groups of related modules can be placed in
# their own subdirectory, which can be added to the Python search path
# in a relatively easy way.
#
# The current version takes a package name and searches the Python
# search path for a directory by that name, and if found adds it to
# the module search path (sys.path). It maintains a list of packages
# that have already been added so adding the same package many times
# is OK.
#
# It is intended to be used in a fairly stylized manner: each module
# that wants to use a particular package, say 'Foo', is supposed to
# contain the following code:
#
# from addpack import addpack
# addpack('Foo')
# <import modules from package Foo>
#
# Additional arguments, when present, provide additional places where
# to look for the package before trying sys.path (these may be either
# strings or lists/tuples of strings). Also, if the package name is a
# full pathname, first the last component is tried in the usual way,
# then the full pathname is tried last. If the package name is a
# *relative* pathname (UNIX: contains a slash but doesn't start with
# one), then nothing special is done. The packages "/foo/bar/bletch"
# and "bletch" are considered the same, but unrelated to "bar/bletch".
#
# If the algorithm finds more than one suitable subdirectory, all are
# added to the search path -- this makes it possible to override part
# of a package. The same path will not be added more than once.
#
# If no directory is found, ImportError is raised.
_packs = {} # {pack: [pathname, ...], ...}
def addpack(pack, *locations):
import os
if os.path.isabs(pack):
base = os.path.basename(pack)
else:
base = pack
if _packs.has_key(base):
return
import sys
path = []
for loc in _flatten(locations) + sys.path:
fn = os.path.join(loc, base)
if fn not in path and os.path.isdir(fn):
path.append(fn)
if pack != base and pack not in path and os.path.isdir(pack):
path.append(pack)
if not path: raise ImportError, 'package ' + pack + ' not found'
_packs[base] = path
for fn in path:
if fn not in sys.path:
sys.path.append(fn)
def _flatten(locations):
locs = []
for loc in locations:
if type(loc) == type(''):
locs.append(loc)
else:
locs = locs + _flatten(loc)
return locs

View File

@ -1,63 +0,0 @@
"""Efficiently compare files, boolean outcome only (equal / not equal).
Tricks (used in this order):
- Files with identical type, size & mtime are assumed to be clones
- Files with different type or size cannot be identical
- We keep a cache of outcomes of earlier comparisons
- We don't fork a process to run 'cmp' but read the files ourselves
"""
import os
cache = {}
def cmp(f1, f2, shallow=1):
"""Compare two files, use the cache if possible.
Return 1 for identical files, 0 for different.
Raise exceptions if either file could not be statted, read, etc."""
s1, s2 = sig(os.stat(f1)), sig(os.stat(f2))
if s1[0] != 8 or s2[0] != 8:
# Either is a not a plain file -- always report as different
return 0
if shallow and s1 == s2:
# type, size & mtime match -- report same
return 1
if s1[:2] != s2[:2]: # Types or sizes differ, don't bother
# types or sizes differ -- report different
return 0
# same type and size -- look in the cache
key = (f1, f2)
try:
cs1, cs2, outcome = cache[key]
# cache hit
if s1 == cs1 and s2 == cs2:
# cached signatures match
return outcome
# stale cached signature(s)
except KeyError:
# cache miss
pass
# really compare
outcome = do_cmp(f1, f2)
cache[key] = s1, s2, outcome
return outcome
def sig(st):
"""Return signature (i.e., type, size, mtime) from raw stat data
0-5: st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid
6-9: st_size, st_atime, st_mtime, st_ctime"""
type = st[0] / 4096
size = st[6]
mtime = st[8]
return type, size, mtime
def do_cmp(f1, f2):
"""Compare two files, really."""
bufsize = 8*1024 # Could be tuned
fp1 = open(f1, 'rb')
fp2 = open(f2, 'rb')
while 1:
b1 = fp1.read(bufsize)
b2 = fp2.read(bufsize)
if b1 != b2: return 0
if not b1: return 1

View File

@ -1,64 +0,0 @@
"""Efficiently compare files, boolean outcome only (equal / not equal).
Tricks (used in this order):
- Use the statcache module to avoid statting files more than once
- Files with identical type, size & mtime are assumed to be clones
- Files with different type or size cannot be identical
- We keep a cache of outcomes of earlier comparisons
- We don't fork a process to run 'cmp' but read the files ourselves
"""
import os
from stat import *
import statcache
# The cache.
#
cache = {}
def cmp(f1, f2, shallow=1):
"""Compare two files, use the cache if possible.
May raise os.error if a stat or open of either fails.
Return 1 for identical files, 0 for different.
Raise exceptions if either file could not be statted, read, etc."""
s1, s2 = sig(statcache.stat(f1)), sig(statcache.stat(f2))
if not S_ISREG(s1[0]) or not S_ISREG(s2[0]):
# Either is a not a plain file -- always report as different
return 0
if shallow and s1 == s2:
# type, size & mtime match -- report same
return 1
if s1[:2] != s2[:2]: # Types or sizes differ, don't bother
# types or sizes differ -- report different
return 0
# same type and size -- look in the cache
key = f1 + ' ' + f2
if cache.has_key(key):
cs1, cs2, outcome = cache[key]
# cache hit
if s1 == cs1 and s2 == cs2:
# cached signatures match
return outcome
# stale cached signature(s)
# really compare
outcome = do_cmp(f1, f2)
cache[key] = s1, s2, outcome
return outcome
def sig(st):
"""Return signature (i.e., type, size, mtime) from raw stat data."""
return S_IFMT(st[ST_MODE]), st[ST_SIZE], st[ST_MTIME]
def do_cmp(f1, f2):
"""Compare two files, really."""
#print ' cmp', f1, f2 # XXX remove when debugged
bufsize = 8*1024 # Could be tuned
fp1 = open(f1, 'rb')
fp2 = open(f2, 'rb')
while 1:
b1 = fp1.read(bufsize)
b2 = fp2.read(bufsize)
if b1 != b2: return 0
if not b1: return 1

View File

@ -1,81 +0,0 @@
# A subroutine for extracting a function name from a code object
# (with cache)
import sys
from stat import *
import string
import os
import linecache
# XXX The functions getcodename() and getfuncname() are now obsolete
# XXX as code and function objects now have a name attribute --
# XXX co.co_name and f.func_name.
# XXX getlineno() is now also obsolete because of the new attribute
# XXX of code objects, co.co_firstlineno.
# Extract the function or class name from a code object.
# This is a bit of a hack, since a code object doesn't contain
# the name directly. So what do we do:
# - get the filename (which *is* in the code object)
# - look in the code string to find the first SET_LINENO instruction
# (this must be the first instruction)
# - get the line from the file
# - if the line starts with 'class' or 'def' (after possible whitespace),
# extract the following identifier
#
# This breaks apart when the function was read from <stdin>
# or constructed by exec(), when the file is not accessible,
# and also when the file has been modified or when a line is
# continued with a backslash before the function or class name.
#
# Because this is a pretty expensive hack, a cache is kept.
SET_LINENO = 127 # The opcode (see "opcode.h" in the Python source)
identchars = string.ascii_letters + string.digits + '_' # Identifier characters
_namecache = {} # The cache
def getcodename(co):
try:
return co.co_name
except AttributeError:
pass
key = `co` # arbitrary but uniquely identifying string
if _namecache.has_key(key): return _namecache[key]
filename = co.co_filename
code = co.co_code
name = ''
if ord(code[0]) == SET_LINENO:
lineno = ord(code[1]) | ord(code[2]) << 8
line = linecache.getline(filename, lineno)
words = line.split()
if len(words) >= 2 and words[0] in ('def', 'class'):
name = words[1]
for i in range(len(name)):
if name[i] not in identchars:
name = name[:i]
break
_namecache[key] = name
return name
# Use the above routine to find a function's name.
def getfuncname(func):
try:
return func.func_name
except AttributeError:
pass
return getcodename(func.func_code)
# A part of the above code to extract just the line number from a code object.
def getlineno(co):
try:
return co.co_firstlineno
except AttributeError:
pass
code = co.co_code
if ord(code[0]) == SET_LINENO:
return ord(code[1]) | ord(code[2]) << 8
else:
return -1

View File

@ -1,202 +0,0 @@
"""A class to build directory diff tools on."""
import os
import dircache
import cmpcache
import statcache
from stat import *
class dircmp:
"""Directory comparison class."""
def new(self, a, b):
"""Initialize."""
self.a = a
self.b = b
# Properties that caller may change before calling self.run():
self.hide = [os.curdir, os.pardir] # Names never to be shown
self.ignore = ['RCS', 'tags'] # Names ignored in comparison
return self
def run(self):
"""Compare everything except common subdirectories."""
self.a_list = filter(dircache.listdir(self.a), self.hide)
self.b_list = filter(dircache.listdir(self.b), self.hide)
self.a_list.sort()
self.b_list.sort()
self.phase1()
self.phase2()
self.phase3()
def phase1(self):
"""Compute common names."""
self.a_only = []
self.common = []
for x in self.a_list:
if x in self.b_list:
self.common.append(x)
else:
self.a_only.append(x)
self.b_only = []
for x in self.b_list:
if x not in self.common:
self.b_only.append(x)
def phase2(self):
"""Distinguish files, directories, funnies."""
self.common_dirs = []
self.common_files = []
self.common_funny = []
for x in self.common:
a_path = os.path.join(self.a, x)
b_path = os.path.join(self.b, x)
ok = 1
try:
a_stat = statcache.stat(a_path)
except os.error, why:
# print 'Can\'t stat', a_path, ':', why[1]
ok = 0
try:
b_stat = statcache.stat(b_path)
except os.error, why:
# print 'Can\'t stat', b_path, ':', why[1]
ok = 0
if ok:
a_type = S_IFMT(a_stat[ST_MODE])
b_type = S_IFMT(b_stat[ST_MODE])
if a_type != b_type:
self.common_funny.append(x)
elif S_ISDIR(a_type):
self.common_dirs.append(x)
elif S_ISREG(a_type):
self.common_files.append(x)
else:
self.common_funny.append(x)
else:
self.common_funny.append(x)
def phase3(self):
"""Find out differences between common files."""
xx = cmpfiles(self.a, self.b, self.common_files)
self.same_files, self.diff_files, self.funny_files = xx
def phase4(self):
"""Find out differences between common subdirectories.
A new dircmp object is created for each common subdirectory,
these are stored in a dictionary indexed by filename.
The hide and ignore properties are inherited from the parent."""
self.subdirs = {}
for x in self.common_dirs:
a_x = os.path.join(self.a, x)
b_x = os.path.join(self.b, x)
self.subdirs[x] = newdd = dircmp().new(a_x, b_x)
newdd.hide = self.hide
newdd.ignore = self.ignore
newdd.run()
def phase4_closure(self):
"""Recursively call phase4() on subdirectories."""
self.phase4()
for x in self.subdirs.keys():
self.subdirs[x].phase4_closure()
def report(self):
"""Print a report on the differences between a and b."""
# Assume that phases 1 to 3 have been executed
# Output format is purposely lousy
print 'diff', self.a, self.b
if self.a_only:
print 'Only in', self.a, ':', self.a_only
if self.b_only:
print 'Only in', self.b, ':', self.b_only
if self.same_files:
print 'Identical files :', self.same_files
if self.diff_files:
print 'Differing files :', self.diff_files
if self.funny_files:
print 'Trouble with common files :', self.funny_files
if self.common_dirs:
print 'Common subdirectories :', self.common_dirs
if self.common_funny:
print 'Common funny cases :', self.common_funny
def report_closure(self):
"""Print reports on self and on subdirs.
If phase 4 hasn't been done, no subdir reports are printed."""
self.report()
try:
x = self.subdirs
except AttributeError:
return # No subdirectories computed
for x in self.subdirs.keys():
print
self.subdirs[x].report_closure()
def report_phase4_closure(self):
"""Report and do phase 4 recursively."""
self.report()
self.phase4()
for x in self.subdirs.keys():
print
self.subdirs[x].report_phase4_closure()
def cmpfiles(a, b, common):
"""Compare common files in two directories.
Return:
- files that compare equal
- files that compare different
- funny cases (can't stat etc.)"""
res = ([], [], [])
for x in common:
res[cmp(os.path.join(a, x), os.path.join(b, x))].append(x)
return res
def cmp(a, b):
"""Compare two files.
Return:
0 for equal
1 for different
2 for funny cases (can't stat, etc.)"""
try:
if cmpcache.cmp(a, b): return 0
return 1
except os.error:
return 2
def filter(list, skip):
"""Return a copy with items that occur in skip removed."""
result = []
for item in list:
if item not in skip: result.append(item)
return result
def demo():
"""Demonstration and testing."""
import sys
import getopt
options, args = getopt.getopt(sys.argv[1:], 'r')
if len(args) != 2:
raise getopt.error, 'need exactly two args'
dd = dircmp().new(args[0], args[1])
dd.run()
if ('-r', '') in options:
dd.report_phase4_closure()
else:
dd.report()
if __name__ == "__main__":
demo()

View File

@ -1,63 +0,0 @@
# Module 'dump'
#
# Print python code that reconstructs a variable.
# This only works in certain cases.
#
# It works fine for:
# - ints and floats (except NaNs and other weird things)
# - strings
# - compounds and lists, provided it works for all their elements
# - imported modules, provided their name is the module name
#
# It works for top-level dictionaries but not for dictionaries
# contained in other objects (could be made to work with some hassle
# though).
#
# It does not work for functions (all sorts), classes, class objects,
# windows, files etc.
#
# Finally, objects referenced by more than one name or contained in more
# than one other object lose their sharing property (this is bad for
# strings used as exception identifiers, for instance).
# Dump a whole symbol table
#
def dumpsymtab(dict):
for key in dict.keys():
dumpvar(key, dict[key])
# Dump a single variable
#
def dumpvar(name, x):
import sys
t = type(x)
if t == type({}):
print name, '= {}'
for key in x.keys():
item = x[key]
if not printable(item):
print '#',
print name, '[', `key`, '] =', `item`
elif t in (type(''), type(0), type(0.0), type([]), type(())):
if not printable(x):
print '#',
print name, '=', `x`
elif t == type(sys):
print 'import', name, '#', x
else:
print '#', name, '=', x
# check if a value is printable in a way that can be read back with input()
#
def printable(x):
t = type(x)
if t in (type(''), type(0), type(0.0)):
return 1
if t in (type([]), type(())):
for item in x:
if not printable(item):
return 0
return 1
if x == {}:
return 1
return 0

View File

@ -1,26 +0,0 @@
import fnmatch
import os
_debug = 0
_prune = ['(*)']
def find(pattern, dir = os.curdir):
list = []
names = os.listdir(dir)
names.sort()
for name in names:
if name in (os.curdir, os.pardir):
continue
fullname = os.path.join(dir, name)
if fnmatch.fnmatch(name, pattern):
list.append(fullname)
if os.path.isdir(fullname) and not os.path.islink(fullname):
for p in _prune:
if fnmatch.fnmatch(name, p):
if _debug: print "skip", `fullname`
break
else:
if _debug: print "descend into", `fullname`
list = list + find(pattern, fullname)
return list

View File

@ -1,623 +0,0 @@
# Text formatting abstractions
# Note -- this module is obsolete, it's too slow anyway
import string
import Para
# A formatter back-end object has one method that is called by the formatter:
# addpara(p), where p is a paragraph object. For example:
# Formatter back-end to do nothing at all with the paragraphs
class NullBackEnd:
#
def __init__(self):
pass
#
def addpara(self, p):
pass
#
def bgn_anchor(self, id):
pass
#
def end_anchor(self, id):
pass
# Formatter back-end to collect the paragraphs in a list
class SavingBackEnd(NullBackEnd):
#
def __init__(self):
self.paralist = []
#
def addpara(self, p):
self.paralist.append(p)
#
def hitcheck(self, h, v):
hits = []
for p in self.paralist:
if p.top <= v <= p.bottom:
for id in p.hitcheck(h, v):
if id not in hits:
hits.append(id)
return hits
#
def extract(self):
text = ''
for p in self.paralist:
text = text + (p.extract())
return text
#
def extractpart(self, long1, long2):
if long1 > long2: long1, long2 = long2, long1
para1, pos1 = long1
para2, pos2 = long2
text = ''
while para1 < para2:
ptext = self.paralist[para1].extract()
text = text + ptext[pos1:]
pos1 = 0
para1 = para1 + 1
ptext = self.paralist[para2].extract()
return text + ptext[pos1:pos2]
#
def whereis(self, d, h, v):
total = 0
for i in range(len(self.paralist)):
p = self.paralist[i]
result = p.whereis(d, h, v)
if result is not None:
return i, result
return None
#
def roundtowords(self, long1, long2):
i, offset = long1
text = self.paralist[i].extract()
while offset > 0 and text[offset-1] != ' ': offset = offset-1
long1 = i, offset
#
i, offset = long2
text = self.paralist[i].extract()
n = len(text)
while offset < n-1 and text[offset] != ' ': offset = offset+1
long2 = i, offset
#
return long1, long2
#
def roundtoparagraphs(self, long1, long2):
long1 = long1[0], 0
long2 = long2[0], len(self.paralist[long2[0]].extract())
return long1, long2
# Formatter back-end to send the text directly to the drawing object
class WritingBackEnd(NullBackEnd):
#
def __init__(self, d, width):
self.d = d
self.width = width
self.lineno = 0
#
def addpara(self, p):
self.lineno = p.render(self.d, 0, self.lineno, self.width)
# A formatter receives a stream of formatting instructions and assembles
# these into a stream of paragraphs on to a back-end. The assembly is
# parametrized by a text measurement object, which must match the output
# operations of the back-end. The back-end is responsible for splitting
# paragraphs up in lines of a given maximum width. (This is done because
# in a windowing environment, when the window size changes, there is no
# need to redo the assembly into paragraphs, but the splitting into lines
# must be done taking the new window size into account.)
# Formatter base class. Initialize it with a text measurement object,
# which is used for text measurements, and a back-end object,
# which receives the completed paragraphs. The formatting methods are:
# setfont(font)
# setleftindent(nspaces)
# setjust(type) where type is 'l', 'c', 'r', or 'lr'
# flush()
# vspace(nlines)
# needvspace(nlines)
# addword(word, nspaces)
class BaseFormatter:
#
def __init__(self, d, b):
# Drawing object used for text measurements
self.d = d
#
# BackEnd object receiving completed paragraphs
self.b = b
#
# Parameters of the formatting model
self.leftindent = 0
self.just = 'l'
self.font = None
self.blanklines = 0
#
# Parameters derived from the current font
self.space = d.textwidth(' ')
self.line = d.lineheight()
self.ascent = d.baseline()
self.descent = self.line - self.ascent
#
# Parameter derived from the default font
self.n_space = self.space
#
# Current paragraph being built
self.para = None
self.nospace = 1
#
# Font to set on the next word
self.nextfont = None
#
def newpara(self):
return Para.Para()
#
def setfont(self, font):
if font is None: return
self.font = self.nextfont = font
d = self.d
d.setfont(font)
self.space = d.textwidth(' ')
self.line = d.lineheight()
self.ascent = d.baseline()
self.descent = self.line - self.ascent
#
def setleftindent(self, nspaces):
self.leftindent = int(self.n_space * nspaces)
if self.para:
hang = self.leftindent - self.para.indent_left
if hang > 0 and self.para.getlength() <= hang:
self.para.makehangingtag(hang)
self.nospace = 1
else:
self.flush()
#
def setrightindent(self, nspaces):
self.rightindent = int(self.n_space * nspaces)
if self.para:
self.para.indent_right = self.rightindent
self.flush()
#
def setjust(self, just):
self.just = just
if self.para:
self.para.just = self.just
#
def flush(self):
if self.para:
self.b.addpara(self.para)
self.para = None
if self.font is not None:
self.d.setfont(self.font)
self.nospace = 1
#
def vspace(self, nlines):
self.flush()
if nlines > 0:
self.para = self.newpara()
tuple = None, '', 0, 0, 0, int(nlines*self.line), 0
self.para.words.append(tuple)
self.flush()
self.blanklines = self.blanklines + nlines
#
def needvspace(self, nlines):
self.flush() # Just to be sure
if nlines > self.blanklines:
self.vspace(nlines - self.blanklines)
#
def addword(self, text, space):
if self.nospace and not text:
return
self.nospace = 0
self.blanklines = 0
if not self.para:
self.para = self.newpara()
self.para.indent_left = self.leftindent
self.para.just = self.just
self.nextfont = self.font
space = int(space * self.space)
self.para.words.append((self.nextfont, text,
self.d.textwidth(text), space, space,
self.ascent, self.descent))
self.nextfont = None
#
def bgn_anchor(self, id):
if not self.para:
self.nospace = 0
self.addword('', 0)
self.para.bgn_anchor(id)
#
def end_anchor(self, id):
if not self.para:
self.nospace = 0
self.addword('', 0)
self.para.end_anchor(id)
# Measuring object for measuring text as viewed on a tty
class NullMeasurer:
#
def __init__(self):
pass
#
def setfont(self, font):
pass
#
def textwidth(self, text):
return len(text)
#
def lineheight(self):
return 1
#
def baseline(self):
return 0
# Drawing object for writing plain ASCII text to a file
class FileWriter:
#
def __init__(self, fp):
self.fp = fp
self.lineno, self.colno = 0, 0
#
def setfont(self, font):
pass
#
def text(self, (h, v), str):
if not str: return
if '\n' in str:
raise ValueError, 'can\'t write \\n'
while self.lineno < v:
self.fp.write('\n')
self.colno, self.lineno = 0, self.lineno + 1
while self.lineno > v:
# XXX This should never happen...
self.fp.write('\033[A') # ANSI up arrow
self.lineno = self.lineno - 1
if self.colno < h:
self.fp.write(' ' * (h - self.colno))
elif self.colno > h:
self.fp.write('\b' * (self.colno - h))
self.colno = h
self.fp.write(str)
self.colno = h + len(str)
# Formatting class to do nothing at all with the data
class NullFormatter(BaseFormatter):
#
def __init__(self):
d = NullMeasurer()
b = NullBackEnd()
BaseFormatter.__init__(self, d, b)
# Formatting class to write directly to a file
class WritingFormatter(BaseFormatter):
#
def __init__(self, fp, width):
dm = NullMeasurer()
dw = FileWriter(fp)
b = WritingBackEnd(dw, width)
BaseFormatter.__init__(self, dm, b)
self.blanklines = 1
#
# Suppress multiple blank lines
def needvspace(self, nlines):
BaseFormatter.needvspace(self, min(1, nlines))
# A "FunnyFormatter" writes ASCII text with a twist: *bold words*,
# _italic text_ and _underlined words_, and `quoted text'.
# It assumes that the fonts are 'r', 'i', 'b', 'u', 'q': (roman,
# italic, bold, underline, quote).
# Moreover, if the font is in upper case, the text is converted to
# UPPER CASE.
class FunnyFormatter(WritingFormatter):
#
def flush(self):
if self.para: finalize(self.para)
WritingFormatter.flush(self)
# Surrounds *bold words* and _italic text_ in a paragraph with
# appropriate markers, fixing the size (assuming these characters'
# width is 1).
openchar = \
{'b':'*', 'i':'_', 'u':'_', 'q':'`', 'B':'*', 'I':'_', 'U':'_', 'Q':'`'}
closechar = \
{'b':'*', 'i':'_', 'u':'_', 'q':'\'', 'B':'*', 'I':'_', 'U':'_', 'Q':'\''}
def finalize(para):
oldfont = curfont = 'r'
para.words.append(('r', '', 0, 0, 0, 0)) # temporary, deleted at end
for i in range(len(para.words)):
fo, te, wi = para.words[i][:3]
if fo is not None: curfont = fo
if curfont != oldfont:
if closechar.has_key(oldfont):
c = closechar[oldfont]
j = i-1
while j > 0 and para.words[j][1] == '': j = j-1
fo1, te1, wi1 = para.words[j][:3]
te1 = te1 + c
wi1 = wi1 + len(c)
para.words[j] = (fo1, te1, wi1) + \
para.words[j][3:]
if openchar.has_key(curfont) and te:
c = openchar[curfont]
te = c + te
wi = len(c) + wi
para.words[i] = (fo, te, wi) + \
para.words[i][3:]
if te: oldfont = curfont
else: oldfont = 'r'
if curfont in string.uppercase:
te = string.upper(te)
para.words[i] = (fo, te, wi) + para.words[i][3:]
del para.words[-1]
# Formatter back-end to draw the text in a window.
# This has an option to draw while the paragraphs are being added,
# to minimize the delay before the user sees anything.
# This manages the entire "document" of the window.
class StdwinBackEnd(SavingBackEnd):
#
def __init__(self, window, drawnow):
self.window = window
self.drawnow = drawnow
self.width = window.getwinsize()[0]
self.selection = None
self.height = 0
window.setorigin(0, 0)
window.setdocsize(0, 0)
self.d = window.begindrawing()
SavingBackEnd.__init__(self)
#
def finish(self):
self.d.close()
self.d = None
self.window.setdocsize(0, self.height)
#
def addpara(self, p):
self.paralist.append(p)
if self.drawnow:
self.height = \
p.render(self.d, 0, self.height, self.width)
else:
p.layout(self.width)
p.left = 0
p.top = self.height
p.right = self.width
p.bottom = self.height + p.height
self.height = p.bottom
#
def resize(self):
self.window.change((0, 0), (self.width, self.height))
self.width = self.window.getwinsize()[0]
self.height = 0
for p in self.paralist:
p.layout(self.width)
p.left = 0
p.top = self.height
p.right = self.width
p.bottom = self.height + p.height
self.height = p.bottom
self.window.change((0, 0), (self.width, self.height))
self.window.setdocsize(0, self.height)
#
def redraw(self, area):
d = self.window.begindrawing()
(left, top), (right, bottom) = area
d.erase(area)
d.cliprect(area)
for p in self.paralist:
if top < p.bottom and p.top < bottom:
v = p.render(d, p.left, p.top, p.right)
if self.selection:
self.invert(d, self.selection)
d.close()
#
def setselection(self, new):
if new:
long1, long2 = new
pos1 = long1[:3]
pos2 = long2[:3]
new = pos1, pos2
if new != self.selection:
d = self.window.begindrawing()
if self.selection:
self.invert(d, self.selection)
if new:
self.invert(d, new)
d.close()
self.selection = new
#
def getselection(self):
return self.selection
#
def extractselection(self):
if self.selection:
a, b = self.selection
return self.extractpart(a, b)
else:
return None
#
def invert(self, d, region):
long1, long2 = region
if long1 > long2: long1, long2 = long2, long1
para1, pos1 = long1
para2, pos2 = long2
while para1 < para2:
self.paralist[para1].invert(d, pos1, None)
pos1 = None
para1 = para1 + 1
self.paralist[para2].invert(d, pos1, pos2)
#
def search(self, prog):
import re, string
if type(prog) is type(''):
prog = re.compile(string.lower(prog))
if self.selection:
iold = self.selection[0][0]
else:
iold = -1
hit = None
for i in range(len(self.paralist)):
if i == iold or i < iold and hit:
continue
p = self.paralist[i]
text = string.lower(p.extract())
match = prog.search(text)
if match:
a, b = match.group(0)
long1 = i, a
long2 = i, b
hit = long1, long2
if i > iold:
break
if hit:
self.setselection(hit)
i = hit[0][0]
p = self.paralist[i]
self.window.show((p.left, p.top), (p.right, p.bottom))
return 1
else:
return 0
#
def showanchor(self, id):
for i in range(len(self.paralist)):
p = self.paralist[i]
if p.hasanchor(id):
long1 = i, 0
long2 = i, len(p.extract())
hit = long1, long2
self.setselection(hit)
self.window.show(
(p.left, p.top), (p.right, p.bottom))
break
# GL extensions
class GLFontCache:
#
def __init__(self):
self.reset()
self.setfont('')
#
def reset(self):
self.fontkey = None
self.fonthandle = None
self.fontinfo = None
self.fontcache = {}
#
def close(self):
self.reset()
#
def setfont(self, fontkey):
if fontkey == '':
fontkey = 'Times-Roman 12'
elif ' ' not in fontkey:
fontkey = fontkey + ' 12'
if fontkey == self.fontkey:
return
if self.fontcache.has_key(fontkey):
handle = self.fontcache[fontkey]
else:
import string
i = string.index(fontkey, ' ')
name, sizestr = fontkey[:i], fontkey[i:]
size = eval(sizestr)
key1 = name + ' 1'
key = name + ' ' + `size`
# NB key may differ from fontkey!
if self.fontcache.has_key(key):
handle = self.fontcache[key]
else:
if self.fontcache.has_key(key1):
handle = self.fontcache[key1]
else:
import fm
handle = fm.findfont(name)
self.fontcache[key1] = handle
handle = handle.scalefont(size)
self.fontcache[fontkey] = \
self.fontcache[key] = handle
self.fontkey = fontkey
if self.fonthandle != handle:
self.fonthandle = handle
self.fontinfo = handle.getfontinfo()
handle.setfont()
class GLMeasurer(GLFontCache):
#
def textwidth(self, text):
return self.fonthandle.getstrwidth(text)
#
def baseline(self):
return self.fontinfo[6] - self.fontinfo[3]
#
def lineheight(self):
return self.fontinfo[6]
class GLWriter(GLFontCache):
#
# NOTES:
# (1) Use gl.ortho2 to use X pixel coordinates!
#
def text(self, (h, v), text):
import gl, fm
gl.cmov2i(h, v + self.fontinfo[6] - self.fontinfo[3])
fm.prstr(text)
#
def setfont(self, fontkey):
oldhandle = self.fonthandle
GLFontCache.setfont(fontkey)
if self.fonthandle != oldhandle:
handle.setfont()
class GLMeasurerWriter(GLMeasurer, GLWriter):
pass
class GLBackEnd(SavingBackEnd):
#
def __init__(self, wid):
import gl
gl.winset(wid)
self.wid = wid
self.width = gl.getsize()[1]
self.height = 0
self.d = GLMeasurerWriter()
SavingBackEnd.__init__(self)
#
def finish(self):
pass
#
def addpara(self, p):
self.paralist.append(p)
self.height = p.render(self.d, 0, self.height, self.width)
#
def redraw(self):
import gl
gl.winset(self.wid)
width = gl.getsize()[1]
if width != self.width:
setdocsize = 1
self.width = width
for p in self.paralist:
p.top = p.bottom = None
d = self.d
v = 0
for p in self.paralist:
v = p.render(d, 0, v, width)

View File

@ -1,79 +0,0 @@
# 'grep'
import regex
from regex_syntax import *
opt_show_where = 0
opt_show_filename = 0
opt_show_lineno = 1
def grep(pat, *files):
return ggrep(RE_SYNTAX_GREP, pat, files)
def egrep(pat, *files):
return ggrep(RE_SYNTAX_EGREP, pat, files)
def emgrep(pat, *files):
return ggrep(RE_SYNTAX_EMACS, pat, files)
def ggrep(syntax, pat, files):
if len(files) == 1 and type(files[0]) == type([]):
files = files[0]
global opt_show_filename
opt_show_filename = (len(files) != 1)
syntax = regex.set_syntax(syntax)
try:
prog = regex.compile(pat)
finally:
syntax = regex.set_syntax(syntax)
for filename in files:
fp = open(filename, 'r')
lineno = 0
while 1:
line = fp.readline()
if not line: break
lineno = lineno + 1
if prog.search(line) >= 0:
showline(filename, lineno, line, prog)
fp.close()
def pgrep(pat, *files):
if len(files) == 1 and type(files[0]) == type([]):
files = files[0]
global opt_show_filename
opt_show_filename = (len(files) != 1)
import re
prog = re.compile(pat)
for filename in files:
fp = open(filename, 'r')
lineno = 0
while 1:
line = fp.readline()
if not line: break
lineno = lineno + 1
if prog.search(line):
showline(filename, lineno, line, prog)
fp.close()
def showline(filename, lineno, line, prog):
if line[-1:] == '\n': line = line[:-1]
if opt_show_lineno:
prefix = `lineno`.rjust(3) + ': '
else:
prefix = ''
if opt_show_filename:
prefix = filename + ': ' + prefix
print prefix + line
if opt_show_where:
start, end = prog.regs()[0]
line = line[:start]
if '\t' not in line:
prefix = ' ' * (len(prefix) + start)
else:
prefix = ' ' * len(prefix)
for c in line:
if c != '\t': c = ' '
prefix = prefix + c
if start == end: prefix = prefix + '\\'
else: prefix = prefix + '^'*(end-start)
print prefix

View File

@ -1,15 +0,0 @@
import struct, fcntl
def writelock(f):
_lock(f, fcntl.F_WRLCK)
def readlock(f):
_lock(f, fcntl.F_RDLCK)
def unlock(f):
_lock(f, fcntl.F_UNLCK)
def _lock(f, op):
dummy = fcntl.fcntl(f.fileno(), fcntl.F_SETLKW,
struct.pack('2h8l', op,
0, 0, 0, 0, 0, 0, 0, 0, 0))

View File

@ -1,73 +0,0 @@
# New dir() function
# This should be the new dir(), except that it should still list
# the current local name space by default
def listattrs(x):
try:
dictkeys = x.__dict__.keys()
except (AttributeError, TypeError):
dictkeys = []
#
try:
methods = x.__methods__
except (AttributeError, TypeError):
methods = []
#
try:
members = x.__members__
except (AttributeError, TypeError):
members = []
#
try:
the_class = x.__class__
except (AttributeError, TypeError):
the_class = None
#
try:
bases = x.__bases__
except (AttributeError, TypeError):
bases = ()
#
total = dictkeys + methods + members
if the_class:
# It's a class instace; add the class's attributes
# that are functions (methods)...
class_attrs = listattrs(the_class)
class_methods = []
for name in class_attrs:
if is_function(getattr(the_class, name)):
class_methods.append(name)
total = total + class_methods
elif bases:
# It's a derived class; add the base class attributes
for base in bases:
base_attrs = listattrs(base)
total = total + base_attrs
total.sort()
return total
i = 0
while i+1 < len(total):
if total[i] == total[i+1]:
del total[i+1]
else:
i = i+1
return total
# Helper to recognize functions
def is_function(x):
return type(x) == type(is_function)
# Approximation of builtin dir(); but note that this lists the user's
# variables by default, not the current local name space.
def dir(x = None):
if x is not None:
return listattrs(x)
else:
import __main__
return listattrs(__main__)

View File

@ -1,433 +0,0 @@
"""New import scheme with package support.
Quick Reference
---------------
- To enable package support, execute "import ni" before importing any
packages. Importing this module automatically installs the relevant
import hooks.
- To create a package named spam containing sub-modules ham, bacon and
eggs, create a directory spam somewhere on Python's module search
path (i.e. spam's parent directory must be one of the directories in
sys.path or $PYTHONPATH); then create files ham.py, bacon.py and
eggs.py inside spam.
- To import module ham from package spam and use function hamneggs()
from that module, you can either do
import spam.ham # *not* "import spam" !!!
spam.ham.hamneggs()
or
from spam import ham
ham.hamneggs()
or
from spam.ham import hamneggs
hamneggs()
- Importing just "spam" does not do what you expect: it creates an
empty package named spam if one does not already exist, but it does
not import spam's submodules. The only submodule that is guaranteed
to be imported is spam.__init__, if it exists. Note that
spam.__init__ is a submodule of package spam. It can reference to
spam's namespace via the '__.' prefix, for instance
__.spam_inited = 1 # Set a package-level variable
Theory of Operation
-------------------
A Package is a module that can contain other modules. Packages can be
nested. Package introduce dotted names for modules, like P.Q.M, which
could correspond to a file P/Q/M.py found somewhere on sys.path. It
is possible to import a package itself, though this makes little sense
unless the package contains a module called __init__.
A package has two variables that control the namespace used for
packages and modules, both initialized to sensible defaults the first
time the package is referenced.
(1) A package's *module search path*, contained in the per-package
variable __path__, defines a list of *directories* where submodules or
subpackages of the package are searched. It is initialized to the
directory containing the package. Setting this variable to None makes
the module search path default to sys.path (this is not quite the same
as setting it to sys.path, since the latter won't track later
assignments to sys.path).
(2) A package's *import domain*, contained in the per-package variable
__domain__, defines a list of *packages* that are searched (using
their respective module search paths) to satisfy imports. It is
initialized to the list consisting of the package itself, its parent
package, its parent's parent, and so on, ending with the root package
(the nameless package containing all top-level packages and modules,
whose module search path is None, implying sys.path).
The default domain implements a search algorithm called "expanding
search". An alternative search algorithm called "explicit search"
fixes the import search path to contain only the root package,
requiring the modules in the package to name all imported modules by
their full name. The convention of using '__' to refer to the current
package (both as a per-module variable and in module names) can be
used by packages using explicit search to refer to modules in the same
package; this combination is known as "explicit-relative search".
The PackageImporter and PackageLoader classes together implement the
following policies:
- There is a root package, whose name is ''. It cannot be imported
directly but may be referenced, e.g. by using '__' from a top-level
module.
- In each module or package, the variable '__' contains a reference to
the parent package; in the root package, '__' points to itself.
- In the name for imported modules (e.g. M in "import M" or "from M
import ..."), a leading '__' refers to the current package (i.e.
the package containing the current module); leading '__.__' and so
on refer to the current package's parent, and so on. The use of
'__' elsewhere in the module name is not supported.
- Modules are searched using the "expanding search" algorithm by
virtue of the default value for __domain__.
- If A.B.C is imported, A is searched using __domain__; then
subpackage B is searched in A using its __path__, and so on.
- Built-in modules have priority: even if a file sys.py exists in a
package, "import sys" imports the built-in sys module.
- The same holds for frozen modules, for better or for worse.
- Submodules and subpackages are not automatically loaded when their
parent packages is loaded.
- The construct "from package import *" is illegal. (It can still be
used to import names from a module.)
- When "from package import module1, module2, ..." is used, those
modules are explicitly loaded.
- When a package is loaded, if it has a submodule __init__, that
module is loaded. This is the place where required submodules can
be loaded, the __path__ variable extended, etc. The __init__ module
is loaded even if the package was loaded only in order to create a
stub for a sub-package: if "import P.Q.R" is the first reference to
P, and P has a submodule __init__, P.__init__ is loaded before P.Q
is even searched.
Caveats:
- It is possible to import a package that has no __init__ submodule;
this is not particularly useful but there may be useful applications
for it (e.g. to manipulate its search paths from the outside!).
- There are no special provisions for os.chdir(). If you plan to use
os.chdir() before you have imported all your modules, it is better
not to have relative pathnames in sys.path. (This could actually be
fixed by changing the implementation of path_join() in the hook to
absolutize paths.)
- Packages and modules are introduced in sys.modules as soon as their
loading is started. When the loading is terminated by an exception,
the sys.modules entries remain around.
- There are no special measures to support mutually recursive modules,
but it will work under the same conditions where it works in the
flat module space system.
- Sometimes dummy entries (whose value is None) are entered in
sys.modules, to indicate that a particular module does not exist --
this is done to speed up the expanding search algorithm when a
module residing at a higher level is repeatedly imported (Python
promises that importing a previously imported module is cheap!)
- Although dynamically loaded extensions are allowed inside packages,
the current implementation (hardcoded in the interpreter) of their
initialization may cause problems if an extension invokes the
interpreter during its initialization.
- reload() may find another version of the module only if it occurs on
the package search path. Thus, it keeps the connection to the
package to which the module belongs, but may find a different file.
XXX Need to have an explicit name for '', e.g. '__root__'.
"""
import imp
import sys
import __builtin__
import ihooks
from ihooks import ModuleLoader, ModuleImporter
class PackageLoader(ModuleLoader):
"""A subclass of ModuleLoader with package support.
find_module_in_dir() will succeed if there's a subdirectory with
the given name; load_module() will create a stub for a package and
load its __init__ module if it exists.
"""
def find_module_in_dir(self, name, dir):
if dir is not None:
dirname = self.hooks.path_join(dir, name)
if self.hooks.path_isdir(dirname):
return None, dirname, ('', '', 'PACKAGE')
return ModuleLoader.find_module_in_dir(self, name, dir)
def load_module(self, name, stuff):
file, filename, info = stuff
suff, mode, type = info
if type == 'PACKAGE':
return self.load_package(name, stuff)
if sys.modules.has_key(name):
m = sys.modules[name]
else:
sys.modules[name] = m = imp.new_module(name)
self.set_parent(m)
if type == imp.C_EXTENSION and '.' in name:
return self.load_dynamic(name, stuff)
else:
return ModuleLoader.load_module(self, name, stuff)
def load_dynamic(self, name, stuff):
file, filename, (suff, mode, type) = stuff
# Hack around restriction in imp.load_dynamic()
i = name.rfind('.')
tail = name[i+1:]
if sys.modules.has_key(tail):
save = sys.modules[tail]
else:
save = None
sys.modules[tail] = imp.new_module(name)
try:
m = imp.load_dynamic(tail, filename, file)
finally:
if save:
sys.modules[tail] = save
else:
del sys.modules[tail]
sys.modules[name] = m
return m
def load_package(self, name, stuff):
file, filename, info = stuff
if sys.modules.has_key(name):
package = sys.modules[name]
else:
sys.modules[name] = package = imp.new_module(name)
package.__path__ = [filename]
self.init_package(package)
return package
def init_package(self, package):
self.set_parent(package)
self.set_domain(package)
self.call_init_module(package)
def set_parent(self, m):
name = m.__name__
if '.' in name:
name = name[:name.rfind('.')]
else:
name = ''
m.__ = sys.modules[name]
def set_domain(self, package):
name = package.__name__
package.__domain__ = domain = [name]
while '.' in name:
name = name[:name.rfind('.')]
domain.append(name)
if name:
domain.append('')
def call_init_module(self, package):
stuff = self.find_module('__init__', package.__path__)
if stuff:
m = self.load_module(package.__name__ + '.__init__', stuff)
package.__init__ = m
class PackageImporter(ModuleImporter):
"""Importer that understands packages and '__'."""
def __init__(self, loader = None, verbose = 0):
ModuleImporter.__init__(self,
loader or PackageLoader(None, verbose), verbose)
def import_module(self, name, globals={}, locals={}, fromlist=[]):
if globals.has_key('__'):
package = globals['__']
else:
# No calling context, assume in root package
package = sys.modules['']
if name[:3] in ('__.', '__'):
p = package
name = name[3:]
while name[:3] in ('__.', '__'):
p = p.__
name = name[3:]
if not name:
return self.finish(package, p, '', fromlist)
if '.' in name:
i = name.find('.')
name, tail = name[:i], name[i:]
else:
tail = ''
mname = p.__name__ and p.__name__+'.'+name or name
m = self.get1(mname)
return self.finish(package, m, tail, fromlist)
if '.' in name:
i = name.find('.')
name, tail = name[:i], name[i:]
else:
tail = ''
for pname in package.__domain__:
mname = pname and pname+'.'+name or name
m = self.get0(mname)
if m: break
else:
raise ImportError, "No such module %s" % name
return self.finish(m, m, tail, fromlist)
def finish(self, module, m, tail, fromlist):
# Got ....A; now get ....A.B.C.D
yname = m.__name__
if tail and sys.modules.has_key(yname + tail): # Fast path
yname, tail = yname + tail, ''
m = self.get1(yname)
while tail:
i = tail.find('.', 1)
if i > 0:
head, tail = tail[:i], tail[i:]
else:
head, tail = tail, ''
yname = yname + head
m = self.get1(yname)
# Got ....A.B.C.D; now finalize things depending on fromlist
if not fromlist:
return module
if '__' in fromlist:
raise ImportError, "Can't import __ from anywhere"
if not hasattr(m, '__path__'): return m
if '*' in fromlist:
raise ImportError, "Can't import * from a package"
for f in fromlist:
if hasattr(m, f): continue
fname = yname + '.' + f
self.get1(fname)
return m
def get1(self, name):
m = self.get(name)
if not m:
raise ImportError, "No module named %s" % name
return m
def get0(self, name):
m = self.get(name)
if not m:
sys.modules[name] = None
return m
def get(self, name):
# Internal routine to get or load a module when its parent exists
if sys.modules.has_key(name):
return sys.modules[name]
if '.' in name:
i = name.rfind('.')
head, tail = name[:i], name[i+1:]
else:
head, tail = '', name
path = sys.modules[head].__path__
stuff = self.loader.find_module(tail, path)
if not stuff:
return None
sys.modules[name] = m = self.loader.load_module(name, stuff)
if head:
setattr(sys.modules[head], tail, m)
return m
def reload(self, module):
name = module.__name__
if '.' in name:
i = name.rfind('.')
head, tail = name[:i], name[i+1:]
path = sys.modules[head].__path__
else:
tail = name
path = sys.modules[''].__path__
stuff = self.loader.find_module(tail, path)
if not stuff:
raise ImportError, "No module named %s" % name
return self.loader.load_module(name, stuff)
def unload(self, module):
if hasattr(module, '__path__'):
raise ImportError, "don't know how to unload packages yet"
PackageImporter.unload(self, module)
def install(self):
if not sys.modules.has_key(''):
sys.modules[''] = package = imp.new_module('')
package.__path__ = None
self.loader.init_package(package)
for m in sys.modules.values():
if not m: continue
if not hasattr(m, '__'):
self.loader.set_parent(m)
ModuleImporter.install(self)
def install(v = 0):
ihooks.install(PackageImporter(None, v))
def uninstall():
ihooks.uninstall()
def ni(v = 0):
install(v)
def no():
uninstall()
def test():
import pdb
try:
testproper()
except:
sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
print
print sys.last_type, ':', sys.last_value
print
pdb.pm()
def testproper():
install(1)
try:
import mactest
print dir(mactest)
raw_input('OK?')
finally:
uninstall()
if __name__ == '__main__':
test()
else:
install()

View File

@ -1,111 +0,0 @@
# Module 'packmail' -- create a self-unpacking shell archive.
# This module works on UNIX and on the Mac; the archives can unpack
# themselves only on UNIX.
import os
from stat import ST_MTIME
# Print help
def help():
print 'All fns have a file open for writing as first parameter'
print 'pack(f, fullname, name): pack fullname as name'
print 'packsome(f, directory, namelist): selected files from directory'
print 'packall(f, directory): pack all files from directory'
print 'packnotolder(f, directory, name): pack all files from directory'
print ' that are not older than a file there'
print 'packtree(f, directory): pack entire directory tree'
# Pack one file
def pack(outfp, file, name):
fp = open(file, 'r')
outfp.write('echo ' + name + '\n')
outfp.write('sed "s/^X//" >"' + name + '" <<"!"\n')
while 1:
line = fp.readline()
if not line: break
if line[-1:] != '\n':
line = line + '\n'
outfp.write('X' + line)
outfp.write('!\n')
fp.close()
# Pack some files from a directory
def packsome(outfp, dirname, names):
for name in names:
print name
file = os.path.join(dirname, name)
pack(outfp, file, name)
# Pack all files from a directory
def packall(outfp, dirname):
names = os.listdir(dirname)
try:
names.remove('.')
except:
pass
try:
names.remove('..')
except:
pass
names.sort()
packsome(outfp, dirname, names)
# Pack all files from a directory that are not older than a give one
def packnotolder(outfp, dirname, oldest):
names = os.listdir(dirname)
try:
names.remove('.')
except:
pass
try:
names.remove('..')
except:
pass
oldest = os.path.join(dirname, oldest)
st = os.stat(oldest)
mtime = st[ST_MTIME]
todo = []
for name in names:
print name, '...',
st = os.stat(os.path.join(dirname, name))
if st[ST_MTIME] >= mtime:
print 'Yes.'
todo.append(name)
else:
print 'No.'
todo.sort()
packsome(outfp, dirname, todo)
# Pack a whole tree (no exceptions)
def packtree(outfp, dirname):
print 'packtree', dirname
outfp.write('mkdir ' + unixfix(dirname) + '\n')
names = os.listdir(dirname)
try:
names.remove('.')
except:
pass
try:
names.remove('..')
except:
pass
subdirs = []
for name in names:
fullname = os.path.join(dirname, name)
if os.path.isdir(fullname):
subdirs.append(fullname)
else:
print 'pack', fullname
pack(outfp, fullname, unixfix(fullname))
for subdirname in subdirs:
packtree(outfp, subdirname)
def unixfix(name):
comps = name.split(os.sep)
res = ''
for comp in comps:
if comp:
if res: res = res + '/'
res = res + comp
return res

View File

@ -1,52 +0,0 @@
# module 'poly' -- Polynomials
# A polynomial is represented by a list of coefficients, e.g.,
# [1, 10, 5] represents 1*x**0 + 10*x**1 + 5*x**2 (or 1 + 10x + 5x**2).
# There is no way to suppress internal zeros; trailing zeros are
# taken out by normalize().
def normalize(p): # Strip unnecessary zero coefficients
n = len(p)
while n:
if p[n-1]: return p[:n]
n = n-1
return []
def plus(a, b):
if len(a) < len(b): a, b = b, a # make sure a is the longest
res = a[:] # make a copy
for i in range(len(b)):
res[i] = res[i] + b[i]
return normalize(res)
def minus(a, b):
neg_b = map(lambda x: -x, b[:])
return plus(a, neg_b)
def one(power, coeff): # Representation of coeff * x**power
res = []
for i in range(power): res.append(0)
return res + [coeff]
def times(a, b):
res = []
for i in range(len(a)):
for j in range(len(b)):
res = plus(res, one(i+j, a[i]*b[j]))
return res
def power(a, n): # Raise polynomial a to the positive integral power n
if n == 0: return [1]
if n == 1: return a
if n/2*2 == n:
b = power(a, n/2)
return times(b, b)
return times(power(a, n-1), a)
def der(a): # First derivative
res = a[1:]
for i in range(len(res)):
res[i] = res[i] * (i+1)
return res
# Computing a primitive function would require rational arithmetic...

View File

@ -1,13 +0,0 @@
# Module 'rand'
# Don't use unless you want compatibility with C's rand()!
import whrandom
def srand(seed):
whrandom.seed(seed%256, seed/256%256, seed/65536%256)
def rand():
return int(whrandom.random() * 32768.0) % 32768
def choice(seq):
return seq[rand() % len(seq)]

View File

@ -1,82 +0,0 @@
"""Maintain a cache of stat() information on files.
There are functions to reset the cache or to selectively remove items.
"""
import warnings
warnings.warn("The statcache module is obsolete. Use os.stat() instead.",
DeprecationWarning)
del warnings
import os as _os
from stat import *
__all__ = ["stat","reset","forget","forget_prefix","forget_dir",
"forget_except_prefix","isdir"]
# The cache. Keys are pathnames, values are os.stat outcomes.
# Remember that multiple threads may be calling this! So, e.g., that
# path in cache returns 1 doesn't mean the cache will still contain
# path on the next line. Code defensively.
cache = {}
def stat(path):
"""Stat a file, possibly out of the cache."""
ret = cache.get(path, None)
if ret is None:
cache[path] = ret = _os.stat(path)
return ret
def reset():
"""Clear the cache."""
cache.clear()
# For thread saftey, always use forget() internally too.
def forget(path):
"""Remove a given item from the cache, if it exists."""
try:
del cache[path]
except KeyError:
pass
def forget_prefix(prefix):
"""Remove all pathnames with a given prefix."""
for path in cache.keys():
if path.startswith(prefix):
forget(path)
def forget_dir(prefix):
"""Forget a directory and all entries except for entries in subdirs."""
# Remove trailing separator, if any. This is tricky to do in a
# x-platform way. For example, Windows accepts both / and \ as
# separators, and if there's nothing *but* a separator we want to
# preserve that this is the root. Only os.path has the platform
# knowledge we need.
from os.path import split, join
prefix = split(join(prefix, "xxx"))[0]
forget(prefix)
for path in cache.keys():
# First check that the path at least starts with the prefix, so
# that when it doesn't we can avoid paying for split().
if path.startswith(prefix) and split(path)[0] == prefix:
forget(path)
def forget_except_prefix(prefix):
"""Remove all pathnames except with a given prefix.
Normally used with prefix = '/' after a chdir().
"""
for path in cache.keys():
if not path.startswith(prefix):
forget(path)
def isdir(path):
"""Return True if directory, else False."""
try:
st = stat(path)
except _os.error:
return False
return S_ISDIR(st.st_mode)

View File

@ -1,177 +0,0 @@
# Print tracebacks, with a dump of local variables.
# Also an interactive stack trace browser.
# Note -- this module is obsolete -- use pdb.pm() instead.
import sys
import os
from stat import *
import linecache
def br(): browser(sys.last_traceback)
def tb(): printtb(sys.last_traceback)
def browser(tb):
if not tb:
print 'No traceback.'
return
tblist = []
while tb:
tblist.append(tb)
tb = tb.tb_next
ptr = len(tblist)-1
tb = tblist[ptr]
while 1:
if tb != tblist[ptr]:
tb = tblist[ptr]
print `ptr` + ':',
printtbheader(tb)
try:
line = raw_input('TB: ')
except KeyboardInterrupt:
print '\n[Interrupted]'
break
except EOFError:
print '\n[EOF]'
break
cmd = line.strip()
if cmd:
if cmd == 'quit':
break
elif cmd == 'list':
browserlist(tb)
elif cmd == 'up':
if ptr-1 >= 0: ptr = ptr-1
else: print 'Bottom of stack.'
elif cmd == 'down':
if ptr+1 < len(tblist): ptr = ptr+1
else: print 'Top of stack.'
elif cmd == 'locals':
printsymbols(tb.tb_frame.f_locals)
elif cmd == 'globals':
printsymbols(tb.tb_frame.f_globals)
elif cmd in ('?', 'help'):
browserhelp()
else:
browserexec(tb, cmd)
def browserlist(tb):
filename = tb.tb_frame.f_code.co_filename
lineno = tb.tb_lineno
last = lineno
first = max(1, last-10)
for i in range(first, last+1):
if i == lineno: prefix = '***' + `i`.rjust(4) + ':'
else: prefix = `i`.rjust(7) + ':'
line = linecache.getline(filename, i)
if line[-1:] == '\n': line = line[:-1]
print prefix + line
def browserexec(tb, cmd):
locals = tb.tb_frame.f_locals
globals = tb.tb_frame.f_globals
try:
exec cmd+'\n' in globals, locals
except:
t, v = sys.exc_info()[:2]
print '*** Exception:',
if type(t) is type(''):
print t,
else:
print t.__name__,
if v is not None:
print ':', v,
print
print 'Type help to get help.'
def browserhelp():
print
print ' This is the traceback browser. Commands are:'
print ' up : move one level up in the call stack'
print ' down : move one level down in the call stack'
print ' locals : print all local variables at this level'
print ' globals : print all global variables at this level'
print ' list : list source code around the failure'
print ' help : print help (what you are reading now)'
print ' quit : back to command interpreter'
print ' Typing any other 1-line statement will execute it'
print ' using the current level\'s symbol tables'
print
def printtb(tb):
while tb:
print1tb(tb)
tb = tb.tb_next
def print1tb(tb):
printtbheader(tb)
if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
printsymbols(tb.tb_frame.f_locals)
def printtbheader(tb):
filename = tb.tb_frame.f_code.co_filename
lineno = tb.tb_lineno
info = '"' + filename + '"(' + `lineno` + ')'
line = linecache.getline(filename, lineno)
if line:
info = info + ': ' + line.strip()
print info
def printsymbols(d):
keys = d.keys()
keys.sort()
for name in keys:
print ' ' + name.ljust(12) + ':',
printobject(d[name], 4)
print
def printobject(v, maxlevel):
if v is None:
print 'None',
elif type(v) in (type(0), type(0.0)):
print v,
elif type(v) is type(''):
if len(v) > 20:
print `v[:17] + '...'`,
else:
print `v`,
elif type(v) is type(()):
print '(',
printlist(v, maxlevel)
print ')',
elif type(v) is type([]):
print '[',
printlist(v, maxlevel)
print ']',
elif type(v) is type({}):
print '{',
printdict(v, maxlevel)
print '}',
else:
print v,
def printlist(v, maxlevel):
n = len(v)
if n == 0: return
if maxlevel <= 0:
print '...',
return
for i in range(min(6, n)):
printobject(v[i], maxlevel-1)
if i+1 < n: print ',',
if n > 6: print '...',
def printdict(v, maxlevel):
keys = v.keys()
n = len(keys)
if n == 0: return
if maxlevel <= 0:
print '...',
return
keys.sort()
for i in range(min(6, n)):
key = keys[i]
print `key` + ':',
printobject(v[key], maxlevel-1)
if i+1 < n: print ',',
if n > 6: print '...',

View File

@ -1,98 +0,0 @@
"""Parse a timezone specification."""
# XXX Unfinished.
# XXX Only the typical form "XXXhhYYY;ddd/hh,ddd/hh" is currently supported.
import warnings
warnings.warn(
"The tzparse module is obsolete and will disappear in the future",
DeprecationWarning)
tzpat = ('^([A-Z][A-Z][A-Z])([-+]?[0-9]+)([A-Z][A-Z][A-Z]);'
'([0-9]+)/([0-9]+),([0-9]+)/([0-9]+)$')
tzprog = None
def tzparse(tzstr):
"""Given a timezone spec, return a tuple of information
(tzname, delta, dstname, daystart, hourstart, dayend, hourend),
where 'tzname' is the name of the timezone, 'delta' is the offset
in hours from GMT, 'dstname' is the name of the daylight-saving
timezone, and 'daystart'/'hourstart' and 'dayend'/'hourend'
specify the starting and ending points for daylight saving time."""
global tzprog
if tzprog is None:
import re
tzprog = re.compile(tzpat)
match = tzprog.match(tzstr)
if not match:
raise ValueError, 'not the TZ syntax I understand'
subs = []
for i in range(1, 8):
subs.append(match.group(i))
for i in (1, 3, 4, 5, 6):
subs[i] = eval(subs[i])
[tzname, delta, dstname, daystart, hourstart, dayend, hourend] = subs
return (tzname, delta, dstname, daystart, hourstart, dayend, hourend)
def tzlocaltime(secs, params):
"""Given a Unix time in seconds and a tuple of information about
a timezone as returned by tzparse(), return the local time in the
form (year, month, day, hour, min, sec, yday, wday, tzname)."""
import time
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = params
year, month, days, hours, mins, secs, yday, wday, isdst = \
time.gmtime(secs - delta*3600)
if (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend):
tzname = dstname
hours = hours + 1
return year, month, days, hours, mins, secs, yday, wday, tzname
def tzset():
"""Determine the current timezone from the "TZ" environment variable."""
global tzparams, timezone, altzone, daylight, tzname
import os
tzstr = os.environ['TZ']
tzparams = tzparse(tzstr)
timezone = tzparams[1] * 3600
altzone = timezone - 3600
daylight = 1
tzname = tzparams[0], tzparams[2]
def isdst(secs):
"""Return true if daylight-saving time is in effect for the given
Unix time in the current timezone."""
import time
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = \
tzparams
year, month, days, hours, mins, secs, yday, wday, isdst = \
time.gmtime(secs - delta*3600)
return (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend)
tzset()
def localtime(secs):
"""Get the local time in the current timezone."""
return tzlocaltime(secs, tzparams)
def test():
from time import asctime, gmtime
import time, sys
now = time.time()
x = localtime(now)
tm = x[:-1] + (0,)
print 'now =', now, '=', asctime(tm), x[-1]
now = now - now % (24*3600)
if sys.argv[1:]: now = now + eval(sys.argv[1])
x = gmtime(now)
tm = x[:-1] + (0,)
print 'gmtime =', now, '=', asctime(tm), 'yday =', x[-2]
jan1 = now - x[-2]*24*3600
x = localtime(jan1)
tm = x[:-1] + (0,)
print 'jan1 =', jan1, '=', asctime(tm), x[-1]
for d in range(85, 95) + range(265, 275):
t = jan1 + d*24*3600
x = localtime(t)
tm = x[:-1] + (0,)
print 'd =', d, 't =', t, '=', asctime(tm), x[-1]

View File

@ -1,25 +0,0 @@
# Module 'util' -- some useful functions that don't fit elsewhere
# NB: These are now built-in functions, but this module is provided
# for compatibility. Don't use in new programs unless you need backward
# compatibility (i.e. need to run with old interpreters).
# Remove an item from a list.
# No complaints if it isn't in the list at all.
# If it occurs more than once, remove the first occurrence.
#
def remove(item, list):
if item in list: list.remove(item)
# Return a string containing a file's contents.
#
def readfile(fn):
return readopenfile(open(fn, 'r'))
# Read an open file until EOF.
#
def readopenfile(fp):
return fp.read()

View File

@ -1 +0,0 @@
from sndhdr import *

View File

@ -1,144 +0,0 @@
"""Wichman-Hill random number generator.
Wichmann, B. A. & Hill, I. D. (1982)
Algorithm AS 183:
An efficient and portable pseudo-random number generator
Applied Statistics 31 (1982) 188-190
see also:
Correction to Algorithm AS 183
Applied Statistics 33 (1984) 123
McLeod, A. I. (1985)
A remark on Algorithm AS 183
Applied Statistics 34 (1985),198-200
USE:
whrandom.random() yields double precision random numbers
uniformly distributed between 0 and 1.
whrandom.seed(x, y, z) must be called before whrandom.random()
to seed the generator
There is also an interface to create multiple independent
random generators, and to choose from other ranges.
Multi-threading note: the random number generator used here is not
thread-safe; it is possible that nearly simultaneous calls in
different theads return the same random value. To avoid this, you
have to use a lock around all calls. (I didn't want to slow this
down in the serial case by using a lock here.)
"""
import warnings
warnings.warn("the whrandom module is deprecated; please use the random module",
DeprecationWarning)
# Translated by Guido van Rossum from C source provided by
# Adrian Baddeley.
class whrandom:
def __init__(self, x = 0, y = 0, z = 0):
"""Initialize an instance.
Without arguments, initialize from current time.
With arguments (x, y, z), initialize from them."""
self.seed(x, y, z)
def seed(self, x = 0, y = 0, z = 0):
"""Set the seed from (x, y, z).
These must be integers in the range [0, 256)."""
if not type(x) == type(y) == type(z) == type(0):
raise TypeError, 'seeds must be integers'
if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
raise ValueError, 'seeds must be in range(0, 256)'
if 0 == x == y == z:
# Initialize from current time
import time
t = long(time.time() * 256)
t = int((t&0xffffff) ^ (t>>24))
t, x = divmod(t, 256)
t, y = divmod(t, 256)
t, z = divmod(t, 256)
# Zero is a poor seed, so substitute 1
self._seed = (x or 1, y or 1, z or 1)
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
# This part is thread-unsafe:
# BEGIN CRITICAL SECTION
x, y, z = self._seed
#
x = (171 * x) % 30269
y = (172 * y) % 30307
z = (170 * z) % 30323
#
self._seed = x, y, z
# END CRITICAL SECTION
#
return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
def uniform(self, a, b):
"""Get a random number in the range [a, b)."""
return a + (b-a) * self.random()
def randint(self, a, b):
"""Get a random integer in the range [a, b] including
both end points.
(Deprecated; use randrange below.)"""
return self.randrange(a, b+1)
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
return seq[int(self.random() * len(seq))]
def randrange(self, start, stop=None, step=1, int=int, default=None):
"""Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
Do not supply the 'int' and 'default' arguments."""
# This code is a bit messy to make it fast for the
# common case while still doing adequate error checking
istart = int(start)
if istart != start:
raise ValueError, "non-integer arg 1 for randrange()"
if stop is default:
if istart > 0:
return int(self.random() * istart)
raise ValueError, "empty range for randrange()"
istop = int(stop)
if istop != stop:
raise ValueError, "non-integer stop for randrange()"
if step == 1:
if istart < istop:
return istart + int(self.random() *
(istop - istart))
raise ValueError, "empty range for randrange()"
istep = int(step)
if istep != step:
raise ValueError, "non-integer step for randrange()"
if istep > 0:
n = (istop - istart + istep - 1) / istep
elif istep < 0:
n = (istop - istart + istep + 1) / istep
else:
raise ValueError, "zero step for randrange()"
if n <= 0:
raise ValueError, "empty range for randrange()"
return istart + istep*int(self.random() * n)
# Initialize from the current time
_inst = whrandom()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
randint = _inst.randint
choice = _inst.choice
randrange = _inst.randrange

View File

@ -1,94 +0,0 @@
# module 'zmod'
# Compute properties of mathematical "fields" formed by taking
# Z/n (the whole numbers modulo some whole number n) and an
# irreducible polynomial (i.e., a polynomial with only complex zeros),
# e.g., Z/5 and X**2 + 2.
#
# The field is formed by taking all possible linear combinations of
# a set of d base vectors (where d is the degree of the polynomial).
#
# Note that this procedure doesn't yield a field for all combinations
# of n and p: it may well be that some numbers have more than one
# inverse and others have none. This is what we check.
#
# Remember that a field is a ring where each element has an inverse.
# A ring has commutative addition and multiplication, a zero and a one:
# 0*x = x*0 = 0, 0+x = x+0 = x, 1*x = x*1 = x. Also, the distributive
# property holds: a*(b+c) = a*b + b*c.
# (XXX I forget if this is an axiom or follows from the rules.)
import poly
# Example N and polynomial
N = 5
P = poly.plus(poly.one(0, 2), poly.one(2, 1)) # 2 + x**2
# Return x modulo y. Returns >= 0 even if x < 0.
def mod(x, y):
return divmod(x, y)[1]
# Normalize a polynomial modulo n and modulo p.
def norm(a, n, p):
a = poly.modulo(a, p)
a = a[:]
for i in range(len(a)): a[i] = mod(a[i], n)
a = poly.normalize(a)
return a
# Make a list of all n^d elements of the proposed field.
def make_all(mat):
all = []
for row in mat:
for a in row:
all.append(a)
return all
def make_elements(n, d):
if d == 0: return [poly.one(0, 0)]
sub = make_elements(n, d-1)
all = []
for a in sub:
for i in range(n):
all.append(poly.plus(a, poly.one(d-1, i)))
return all
def make_inv(all, n, p):
x = poly.one(1, 1)
inv = []
for a in all:
inv.append(norm(poly.times(a, x), n, p))
return inv
def checkfield(n, p):
all = make_elements(n, len(p)-1)
inv = make_inv(all, n, p)
all1 = all[:]
inv1 = inv[:]
all1.sort()
inv1.sort()
if all1 == inv1: print 'BINGO!'
else:
print 'Sorry:', n, p
print all
print inv
def rj(s, width):
if type(s) is not type(''): s = `s`
n = len(s)
if n >= width: return s
return ' '*(width - n) + s
def lj(s, width):
if type(s) is not type(''): s = `s`
n = len(s)
if n >= width: return s
return s + ' '*(width - n)

View File

@ -1,192 +0,0 @@
#! /usr/bin/env python
r"""Convert old ("regex") regular expressions to new syntax ("re").
When imported as a module, there are two functions, with their own
strings:
convert(s, syntax=None) -- convert a regex regular expression to re syntax
quote(s) -- return a quoted string literal
When used as a script, read a Python string literal (or any other
expression evaluating to a string) from stdin, and write the
translated expression to stdout as a string literal. Unless stdout is
a tty, no trailing \n is written to stdout. This is done so that it
can be used with Emacs C-U M-| (shell-command-on-region with argument
which filters the region through the shell command).
No attempt has been made at coding for performance.
Translation table...
\( ( (unless RE_NO_BK_PARENS set)
\) ) (unless RE_NO_BK_PARENS set)
\| | (unless RE_NO_BK_VBAR set)
\< \b (not quite the same, but alla...)
\> \b (not quite the same, but alla...)
\` \A
\' \Z
Not translated...
.
^
$
*
+ (unless RE_BK_PLUS_QM set, then to \+)
? (unless RE_BK_PLUS_QM set, then to \?)
\
\b
\B
\w
\W
\1 ... \9
Special cases...
Non-printable characters are always replaced by their 3-digit
escape code (except \t, \n, \r, which use mnemonic escapes)
Newline is turned into | when RE_NEWLINE_OR is set
XXX To be done...
[...] (different treatment of backslashed items?)
[^...] (different treatment of backslashed items?)
^ $ * + ? (in some error contexts these are probably treated differently)
\vDD \DD (in the regex docs but only works when RE_ANSI_HEX set)
"""
import warnings
warnings.filterwarnings("ignore", ".* regex .*", DeprecationWarning, __name__,
append=1)
import regex
from regex_syntax import * # RE_*
__all__ = ["convert","quote"]
# Default translation table
mastertable = {
r'\<': r'\b',
r'\>': r'\b',
r'\`': r'\A',
r'\'': r'\Z',
r'\(': '(',
r'\)': ')',
r'\|': '|',
'(': r'\(',
')': r'\)',
'|': r'\|',
'\t': r'\t',
'\n': r'\n',
'\r': r'\r',
}
def convert(s, syntax=None):
"""Convert a regex regular expression to re syntax.
The first argument is the regular expression, as a string object,
just like it would be passed to regex.compile(). (I.e., pass the
actual string object -- string quotes must already have been
removed and the standard escape processing has already been done,
e.g. by eval().)
The optional second argument is the regex syntax variant to be
used. This is an integer mask as passed to regex.set_syntax();
the flag bits are defined in regex_syntax. When not specified, or
when None is given, the current regex syntax mask (as retrieved by
regex.get_syntax()) is used -- which is 0 by default.
The return value is a regular expression, as a string object that
could be passed to re.compile(). (I.e., no string quotes have
been added -- use quote() below, or repr().)
The conversion is not always guaranteed to be correct. More
syntactical analysis should be performed to detect borderline
cases and decide what to do with them. For example, 'x*?' is not
translated correctly.
"""
table = mastertable.copy()
if syntax is None:
syntax = regex.get_syntax()
if syntax & RE_NO_BK_PARENS:
del table[r'\('], table[r'\)']
del table['('], table[')']
if syntax & RE_NO_BK_VBAR:
del table[r'\|']
del table['|']
if syntax & RE_BK_PLUS_QM:
table['+'] = r'\+'
table['?'] = r'\?'
table[r'\+'] = '+'
table[r'\?'] = '?'
if syntax & RE_NEWLINE_OR:
table['\n'] = '|'
res = ""
i = 0
end = len(s)
while i < end:
c = s[i]
i = i+1
if c == '\\':
c = s[i]
i = i+1
key = '\\' + c
key = table.get(key, key)
res = res + key
else:
c = table.get(c, c)
res = res + c
return res
def quote(s, quote=None):
"""Convert a string object to a quoted string literal.
This is similar to repr() but will return a "raw" string (r'...'
or r"...") when the string contains backslashes, instead of
doubling all backslashes. The resulting string does *not* always
evaluate to the same string as the original; however it will do
just the right thing when passed into re.compile().
The optional second argument forces the string quote; it must be
a single character which is a valid Python string quote.
"""
if quote is None:
q = "'"
altq = "'"
if q in s and altq not in s:
q = altq
else:
assert quote in ('"', "'", '"""', "'''")
q = quote
res = q
for c in s:
if c == q: c = '\\' + c
elif c < ' ' or c > '~': c = "\\%03o" % ord(c)
res = res + c
res = res + q
if '\\' in res:
res = 'r' + res
return res
def main():
"""Main program -- called when run as a script."""
import sys
s = eval(sys.stdin.read())
sys.stdout.write(quote(convert(s)))
if sys.stdout.isatty():
sys.stdout.write("\n")
if __name__ == '__main__':
main()

View File

@ -1,53 +0,0 @@
"""Constants for selecting regexp syntaxes for the obsolete regex module.
This module is only for backward compatibility. "regex" has now
been replaced by the new regular expression module, "re".
These bits are passed to regex.set_syntax() to choose among
alternative regexp syntaxes.
"""
# 1 means plain parentheses serve as grouping, and backslash
# parentheses are needed for literal searching.
# 0 means backslash-parentheses are grouping, and plain parentheses
# are for literal searching.
RE_NO_BK_PARENS = 1
# 1 means plain | serves as the "or"-operator, and \| is a literal.
# 0 means \| serves as the "or"-operator, and | is a literal.
RE_NO_BK_VBAR = 2
# 0 means plain + or ? serves as an operator, and \+, \? are literals.
# 1 means \+, \? are operators and plain +, ? are literals.
RE_BK_PLUS_QM = 4
# 1 means | binds tighter than ^ or $.
# 0 means the contrary.
RE_TIGHT_VBAR = 8
# 1 means treat \n as an _OR operator
# 0 means treat it as a normal character
RE_NEWLINE_OR = 16
# 0 means that a special characters (such as *, ^, and $) always have
# their special meaning regardless of the surrounding context.
# 1 means that special characters may act as normal characters in some
# contexts. Specifically, this applies to:
# ^ - only special at the beginning, or after ( or |
# $ - only special at the end, or before ) or |
# *, +, ? - only special when not after the beginning, (, or |
RE_CONTEXT_INDEP_OPS = 32
# ANSI sequences (\n etc) and \xhh
RE_ANSI_HEX = 64
# No GNU extensions
RE_NO_GNU_EXTENSIONS = 128
# Now define combinations of bits for the standard possibilities.
RE_SYNTAX_AWK = (RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS)
RE_SYNTAX_EGREP = (RE_SYNTAX_AWK | RE_NEWLINE_OR)
RE_SYNTAX_GREP = (RE_BK_PLUS_QM | RE_NEWLINE_OR)
RE_SYNTAX_EMACS = 0
# (Python's obsolete "regexp" module used a syntax similar to awk.)

View File

@ -1,198 +0,0 @@
"""Regexp-based split and replace using the obsolete regex module.
This module is only for backward compatibility. These operations
are now provided by the new regular expression module, "re".
sub(pat, repl, str): replace first occurrence of pattern in string
gsub(pat, repl, str): replace all occurrences of pattern in string
split(str, pat, maxsplit): split string using pattern as delimiter
splitx(str, pat, maxsplit): split string using pattern as delimiter plus
return delimiters
"""
import warnings
warnings.warn("the regsub module is deprecated; please use re.sub()",
DeprecationWarning)
# Ignore further deprecation warnings about this module
warnings.filterwarnings("ignore", "", DeprecationWarning, __name__)
import regex
__all__ = ["sub","gsub","split","splitx","capwords"]
# Replace first occurrence of pattern pat in string str by replacement
# repl. If the pattern isn't found, the string is returned unchanged.
# The replacement may contain references \digit to subpatterns and
# escaped backslashes. The pattern may be a string or an already
# compiled pattern.
def sub(pat, repl, str):
prog = compile(pat)
if prog.search(str) >= 0:
regs = prog.regs
a, b = regs[0]
str = str[:a] + expand(repl, regs, str) + str[b:]
return str
# Replace all (non-overlapping) occurrences of pattern pat in string
# str by replacement repl. The same rules as for sub() apply.
# Empty matches for the pattern are replaced only when not adjacent to
# a previous match, so e.g. gsub('', '-', 'abc') returns '-a-b-c-'.
def gsub(pat, repl, str):
prog = compile(pat)
new = ''
start = 0
first = 1
while prog.search(str, start) >= 0:
regs = prog.regs
a, b = regs[0]
if a == b == start and not first:
if start >= len(str) or prog.search(str, start+1) < 0:
break
regs = prog.regs
a, b = regs[0]
new = new + str[start:a] + expand(repl, regs, str)
start = b
first = 0
new = new + str[start:]
return new
# Split string str in fields separated by delimiters matching pattern
# pat. Only non-empty matches for the pattern are considered, so e.g.
# split('abc', '') returns ['abc'].
# The optional 3rd argument sets the number of splits that are performed.
def split(str, pat, maxsplit = 0):
return intsplit(str, pat, maxsplit, 0)
# Split string str in fields separated by delimiters matching pattern
# pat. Only non-empty matches for the pattern are considered, so e.g.
# split('abc', '') returns ['abc']. The delimiters are also included
# in the list.
# The optional 3rd argument sets the number of splits that are performed.
def splitx(str, pat, maxsplit = 0):
return intsplit(str, pat, maxsplit, 1)
# Internal function used to implement split() and splitx().
def intsplit(str, pat, maxsplit, retain):
prog = compile(pat)
res = []
start = next = 0
splitcount = 0
while prog.search(str, next) >= 0:
regs = prog.regs
a, b = regs[0]
if a == b:
next = next + 1
if next >= len(str):
break
else:
res.append(str[start:a])
if retain:
res.append(str[a:b])
start = next = b
splitcount = splitcount + 1
if (maxsplit and (splitcount >= maxsplit)):
break
res.append(str[start:])
return res
# Capitalize words split using a pattern
def capwords(str, pat='[^a-zA-Z0-9_]+'):
words = splitx(str, pat)
for i in range(0, len(words), 2):
words[i] = words[i].capitalize()
return "".join(words)
# Internal subroutines:
# compile(pat): compile a pattern, caching already compiled patterns
# expand(repl, regs, str): expand \digit escapes in replacement string
# Manage a cache of compiled regular expressions.
#
# If the pattern is a string a compiled version of it is returned. If
# the pattern has been used before we return an already compiled
# version from the cache; otherwise we compile it now and save the
# compiled version in the cache, along with the syntax it was compiled
# with. Instead of a string, a compiled regular expression can also
# be passed.
cache = {}
def compile(pat):
if type(pat) != type(''):
return pat # Assume it is a compiled regex
key = (pat, regex.get_syntax())
if key in cache:
prog = cache[key] # Get it from the cache
else:
prog = cache[key] = regex.compile(pat)
return prog
def clear_cache():
global cache
cache = {}
# Expand \digit in the replacement.
# Each occurrence of \digit is replaced by the substring of str
# indicated by regs[digit]. To include a literal \ in the
# replacement, double it; other \ escapes are left unchanged (i.e.
# the \ and the following character are both copied).
def expand(repl, regs, str):
if '\\' not in repl:
return repl
new = ''
i = 0
ord0 = ord('0')
while i < len(repl):
c = repl[i]; i = i+1
if c != '\\' or i >= len(repl):
new = new + c
else:
c = repl[i]; i = i+1
if '0' <= c <= '9':
a, b = regs[ord(c)-ord0]
new = new + str[a:b]
elif c == '\\':
new = new + c
else:
new = new + '\\' + c
return new
# Test program, reads sequences "pat repl str" from stdin.
# Optional argument specifies pattern used to split lines.
def test():
import sys
if sys.argv[1:]:
delpat = sys.argv[1]
else:
delpat = '[ \t\n]+'
while 1:
if sys.stdin.isatty(): sys.stderr.write('--> ')
line = sys.stdin.readline()
if not line: break
if line[-1] == '\n': line = line[:-1]
fields = split(line, delpat)
if len(fields) != 3:
print 'Sorry, not three fields'
print 'split:', repr(fields)
continue
[pat, repl, str] = split(line, delpat)
print 'sub :', repr(sub(pat, repl, str))
print 'gsub:', repr(gsub(pat, repl, str))

View File

@ -136,7 +136,7 @@ class RExec(ihooks._Verbose):
ok_builtin_modules = ('audioop', 'array', 'binascii',
'cmath', 'errno', 'imageop',
'marshal', 'math', 'md5', 'operator',
'parser', 'regex', 'select',
'parser', 'select',
'sha', '_sre', 'strop', 'struct', 'time',
'_weakref')

View File

@ -128,8 +128,6 @@ class AllTest(unittest.TestCase):
self.check_all("quopri")
self.check_all("random")
self.check_all("re")
self.check_all("reconvert")
self.check_all("regsub")
self.check_all("repr")
self.check_all("rexec")
self.check_all("rfc822")

View File

@ -1,113 +0,0 @@
from test.test_support import verbose, sortdict
import warnings
warnings.filterwarnings("ignore", "the regex module is deprecated",
DeprecationWarning, __name__)
import regex
from regex_syntax import *
re = 'a+b+c+'
print 'no match:', regex.match(re, 'hello aaaabcccc world')
print 'successful search:', regex.search(re, 'hello aaaabcccc world')
try:
cre = regex.compile('\(' + re)
except regex.error:
print 'caught expected exception'
else:
print 'expected regex.error not raised'
print 'failed awk syntax:', regex.search('(a+)|(b+)', 'cdb')
prev = regex.set_syntax(RE_SYNTAX_AWK)
print 'successful awk syntax:', regex.search('(a+)|(b+)', 'cdb')
regex.set_syntax(prev)
print 'failed awk syntax:', regex.search('(a+)|(b+)', 'cdb')
re = '\(<one>[0-9]+\) *\(<two>[0-9]+\)'
print 'matching with group names and compile()'
cre = regex.compile(re)
print cre.match('801 999')
try:
print cre.group('one')
except regex.error:
print 'caught expected exception'
else:
print 'expected regex.error not raised'
print 'matching with group names and symcomp()'
cre = regex.symcomp(re)
print cre.match('801 999')
print cre.group(0)
print cre.group('one')
print cre.group(1, 2)
print cre.group('one', 'two')
print 'realpat:', cre.realpat
print 'groupindex:', sortdict(cre.groupindex)
re = 'world'
cre = regex.compile(re)
print 'not case folded search:', cre.search('HELLO WORLD')
cre = regex.compile(re, regex.casefold)
print 'case folded search:', cre.search('HELLO WORLD')
print '__members__:', cre.__members__
print 'regs:', cre.regs
print 'last:', cre.last
print 'translate:', len(cre.translate)
print 'givenpat:', cre.givenpat
print 'match with pos:', cre.match('hello world', 7)
print 'search with pos:', cre.search('hello world there world', 7)
print 'bogus group:', cre.group(0, 1, 3)
try:
print 'no name:', cre.group('one')
except regex.error:
print 'caught expected exception'
else:
print 'expected regex.error not raised'
from regex_tests import *
if verbose: print 'Running regex_tests test suite'
for t in tests:
pattern=s=outcome=repl=expected=None
if len(t)==5:
pattern, s, outcome, repl, expected = t
elif len(t)==3:
pattern, s, outcome = t
else:
raise ValueError, ('Test tuples should have 3 or 5 fields',t)
try:
obj=regex.compile(pattern)
except regex.error:
if outcome==SYNTAX_ERROR: pass # Expected a syntax error
else:
# Regex syntax errors aren't yet reported, so for
# the official test suite they'll be quietly ignored.
pass
#print '=== Syntax error:', t
else:
try:
result=obj.search(s)
except regex.error, msg:
print '=== Unexpected exception', t, repr(msg)
if outcome==SYNTAX_ERROR:
# This should have been a syntax error; forget it.
pass
elif outcome==FAIL:
if result==-1: pass # No match, as expected
else: print '=== Succeeded incorrectly', t
elif outcome==SUCCEED:
if result!=-1:
# Matched, as expected, so now we compute the
# result string and compare it to our expected result.
start, end = obj.regs[0]
found=s[start:end]
groups=obj.group(1,2,3,4,5,6,7,8,9,10)
vardict=vars()
for i in range(len(groups)):
vardict['g'+str(i+1)]=str(groups[i])
repl=eval(repl)
if repl!=expected:
print '=== grouping error', t, repr(repl)+' should be '+repr(expected)
else:
print '=== Failed incorrectly', t

View File

@ -68,7 +68,6 @@ import posixfile
import profile
import pstats
import py_compile
#import reconvert
import repr
try:
import rlcompleter # not available on Windows

View File

@ -176,8 +176,6 @@ class PyBuildExt(build_ext):
#
# Some modules that are normally always on:
exts.append( Extension('regex', ['regexmodule.c', 'regexpr.c']) )
exts.append( Extension('_weakref', ['_weakref.c']) )
exts.append( Extension('_symtable', ['symtablemodule.c']) )

View File

@ -291,7 +291,14 @@ Core and builtins
Extension Modules
-----------------
- Swapped re and sre, so help(re) provides full help. importing sre
- Everything under lib-old was removed. This includes the following modules:
Para, addpack, cmp, cmpcache, codehack, dircmp, dump, find, fmt, grep,
lockfile, newdir, ni, packmail, poly, rand, statcache, tb, tzparse,
util, whatsound, whrandom, zmod
- The following modules were removed: regsub, reconvert, regex, regex_syntax.
- re and sre were swapped, so help(re) provides full help. importing sre
is deprecated. The undocumented re.engine variable no longer exists.
- Bug #1448490: Fixed a bug that ISO-2022 codecs could not handle

View File

@ -1956,8 +1956,6 @@ quopri Conversions to/from quoted-printable transport encoding.
rand Don't use unless you want compatibility with C's rand().
random Random variable generators
re Regular Expressions.
reconvert Convert old ("regex") regular expressions to new syntax
("re").
repr Redo repr() but with limits on most sizes.
rexec Restricted execution facilities ("safe" exec, eval, etc).
rfc822 RFC-822 message manipulation class.
@ -2035,7 +2033,6 @@ zipfile Read & write PK zipped files.
array Obj efficiently representing arrays of basic values
math Math functions of C standard
time Time-related functions (also the newer datetime module)
regex Regular expression matching operations
marshal Read and write some python values in binary format
struct Convert between python values and C structs

View File

@ -1,690 +0,0 @@
/*
XXX support range parameter on search
XXX support mstop parameter on search
*/
/* Regular expression objects */
/* This uses Tatu Ylonen's copyleft-free reimplementation of
GNU regular expressions */
#include "Python.h"
#include <ctype.h>
#include "regexpr.h"
static PyObject *RegexError; /* Exception */
typedef struct {
PyObject_HEAD
struct re_pattern_buffer re_patbuf; /* The compiled expression */
struct re_registers re_regs; /* The registers from the last match */
char re_fastmap[256]; /* Storage for fastmap */
PyObject *re_translate; /* String object for translate table */
PyObject *re_lastok; /* String object last matched/searched */
PyObject *re_groupindex; /* Group name to index dictionary */
PyObject *re_givenpat; /* Pattern with symbolic groups */
PyObject *re_realpat; /* Pattern without symbolic groups */
} regexobject;
/* Regex object methods */
static void
reg_dealloc(regexobject *re)
{
if (re->re_patbuf.buffer)
free(re->re_patbuf.buffer);
Py_XDECREF(re->re_translate);
Py_XDECREF(re->re_lastok);
Py_XDECREF(re->re_groupindex);
Py_XDECREF(re->re_givenpat);
Py_XDECREF(re->re_realpat);
PyObject_Del(re);
}
static PyObject *
makeresult(struct re_registers *regs)
{
PyObject *v;
int i;
static PyObject *filler = NULL;
if (filler == NULL) {
filler = Py_BuildValue("(ii)", -1, -1);
if (filler == NULL)
return NULL;
}
v = PyTuple_New(RE_NREGS);
if (v == NULL)
return NULL;
for (i = 0; i < RE_NREGS; i++) {
int lo = regs->start[i];
int hi = regs->end[i];
PyObject *w;
if (lo == -1 && hi == -1) {
w = filler;
Py_INCREF(w);
}
else
w = Py_BuildValue("(ii)", lo, hi);
if (w == NULL || PyTuple_SetItem(v, i, w) < 0) {
Py_DECREF(v);
return NULL;
}
}
return v;
}
static PyObject *
regobj_match(regexobject *re, PyObject *args)
{
PyObject *argstring;
char *buffer;
int size;
int offset = 0;
int result;
if (!PyArg_ParseTuple(args, "O|i:match", &argstring, &offset))
return NULL;
if (!PyArg_Parse(argstring, "t#", &buffer, &size))
return NULL;
if (offset < 0 || offset > size) {
PyErr_SetString(RegexError, "match offset out of range");
return NULL;
}
Py_XDECREF(re->re_lastok);
re->re_lastok = NULL;
result = _Py_re_match(&re->re_patbuf, (unsigned char *)buffer, size, offset,
&re->re_regs);
if (result < -1) {
/* Serious failure of some sort; if re_match didn't
set an exception, raise a generic error */
if (!PyErr_Occurred())
PyErr_SetString(RegexError, "match failure");
return NULL;
}
if (result >= 0) {
Py_INCREF(argstring);
re->re_lastok = argstring;
}
return PyInt_FromLong((long)result); /* Length of the match or -1 */
}
static PyObject *
regobj_search(regexobject *re, PyObject *args)
{
PyObject *argstring;
char *buffer;
int size;
int offset = 0;
int range;
int result;
if (!PyArg_ParseTuple(args, "O|i:search", &argstring, &offset))
return NULL;
if (!PyArg_Parse(argstring, "t#:search", &buffer, &size))
return NULL;
if (offset < 0 || offset > size) {
PyErr_SetString(RegexError, "search offset out of range");
return NULL;
}
/* NB: In Emacs 18.57, the documentation for re_search[_2] and
the implementation don't match: the documentation states that
|range| positions are tried, while the code tries |range|+1
positions. It seems more productive to believe the code! */
range = size - offset;
Py_XDECREF(re->re_lastok);
re->re_lastok = NULL;
result = _Py_re_search(&re->re_patbuf, (unsigned char *)buffer, size, offset, range,
&re->re_regs);
if (result < -1) {
/* Serious failure of some sort; if re_match didn't
set an exception, raise a generic error */
if (!PyErr_Occurred())
PyErr_SetString(RegexError, "match failure");
return NULL;
}
if (result >= 0) {
Py_INCREF(argstring);
re->re_lastok = argstring;
}
return PyInt_FromLong((long)result); /* Position of the match or -1 */
}
/* get the group from the regex where index can be a string (group name) or
an integer index [0 .. 99]
*/
static PyObject*
group_from_index(regexobject *re, PyObject *index)
{
int i, a, b;
char *v;
if (PyString_Check(index))
if (re->re_groupindex == NULL ||
!(index = PyDict_GetItem(re->re_groupindex, index)))
{
PyErr_SetString(RegexError,
"group() group name doesn't exist");
return NULL;
}
i = PyInt_AsLong(index);
if (i == -1 && PyErr_Occurred())
return NULL;
if (i < 0 || i >= RE_NREGS) {
PyErr_SetString(RegexError, "group() index out of range");
return NULL;
}
if (re->re_lastok == NULL) {
PyErr_SetString(RegexError,
"group() only valid after successful match/search");
return NULL;
}
a = re->re_regs.start[i];
b = re->re_regs.end[i];
if (a < 0 || b < 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!(v = PyString_AsString(re->re_lastok)))
return NULL;
return PyString_FromStringAndSize(v+a, b-a);
}
static PyObject *
regobj_group(regexobject *re, PyObject *args)
{
int n = PyTuple_Size(args);
int i;
PyObject *res = NULL;
if (n < 0)
return NULL;
if (n == 0) {
PyErr_SetString(PyExc_TypeError, "not enough arguments");
return NULL;
}
if (n == 1) {
/* return value is a single string */
PyObject *index = PyTuple_GetItem(args, 0);
if (!index)
return NULL;
return group_from_index(re, index);
}
/* return value is a tuple */
if (!(res = PyTuple_New(n)))
return NULL;
for (i = 0; i < n; i++) {
PyObject *index = PyTuple_GetItem(args, i);
PyObject *group = NULL;
if (!index)
goto finally;
if (!(group = group_from_index(re, index)))
goto finally;
if (PyTuple_SetItem(res, i, group) < 0)
goto finally;
}
return res;
finally:
Py_DECREF(res);
return NULL;
}
static struct PyMethodDef reg_methods[] = {
{"match", (PyCFunction)regobj_match, METH_VARARGS},
{"search", (PyCFunction)regobj_search, METH_VARARGS},
{"group", (PyCFunction)regobj_group, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
static char* members[] = {
"last", "regs", "translate",
"groupindex", "realpat", "givenpat",
NULL
};
static PyObject *
regobj_getattr(regexobject *re, char *name)
{
if (strcmp(name, "regs") == 0) {
if (re->re_lastok == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
return makeresult(&re->re_regs);
}
if (strcmp(name, "last") == 0) {
if (re->re_lastok == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_lastok);
return re->re_lastok;
}
if (strcmp(name, "translate") == 0) {
if (re->re_translate == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_translate);
return re->re_translate;
}
if (strcmp(name, "groupindex") == 0) {
if (re->re_groupindex == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_groupindex);
return re->re_groupindex;
}
if (strcmp(name, "realpat") == 0) {
if (re->re_realpat == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_realpat);
return re->re_realpat;
}
if (strcmp(name, "givenpat") == 0) {
if (re->re_givenpat == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_givenpat);
return re->re_givenpat;
}
if (strcmp(name, "__members__") == 0) {
int i = 0;
PyObject *list = NULL;
/* okay, so it's unlikely this list will change that often.
still, it's easier to change it in just one place.
*/
while (members[i])
i++;
if (!(list = PyList_New(i)))
return NULL;
i = 0;
while (members[i]) {
PyObject* v = PyString_FromString(members[i]);
if (!v || PyList_SetItem(list, i, v) < 0) {
Py_DECREF(list);
return NULL;
}
i++;
}
return list;
}
return Py_FindMethod(reg_methods, (PyObject *)re, name);
}
static PyTypeObject Regextype = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"regex.regex", /*tp_name*/
sizeof(regexobject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)reg_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)regobj_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
};
/* reference counting invariants:
pattern: borrowed
translate: borrowed
givenpat: borrowed
groupindex: transferred
*/
static PyObject *
newregexobject(PyObject *pattern, PyObject *translate, PyObject *givenpat, PyObject *groupindex)
{
regexobject *re;
char *pat;
int size;
if (!PyArg_Parse(pattern, "t#", &pat, &size))
return NULL;
if (translate != NULL && PyString_Size(translate) != 256) {
PyErr_SetString(RegexError,
"translation table must be 256 bytes");
return NULL;
}
re = PyObject_New(regexobject, &Regextype);
if (re != NULL) {
char *error;
re->re_patbuf.buffer = NULL;
re->re_patbuf.allocated = 0;
re->re_patbuf.fastmap = (unsigned char *)re->re_fastmap;
if (translate) {
re->re_patbuf.translate = (unsigned char *)PyString_AsString(translate);
if (!re->re_patbuf.translate)
goto finally;
Py_INCREF(translate);
}
else
re->re_patbuf.translate = NULL;
re->re_translate = translate;
re->re_lastok = NULL;
re->re_groupindex = groupindex;
Py_INCREF(pattern);
re->re_realpat = pattern;
Py_INCREF(givenpat);
re->re_givenpat = givenpat;
error = _Py_re_compile_pattern((unsigned char *)pat, size, &re->re_patbuf);
if (error != NULL) {
PyErr_SetString(RegexError, error);
goto finally;
}
}
return (PyObject *)re;
finally:
Py_DECREF(re);
return NULL;
}
static PyObject *
regex_compile(PyObject *self, PyObject *args)
{
PyObject *pat = NULL;
PyObject *tran = NULL;
if (!PyArg_ParseTuple(args, "S|S:compile", &pat, &tran))
return NULL;
return newregexobject(pat, tran, pat, NULL);
}
static PyObject *
symcomp(PyObject *pattern, PyObject *gdict)
{
char *opat, *oend, *o, *n, *g, *v;
int group_count = 0;
int sz;
int escaped = 0;
char name_buf[128];
PyObject *npattern;
int require_escape = re_syntax & RE_NO_BK_PARENS ? 0 : 1;
if (!(opat = PyString_AsString(pattern)))
return NULL;
if ((sz = PyString_Size(pattern)) < 0)
return NULL;
oend = opat + sz;
o = opat;
if (oend == opat) {
Py_INCREF(pattern);
return pattern;
}
if (!(npattern = PyString_FromStringAndSize((char*)NULL, sz)) ||
!(n = PyString_AsString(npattern)))
return NULL;
while (o < oend) {
if (*o == '(' && escaped == require_escape) {
char *backtrack;
escaped = 0;
++group_count;
*n++ = *o;
if (++o >= oend || *o != '<')
continue;
/* *o == '<' */
if (o+1 < oend && *(o+1) == '>')
continue;
backtrack = o;
g = name_buf;
for (++o; o < oend;) {
if (*o == '>') {
PyObject *group_name = NULL;
PyObject *group_index = NULL;
*g++ = '\0';
group_name = PyString_FromString(name_buf);
group_index = PyInt_FromLong(group_count);
if (group_name == NULL ||
group_index == NULL ||
PyDict_SetItem(gdict, group_name,
group_index) != 0)
{
Py_XDECREF(group_name);
Py_XDECREF(group_index);
Py_XDECREF(npattern);
return NULL;
}
Py_DECREF(group_name);
Py_DECREF(group_index);
++o; /* eat the '>' */
break;
}
if (!isalnum(Py_CHARMASK(*o)) && *o != '_') {
o = backtrack;
break;
}
*g++ = *o++;
}
}
else if (*o == '[' && !escaped) {
*n++ = *o;
++o; /* eat the char following '[' */
*n++ = *o;
while (o < oend && *o != ']') {
++o;
*n++ = *o;
}
if (o < oend)
++o;
}
else if (*o == '\\') {
escaped = 1;
*n++ = *o;
++o;
}
else {
escaped = 0;
*n++ = *o;
++o;
}
}
if (!(v = PyString_AsString(npattern))) {
Py_DECREF(npattern);
return NULL;
}
/* _PyString_Resize() decrements npattern on failure */
_PyString_Resize(&npattern, n - v);
return npattern;
}
static PyObject *
regex_symcomp(PyObject *self, PyObject *args)
{
PyObject *pattern;
PyObject *tran = NULL;
PyObject *gdict = NULL;
PyObject *npattern;
PyObject *retval = NULL;
if (!PyArg_ParseTuple(args, "S|S:symcomp", &pattern, &tran))
return NULL;
gdict = PyDict_New();
if (gdict == NULL || (npattern = symcomp(pattern, gdict)) == NULL) {
Py_XDECREF(gdict);
return NULL;
}
retval = newregexobject(npattern, tran, pattern, gdict);
Py_DECREF(npattern);
return retval;
}
static PyObject *cache_pat;
static PyObject *cache_prog;
static int
update_cache(PyObject *pat)
{
PyObject *tuple = PyTuple_Pack(1, pat);
int status = 0;
if (!tuple)
return -1;
if (pat != cache_pat) {
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = regex_compile((PyObject *)NULL, tuple);
if (cache_prog == NULL) {
status = -1;
goto finally;
}
cache_pat = pat;
Py_INCREF(cache_pat);
}
finally:
Py_DECREF(tuple);
return status;
}
static PyObject *
regex_match(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_ParseTuple(args, "SS:match", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_match((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_search(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_ParseTuple(args, "SS:search", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_search((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_set_syntax(PyObject *self, PyObject *args)
{
int syntax;
if (!PyArg_ParseTuple(args, "i:set_syntax", &syntax))
return NULL;
syntax = re_set_syntax(syntax);
/* wipe the global pattern cache */
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = NULL;
return PyInt_FromLong((long)syntax);
}
static PyObject *
regex_get_syntax(PyObject *self)
{
return PyInt_FromLong((long)re_syntax);
}
static struct PyMethodDef regex_global_methods[] = {
{"compile", regex_compile, METH_VARARGS},
{"symcomp", regex_symcomp, METH_VARARGS},
{"match", regex_match, METH_VARARGS},
{"search", regex_search, METH_VARARGS},
{"set_syntax", regex_set_syntax, METH_VARARGS},
{"get_syntax", (PyCFunction)regex_get_syntax, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
PyMODINIT_FUNC
initregex(void)
{
PyObject *m, *d, *v;
int i;
char *s;
/* Initialize object type */
Regextype.ob_type = &PyType_Type;
m = Py_InitModule("regex", regex_global_methods);
if (m == NULL)
return;
d = PyModule_GetDict(m);
if (PyErr_Warn(PyExc_DeprecationWarning,
"the regex module is deprecated; "
"please use the re module") < 0)
return;
/* Initialize regex.error exception */
v = RegexError = PyErr_NewException("regex.error", NULL, NULL);
if (v == NULL || PyDict_SetItemString(d, "error", v) != 0)
goto finally;
/* Initialize regex.casefold constant */
if (!(v = PyString_FromStringAndSize((char *)NULL, 256)))
goto finally;
if (!(s = PyString_AsString(v)))
goto finally;
for (i = 0; i < 256; i++) {
if (isupper(i))
s[i] = tolower(i);
else
s[i] = i;
}
if (PyDict_SetItemString(d, "casefold", v) < 0)
goto finally;
Py_DECREF(v);
if (!PyErr_Occurred())
return;
finally:
/* Nothing */ ;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +0,0 @@
/*
* -*- mode: c-mode; c-file-style: python -*-
*/
#ifndef Py_REGEXPR_H
#define Py_REGEXPR_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* regexpr.h
*
* Author: Tatu Ylonen <ylo@ngs.fi>
*
* Copyright (c) 1991 Tatu Ylonen, Espoo, Finland
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies. This
* software is provided "as is" without express or implied warranty.
*
* Created: Thu Sep 26 17:15:36 1991 ylo
* Last modified: Mon Nov 4 15:49:46 1991 ylo
*/
/* $Id$ */
#ifndef REGEXPR_H
#define REGEXPR_H
#define RE_NREGS 100 /* number of registers available */
typedef struct re_pattern_buffer
{
unsigned char *buffer; /* compiled pattern */
int allocated; /* allocated size of compiled pattern */
int used; /* actual length of compiled pattern */
unsigned char *fastmap; /* fastmap[ch] is true if ch can start pattern */
unsigned char *translate; /* translation to apply during compilation/matching */
unsigned char fastmap_accurate; /* true if fastmap is valid */
unsigned char can_be_null; /* true if can match empty string */
unsigned char uses_registers; /* registers are used and need to be initialized */
int num_registers; /* number of registers used */
unsigned char anchor; /* anchor: 0=none 1=begline 2=begbuf */
} *regexp_t;
typedef struct re_registers
{
int start[RE_NREGS]; /* start offset of region */
int end[RE_NREGS]; /* end offset of region */
} *regexp_registers_t;
/* bit definitions for syntax */
#define RE_NO_BK_PARENS 1 /* no quoting for parentheses */
#define RE_NO_BK_VBAR 2 /* no quoting for vertical bar */
#define RE_BK_PLUS_QM 4 /* quoting needed for + and ? */
#define RE_TIGHT_VBAR 8 /* | binds tighter than ^ and $ */
#define RE_NEWLINE_OR 16 /* treat newline as or */
#define RE_CONTEXT_INDEP_OPS 32 /* ^$?*+ are special in all contexts */
#define RE_ANSI_HEX 64 /* ansi sequences (\n etc) and \xhh */
#define RE_NO_GNU_EXTENSIONS 128 /* no gnu extensions */
/* definitions for some common regexp styles */
#define RE_SYNTAX_AWK (RE_NO_BK_PARENS|RE_NO_BK_VBAR|RE_CONTEXT_INDEP_OPS)
#define RE_SYNTAX_EGREP (RE_SYNTAX_AWK|RE_NEWLINE_OR)
#define RE_SYNTAX_GREP (RE_BK_PLUS_QM|RE_NEWLINE_OR)
#define RE_SYNTAX_EMACS 0
#define Sword 1
#define Swhitespace 2
#define Sdigit 4
#define Soctaldigit 8
#define Shexdigit 16
/* Rename all exported symbols to avoid conflicts with similarly named
symbols in some systems' standard C libraries... */
#define re_syntax _Py_re_syntax
#define re_syntax_table _Py_re_syntax_table
#define re_compile_initialize _Py_re_compile_initialize
#define re_set_syntax _Py_re_set_syntax
#define re_compile_pattern _Py_re_compile_pattern
#define re_match _Py_re_match
#define re_search _Py_re_search
#define re_compile_fastmap _Py_re_compile_fastmap
#define re_comp _Py_re_comp
#define re_exec _Py_re_exec
#ifdef HAVE_PROTOTYPES
extern int re_syntax;
/* This is the actual syntax mask. It was added so that Python could do
* syntax-dependent munging of patterns before compilation. */
extern unsigned char re_syntax_table[256];
void re_compile_initialize(void);
int re_set_syntax(int syntax);
/* This sets the syntax to use and returns the previous syntax. The
* syntax is specified by a bit mask of the above defined bits. */
char *re_compile_pattern(unsigned char *regex, int regex_size, regexp_t compiled);
/* This compiles the regexp (given in regex and length in regex_size).
* This returns NULL if the regexp compiled successfully, and an error
* message if an error was encountered. The buffer field must be
* initialized to a memory area allocated by malloc (or to NULL) before
* use, and the allocated field must be set to its length (or 0 if
* buffer is NULL). Also, the translate field must be set to point to a
* valid translation table, or NULL if it is not used. */
int re_match(regexp_t compiled, unsigned char *string, int size, int pos,
regexp_registers_t old_regs);
/* This tries to match the regexp against the string. This returns the
* length of the matched portion, or -1 if the pattern could not be
* matched and -2 if an error (such as failure stack overflow) is
* encountered. */
int re_search(regexp_t compiled, unsigned char *string, int size, int startpos,
int range, regexp_registers_t regs);
/* This searches for a substring matching the regexp. This returns the
* first index at which a match is found. range specifies at how many
* positions to try matching; positive values indicate searching
* forwards, and negative values indicate searching backwards. mstop
* specifies the offset beyond which a match must not go. This returns
* -1 if no match is found, and -2 if an error (such as failure stack
* overflow) is encountered. */
void re_compile_fastmap(regexp_t compiled);
/* This computes the fastmap for the regexp. For this to have any effect,
* the calling program must have initialized the fastmap field to point
* to an array of 256 characters. */
#else /* HAVE_PROTOTYPES */
extern int re_syntax;
extern unsigned char re_syntax_table[256];
void re_compile_initialize();
int re_set_syntax();
char *re_compile_pattern();
int re_match();
int re_search();
void re_compile_fastmap();
#endif /* HAVE_PROTOTYPES */
#endif /* REGEXPR_H */
#ifdef __cplusplus
}
#endif
#endif /* !Py_REGEXPR_H */

View File

@ -535,14 +535,6 @@ SOURCE=..\..\Objects\rangeobject.c
# End Source File
# Begin Source File
SOURCE=..\..\Modules\regexmodule.c
# End Source File
# Begin Source File
SOURCE=..\..\Modules\regexpr.c
# End Source File
# Begin Source File
SOURCE=..\..\Modules\rgbimgmodule.c
# End Source File
# Begin Source File

View File

@ -304,8 +304,6 @@ SRC.MODULES= $(addprefix $(TOP), \
Modules/md5module.c \
Modules/operator.c \
Modules/_randommodule.c \
Modules/regexmodule.c \
Modules/regexpr.c \
Modules/rgbimgmodule.c \
Modules/shamodule.c \
Modules/_sre.c \

View File

@ -948,34 +948,6 @@ readline.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\class
$(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \
$(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
regexmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
$(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
$(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
$(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
$(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
$(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
$(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
$(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
$(PY_INCLUDE)\rangeobject.h $(PY_MODULES)\regexpr.h $(PY_INCLUDE)\sliceobject.h \
$(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
$(PY_INCLUDE)\tupleobject.h
regexpr.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
$(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
$(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
$(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
$(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
$(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
$(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
$(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
$(PY_INCLUDE)\rangeobject.h $(PY_MODULES)\regexpr.h $(PY_INCLUDE)\sliceobject.h \
$(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
$(PY_INCLUDE)\tupleobject.h
resource.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\time.h $(PY_INCLUDE)\ceval.h \
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \

View File

@ -699,30 +699,6 @@ readline.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
traceback.h tupleobject.h
regexmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
import.h intobject.h intrcheck.h listobject.h longobject.h \
methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
pythonrun.h rangeobject.h regexpr.h sliceobject.h stringobject.h \
sysmodule.h traceback.h tupleobject.h
regexpr.obj: abstract.h ceval.h classobject.h cobject.h \
complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
funcobject.h import.h intobject.h intrcheck.h listobject.h \
longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
pystate.h python.h pythonrun.h rangeobject.h regexpr.h \
sliceobject.h stringobject.h sysmodule.h traceback.h tupleobject.h
reopmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \
import.h intobject.h intrcheck.h listobject.h longobject.h \
methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \
object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \
pythonrun.h rangeobject.h regexpr.h sliceobject.h stringobject.h \
sysmodule.h traceback.h tupleobject.h
resource.obj: abstract.h c:\mptn\include\sys\time.h ceval.h classobject.h \
cobject.h complexobject.h pyconfig.h dictobject.h fileobject.h \
floatobject.h funcobject.h import.h intobject.h intrcheck.h \

View File

@ -5,23 +5,23 @@ import sys
# change this module too.
try:
import string
import os
except:
print """Could not import the standard "string" module.
print """Could not import the standard "os" module.
Please check your PYTHONPATH environment variable."""
sys.exit(1)
try:
import regex_syntax
import symbol
except:
print """Could not import the standard "regex_syntax" module. If this is
print """Could not import the standard "symbol" module. If this is
a PC, you should add the dos_8x3 directory to your PYTHONPATH."""
sys.exit(1)
import os
for dir in sys.path:
file = os.path.join(dir, "string.py")
file = os.path.join(dir, "os.py")
if os.path.isfile(file):
test = os.path.join(dir, "test")
if os.path.isdir(test):

View File

@ -706,12 +706,6 @@
<File
RelativePath="..\Objects\rangeobject.c">
</File>
<File
RelativePath="..\Modules\regexmodule.c">
</File>
<File
RelativePath="..\Modules\regexpr.c">
</File>
<File
RelativePath="..\Modules\rgbimgmodule.c">
</File>

View File

@ -74,7 +74,6 @@ MODULES_DYNAMIC =\
@.^.Lib.md5/pyd\
@.^.Lib.operator/pyd\
@.^.Lib.parser/pyd\
@.^.Lib.regex/pyd\
@.^.Lib.rgbimg/pyd\
@.^.Lib.sha/pyd\
@.^.Lib.signal/pyd\
@ -284,10 +283,6 @@ $(LIB_PYTHON): $(OBJECTS)
@.^.Lib.parser/pyd: @.^.Modules.o.parsermodule s.linktab
$(MAKEDLK) -d @.^.Lib.parser/pyd -s s.linktab -o @.^.Modules.o.parsermodule -e initparser
@.^.Lib.regex/pyd: @.^.Modules.o.regexmodule @.^.Modules.o.regexpr s.linktab
$(LINK) -aof -o @.^.Modules.o.regexlink @.^.Modules.o.regexmodule @.^.Modules.o.regexpr
$(MAKEDLK) -d @.^.Lib.regex/pyd -s s.linktab -o @.^.Modules.o.regexlink -e initregex
@.^.Lib.rgbimg/pyd: @.^.Modules.o.rgbimgmodule s.linktab
$(MAKEDLK) -d @.^.Lib.rgbimg/pyd -s s.linktab -o @.^.Modules.o.rgbimgmodule -e initrgbimg

View File

@ -30,7 +30,7 @@
# into a program for a different change to Python programs...
import sys
import regex
import re
import os
from stat import *
@ -53,7 +53,7 @@ def main():
if fix(arg): bad = 1
sys.exit(bad)
ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
def ispython(name):
return ispythonprog.match(name) >= 0
@ -148,12 +148,12 @@ def fix(filename):
# This expression doesn't catch *all* class definition headers,
# but it's pretty darn close.
classexpr = '^\([ \t]*class +[a-zA-Z0-9_]+\) *( *) *\(\(=.*\)?\):'
classprog = regex.compile(classexpr)
classexpr = '^([ \t]*class +[a-zA-Z0-9_]+) *( *) *((=.*)?):'
classprog = re.compile(classexpr)
# Expressions for finding base class expressions.
baseexpr = '^ *\(.*\) *( *) *$'
baseprog = regex.compile(baseexpr)
baseexpr = '^ *(.*) *( *) *$'
baseprog = re.compile(baseexpr)
def fixline(line):
if classprog.match(line) < 0: # No 'class' keyword -- no change

View File

@ -35,7 +35,7 @@
# files.
import sys
import regex
import re
import os
from stat import *
import getopt
@ -90,7 +90,7 @@ def main():
# Change this regular expression to select a different set of files
Wanted = '^[a-zA-Z0-9_]+\.[ch]$'
def wanted(name):
return regex.match(Wanted, name) >= 0
return re.match(Wanted, name) >= 0
def recursedown(dirname):
dbg('recursedown(%r)\n' % (dirname,))
@ -212,12 +212,12 @@ Number = Floatnumber + '\|' + Intnumber
# Anything else is an operator -- don't list this explicitly because of '/*'
OutsideComment = (Identifier, Number, String, Char, CommentStart)
OutsideCommentPattern = '\(' + '\|'.join(OutsideComment) + '\)'
OutsideCommentProgram = regex.compile(OutsideCommentPattern)
OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')'
OutsideCommentProgram = re.compile(OutsideCommentPattern)
InsideComment = (Identifier, Number, CommentEnd)
InsideCommentPattern = '\(' + '\|'.join(InsideComment) + '\)'
InsideCommentProgram = regex.compile(InsideCommentPattern)
InsideCommentPattern = '(' + '|'.join(InsideComment) + ')'
InsideCommentProgram = re.compile(InsideCommentPattern)
def initfixline():
global Program

View File

@ -27,7 +27,6 @@
# preprocessor commands.
import sys
import regex
import getopt
defs = []

View File

@ -27,7 +27,7 @@
# into a program for a different change to Python programs...
import sys
import regex
import re
import os
from stat import *
@ -50,7 +50,7 @@ def main():
if fix(arg): bad = 1
sys.exit(bad)
ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
def ispython(name):
return ispythonprog.match(name) >= 0
@ -101,7 +101,7 @@ def fix(filename):
if lineno == 1 and g is None and line[:2] == '#!':
# Check for non-Python scripts
words = line[2:].split()
if words and regex.search('[pP]ython', words[0]) < 0:
if words and re.search('[pP]ython', words[0]) < 0:
msg = filename + ': ' + words[0]
msg = msg + ' script; not fixed\n'
err(msg)
@ -158,8 +158,8 @@ def fix(filename):
return 0
fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *\(( *\(.*\) *)\) *) *:'
fixprog = regex.compile(fixpat)
fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *(( *(.*) *)) *) *:'
fixprog = re.compile(fixpat)
def fixline(line):
if fixprog.match(line) >= 0:

View File

@ -22,7 +22,7 @@
import sys
import os
import getopt
import regex
import re
# Types of symbols.
#
@ -32,7 +32,7 @@ ignore = 'Nntrgdsbavuc'
# Regular expression to parse "nm -o" output.
#
matcher = regex.compile('\(.*\):\t?........ \(.\) \(.*\)$')
matcher = re.compile('(.*):\t?........ (.) (.*)$')
# Store "item" in "dict" under "key".
# The dictionary maps keys to lists of items.

View File

@ -20,7 +20,7 @@
# into a program for a different change to Python programs...
import sys
import regex
import re
import os
from stat import *
import getopt
@ -59,7 +59,7 @@ def main():
if fix(arg): bad = 1
sys.exit(bad)
ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
def ispython(name):
return ispythonprog.match(name) >= 0

View File

@ -21,7 +21,7 @@
import sys
import regex
import re
import os
@ -57,8 +57,8 @@ def main():
# Compiled regular expressions to search for import statements
#
m_import = regex.compile('^[ \t]*from[ \t]+\([^ \t]+\)[ \t]+')
m_from = regex.compile('^[ \t]*import[ \t]+\([^#]+\)')
m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')
# Collect data from one file

View File

@ -326,8 +326,6 @@ class PyBuildExt(build_ext):
#
# Some modules that are normally always on:
exts.append( Extension('regex', ['regexmodule.c', 'regexpr.c']) )
exts.append( Extension('_weakref', ['_weakref.c']) )
# array objects