]> granicus.if.org Git - python/commitdiff
Merge part of the trunk changes into the p3yk branch. This merges from 43030
authorThomas Wouters <thomas@python.org>
Fri, 21 Apr 2006 09:43:23 +0000 (09:43 +0000)
committerThomas Wouters <thomas@python.org>
Fri, 21 Apr 2006 09:43:23 +0000 (09:43 +0000)
(branch-creation time) up to 43067. 43068 and 43069 contain a little
swapping action between re.py and sre.py, and this mightily confuses svn
merge, so later changes are going in separately.

This merge should break no additional tests.

The last-merged revision is going in a 'last_merge' property on '.' (the
branch directory.) Arbitrarily chosen, really; if there's a BCP for this, I
couldn't find it, but we can easily change it afterwards ;)

116 files changed:
Doc/lib/libcodecs.tex
Doc/whatsnew/whatsnew25.tex
Include/codecs.h
Lib/StringIO.py
Lib/codecs.py
Lib/encodings/__init__.py
Lib/encodings/ascii.py
Lib/encodings/base64_codec.py
Lib/encodings/bz2_codec.py
Lib/encodings/charmap.py
Lib/encodings/cp037.py
Lib/encodings/cp1006.py
Lib/encodings/cp1026.py
Lib/encodings/cp1140.py
Lib/encodings/cp1250.py
Lib/encodings/cp1251.py
Lib/encodings/cp1252.py
Lib/encodings/cp1253.py
Lib/encodings/cp1254.py
Lib/encodings/cp1255.py
Lib/encodings/cp1256.py
Lib/encodings/cp1257.py
Lib/encodings/cp1258.py
Lib/encodings/cp424.py
Lib/encodings/cp437.py
Lib/encodings/cp500.py
Lib/encodings/cp737.py
Lib/encodings/cp775.py
Lib/encodings/cp850.py
Lib/encodings/cp852.py
Lib/encodings/cp855.py
Lib/encodings/cp856.py
Lib/encodings/cp857.py
Lib/encodings/cp860.py
Lib/encodings/cp861.py
Lib/encodings/cp862.py
Lib/encodings/cp863.py
Lib/encodings/cp864.py
Lib/encodings/cp865.py
Lib/encodings/cp866.py
Lib/encodings/cp869.py
Lib/encodings/cp874.py
Lib/encodings/cp875.py
Lib/encodings/hex_codec.py
Lib/encodings/hp_roman8.py
Lib/encodings/idna.py
Lib/encodings/iso8859_1.py
Lib/encodings/iso8859_10.py
Lib/encodings/iso8859_11.py
Lib/encodings/iso8859_13.py
Lib/encodings/iso8859_14.py
Lib/encodings/iso8859_15.py
Lib/encodings/iso8859_16.py
Lib/encodings/iso8859_2.py
Lib/encodings/iso8859_3.py
Lib/encodings/iso8859_4.py
Lib/encodings/iso8859_5.py
Lib/encodings/iso8859_6.py
Lib/encodings/iso8859_7.py
Lib/encodings/iso8859_8.py
Lib/encodings/iso8859_9.py
Lib/encodings/koi8_r.py
Lib/encodings/koi8_u.py
Lib/encodings/latin_1.py
Lib/encodings/mac_arabic.py
Lib/encodings/mac_centeuro.py
Lib/encodings/mac_croatian.py
Lib/encodings/mac_cyrillic.py
Lib/encodings/mac_farsi.py
Lib/encodings/mac_greek.py
Lib/encodings/mac_iceland.py
Lib/encodings/mac_latin2.py
Lib/encodings/mac_roman.py
Lib/encodings/mac_romanian.py
Lib/encodings/mac_turkish.py
Lib/encodings/mbcs.py
Lib/encodings/palmos.py
Lib/encodings/ptcp154.py
Lib/encodings/punycode.py
Lib/encodings/quopri_codec.py
Lib/encodings/raw_unicode_escape.py
Lib/encodings/rot_13.py
Lib/encodings/string_escape.py
Lib/encodings/tis_620.py
Lib/encodings/undefined.py
Lib/encodings/unicode_escape.py
Lib/encodings/unicode_internal.py
Lib/encodings/utf_16.py
Lib/encodings/utf_16_be.py
Lib/encodings/utf_16_le.py
Lib/encodings/utf_7.py
Lib/encodings/utf_8.py
Lib/encodings/utf_8_sig.py
Lib/encodings/uu_codec.py
Lib/encodings/zlib_codec.py
Lib/logging/__init__.py
Lib/runpy.py [new file with mode: 0755]
Lib/test/regrtest.py
Lib/test/test_StringIO.py
Lib/test/test___all__.py
Lib/test/test_codecs.py
Lib/test/test_runpy.py [new file with mode: 0644]
Lib/test/time_hashlib.py [moved from Lib/test/test_hashlib_speed.py with 92% similarity]
Makefile.pre.in
Modules/_ctypes/_ctypes.c
Modules/_ctypes/cfield.c
Modules/_ctypes/ctypes.h
Modules/_testcapimodule.c
Modules/cStringIO.c
Modules/main.c
Modules/xxmodule.c
Objects/obmalloc.c
Python/codecs.c
Tools/buildbot/clean.bat
Tools/unicode/Makefile
Tools/unicode/gencodec.py

index 9e92217baacbcb8466db0c34f14de72b588556da..1806ef0addd3559fd989eeb7f1471f453dbdc634 100644 (file)
@@ -24,8 +24,19 @@ It defines the following functions:
 \begin{funcdesc}{register}{search_function}
 Register a codec search function. Search functions are expected to
 take one argument, the encoding name in all lower case letters, and
-return a tuple of functions \code{(\var{encoder}, \var{decoder}, \var{stream_reader},
-\var{stream_writer})} taking the following arguments:
+return a \class{CodecInfo} object having the following attributes:
+
+\begin{itemize}
+  \item \code{name} The name of the encoding;
+  \item \code{encoder} The stateless encoding function;
+  \item \code{decoder} The stateless decoding function;
+  \item \code{incrementalencoder} An incremental encoder class or factory function;
+  \item \code{incrementaldecoder} An incremental decoder class or factory function;
+  \item \code{streamwriter} A stream writer class or factory function;
+  \item \code{streamreader} A stream reader class or factory function.
+\end{itemize}
+
+The various functions or classes take the following arguments:
 
   \var{encoder} and \var{decoder}: These must be functions or methods
   which have the same interface as the
@@ -33,7 +44,17 @@ return a tuple of functions \code{(\var{encoder}, \var{decoder}, \var{stream_rea
   Codec Interface). The functions/methods are expected to work in a
   stateless mode.
 
-  \var{stream_reader} and \var{stream_writer}: These have to be
+  \var{incrementalencoder} and \var{incrementalencoder}: These have to be
+  factory functions providing the following interface:
+
+        \code{factory(\var{errors}='strict')}
+
+  The factory functions must return objects providing the interfaces
+  defined by the base classes \class{IncrementalEncoder} and
+  \class{IncrementalEncoder}, respectively. Incremental codecs can maintain
+  state.
+
+  \var{streamreader} and \var{streamwriter}: These have to be
   factory functions providing the following interface:
 
         \code{factory(\var{stream}, \var{errors}='strict')}
@@ -58,13 +79,13 @@ return \code{None}.
 \end{funcdesc}
 
 \begin{funcdesc}{lookup}{encoding}
-Looks up a codec tuple in the Python codec registry and returns the
-function tuple as defined above.
+Looks up the codec info in the Python codec registry and returns a
+\class{CodecInfo} object as defined above.
 
 Encodings are first looked up in the registry's cache. If not found,
-the list of registered search functions is scanned. If no codecs tuple
-is found, a \exception{LookupError} is raised. Otherwise, the codecs
-tuple is stored in the cache and returned to the caller.
+the list of registered search functions is scanned. If no \class{CodecInfo}
+object is found, a \exception{LookupError} is raised. Otherwise, the
+\class{CodecInfo} object is stored in the cache and returned to the caller.
 \end{funcdesc}
 
 To simplify access to the various codecs, the module provides these
@@ -85,6 +106,22 @@ function.
 Raises a \exception{LookupError} in case the encoding cannot be found.
 \end{funcdesc}
 
+\begin{funcdesc}{getincrementalencoder}{encoding}
+Lookup up the codec for the given encoding and return its incremental encoder
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found or the
+codec doesn't support an incremental encoder.
+\end{funcdesc}
+
+\begin{funcdesc}{getincrementaldecoder}{encoding}
+Lookup up the codec for the given encoding and return its incremental decoder
+class or factory function.
+
+Raises a \exception{LookupError} in case the encoding cannot be found or the
+codec doesn't support an incremental decoder.
+\end{funcdesc}
+
 \begin{funcdesc}{getreader}{encoding}
 Lookup up the codec for the given encoding and return its StreamReader
 class or factory function.
@@ -188,6 +225,18 @@ If \var{output} is not given, it defaults to \var{input}.
 an encoding error occurs.
 \end{funcdesc}
 
+\begin{funcdesc}{iterencode}{iterable, encoding\optional{, errors}}
+Uses an incremental encoder to iteratively encode the input provided by
+\var{iterable}. This function is a generator. \var{errors} (as well as
+any other keyword argument) is passed through to the incremental encoder.
+\end{funcdesc}
+
+\begin{funcdesc}{iterdecode}{iterable, encoding\optional{, errors}}
+Uses an incremental decoder to iteratively decode the input provided by
+\var{iterable}. This function is a generator. \var{errors} (as well as
+any other keyword argument) is passed through to the incremental encoder.
+\end{funcdesc}
+
 The module also provides the following constants which are useful
 for reading and writing to platform dependent files:
 
@@ -292,6 +341,109 @@ function interfaces of the stateless encoder and decoder:
   empty object of the output object type in this situation.
 \end{methoddesc}
 
+The \class{IncrementalEncoder} and \class{IncrementalDecoder} classes provide
+the basic interface for incremental encoding and decoding. Encoding/decoding the
+input isn't done with one call to the stateless encoder/decoder function,
+but with multiple calls to the \method{encode}/\method{decode} method of the
+incremental encoder/decoder. The incremental encoder/decoder keeps track of
+the encoding/decoding process during method calls.
+
+The joined output of calls to the \method{encode}/\method{decode} method is the
+same as if the all single inputs where joined into one, and this input was
+encoded/decoded with the stateless encoder/decoder.
+
+
+\subsubsection{IncrementalEncoder Objects \label{incremental-encoder-objects}}
+
+The \class{IncrementalEncoder} class is used for encoding an input in multiple
+steps. It defines the following methods which every incremental encoder must
+define in order to be compatible to the Python codec registry.
+
+\begin{classdesc}{IncrementalEncoder}{\optional{errors}}
+  Constructor for a \class{IncrementalEncoder} instance.
+
+  All incremental encoders must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  The \class{IncrementalEncoder} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are predefined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character
+    \item \code{'xmlcharrefreplace'} Replace with the appropriate XML
+                     character reference
+    \item \code{'backslashreplace'} Replace with backslashed escape sequences.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{IncrementalEncoder} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{encode}{object\optional{, final}}
+  Encodes \var{object} (taking the current state of the encoder into account)
+  and returns the resulting encoded object. If this is the last call to
+  \method{encode} \var{final} must be true (the default is false).
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Reset the encoder to the initial state.
+\end{methoddesc}
+
+
+\subsubsection{IncrementalDecoder Objects \label{incremental-decoder-objects}}
+
+The \class{IncrementalDecoder} class is used for decoding an input in multiple
+steps. It defines the following methods which every incremental decoder must
+define in order to be compatible to the Python codec registry.
+
+\begin{classdesc}{IncrementalDecoder}{\optional{errors}}
+  Constructor for a \class{IncrementalDecoder} instance.
+
+  All incremental decoders must provide this constructor interface. They are
+  free to add additional keyword arguments, but only the ones defined
+  here are used by the Python codec registry.
+
+  The \class{IncrementalDecoder} may implement different error handling
+  schemes by providing the \var{errors} keyword argument. These
+  parameters are predefined:
+
+  \begin{itemize}
+    \item \code{'strict'} Raise \exception{ValueError} (or a subclass);
+                          this is the default.
+    \item \code{'ignore'} Ignore the character and continue with the next.
+    \item \code{'replace'} Replace with a suitable replacement character.
+  \end{itemize}
+
+  The \var{errors} argument will be assigned to an attribute of the
+  same name. Assigning to this attribute makes it possible to switch
+  between different error handling strategies during the lifetime
+  of the \class{IncrementalEncoder} object.
+
+  The set of allowed values for the \var{errors} argument can
+  be extended with \function{register_error()}.
+\end{classdesc}
+
+\begin{methoddesc}{decode}{object\optional{, final}}
+  Decodes \var{object} (taking the current state of the decoder into account)
+  and returns the resulting decoded object. If this is the last call to
+  \method{decode} \var{final} must be true (the default is false).
+\end{methoddesc}
+
+\begin{methoddesc}{reset}{}
+  Reset the decoder to the initial state.
+\end{methoddesc}
+
+
 The \class{StreamWriter} and \class{StreamReader} classes provide
 generic working interfaces which can be used to implement new
 encodings submodules very easily. See \module{encodings.utf_8} for an
index ff64af0c534ab95a6771a4091df8324d38c038e8..57432855ac3d5686f292a2d2ae17bcbfa54f360b 100644 (file)
@@ -209,6 +209,12 @@ implemented by Richard Jones and Fred Drake.}
 % XXX write this
 
 
+%======================================================================
+\section{PEP 338: Executing Modules as Scripts}
+
+% XXX write this
+
+
 %======================================================================
 \section{PEP 341: Unified try/except/finally}
 
index 82f18cdc5e7a326b735b7d63ba7909a8a3f129ad..0d76241dbf593c468b96db81a31f59c68c562510 100644 (file)
@@ -29,15 +29,15 @@ PyAPI_FUNC(int) PyCodec_Register(
 
 /* Codec register lookup API.
 
-   Looks up the given encoding and returns a tuple (encoder, decoder,
-   stream reader, stream writer) of functions which implement the
-   different aspects of processing the encoding.
+   Looks up the given encoding and returns a CodecInfo object with
+   function attributes which implement the different aspects of
+   processing the encoding.
 
    The encoding string is looked up converted to all lower-case
    characters. This makes encodings looked up through this mechanism
    effectively case-insensitive.
 
-   If no codec is found, a KeyError is set and NULL returned. 
+   If no codec is found, a KeyError is set and NULL returned.
 
    As side effect, this tries to load the encodings package, if not
    yet done. This is part of the lazy load strategy for the encodings
@@ -101,6 +101,20 @@ PyAPI_FUNC(PyObject *) PyCodec_Decoder(
        const char *encoding
        );
 
+/* Get a IncrementalEncoder object for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
+       const char *encoding,
+       const char *errors
+       );
+
+/* Get a IncrementalDecoder object function for the given encoding. */
+
+PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
+       const char *encoding,
+       const char *errors
+       );
+
 /* Get a StreamReader factory function for the given encoding. */
 
 PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
index 5c463fbc1c94cf09cd9f6e8e4166f928c32c2fa9..1e5f25408d7001cd0aabd55944b6484980d90b9e 100644 (file)
@@ -72,8 +72,7 @@ class StringIO:
         method is called repeatedly. This method returns the next input line,
         or raises StopIteration when EOF is hit.
         """
-        if self.closed:
-            raise StopIteration
+        _complain_ifclosed(self.closed)
         r = self.readline()
         if not r:
             raise StopIteration
index 6895a228fed75a7be16a9be7dab8c925a151a61b..28856c714e9d2b94ce3d6268c48822892bb0f606 100644 (file)
@@ -73,6 +73,23 @@ BOM64_BE = BOM_UTF32_BE
 
 ### Codec base classes (defining the API)
 
+class CodecInfo(tuple):
+
+    def __new__(cls, encode, decode, streamreader=None, streamwriter=None,
+        incrementalencoder=None, incrementaldecoder=None, name=None):
+        self = tuple.__new__(cls, (encode, decode, streamreader, streamwriter))
+        self.name = name
+        self.encode = encode
+        self.decode = decode
+        self.incrementalencoder = incrementalencoder
+        self.incrementaldecoder = incrementaldecoder
+        self.streamwriter = streamwriter
+        self.streamreader = streamreader
+        return self
+
+    def __repr__(self):
+        return "<%s.%s object for encoding %s at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, id(self))
+
 class Codec:
 
     """ Defines the interface for stateless encoders/decoders.
@@ -137,6 +154,88 @@ class Codec:
         """
         raise NotImplementedError
 
+class IncrementalEncoder(object):
+    """
+    A IncrementalEncoder encodes an input in multiple steps. The input can be
+    passed piece by piece to the encode() method. The IncrementalEncoder remembers
+    the state of the Encoding process between calls to encode().
+    """
+    def __init__(self, errors='strict'):
+        """
+        Creates a IncrementalEncoder instance.
+
+        The IncrementalEncoder may use different error handling schemes by
+        providing the errors keyword argument. See the module docstring
+        for a list of possible values.
+        """
+        self.errors = errors
+        self.buffer = ""
+
+    def encode(self, input, final=False):
+        """
+        Encodes input and returns the resulting object.
+        """
+        raise NotImplementedError
+
+    def reset(self):
+        """
+        Resets the encoder to the initial state.
+        """
+
+class IncrementalDecoder(object):
+    """
+    An IncrementalDecoder decodes an input in multiple steps. The input can be
+    passed piece by piece to the decode() method. The IncrementalDecoder
+    remembers the state of the decoding process between calls to decode().
+    """
+    def __init__(self, errors='strict'):
+        """
+        Creates a IncrementalDecoder instance.
+
+        The IncrementalDecoder may use different error handling schemes by
+        providing the errors keyword argument. See the module docstring
+        for a list of possible values.
+        """
+        self.errors = errors
+
+    def decode(self, input, final=False):
+        """
+        Decodes input and returns the resulting object.
+        """
+        raise NotImplementedError
+
+    def reset(self):
+        """
+        Resets the decoder to the initial state.
+        """
+
+class BufferedIncrementalDecoder(IncrementalDecoder):
+    """
+    This subclass of IncrementalDecoder can be used as the baseclass for an
+    incremental decoder if the decoder must be able to handle incomplete byte
+    sequences.
+    """
+    def __init__(self, errors='strict'):
+        IncrementalDecoder.__init__(self, errors)
+        self.buffer = "" # undecoded input that is kept between calls to decode()
+
+    def _buffer_decode(self, input, errors, final):
+        # Overwrite this method in subclasses: It must decode input
+        # and return an (output, length consumed) tuple
+        raise NotImplementedError
+
+    def decode(self, input, final=False):
+        # decode input (taking the buffer into account)
+        data = self.buffer + input
+        (result, consumed) = self._buffer_decode(data, self.errors, final)
+        # keep undecoded input until the next call
+        self.buffer = data[consumed:]
+        return result
+
+    def reset(self):
+        IncrementalDecoder.reset(self)
+        self.bytebuffer = ""
+
 #
 # The StreamWriter and StreamReader class provide generic working
 # interfaces which can be used to implement new encoding submodules
@@ -666,8 +765,8 @@ def open(filename, mode='rb', encoding=None, errors='strict', buffering=1):
     file = __builtin__.open(filename, mode, buffering)
     if encoding is None:
         return file
-    (e, d, sr, sw) = lookup(encoding)
-    srw = StreamReaderWriter(file, sr, sw, errors)
+    info = lookup(encoding)
+    srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors)
     # Add attributes to simplify introspection
     srw.encoding = encoding
     return srw
@@ -699,11 +798,9 @@ def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
     """
     if file_encoding is None:
         file_encoding = data_encoding
-    encode, decode = lookup(data_encoding)[:2]
-    Reader, Writer = lookup(file_encoding)[2:]
-    sr = StreamRecoder(file,
-                       encode, decode, Reader, Writer,
-                       errors)
+    info = lookup(data_encoding)
+    sr = StreamRecoder(file, info.encode, info.decode,
+                       info.streamreader, info.streamwriter, errors)
     # Add attributes to simplify introspection
     sr.data_encoding = data_encoding
     sr.file_encoding = file_encoding
@@ -719,7 +816,7 @@ def getencoder(encoding):
         Raises a LookupError in case the encoding cannot be found.
 
     """
-    return lookup(encoding)[0]
+    return lookup(encoding).encode
 
 def getdecoder(encoding):
 
@@ -729,7 +826,35 @@ def getdecoder(encoding):
         Raises a LookupError in case the encoding cannot be found.
 
     """
-    return lookup(encoding)[1]
+    return lookup(encoding).decode
+
+def getincrementalencoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its IncrementalEncoder class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found
+        or the codecs doesn't provide an incremental encoder.
+
+    """
+    encoder = lookup(encoding).incrementalencoder
+    if encoder is None:
+        raise LookupError(encoding)
+    return encoder
+
+def getincrementaldecoder(encoding):
+
+    """ Lookup up the codec for the given encoding and return
+        its IncrementalDecoder class or factory function.
+
+        Raises a LookupError in case the encoding cannot be found
+        or the codecs doesn't provide an incremental decoder.
+
+    """
+    decoder = lookup(encoding).incrementaldecoder
+    if decoder is None:
+        raise LookupError(encoding)
+    return decoder
 
 def getreader(encoding):
 
@@ -739,7 +864,7 @@ def getreader(encoding):
         Raises a LookupError in case the encoding cannot be found.
 
     """
-    return lookup(encoding)[2]
+    return lookup(encoding).streamreader
 
 def getwriter(encoding):
 
@@ -749,7 +874,43 @@ def getwriter(encoding):
         Raises a LookupError in case the encoding cannot be found.
 
     """
-    return lookup(encoding)[3]
+    return lookup(encoding).streamwriter
+
+def iterencode(iterator, encoding, errors='strict', **kwargs):
+    """
+    Encoding iterator.
+
+    Encodes the input strings from the iterator using a IncrementalEncoder.
+
+    errors and kwargs are passed through to the IncrementalEncoder
+    constructor.
+    """
+    encoder = getincrementalencoder(encoding)(errors, **kwargs)
+    for input in iterator:
+        output = encoder.encode(input)
+        if output:
+            yield output
+    output = encoder.encode("", True)
+    if output:
+        yield output
+
+def iterdecode(iterator, encoding, errors='strict', **kwargs):
+    """
+    Decoding iterator.
+
+    Decodes the input strings from the iterator using a IncrementalDecoder.
+
+    errors and kwargs are passed through to the IncrementalDecoder
+    constructor.
+    """
+    decoder = getincrementaldecoder(encoding)(errors, **kwargs)
+    for input in iterator:
+        output = decoder.decode(input)
+        if output:
+            yield output
+    output = decoder.decode("", True)
+    if output:
+        yield output
 
 ### Helpers for charmap-based codecs
 
index ddaacb9e3f2c7af1c5818f8f13da252051649439..1f469bf7d65a0b875fb92c138fcdcb9587dcde4b 100644 (file)
@@ -9,9 +9,10 @@
 
     Each codec module must export the following interface:
 
-    * getregentry() -> (encoder, decoder, stream_reader, stream_writer)
-    The getregentry() API must return callable objects which adhere to
-    the Python Codec Interface Standard.
+    * getregentry() -> codecs.CodecInfo object
+    The getregentry() API must a CodecInfo object with encoder, decoder,
+    incrementalencoder, incrementaldecoder, streamwriter and streamreader
+    atttributes which adhere to the Python Codec Interface Standard.
 
     In addition, a module may optionally also define the following
     APIs which are then used by the package's codec search function:
@@ -113,16 +114,24 @@ def search_function(encoding):
         return None
 
     # Now ask the module for the registry entry
-    entry = tuple(getregentry())
-    if len(entry) != 4:
-        raise CodecRegistryError,\
-              'module "%s" (%s) failed to register' % \
-              (mod.__name__, mod.__file__)
-    for obj in entry:
-        if not callable(obj):
+    entry = getregentry()
+    if not isinstance(entry, codecs.CodecInfo):
+        if not 4 <= len(entry) <= 7:
             raise CodecRegistryError,\
-                  'incompatible codecs in module "%s" (%s)' % \
+                 'module "%s" (%s) failed to register' % \
                   (mod.__name__, mod.__file__)
+        if not callable(entry[0]) or \
+           not callable(entry[1]) or \
+           (entry[2] is not None and not callable(entry[2])) or \
+           (entry[3] is not None and not callable(entry[3])) or \
+           (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \
+           (len(entry) > 5 and entry[5] is not None and not callable(entry[5])):
+            raise CodecRegistryError,\
+                'incompatible codecs in module "%s" (%s)' % \
+                (mod.__name__, mod.__file__)
+        if len(entry)<7 or entry[6] is None:
+            entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],)
+        entry = codecs.CodecInfo(*entry)
 
     # Cache the codec registry entry
     _cache[encoding] = entry
index 05fc36a55334e33f10aa6c2c29791d649fd4b73a..2033cde97484a9ba86f9008dabd15ac846c663ee 100644 (file)
@@ -17,6 +17,14 @@ class Codec(codecs.Codec):
     encode = codecs.ascii_encode
     decode = codecs.ascii_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.ascii_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.ascii_decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -31,5 +39,12 @@ class StreamConverter(StreamWriter,StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='ascii',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 085ab1471708a415dd7f3dd5082e56357da1f612..f84e7808e99433f8666b986d5abb35d446047065 100644 (file)
@@ -49,6 +49,16 @@ class Codec(codecs.Codec):
     def decode(self, input,errors='strict'):
         return base64_decode(input,errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return base64.encodestring(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return base64.decodestring(input)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -58,5 +68,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (base64_encode,base64_decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='base64',
+        encode=base64_encode,
+        decode=base64_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 870474ca1775c289be7c0ac2006c47a6a6f66572..81e84b6fb8993dc16cca67d548d4dbb2868b0e70 100644 (file)
@@ -51,6 +51,16 @@ class Codec(codecs.Codec):
     def decode(self, input, errors='strict'):
         return bz2_decode(input, errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return bz2.compress(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return bz2.decompress(input)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -60,5 +70,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (bz2_encode,bz2_decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name="bz2",
+        encode=bz2_encode,
+        decode=bz2_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 9bd93ecc334fd7c1f42595d9bdb655aae7c51ebd..81189b161a64ad2edbe9172597d848e64b28b28c 100644 (file)
@@ -21,30 +21,49 @@ class Codec(codecs.Codec):
     encode = codecs.charmap_encode
     decode = codecs.charmap_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict', mapping=None):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.mapping = mapping
+
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input, self.errors, self.mapping)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def __init__(self, errors='strict', mapping=None):
+        codecs.IncrementalDecoder.__init__(self, errors)
+        self.mapping = mapping
+
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input, self.errors, self.mapping)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
 
     def __init__(self,stream,errors='strict',mapping=None):
-
         codecs.StreamWriter.__init__(self,stream,errors)
         self.mapping = mapping
 
     def encode(self,input,errors='strict'):
-
         return Codec.encode(input,errors,self.mapping)
 
 class StreamReader(Codec,codecs.StreamReader):
 
     def __init__(self,stream,errors='strict',mapping=None):
-
         codecs.StreamReader.__init__(self,stream,errors)
         self.mapping = mapping
 
     def decode(self,input,errors='strict'):
-
         return Codec.decode(input,errors,self.mapping)
 
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='charmap',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 5864c4b0bb9f8923e9e70380295f58113a9278bf..7e589a92a5f0850f2d69d511dc3bbe38a96f58ef 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp037 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp037',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index d94563d14d0b0658fc9d23c457bd4e7d1f8aaf02..782996951f89fbab3648d20c737f38b4e1c20746 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1006',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 648bed0198a96e23a4a2843eb421c33d7329fc68..01c88044d8c1130e175a1b753045142f8592d5e2 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1026',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 6507552bab2da2694ef6dbf17621fd8fe96a5945..ac8d41bc7be38f6ac699c751bab8186757e26164 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'python-mappings/CP1140.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1140',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 73427bc3066263d8c128c284124dc0cd0b9c3225..6e6f57c05eec44752e683bcbe77f6ee5768c1bc5 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1250',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index f3e107efa96cd87c7feb97a614e7eddde17571fc..ed835fe2562157cc16899c748bbd3f99a9a7c1d2 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1251',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index ea7561d1e6f38bc4ebda83b96d0c742ab5f41aed..e5b6905eaeedfb9752dfeed0179446611fc7fb63 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1252',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 5feefb38148d9549ddb199154f9b2382b11c5373..3ce70b25d94211c7bf3847e0d6fd40a8e629c54d 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1253',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 6769e1be141101f2d97eab8c117abeff05ebc018..31cd48c1a50e0ac9cedaa403460b00f981760cfb 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1254',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index b994f9d844f790df737cd8e09b5fbb0fcd104205..47c43ce90ae7020b1930751052ddaaa22b36c914 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1255',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 5da425e3d50b1aaa2a3d97ad5dd557bcc4230431..e90393b6a7f990c7bd25ec6df74a4df383839fb2 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1256',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 237a5317954a07425f3263fca72c4be594fa28c3..dcc81c09eb703d35d100e00c6fc5d21dde556dba 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1257',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 5de3fd86607ffaf0a22027538038e33f78488d92..d4d22712e37546aac4a95810c771c3fa120fda3a 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp1258',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index d19c756c265169a225c93192c09799d86f4051e1..966aecb09916616ec566f9a8a5691688c47bde5f 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp424',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index e9cefaf418b2b6b7655d14a58282c7eaafe75803..52cd8829428cbb923f10403b5a02c40b7cc2bb85 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp437',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 3bbefa086b14a3a30298efcb70891d3cb366b14e..83af090700d165122266f6428138c548575897e6 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp500',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 883a8bac73e06bc80b0bf0f14595097d9b6abfde..d6544482d2ddbdc6c4db296952db7081a9d9478a 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp737 generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp737',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 1b39188cf47709c44b7f749dc3891ff6325281c7..6a456a5825e4c3682bd08ab8abe52df7425f65d1 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,9 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
-
+    return codecs.CodecInfo(
+        name='cp775',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 ### Decoding Map
 
 decoding_map = codecs.make_identity_dict(range(256))
index 6481ee0a4709e157c43576f575235f693144c60a..0c8478c8b205a8ce69eac95a00b75f319d49c5e1 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp850',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 749b0da2e1f2f2975a015a21ec831f990eb784ed..069d5473b500050939696adeb78c41ae0ac9bdce 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp852',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 13146c99f0d1b0afb414eb0c8f70447fdfa0e443..241ef9d1e86e4edb1c8452d8aecafb8670c8a2d0 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp855',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 5823dff8eebac3ce3fbc9c3a8002f3409388cdf7..c72fcad9f943f79bc3c024889c59539006902c8a 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp856',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 6c5cdbbc84abd378ec944925364cd0f629f811c4..c24191b04dc40f4b9544fe49c6a19b1512f5d851 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp857',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index cd7cdf44d7bf873f446b8dbe1c911a79d160d2f5..4acb0cf36269eff1ff4ba7b4806c0db8fbde1146 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp860',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index b140f2e33d307b6ca749fbb79a591cd3466965e9..0939b5b1eefcb2033be8a26d2462d2263093fdb6 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp861',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index badec0845dbe004c9cf63ba141971389a3d6619c..ea0405ca1ba4c2e280afefc2d4050c35e8077b48 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp862',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 812bc3d45140a49c877547694198d1f06ad2808e..62dfabf66ab0d19644b626f1638d4a5c8ef3a7ab 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp863',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 41f2ea385fecc9728f4bf9ef41f44c346a8c87eb..02a0e733a8733743343bad41f0c4c4c77dfe86eb 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp864',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 8e68c6b54a954faf923eb15ccbc3ce2023c68d3b..e9f45f1b508b8f86aa72a11caacf4c682411186b 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp865',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 4c0dd8cc721da01e84f1e8b8b77483b652ac7c70..29cd85a3f10b05eac36ef93749ba593a485f816e 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp866',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 1747546f81e0fcb559d88395fb4f43759aa4f1b8..b4dc99bf2540b7767f70bc70ed8e67998c2c0fa7 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp869',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 5e1fea13a7749227c25953a1f0ba4c6969ef1c7c..591e8aa39faf6134e248ef53c8a8dd6ca2ce7d8f 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp874',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index ccebb847bbbe60357ee1a1bb282cfd1029d20912..879d5a4bc797b62284a4b76584cee17794694fdb 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py.
+""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='cp875',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 5c6e4a4e198c6eb0af87396bd039d8bf6e611838..91b38d952e1f9e638e34b867ec74fa4eb2323e9f 100644 (file)
@@ -49,6 +49,16 @@ class Codec(codecs.Codec):
     def decode(self, input,errors='strict'):
         return hex_decode(input,errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return binascii.b2a_hex(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return binascii.a2b_hex(input)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -58,5 +68,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (hex_encode,hex_decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='hex',
+        encode=hex_encode,
+        decode=hex_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 4f201b8b112732b3dc213d6c2c31e3ff9bfa1aed..dbaaa72d76dd0e8fdbac4b88319e861fe198f82a 100644 (file)
@@ -14,13 +14,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_map)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -30,8 +36,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='hp-roman8',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
 
 ### Decoding Map
 
index 3d3ed23ce6199bef6945adcb41581775b1cdacad..8bdae32cea7349059608dc7296351726a6985dfb 100644 (file)
@@ -194,6 +194,14 @@ class Codec(codecs.Codec):
 
         return u".".join(result)+trailing_dot, len(input)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return Codec().encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return Codec().decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -203,5 +211,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='idna',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 6aaea7c0131393a5b9c80d80133a572012c4f626..b985585b313fb600c1fd2c5e5ba619e84cf17acb 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-1',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 26b55c969b4759079dbb2a2122390c3198a5b987..8588430848d907824eaa256179f4cc781c08a688 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-10',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index ef17167a6bda5fc1de7e620037842a246b97e577..fffe6922ced4deeb503ab9d738a4fbd106daaf6e 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-11',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 0e10c7d144107d406e9a1f53c30a0c7800b5a35d..a8905806a51e93b0e4920abc236d925107d3cb1f 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-13',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index b98103189587dfa21b1f923fad4489b57160df53..afa458c9c2e6f60e1621a546421d620c1a8d27ab 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-14',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index f50a90421efdb05086627fdd42d5fb4e618d8c18..4a8334e9e99789b3cb9c76ab3a34c582d17c20e5 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-15',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index ce8bc5b48e9ba00ab2fc9444e7e8ecba173e4407..aeebfb6fde22fc84236bb17b9ede2c90162b8c98 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-16',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 417b451ef0ae3c0a6370bdc978872c5559fc2b52..845f3227a73d82f1367d3b15614c4db12ae9eb47 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-2',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index c3ad3a99c54efc63cc2fc2b9e0dce3dc2dc5a896..fbc87755223353613004137af62d3ca2fc12d04a 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-3',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index b65685aaa304c99e1fdae966c6a7ee40e734f7a2..e705954ca807d144c6ffa4880f416d3cd5c658be 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-4',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 59fe37245fbd679ff503880a03cb1c4384650782..93a4e90246dda82b91d2dcee8effca08824e3c1b 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-5',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index b07661d93d78991af7a6c59a7e1ff83d5fb52be0..f911cc41927762c291cd7bc0c718d66bfc8e7f19 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-6',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 54d0997d5f15aa40d6e640d750a197810effe5bb..4cce6e234724ec60020a0e7827cfcd0baae61085 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-7',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 24ba1bbb21ce24125157f08f020d10f67178f5cd..8c29a87b662882aefed2413ec3706401c8206ee4 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-8',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 940d92b75f44fded8eb3402d0510fefc70884010..9648e9f8c3845bbe692532b491aaf90601902b8c 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py.
+""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-9',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index f2723def5bd08fb25960fc7d7b116ae857d45994..3efeb56edd266eab600713228134e82508aded5b 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py.
+""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='koi8-r',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 9bbcf7cbbdaca6d4cc8371112aca2daefbb2f54e..5f46db1700cf9773fd785bc20b5c2b8d6d75a302 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'python-mappings/KOI8-U.TXT' with gencodec.py.
+""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='koi8-u',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 0e55917b3da8bf166c9ea11aae2f71b7576ec217..370160c0cb512f25573985bce277ea2f590a420c 100644 (file)
@@ -17,6 +17,14 @@ class Codec(codecs.Codec):
     encode = codecs.latin_1_encode
     decode = codecs.latin_1_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.latin_1_encode(input,self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.latin_1_decode(input,self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -31,5 +39,12 @@ class StreamConverter(StreamWriter,StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='iso8859-1',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 6c096b4ef49c5a2ec4597916e7161dc38f5bbc87..7a7d3c5f7fe41be0b0ab8e1afbe25984789636d8 100644 (file)
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-arabic',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index d7d67ecbeecfdcc302fa472ca1dd879086b3cf41..54a1510333a5ba47b280eecb679e8df9dae56c53 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_centeuro generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-centeuro',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 96e118797027bb69fc9eba402b13bb3fd76c2d19..9e93cddf3ced1ac64e86c8ce8a93961809822b63 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-croatian',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index f1b1fb0c8e5125764bb101234984d499324ae1f7..8ffd715138a869ce0ce82b03214444279ed4e3fd 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-cyrillic',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 2b61e27058a31123740489e07cc496812ce3fdb8..6d26a42960480100ccfb851387f4ff5a5d659845 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-farsi',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index c2dd26fe3ca8defe884817e4f396803c6ea2ddf4..7264f9ae9d59222666157bf99e490075fde9ce82 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-greek',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index d305d2982151547fdc1157388fb005ea7cd5f262..5d8d9ad93f5a444af5f895a8c26b391370112d86 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-iceland',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index f5d5225802de3a86a26df01e0fc6ab982ef43d80..e322be236c3efdd66af473d753a049140b83a3bc 100644 (file)
@@ -14,13 +14,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_map)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -30,8 +36,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-latin2',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index d23aeba2cc7ad5b94c02f79040eb2b578da0dc7c..9552e531aae3dd6210ecafcb955886757f446f3d 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-roman',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 5c35a644577ef687c545b1b3f2fb35b166b9b464..51282c3c097b537f3337b27f531cbe01dca109bf 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-romanian',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index 79894ba8a8ed58b425becb87bb539f3c50027543..4e5641f181254e6fe3d7784c3c46eae8fc30500a 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py.
+""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mac-turkish',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index c79f47c3afcc0874bff0d71a282593c6a6489e31..ff77fdee9435aa92e4cc87c9d1961117ea275f3c 100644 (file)
@@ -18,6 +18,13 @@ class Codec(codecs.Codec):
     encode = codecs.mbcs_encode
     decode = codecs.mbcs_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.mbcs_encode(input,self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.mbcs_decode(input,self.errors)[0]
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -32,5 +39,12 @@ class StreamConverter(StreamWriter,StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='mbcs',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index c0f06064e4b7550259f2b386622135987aad350c..4b77e2ba9142ebc3f8a9f4a3dc2df89e39b5c50a 100644 (file)
@@ -15,6 +15,14 @@ class Codec(codecs.Codec):
     def decode(self,input,errors='strict'):
         return codecs.charmap_decode(input,errors,decoding_map)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -24,7 +32,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='palmos',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 5cdd98c4aa76f520284ccb129d0fb2c92595d445..aef897538f5e3542229e661f1679d39c21912c6b 100644 (file)
@@ -14,13 +14,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_map)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -30,8 +36,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='ptcp154',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 ### Decoding Map
 
index 82fd4585f57d03cd71a1483cd3c38d21fd7ce516..2cde8b93a8e1bbcc347e591cfae8e390a462b3d6 100644 (file)
@@ -197,18 +197,27 @@ def punycode_decode(text, errors):
 ### Codec APIs
 
 class Codec(codecs.Codec):
-    def encode(self,input,errors='strict'):
 
+    def encode(self,input,errors='strict'):
         res = punycode_encode(input)
         return res, len(input)
 
     def decode(self,input,errors='strict'):
-
         if errors not in ('strict', 'replace', 'ignore'):
             raise UnicodeError, "Unsupported error handling "+errors
         res = punycode_decode(input, errors)
         return res, len(input)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return punycode_encode(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        if errors not in ('strict', 'replace', 'ignore'):
+            raise UnicodeError, "Unsupported error handling "+errors
+        return punycode_decode(input, errors)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -218,5 +227,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='punycode',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index d98b5ed04bf5b0944ed97658ed79936ae9dd69ee..b802ae62d2a20565beacb16648237f43cc659488 100644 (file)
@@ -46,6 +46,14 @@ class Codec(codecs.Codec):
     def decode(self, input,errors='strict'):
         return quopri_decode(input,errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return quopri_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return quopri_decode(input, self.errors)[0]
+
 class StreamWriter(Codec, codecs.StreamWriter):
     pass
 
@@ -55,4 +63,12 @@ class StreamReader(Codec,codecs.StreamReader):
 # encodings module API
 
 def getregentry():
-    return (quopri_encode, quopri_decode, StreamReader, StreamWriter)
+    return codecs.CodecInfo(
+        name='quopri',
+        encode=quopri_encode,
+        decode=quopri_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index a2f3fffaddb37e2f63f6986c1fcf4034e142d1a5..2b919b40d3788a7bd7dab3a983af091deb48a235 100644 (file)
@@ -17,6 +17,14 @@ class Codec(codecs.Codec):
     encode = codecs.raw_unicode_escape_encode
     decode = codecs.raw_unicode_escape_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.raw_unicode_escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.raw_unicode_escape_decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -26,5 +34,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='raw-unicode-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index c628181bfdcdff755ad7ce54ad3443703444d391..52b6431cf30d5edcc7454352cce4a8f7fe2581fe 100644 (file)
@@ -14,13 +14,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_map)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -30,8 +36,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='rot-13',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
 
 ### Decoding Map
 
index c02bfeef2e6a02faf87f7765c2982d610ab4165a..e329a2607de4d59fa014de61b5949db862e3112c 100644 (file)
@@ -12,6 +12,14 @@ class Codec(codecs.Codec):
     encode = codecs.escape_encode
     decode = codecs.escape_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.escape_decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -19,5 +27,12 @@ class StreamReader(Codec,codecs.StreamReader):
     pass
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='string-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index aa1823efed08529c1d282beb5173823cfff03a2b..166d93268bf2cb6c2a1d3338b8c613a70e4bd9ec 100644 (file)
@@ -1,4 +1,4 @@
-""" Python Character Mapping Codec generated from 'python-mappings/TIS-620.TXT' with gencodec.py.
+""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py.
 
 """#"
 
@@ -9,13 +9,19 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
     def decode(self,input,errors='strict'):
-
         return codecs.charmap_decode(input,errors,decoding_table)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -25,8 +31,15 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='tis-620',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
 
 
 ### Decoding Table
index d2277ac18d79bf1dd4eadb4fdd30694ce3785990..4690288355c710bc227c0990fb37f36e23186ea1 100644 (file)
@@ -16,10 +16,18 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-        raise UnicodeError, "undefined encoding"
+        raise UnicodeError("undefined encoding")
 
     def decode(self,input,errors='strict'):
-        raise UnicodeError, "undefined encoding"
+        raise UnicodeError("undefined encoding")
+
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        raise UnicodeError("undefined encoding")
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        raise UnicodeError("undefined encoding")
 
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
@@ -30,5 +38,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='undefined',
+        encode=Codec().encode,
+        decode=Codec().decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 8fb629316b64b2ab5e88dcf78823b0fecf2b6444..817f93265a4634c9907b591b645a09cda73dcbf2 100644 (file)
@@ -17,6 +17,14 @@ class Codec(codecs.Codec):
     encode = codecs.unicode_escape_encode
     decode = codecs.unicode_escape_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.unicode_escape_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.unicode_escape_decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -26,5 +34,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='unicode-escape',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 3bd2fa0922c8310a75461985acd80a0a4b70f901..df3e7752d20a8e15c985742f11265b0ec7b3277b 100644 (file)
@@ -17,6 +17,14 @@ class Codec(codecs.Codec):
     encode = codecs.unicode_internal_encode
     decode = codecs.unicode_internal_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.unicode_internal_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return codecs.unicode_internal_decode(input, self.errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -26,5 +34,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='unicode-internal',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+    )
index 95abb056248af8ba1a90cc6232d42d6af24735c7..eff08f387822c7dd36bf939bdc49d8db04543db7 100644 (file)
@@ -15,6 +15,47 @@ encode = codecs.utf_16_encode
 def decode(input, errors='strict'):
     return codecs.utf_16_decode(input, errors, True)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.encoder = None
+
+    def encode(self, input, final=False):
+        if self.encoder is None:
+            result = codecs.utf_16_encode(input, self.errors)[0]
+            if sys.byteorder == 'little':
+                self.encoder = codecs.utf_16_le_encode
+            else:
+                self.encoder = codecs.utf_16_be_encode
+            return result
+        return self.encoder(input, self.errors)[0]
+
+    def reset(self):
+        codecs.IncrementalEncoder.reset(self)
+        self.encoder = None
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def __init__(self, errors='strict'):
+        codecs.BufferedIncrementalDecoder.__init__(self, errors)
+        self.decoder = None
+
+    def _buffer_decode(self, input, errors, final):
+        if self.decoder is None:
+            (output, consumed, byteorder) = \
+                codecs.utf_16_ex_decode(input, errors, 0, final)
+            if byteorder == -1:
+                self.decoder = codecs.utf_16_le_decode
+            elif byteorder == 1:
+                self.decoder = codecs.utf_16_be_decode
+            elif consumed >= 2:
+                raise UnicodeError("UTF-16 stream does not start with BOM")
+            return (output, consumed)
+        return self.decoder(input, self.errors, final)
+
+    def reset(self):
+        codecs.BufferedIncrementalDecoder.reset(self)
+        self.decoder = None
+
 class StreamWriter(codecs.StreamWriter):
     def __init__(self, stream, errors='strict'):
         self.bom_written = False
@@ -52,5 +93,12 @@ class StreamReader(codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (encode,decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-16',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 9a51f8ca10184ae3b77237a21af09d8bcdfffe5d..86b458eb9bcd96b50f128df1978a14f5d1e41835 100644 (file)
@@ -15,6 +15,13 @@ encode = codecs.utf_16_be_encode
 def decode(input, errors='strict'):
     return codecs.utf_16_be_decode(input, errors, True)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_16_be_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_16_be_decode
+
 class StreamWriter(codecs.StreamWriter):
     encode = codecs.utf_16_be_encode
 
@@ -24,5 +31,12 @@ class StreamReader(codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (encode,decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-16-be',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 95ca830484bee13ab7aa042e7012834de1412c00..ec454142eedf251e31eab481a1cbea6424273a0a 100644 (file)
@@ -15,15 +15,28 @@ encode = codecs.utf_16_le_encode
 def decode(input, errors='strict'):
     return codecs.utf_16_le_decode(input, errors, True)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_16_le_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_16_le_decode
+
 class StreamWriter(codecs.StreamWriter):
     encode = codecs.utf_16_le_encode
 
 class StreamReader(codecs.StreamReader):
     decode = codecs.utf_16_le_decode
 
-
 ### encodings module API
 
 def getregentry():
-
-    return (encode,decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-16-le',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index ee78d09ee8b31eb1f2bab5baca3e6cebf97e0880..d78d1926b30da2f90c76b67ae2253f00d0f18a5a 100644 (file)
@@ -13,6 +13,14 @@ class Codec(codecs.Codec):
     encode = codecs.utf_7_encode
     decode = codecs.utf_7_decode
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_7_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def _buffer_decode(self, input, errors, final):
+        return codecs.utf_7_decode(input, self.errors)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -22,5 +30,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec.encode,Codec.decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-7',
+        encode=Codec.encode,
+        decode=Codec.decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 9cb0b4b27b40ae07eab0a9a67b26ec67b8ce5484..1bf6336571547bcec3f5aa7978ff1c7f247490ce 100644 (file)
@@ -15,6 +15,13 @@ encode = codecs.utf_8_encode
 def decode(input, errors='strict'):
     return codecs.utf_8_decode(input, errors, True)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.utf_8_encode(input, self.errors)[0]
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    _buffer_decode = codecs.utf_8_decode
+
 class StreamWriter(codecs.StreamWriter):
     encode = codecs.utf_8_encode
 
@@ -24,5 +31,12 @@ class StreamReader(codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (encode,decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-8',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index fa437e69290c9f74d4e7d404f9d8e2e1fa1e2cb2..cd14ab0765e4f842405141be80bdbe6019f02870 100644 (file)
@@ -22,6 +22,42 @@ def decode(input, errors='strict'):
     (output, consumed) = codecs.utf_8_decode(input, errors, True)
     return (output, consumed+prefix)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def __init__(self, errors='strict'):
+        codecs.IncrementalEncoder.__init__(self, errors)
+        self.first = True
+
+    def encode(self, input, final=False):
+        if self.first:
+            self.first = False
+            return codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0]
+        else:
+            return codecs.utf_8_encode(input, errors)[0]
+
+    def reset(self):
+        codecs.IncrementalEncoder.reset(self)
+        self.first = True
+
+class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
+    def __init__(self, errors='strict'):
+        codecs.BufferedIncrementalDecoder.__init__(self, errors)
+        self.first = True
+
+    def _buffer_decode(self, input, errors, final):
+        if self.first and codecs.BOM_UTF8.startswith(input): # might be a BOM
+            if len(input) < 3:
+                # not enough data to decide if this really is a BOM
+                # => try again on the next call
+                return (u"", 0)
+            (output, consumed) = codecs.utf_8_decode(input[3:], errors, final)
+            self.first = False
+            return (output, consumed+3)
+        return codecs.utf_8_decode(input, errors, final)
+
+    def reset(self):
+        codecs.BufferedIncrementalDecoder.reset(self)
+        self.first = True
+
 class StreamWriter(codecs.StreamWriter):
     def reset(self):
         codecs.StreamWriter.reset(self)
@@ -53,5 +89,12 @@ class StreamReader(codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (encode,decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='utf-8-sig',
+        encode=encode,
+        decode=decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index a70ff9e8efd14598e5f6c42b8c29a6b56c10f4ae..0877fe1ab07c5a0dacf2da021ecd17f70a5ae7c8 100644 (file)
@@ -96,9 +96,18 @@ class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
         return uu_encode(input,errors)
+
     def decode(self,input,errors='strict'):
         return uu_decode(input,errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return uu_encode(input, errors)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        return uu_decode(input, errors)[0]
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -108,5 +117,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (uu_encode,uu_decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='uu',
+        encode=uu_encode,
+        decode=uu_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 9b6e4d12fef3332ec5b93737a61f62e30087405c..2694f15511608c24c000021aaf5766897c30914f 100644 (file)
@@ -50,6 +50,16 @@ class Codec(codecs.Codec):
     def decode(self, input, errors='strict'):
         return zlib_decode(input, errors)
 
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        assert self.errors == 'strict'
+        return zlib.compress(input)
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):
+        assert self.errors == 'strict'
+        return zlib.decompress(input)
+
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
 
@@ -59,5 +69,12 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (zlib_encode,zlib_decode,StreamReader,StreamWriter)
+    return codecs.CodecInfo(
+        name='zlib',
+        encode=zlib_encode,
+        decode=zlib_decode,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+        streamreader=StreamReader,
+        streamwriter=StreamWriter,
+    )
index 4b2f8a668ad58d4d9886540ee5cff410fe173279..7db0dabc9edaa7d88938801cbfae4aac661d164b 100644 (file)
@@ -1058,13 +1058,16 @@ class Logger(Filterer):
         file name, line number and function name.
         """
         f = currentframe().f_back
-        while 1:
+        rv = "(unknown file)", 0, "(unknown function)"
+        while hasattr(f, "f_code"):
             co = f.f_code
             filename = os.path.normcase(co.co_filename)
             if filename == _srcfile:
                 f = f.f_back
                 continue
-            return filename, f.f_lineno, co.co_name
+            rv = (filename, f.f_lineno, co.co_name)
+            break
+        return rv
 
     def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
         """
diff --git a/Lib/runpy.py b/Lib/runpy.py
new file mode 100755 (executable)
index 0000000..afb0098
--- /dev/null
@@ -0,0 +1,431 @@
+"""runpy.py - locating and running Python code using the module namespace
+
+Provides support for locating and running Python scripts using the Python
+module namespace instead of the native filesystem.
+
+This allows Python code to play nicely with non-filesystem based PEP 302
+importers when locating support scripts as well as when importing modules.
+"""
+# Written by Nick Coghlan <ncoghlan at gmail.com>
+#    to implement PEP 338 (Executing Modules as Scripts)
+
+import sys
+import imp
+
+__all__ = [
+    "run_module",
+]
+
+try:
+    _get_loader = imp.get_loader
+except AttributeError:
+    # get_loader() is not provided by the imp module, so emulate it
+    # as best we can using the PEP 302 import machinery exposed since
+    # Python 2.3. The emulation isn't perfect, but the differences
+    # in the way names are shadowed shouldn't matter in practice.
+    import os.path
+    import marshal                           # Handle compiled Python files
+
+    # This helper is needed in order for the PEP 302 emulation to
+    # correctly handle compiled files
+    def _read_compiled_file(compiled_file):
+        magic = compiled_file.read(4)
+        if magic != imp.get_magic():
+            return None
+        try:
+            compiled_file.read(4) # Skip timestamp
+            return marshal.load(compiled_file)
+        except Exception:
+            return None
+
+    class _AbsoluteImporter(object):
+        """PEP 302 importer wrapper for top level import machinery"""
+        def find_module(self, mod_name, path=None):
+            if path is not None:
+                return None
+            try:
+                file, filename, mod_info = imp.find_module(mod_name)
+            except ImportError:
+                return None
+            suffix, mode, mod_type = mod_info
+            if mod_type == imp.PY_SOURCE:
+                loader = _SourceFileLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.PY_COMPILED:
+                loader = _CompiledFileLoader(mod_name, file,
+                                             filename, mod_info)
+            elif mod_type == imp.PKG_DIRECTORY:
+                loader = _PackageDirLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.C_EXTENSION:
+                loader = _FileSystemLoader(mod_name, file,
+                                           filename, mod_info)
+            else:
+                loader = _BasicLoader(mod_name, file,
+                                      filename, mod_info)
+            return loader
+
+
+    class _FileSystemImporter(object):
+        """PEP 302 importer wrapper for filesystem based imports"""
+        def __init__(self, path_item=None):
+            if path_item is not None:
+                if path_item != '' and not os.path.isdir(path_item):
+                    raise ImportError("%s is not a directory" % path_item)
+                self.path_dir = path_item
+            else:
+                raise ImportError("Filesystem importer requires "
+                                  "a directory name")
+
+        def find_module(self, mod_name, path=None):
+            if path is not None:
+                return None
+            path_dir = self.path_dir
+            if path_dir == '':
+                path_dir = os.getcwd()
+            sub_name = mod_name.rsplit(".", 1)[-1]
+            try:
+                file, filename, mod_info = imp.find_module(sub_name,
+                                                           [path_dir])
+            except ImportError:
+                return None
+            if not filename.startswith(path_dir):
+                return None
+            suffix, mode, mod_type = mod_info
+            if mod_type == imp.PY_SOURCE:
+                loader = _SourceFileLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.PY_COMPILED:
+                loader = _CompiledFileLoader(mod_name, file,
+                                             filename, mod_info)
+            elif mod_type == imp.PKG_DIRECTORY:
+                loader = _PackageDirLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.C_EXTENSION:
+                loader = _FileSystemLoader(mod_name, file,
+                                           filename, mod_info)
+            else:
+                loader = _BasicLoader(mod_name, file,
+                                      filename, mod_info)
+            return loader
+
+
+    class _BasicLoader(object):
+        """PEP 302 loader wrapper for top level import machinery"""
+        def __init__(self, mod_name, file, filename, mod_info):
+            self.mod_name = mod_name
+            self.file = file
+            self.filename = filename
+            self.mod_info = mod_info
+
+        def _fix_name(self, mod_name):
+            if mod_name is None:
+                mod_name = self.mod_name
+            elif mod_name != self.mod_name:
+                raise ImportError("Loader for module %s cannot handle "
+                                  "module %s" % (self.mod_name, mod_name))
+            return mod_name
+
+        def load_module(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            mod = imp.load_module(mod_name, self.file,
+                                  self.filename, self.mod_info)
+            mod.__loader__ = self  # for introspection
+            return mod
+
+        def get_code(self, mod_name=None):
+            return None
+
+        def get_source(self, mod_name=None):
+            return None
+
+        def is_package(self, mod_name=None):
+            return False
+
+        def close(self):
+            if self.file:
+                self.file.close()
+
+        def __del__(self):
+            self.close()
+
+
+    class _FileSystemLoader(_BasicLoader):
+        """PEP 302 loader wrapper for filesystem based imports"""
+        def get_code(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_code(mod_name)
+
+        def get_data(self, pathname):
+            return open(pathname, "rb").read()
+
+        def get_filename(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_filename(mod_name)
+
+        def get_source(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_source(mod_name)
+
+        def is_package(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._is_package(mod_name)
+
+        def _get_code(self, mod_name):
+            return None
+
+        def _get_filename(self, mod_name):
+            return self.filename
+
+        def _get_source(self, mod_name):
+            return None
+
+        def _is_package(self, mod_name):
+            return False
+
+    class _PackageDirLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PKG_DIRECTORY directories"""
+        def _is_package(self, mod_name):
+            return True
+
+
+    class _SourceFileLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PY_SOURCE modules"""
+        def _get_code(self, mod_name):
+            return compile(self._get_source(mod_name),
+                           self.filename, 'exec')
+
+        def _get_source(self, mod_name):
+            f = self.file
+            f.seek(0)
+            return f.read()
+
+
+    class _CompiledFileLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PY_COMPILED modules"""
+        def _get_code(self, mod_name):
+            f = self.file
+            f.seek(0)
+            return _read_compiled_file(f)
+
+
+    def _get_importer(path_item):
+        """Retrieve a PEP 302 importer for the given path item
+
+        The returned importer is cached in sys.path_importer_cache
+        if it was newly created by a path hook.
+
+        If there is no importer, a wrapper around the basic import
+        machinery is returned. This wrapper is never inserted into
+        the importer cache (None is inserted instead).
+
+        The cache (or part of it) can be cleared manually if a
+        rescan of sys.path_hooks is necessary.
+        """
+        try:
+            importer = sys.path_importer_cache[path_item]
+        except KeyError:
+            for path_hook in sys.path_hooks:
+                try:
+                    importer = path_hook(path_item)
+                    break
+                except ImportError:
+                    pass
+            else:
+                importer = None
+            sys.path_importer_cache[path_item] = importer
+        if importer is None:
+            try:
+                importer = _FileSystemImporter(path_item)
+            except ImportError:
+                pass
+        return importer
+
+
+    def _get_path_loader(mod_name, path=None):
+        """Retrieve a PEP 302 loader using a path importer"""
+        if path is None:
+            path = sys.path
+            absolute_loader = _AbsoluteImporter().find_module(mod_name)
+            if isinstance(absolute_loader, _FileSystemLoader):
+                # Found in filesystem, so scan path hooks
+                # before accepting this one as the right one
+                loader = None
+            else:
+                # Not found in filesystem, so use top-level loader
+                loader = absolute_loader
+        else:
+            loader = absolute_loader = None
+        if loader is None:
+            for path_item in path:
+                importer = _get_importer(path_item)
+                if importer is not None:
+                    loader = importer.find_module(mod_name)
+                    if loader is not None:
+                        # Found a loader for our module
+                        break
+            else:
+                # No path hook found, so accept the top level loader
+                loader = absolute_loader
+        return loader
+
+    def _get_package(pkg_name):
+        """Retrieve a named package"""
+        pkg = __import__(pkg_name)
+        sub_pkg_names = pkg_name.split(".")
+        for sub_pkg in sub_pkg_names[1:]:
+            pkg = getattr(pkg, sub_pkg)
+        return pkg
+
+    def _get_loader(mod_name, path=None):
+        """Retrieve a PEP 302 loader for the given module or package
+
+        If the module or package is accessible via the normal import
+        mechanism, a wrapper around the relevant part of that machinery
+        is returned.
+
+        Non PEP 302 mechanisms (e.g. the Windows registry) used by the
+        standard import machinery to find files in alternative locations
+        are partially supported, but are searched AFTER sys.path. Normally,
+        these locations are searched BEFORE sys.path, preventing sys.path
+        entries from shadowing them.
+        For this to cause a visible difference in behaviour, there must
+        be a module or package name that is accessible via both sys.path
+        and one of the non PEP 302 file system mechanisms. In this case,
+        the emulation will find the former version, while the builtin
+        import mechanism will find the latter.
+        Items of the following types can be affected by this discrepancy:
+            imp.C_EXTENSION
+            imp.PY_SOURCE
+            imp.PY_COMPILED
+            imp.PKG_DIRECTORY
+        """
+        try:
+            loader = sys.modules[mod_name].__loader__
+        except (KeyError, AttributeError):
+            loader = None
+        if loader is None:
+            imp.acquire_lock()
+            try:
+                # Module not in sys.modules, or uses an unhooked loader
+                parts = mod_name.rsplit(".", 1)
+                if len(parts) == 2:
+                    # Sub package, so use parent package's path
+                    pkg_name, sub_name = parts
+                    if pkg_name and pkg_name[0] != '.':
+                        if path is not None:
+                            raise ImportError("Path argument must be None "
+                                            "for a dotted module name")
+                        pkg = _get_package(pkg_name)
+                        try:
+                            path = pkg.__path__
+                        except AttributeError:
+                            raise ImportError(pkg_name +
+                                            " is not a package")
+                    else:
+                        raise ImportError("Relative import syntax is not "
+                                          "supported by _get_loader()")
+                else:
+                    # Top level module, so stick with default path
+                    sub_name = mod_name
+
+                for importer in sys.meta_path:
+                    loader = importer.find_module(mod_name, path)
+                    if loader is not None:
+                        # Found a metahook to handle the module
+                        break
+                else:
+                    # Handling via the standard path mechanism
+                    loader = _get_path_loader(mod_name, path)
+            finally:
+                imp.release_lock()
+        return loader
+
+
+# This helper is needed due to a missing component in the PEP 302
+# loader protocol (specifically, "get_filename" is non-standard)
+def _get_filename(loader, mod_name):
+    try:
+        get_filename = loader.get_filename
+    except AttributeError:
+        return None
+    else:
+        return get_filename(mod_name)
+
+# ------------------------------------------------------------
+# Done with the import machinery emulation, on with the code!
+
+def _run_code(code, run_globals, init_globals,
+              mod_name, mod_fname, mod_loader):
+    """Helper for _run_module_code"""
+    if init_globals is not None:
+        run_globals.update(init_globals)
+    run_globals.update(__name__ = mod_name,
+                       __file__ = mod_fname,
+                       __loader__ = mod_loader)
+    exec code in run_globals
+    return run_globals
+
+def _run_module_code(code, init_globals=None,
+                    mod_name=None, mod_fname=None,
+                    mod_loader=None, alter_sys=False):
+    """Helper for run_module"""
+    # Set up the top level namespace dictionary
+    if alter_sys:
+        # Modify sys.argv[0] and sys.module[mod_name]
+        temp_module = imp.new_module(mod_name)
+        mod_globals = temp_module.__dict__
+        saved_argv0 = sys.argv[0]
+        restore_module = mod_name in sys.modules
+        if restore_module:
+            saved_module = sys.modules[mod_name]
+        imp.acquire_lock()
+        try:
+            sys.argv[0] = mod_fname
+            sys.modules[mod_name] = temp_module
+            try:
+                _run_code(code, mod_globals, init_globals,
+                          mod_name, mod_fname, mod_loader)
+            finally:
+                sys.argv[0] = saved_argv0
+                if restore_module:
+                    sys.modules[mod_name] = saved_module
+                else:
+                    del sys.modules[mod_name]
+        finally:
+            imp.release_lock()
+        # Copy the globals of the temporary module, as they
+        # may be cleared when the temporary module goes away
+        return mod_globals.copy()
+    else:
+        # Leave the sys module alone
+        return _run_code(code, {}, init_globals,
+                         mod_name, mod_fname, mod_loader)
+
+
+def run_module(mod_name, init_globals=None,
+                         run_name=None, alter_sys=False):
+    """Execute a module's code without importing it
+
+       Returns the resulting top level namespace dictionary
+    """
+    loader = _get_loader(mod_name)
+    if loader is None:
+        raise ImportError("No module named " + mod_name)
+    code = loader.get_code(mod_name)
+    if code is None:
+        raise ImportError("No code object available for " + mod_name)
+    filename = _get_filename(loader, mod_name)
+    if run_name is None:
+        run_name = mod_name
+    return _run_module_code(code, init_globals, run_name,
+                            filename, loader, alter_sys)
+
+
+if __name__ == "__main__":
+    # Run the module specified as the next command line argument
+    if len(sys.argv) < 2:
+        print >> sys.stderr, "No module specified for execution"
+    else:
+        del sys.argv[0] # Make the requested module sys.argv[0]
+        run_module(sys.argv[0], run_name="__main__", alter_sys=True)
index b4c229ac4bc7f73c0592201bd5a477e3212a35d3..b8509129c87d4bec70ed9c53bbfce895baa0e2f3 100755 (executable)
@@ -1136,9 +1136,6 @@ class _ExpectedSkips:
             s = _expectations[sys.platform]
             self.expected = set(s.split())
 
-            # this isn't a regularly run unit test, it is always skipped
-            self.expected.add('test_hashlib_speed')
-
             if not os.path.supports_unicode_filenames:
                 self.expected.add('test_pep277')
 
index c61f7cc54a3c401dbcac7c224b3eb4ee86beee30..cc3367fed8d16bdfa9a4b0c68c8b0832576fbf32 100644 (file)
@@ -75,6 +75,13 @@ class TestGenericStringIO(unittest.TestCase):
         f.close()
         self.assertEqual(f.closed, True)
 
+    def test_isatty(self):
+        f = self.MODULE.StringIO()
+        self.assertRaises(TypeError, f.isatty, None)
+        self.assertEqual(f.isatty(), False)
+        f.close()
+        self.assertRaises(ValueError, f.isatty)
+
     def test_iterator(self):
         eq = self.assertEqual
         unless = self.failUnless
@@ -87,6 +94,8 @@ class TestGenericStringIO(unittest.TestCase):
             eq(line, self._line + '\n')
             i += 1
         eq(i, 5)
+        self._fp.close()
+        self.assertRaises(ValueError, self._fp.next)
 
 class TestStringIO(TestGenericStringIO):
     MODULE = StringIO
index 7bf5314015852c8b60afbffcfa3e1bef879c3097..74a9cdf05b5056b334306a14c1813224f87ad710 100644 (file)
@@ -5,8 +5,6 @@ from test.test_support import verify, verbose
 import sys
 import warnings
 
-warnings.filterwarnings("ignore", ".* 'pre' .*", DeprecationWarning,
-                        r'pre$')
 warnings.filterwarnings("ignore", ".* regsub .*", DeprecationWarning,
                         r'^regsub$')
 warnings.filterwarnings("ignore",
@@ -122,7 +120,6 @@ class AllTest(unittest.TestCase):
         self.check_all("poplib")
         self.check_all("posixpath")
         self.check_all("pprint")
-        self.check_all("pre")  # deprecated
         self.check_all("profile")
         self.check_all("pstats")
         self.check_all("pty")
index 3944d654525db6d1cdff848e566b31049bfbc39f..913aa91168ad1a30c4fa58d198ccf6150d9f59d5 100644 (file)
@@ -41,6 +41,33 @@ class ReadTest(unittest.TestCase):
         self.assertEqual(r.bytebuffer, "")
         self.assertEqual(r.charbuffer, u"")
 
+        # do the check again, this time using a incremental decoder
+        d = codecs.getincrementaldecoder(self.encoding)()
+        result = u""
+        for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+            result += d.decode(c)
+            self.assertEqual(result, partialresult)
+        # check that there's nothing left in the buffers
+        self.assertEqual(d.decode("", True), u"")
+        self.assertEqual(d.buffer, "")
+
+        # Check whether the rest method works properly
+        d.reset()
+        result = u""
+        for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+            result += d.decode(c)
+            self.assertEqual(result, partialresult)
+        # check that there's nothing left in the buffers
+        self.assertEqual(d.decode("", True), u"")
+        self.assertEqual(d.buffer, "")
+
+        # check iterdecode()
+        encoded = input.encode(self.encoding)
+        self.assertEqual(
+            input,
+            u"".join(codecs.iterdecode(encoded, self.encoding))
+        )
+
     def test_readline(self):
         def getreader(input):
             stream = StringIO.StringIO(input.encode(self.encoding))
@@ -977,6 +1004,12 @@ class BasicUnicodeTest(unittest.TestCase):
     def test_basics(self):
         s = u"abc123" # all codecs should be able to encode these
         for encoding in all_unicode_encodings:
+            name = codecs.lookup(encoding).name
+            if encoding.endswith("_codec"):
+                name += "_codec"
+            elif encoding == "latin_1":
+                name = "latin_1"
+            self.assertEqual(encoding.replace("_", "-"), name.replace("_", "-"))
             (bytes, size) = codecs.getencoder(encoding)(s)
             if encoding != "unicode_internal":
                 self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding))
@@ -999,6 +1032,30 @@ class BasicUnicodeTest(unittest.TestCase):
                     decodedresult += reader.read()
                 self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
 
+                # check incremental decoder/encoder and iterencode()/iterdecode()
+                try:
+                    encoder = codecs.getincrementalencoder(encoding)()
+                except LookupError: # no IncrementalEncoder
+                    pass
+                else:
+                    # check incremental decoder/encoder
+                    encodedresult = ""
+                    for c in s:
+                        encodedresult += encoder.encode(c)
+                    decoder = codecs.getincrementaldecoder(encoding)()
+                    decodedresult = u""
+                    for c in encodedresult:
+                        decodedresult += decoder.decode(c)
+                    self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+                    # check iterencode()/iterdecode()
+                    result = u"".join(codecs.iterdecode(codecs.iterencode(s, encoding), encoding))
+                    self.assertEqual(result, s, "%r != %r (encoding=%r)" % (result, s, encoding))
+
+                    # check iterencode()/iterdecode() with empty string
+                    result = u"".join(codecs.iterdecode(codecs.iterencode(u"", encoding), encoding))
+                    self.assertEqual(result, u"")
+
     def test_seek(self):
         # all codecs should be able to encode these
         s = u"%s\n%s\n" % (100*u"abc123", 100*u"def456")
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
new file mode 100644 (file)
index 0000000..88e9900
--- /dev/null
@@ -0,0 +1,172 @@
+# Test the runpy module
+import unittest
+import os
+import os.path
+import sys
+import tempfile
+from test.test_support import verbose, run_unittest
+from runpy import _run_module_code, run_module
+
+# Set up the test code and expected results
+
+class RunModuleCodeTest(unittest.TestCase):
+
+    expected_result = ["Top level assignment", "Lower level reference"]
+    test_source = (
+        "# Check basic code execution\n"
+        "result = ['Top level assignment']\n"
+        "def f():\n"
+        "    result.append('Lower level reference')\n"
+        "f()\n"
+        "# Check the sys module\n"
+        "import sys\n"
+        "run_argv0 = sys.argv[0]\n"
+        "if __name__ in sys.modules:\n"
+        "    run_name = sys.modules[__name__].__name__\n"
+        "# Check nested operation\n"
+        "import runpy\n"
+        "nested = runpy._run_module_code('x=1\\n', mod_name='<run>',\n"
+        "                                          alter_sys=True)\n"
+    )
+
+
+    def test_run_module_code(self):
+        initial = object()
+        name = "<Nonsense>"
+        file = "Some other nonsense"
+        loader = "Now you're just being silly"
+        d1 = dict(initial=initial)
+        saved_argv0 = sys.argv[0]
+        d2 = _run_module_code(self.test_source,
+                              d1,
+                              name,
+                              file,
+                              loader,
+                              True)
+        self.failUnless("result" not in d1)
+        self.failUnless(d2["initial"] is initial)
+        self.failUnless(d2["result"] == self.expected_result)
+        self.failUnless(d2["nested"]["x"] == 1)
+        self.failUnless(d2["__name__"] is name)
+        self.failUnless(d2["run_name"] is name)
+        self.failUnless(d2["__file__"] is file)
+        self.failUnless(d2["run_argv0"] is file)
+        self.failUnless(d2["__loader__"] is loader)
+        self.failUnless(sys.argv[0] is saved_argv0)
+        self.failUnless(name not in sys.modules)
+
+    def test_run_module_code_defaults(self):
+        saved_argv0 = sys.argv[0]
+        d = _run_module_code(self.test_source)
+        self.failUnless(d["result"] == self.expected_result)
+        self.failUnless(d["__name__"] is None)
+        self.failUnless(d["__file__"] is None)
+        self.failUnless(d["__loader__"] is None)
+        self.failUnless(d["run_argv0"] is saved_argv0)
+        self.failUnless("run_name" not in d)
+        self.failUnless(sys.argv[0] is saved_argv0)
+
+class RunModuleTest(unittest.TestCase):
+
+    def expect_import_error(self, mod_name):
+        try:
+            run_module(mod_name)
+        except ImportError:
+            pass
+        else:
+            self.fail("Expected import error for " + mod_name)
+
+    def test_invalid_names(self):
+        self.expect_import_error("sys")
+        self.expect_import_error("sys.imp.eric")
+        self.expect_import_error("os.path.half")
+        self.expect_import_error("a.bee")
+        self.expect_import_error(".howard")
+        self.expect_import_error("..eaten")
+
+    def test_library_module(self):
+        run_module("runpy")
+
+    def _make_pkg(self, source, depth):
+        pkg_name = "__runpy_pkg__"
+        init_fname = "__init__"+os.extsep+"py"
+        test_fname = "runpy_test"+os.extsep+"py"
+        pkg_dir = sub_dir = tempfile.mkdtemp()
+        if verbose: print "  Package tree in:", sub_dir
+        sys.path.insert(0, pkg_dir)
+        if verbose: print "  Updated sys.path:", sys.path[0]
+        for i in range(depth):
+            sub_dir = os.path.join(sub_dir, pkg_name)
+            os.mkdir(sub_dir)
+            if verbose: print "  Next level in:", sub_dir
+            pkg_fname = os.path.join(sub_dir, init_fname)
+            pkg_file = open(pkg_fname, "w")
+            pkg_file.close()
+            if verbose: print "  Created:", pkg_fname
+        mod_fname = os.path.join(sub_dir, test_fname)
+        mod_file = open(mod_fname, "w")
+        mod_file.write(source)
+        mod_file.close()
+        if verbose: print "  Created:", mod_fname
+        mod_name = (pkg_name+".")*depth + "runpy_test"
+        return pkg_dir, mod_fname, mod_name
+
+    def _del_pkg(self, top, depth, mod_name):
+        for i in range(depth+1): # Don't forget the module itself
+            parts = mod_name.rsplit(".", i)
+            entry = parts[0]
+            try:
+                del sys.modules[entry]
+            except KeyError, ex:
+                if verbose: print ex # Persist with cleaning up
+        if verbose: print "  Removed sys.modules entries"
+        del sys.path[0]
+        if verbose: print "  Removed sys.path entry"
+        for root, dirs, files in os.walk(top, topdown=False):
+            for name in files:
+                try:
+                    os.remove(os.path.join(root, name))
+                except OSError, ex:
+                    if verbose: print ex # Persist with cleaning up
+            for name in dirs:
+                fullname = os.path.join(root, name)
+                try:
+                    os.rmdir(fullname)
+                except OSError, ex:
+                    if verbose: print ex # Persist with cleaning up
+        try:
+            os.rmdir(top)
+            if verbose: print "  Removed package tree"
+        except OSError, ex:
+            if verbose: print ex # Persist with cleaning up
+
+    def _check_module(self, depth):
+        pkg_dir, mod_fname, mod_name = (
+               self._make_pkg("x=1\n", depth))
+        try:
+            if verbose: print "Running from source:", mod_name
+            d1 = run_module(mod_name) # Read from source
+            self.failUnless(d1["x"] == 1)
+            del d1 # Ensure __loader__ entry doesn't keep file open
+            __import__(mod_name)
+            os.remove(mod_fname)
+            if verbose: print "Running from compiled:", mod_name
+            d2 = run_module(mod_name) # Read from bytecode
+            self.failUnless(d2["x"] == 1)
+            del d2 # Ensure __loader__ entry doesn't keep file open
+        finally:
+            self._del_pkg(pkg_dir, depth, mod_name)
+        if verbose: print "Module executed successfully"
+
+    def test_run_module(self):
+        for depth in range(4):
+            if verbose: print "Testing package depth:", depth
+            self._check_module(depth)
+
+
+def test_main():
+    run_unittest(RunModuleCodeTest)
+    run_unittest(RunModuleTest)
+
+if __name__ == "__main__":
+    test_main()
similarity index 92%
rename from Lib/test/test_hashlib_speed.py
rename to Lib/test/time_hashlib.py
index c84a62bdf332f28411cca4112c9aae00f23c2772..1bf707da19b31a3e9f90163c39f3a88530214ad5 100644 (file)
@@ -1,15 +1,14 @@
+# It's intended that this script be run by hand.  It runs speed tests on
+# hashlib functions; it does not test for correctness.
 
 import sys, time
 import hashlib
-from test import test_support
 
 
 def creatorFunc():
     raise RuntimeError, "eek, creatorFunc not overridden"
 
-
 def test_scaled_msg(scale, name):
-
     iterations = 106201/scale * 20
     longStr = 'Z'*scale
 
@@ -39,10 +38,6 @@ def test_zero():
 
 
 
-### this 'test' is not normally run.  skip it if the test runner finds it
-if __name__ != '__main__':
-    raise test_support.TestSkipped, "not a unit test (stand alone benchmark)"
-
 hName = sys.argv[1]
 
 #
index 5f2e98408fd71f1b5bd7122a58cae5d0ff9b83cc..056b57803ab9045cde3c25ec921d7bf89c1caf25 100644 (file)
@@ -974,6 +974,8 @@ clean:
        find . -name '*.o' -exec rm -f {} ';'
        find . -name '*.s[ol]' -exec rm -f {} ';'
        find $(srcdir) -name '*.py[co]' -exec rm -f {} ';'
+       find $(srcdir) -name 'fficonfig.h' -exec rm -f {} ';'
+       find $(srcdir) -name 'fficonfig.py' -exec rm -f {} ';'
 
 clobber: clean
        -rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
index 7c5da64db414a43c01a2a578699756a0a95893f5..926c85bce8a6f6aaacf3c6adfde1bdbba79e00c8 100644 (file)
@@ -3674,7 +3674,11 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length)
                if (cache == NULL)
                        return NULL;
        }
+#if (PY_VERSION_HEX < 0x02050000)
+       key = Py_BuildValue("(Oi)", itemtype, length);
+#else
        key = Py_BuildValue("(On)", itemtype, length);
+#endif
        if (!key)
                return NULL;
        result = PyDict_GetItem(cache, key);
@@ -3698,7 +3702,11 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length)
 #endif
 
        result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
+#if (PY_VERSION_HEX < 0x02050000)
+                                      "s(O){s:i,s:O}",
+#else
                                       "s(O){s:n,s:O}",
+#endif
                                       name,
                                       &Array_Type,
                                       "_length_",
index de41571b101f2f828a24017579e3736d34a0b61d..336f26543f63b76b4350b4da00ec0377dae9bc05 100644 (file)
@@ -250,11 +250,21 @@ CField_repr(CFieldObject *self)
        name = ((PyTypeObject *)self->proto)->tp_name;
 
        if (bits)
-               result = PyString_FromFormat("<Field type=%s, ofs=%d:%d, bits=%d>",
-                                            name, (int)self->offset, size, bits);
+               result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+                       "<Field type=%s, ofs=%d:%d, bits=%d>",
+#else
+                       "<Field type=%s, ofs=%zd:%d, bits=%d>",
+#endif
+                       name, self->offset, size, bits);
        else
-               result = PyString_FromFormat("<Field type=%s, ofs=%d, size=%d>",
-                                            name, (int)self->offset, size);
+               result = PyString_FromFormat(
+#if (PY_VERSION_HEX < 0x02050000)
+                       "<Field type=%s, ofs=%d, size=%d>",
+#else
+                       "<Field type=%s, ofs=%zd, size=%d>",
+#endif
+                       name, self->offset, size);
        return result;
 }
 
index 9347c99d23b19f0b7860aaee2299b7a52aaf6a84..179dcf16166b5ab03b0d148696d30a8cc2085403 100644 (file)
@@ -1,5 +1,18 @@
 /******************************************************************/
 
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#define lenfunc inquiry
+#define readbufferproc getreadbufferproc
+#define writebufferproc getwritebufferproc
+#define segcountproc getsegcountproc
+#define charbufferproc getcharbufferproc
+#define ssizeargfunc intargfunc
+#define ssizessizeargfunc intintargfunc
+#define ssizeobjargproc intobjargproc
+#define ssizessizeobjargproc intintobjargproc
+#endif
+
 #ifndef MS_WIN32
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
index 913c49aba72cdb28f2ae9e40ef4cf48e4b662022..6d8ea3c6693c82b8ab3122cb979bb59eceecc304 100644 (file)
@@ -522,6 +522,18 @@ test_long_numbits(PyObject *self)
        return Py_None;
 }
 
+/* Example passing NULLs to PyObject_Str(NULL) and PyObject_Unicode(NULL). */
+
+static PyObject *
+test_null_strings(PyObject *self)
+{
+       PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Unicode(NULL);
+       PyObject *tuple = PyTuple_Pack(2, o1, o2);
+       Py_XDECREF(o1);
+       Py_XDECREF(o2);
+       return tuple;
+}
+
 static PyObject *
 raise_exception(PyObject *self, PyObject *args)
 {
@@ -597,6 +609,7 @@ static PyMethodDef TestMethods[] = {
        {"test_long_api",       (PyCFunction)test_long_api,      METH_NOARGS},
        {"test_long_numbits",   (PyCFunction)test_long_numbits,  METH_NOARGS},
        {"test_k_code",         (PyCFunction)test_k_code,        METH_NOARGS},
+       {"test_null_strings",   (PyCFunction)test_null_strings,  METH_NOARGS},
 
        {"getargs_b",           (PyCFunction)getargs_b,          METH_VARARGS},
        {"getargs_B",           (PyCFunction)getargs_B,          METH_VARARGS},
index fd28aa9324dee17cce77eb5612b653f9a7fc401d..bdc9f00d39d3e3c4294b57a9fd201ab5dac13431 100644 (file)
@@ -144,7 +144,8 @@ PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
 
 static PyObject *
 IO_isatty(IOobject *self, PyObject *unused) {
-       Py_INCREF(Py_False);
+        if (!IO__opencheck(self)) return NULL;
+        Py_INCREF(Py_False);
         return Py_False;
 }
 
index c8298fbf768333f94e630bb57595cb280d1cff81..b3ce16e3e25bd29e39af23266b104122266ee274 100644 (file)
@@ -130,27 +130,42 @@ static void RunStartupFile(PyCompilerFlags *cf)
        }
 }
 
-/* Get the path to a top-level module */
-static struct filedescr * FindModule(const char *module,
-                                    FILE **fp, char **filename)
-{
-       struct filedescr *fdescr = NULL;
-       *fp = NULL;
-       *filename = malloc(MAXPATHLEN);
-
-       if (*filename == NULL)
-               return NULL;
-
-       /* Find the actual module source code */
-       fdescr = _PyImport_FindModule(module, NULL,
-                                       *filename, MAXPATHLEN, fp, NULL);
 
-       if (fdescr == NULL) {
-               free(*filename);
-               *filename = NULL;
+static int RunModule(char *module)
+{
+       PyObject *runpy, *runmodule, *runargs, *result;
+       runpy = PyImport_ImportModule("runpy");
+       if (runpy == NULL) {
+               fprintf(stderr, "Could not import runpy module\n");
+               return -1;
        }
-
-       return fdescr;
+       runmodule = PyObject_GetAttrString(runpy, "run_module");
+       if (runmodule == NULL) {
+               fprintf(stderr, "Could not access runpy.run_module\n");
+               Py_DECREF(runpy);
+               return -1;
+       }
+       runargs = Py_BuildValue("sOsO", module,
+                                                       Py_None, "__main__", Py_True);
+       if (runargs == NULL) {
+               fprintf(stderr,
+                               "Could not create arguments for runpy.run_module\n");
+               Py_DECREF(runpy);
+               Py_DECREF(runmodule);
+               return -1;
+       }
+       result = PyObject_Call(runmodule, runargs, NULL);
+       if (result == NULL) {
+               PyErr_Print();
+       }
+       Py_DECREF(runpy);
+       Py_DECREF(runmodule);
+       Py_DECREF(runargs);
+       if (result == NULL) {
+               return -1;
+       }
+       Py_DECREF(result);
+       return 0;
 }
 
 /* Main program */
@@ -410,28 +425,9 @@ Py_Main(int argc, char **argv)
        }
 
        if (module != NULL) {
-               /* Backup _PyOS_optind and find the real file */
-                struct filedescr *fdescr = NULL;
+               /* Backup _PyOS_optind and force sys.arv[0] = module */
                _PyOS_optind--;
-               if ((fdescr = FindModule(module, &fp, &filename))) {
-                       argv[_PyOS_optind] = filename;
-               } else {
-                       fprintf(stderr, "%s: module %s not found\n",
-                               argv[0], module);
-                       return 2;
-               }
-               if (!fp) {
-                       fprintf(stderr,
-                               "%s: module %s has no associated file\n",
-                               argv[0], module);
-                       return 2;
-               }
-               if (!_PyImport_IsScript(fdescr)) {
-                       fprintf(stderr,
-                               "%s: module %s not usable as script\n  (%s)\n",
-                               argv[0], module, filename);
-                       return 2;
-               }
+        argv[_PyOS_optind] = module;
        }
 
        PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
@@ -450,9 +446,8 @@ Py_Main(int argc, char **argv)
                sts = PyRun_SimpleStringFlags(command, &cf) != 0;
                free(command);
        } else if (module) {
-               sts = PyRun_AnyFileExFlags(fp, filename, 1, &cf) != 0;
+               sts = RunModule(module);
                free(module);
-               free(filename);
        }
        else {
                if (filename == NULL && stdin_is_interactive) {
index df312eb72a147bf3457f178b7d246e0b3f9528e4..ea66eefa0a6829f0755021b76c7e2031289e5eda 100644 (file)
@@ -197,18 +197,6 @@ xx_bug(PyObject *self, PyObject *args)
        return Py_None;
 }
 
-/* Example passing NULLs to PyObject_Str(NULL) and PyObject_Unicode(NULL). */
-
-static PyObject *
-xx_null(PyObject *self, PyObject *noargs)
-{
-       PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Unicode(NULL);
-       PyObject *tuple = PyTuple_Pack(2, o1, o2);
-       Py_XDECREF(o1);
-       Py_XDECREF(o2);
-       return tuple;
-}
-
 /* Test bad format character */
 
 static PyObject *
@@ -343,8 +331,6 @@ static PyMethodDef xx_methods[] = {
                PyDoc_STR("new() -> new Xx object")},
        {"bug",         xx_bug,         METH_VARARGS,
                PyDoc_STR("bug(o) -> None")},
-       {"null",        xx_null,        METH_NOARGS,
-               PyDoc_STR("null(o) -> ('NULL', u'NULL')")},
        {NULL,          NULL}           /* sentinel */
 };
 
index 3ee21e43c31bb557bbd430ccd96cab8dc595f10c..870f93c72173842aea442c66bf9264f12da9ccf5 100644 (file)
  * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
  */
 #undef  uchar
-#define uchar                  unsigned char   /* assuming == 8 bits  */
+#define uchar  unsigned char   /* assuming == 8 bits  */
 
 #undef  uint
-#define uint                   unsigned int    /* assuming >= 16 bits */
+#define uint   unsigned int    /* assuming >= 16 bits */
 
 #undef  ulong
-#define ulong                  unsigned long   /* assuming >= 32 bits */
+#define ulong  unsigned long   /* assuming >= 32 bits */
 
 #undef uptr
-#define uptr                   Py_uintptr_t
+#define uptr   Py_uintptr_t
 
 /* When you say memory, my mind reasons in terms of (pointers to) blocks */
 typedef uchar block;
@@ -246,6 +246,47 @@ struct pool_header {
 
 typedef struct pool_header *poolp;
 
+/* Record keeping for arenas. */
+struct arena_object {
+       /* The address of the arena, as returned by malloc.  Note that 0
+        * will never be returned by a successful malloc, and is used
+        * here to mark an arena_object that doesn't correspond to an
+        * allocated arena.
+        */
+       uptr address;
+
+       /* Pool-aligned pointer to the next pool to be carved off. */
+       block* pool_address;
+
+       /* The number of available pools in the arena:  free pools + never-
+        * allocated pools.
+        */
+       uint nfreepools;
+
+       /* The total number of pools in the arena, whether or not available. */
+       uint ntotalpools;
+
+       /* Singly-linked list of available pools. */
+       struct pool_header* freepools;
+
+       /* Whenever this arena_object is not associated with an allocated
+        * arena, the nextarena member is used to link all unassociated
+        * arena_objects in the singly-linked `unused_arena_objects` list.
+        * The prevarena member is unused in this case.
+        *
+        * When this arena_object is associated with an allocated arena
+        * with at least one available pool, both members are used in the
+        * doubly-linked `usable_arenas` list, which is maintained in
+        * increasing order of `nfreepools` values.
+        *
+        * Else this arena_object is associated with an allocated arena
+        * all of whose pools are in use.  `nextarena` and `prevarena`
+        * are both meaningless in this case.
+        */
+       struct arena_object* nextarena;
+       struct arena_object* prevarena;
+};
+
 #undef  ROUNDUP
 #define ROUNDUP(x)             (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
 #define POOL_OVERHEAD          ROUNDUP(sizeof(struct pool_header))
@@ -277,8 +318,9 @@ all partially used pools holding small blocks with "size class idx" i. So
 usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
 16, and so on:  index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
 
-Pools are carved off the current arena highwater mark (file static arenabase)
-as needed.  Once carved off, a pool is in one of three states forever after:
+Pools are carved off an arena's highwater mark (an arena_object's pool_address
+member) as needed.  Once carved off, a pool is in one of three states forever
+after:
 
 used == partially used, neither empty nor full
     At least one block in the pool is currently allocated, and at least one
@@ -303,7 +345,7 @@ full == all the pool's blocks are currently allocated
 
 empty == all the pool's blocks are currently available for allocation
     On transition to empty, a pool is unlinked from its usedpools[] list,
-    and linked to the front of the (file static) singly-linked freepools list,
+    and linked to the front of its arena_object's singly-linked freepools list,
     via its nextpool member.  The prevpool member has no meaning in this case.
     Empty pools have no inherent size class:  the next time a malloc finds
     an empty list in usedpools[], it takes the first pool off of freepools.
@@ -392,151 +434,243 @@ static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
 #endif /* NB_SMALL_SIZE_CLASSES >  8 */
 };
 
-/*
- * Free (cached) pools
+/*==========================================================================
+Arena management.
+
+`arenas` is a vector of arena_objects.  It contains maxarenas entries, some of
+which may not be currently used (== they're arena_objects that aren't
+currently associated with an allocated arena).  Note that arenas proper are
+separately malloc'ed.
+
+Prior to Python 2.5, arenas were never free()'ed.  Starting with Python 2.5,
+we do try to free() arenas, and use some mild heuristic strategies to increase
+the likelihood that arenas eventually can be freed.
+
+unused_arena_objects
+
+    This is a singly-linked list of the arena_objects that are currently not
+    being used (no arena is associated with them).  Objects are taken off the
+    head of the list in new_arena(), and are pushed on the head of the list in
+    PyObject_Free() when the arena is empty.  Key invariant:  an arena_object
+    is on this list if and only if its .address member is 0.
+
+usable_arenas
+
+    This is a doubly-linked list of the arena_objects associated with arenas
+    that have pools available.  These pools are either waiting to be reused,
+    or have not been used before.  The list is sorted to have the most-
+    allocated arenas first (ascending order based on the nfreepools member).
+    This means that the next allocation will come from a heavily used arena,
+    which gives the nearly empty arenas a chance to be returned to the system.
+    In my unscientific tests this dramatically improved the number of arenas
+    that could be freed.
+
+Note that an arena_object associated with an arena all of whose pools are
+currently in use isn't on either list.
+*/
+
+/* Array of objects used to track chunks of memory (arenas). */
+static struct arena_object* arenas = NULL;
+/* Number of slots currently allocated in the `arenas` vector. */
+static uint maxarenas = 0;
+
+/* The head of the singly-linked, NULL-terminated list of available
+ * arena_objects.
  */
-static poolp freepools = NULL;         /* free list for cached pools */
+static struct arena_object* unused_arena_objects = NULL;
 
-/*==========================================================================*/
-/* Arena management. */
+/* The head of the doubly-linked, NULL-terminated at each end, list of
+ * arena_objects associated with arenas that have pools available.
+ */
+static struct arena_object* usable_arenas = NULL;
 
-/* arenas is a vector of arena base addresses, in order of allocation time.
- * arenas currently contains narenas entries, and has space allocated
- * for at most maxarenas entries.
- *
- * CAUTION:  See the long comment block about thread safety in new_arena():
- * the code currently relies in deep ways on that this vector only grows,
- * and only grows by appending at the end.  For now we never return an arena
- * to the OS.
+/* How many arena_objects do we initially allocate?
+ * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
+ * `arenas` vector.
  */
-static uptr *volatile arenas = NULL;   /* the pointer itself is volatile */
-static volatile uint narenas = 0;
-static uint maxarenas = 0;
+#define INITIAL_ARENA_OBJECTS 16
 
-/* Number of pools still available to be allocated in the current arena. */
-static uint nfreepools = 0;
+/* Number of arenas allocated that haven't been free()'d. */
+static ulong narenas_currently_allocated = 0;
 
-/* Free space start address in current arena.  This is pool-aligned. */
-static block *arenabase = NULL;
+#ifdef PYMALLOC_DEBUG
+/* Total number of times malloc() called to allocate an arena. */
+static ulong ntimes_arena_allocated = 0;
+/* High water mark (max value ever seen) for narenas_currently_allocated. */
+static ulong narenas_highwater = 0;
+#endif
 
-/* Allocate a new arena and return its base address.  If we run out of
- * memory, return NULL.
+/* Allocate a new arena.  If we run out of memory, return NULL.  Else
+ * allocate a new arena, and return the address of an arena_object
+ * describing the new arena.  It's expected that the caller will set
+ * `usable_arenas` to the return value.
  */
-static block *
+static struct arena_object*
 new_arena(void)
 {
+       struct arena_object* arenaobj;
        uint excess;    /* number of bytes above pool alignment */
-       block *bp = (block *)malloc(ARENA_SIZE);
-       if (bp == NULL)
-               return NULL;
 
 #ifdef PYMALLOC_DEBUG
        if (Py_GETENV("PYTHONMALLOCSTATS"))
                _PyObject_DebugMallocStats();
 #endif
+       if (unused_arena_objects == NULL) {
+               uint i;
+               uint numarenas;
+               size_t nbytes;
 
-       /* arenabase <- first pool-aligned address in the arena
-          nfreepools <- number of whole pools that fit after alignment */
-       arenabase = bp;
-       nfreepools = ARENA_SIZE / POOL_SIZE;
-       assert(POOL_SIZE * nfreepools == ARENA_SIZE);
-       excess = (uint) ((Py_uintptr_t)bp & POOL_SIZE_MASK);
-       if (excess != 0) {
-               --nfreepools;
-               arenabase += POOL_SIZE - excess;
-       }
+               /* Double the number of arena objects on each allocation.
+                * Note that it's possible for `numarenas` to overflow.
+                */
+               numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
+               if (numarenas <= maxarenas)
+                       return NULL;    /* overflow */
+               nbytes = numarenas * sizeof(*arenas);
+               if (nbytes / sizeof(*arenas) != numarenas)
+                       return NULL;    /* overflow */
+               arenaobj = realloc(arenas, nbytes);
+               if (arenaobj == NULL)
+                       return NULL;
+               arenas = arenaobj;
+
+               /* We might need to fix pointers that were copied.  However,
+                * new_arena only gets called when all the pages in the
+                * previous arenas are full.  Thus, there are *no* pointers
+                * into the old array. Thus, we don't have to worry about
+                * invalid pointers.  Just to be sure, some asserts:
+                */
+               assert(usable_arenas == NULL);
+               assert(unused_arena_objects == NULL);
+
+               /* Put the new arenas on the unused_arena_objects list. */
+               for (i = maxarenas; i < numarenas; ++i) {
+                       arenas[i].address = 0;  /* mark as unassociated */
+                       arenas[i].nextarena = i < numarenas - 1 ?
+                                              &arenas[i+1] : NULL;
+               }
 
-       /* Make room for a new entry in the arenas vector. */
-       if (arenas == NULL) {
-               assert(narenas == 0 && maxarenas == 0);
-               arenas = (uptr *)malloc(16 * sizeof(*arenas));
-               if (arenas == NULL)
-                       goto error;
-               maxarenas = 16;
+               /* Update globals. */
+               unused_arena_objects = &arenas[maxarenas];
+               maxarenas = numarenas;
        }
-       else if (narenas == maxarenas) {
-               /* Grow arenas.
-                *
-                * Exceedingly subtle:  Someone may be calling the pymalloc
-                * free via PyMem_{DEL, Del, FREE, Free} without holding the
-                *.GIL.  Someone else may simultaneously be calling the
-                * pymalloc malloc while holding the GIL via, e.g.,
-                * PyObject_New.  Now the pymalloc free may index into arenas
-                * for an address check, while the pymalloc malloc calls
-                * new_arena and we end up here to grow a new arena *and*
-                * grow the arenas vector.  If the value for arenas pymalloc
-                * free picks up "vanishes" during this resize, anything may
-                * happen, and it would be an incredibly rare bug.  Therefore
-                * the code here takes great pains to make sure that, at every
-                * moment, arenas always points to an intact vector of
-                * addresses.  It doesn't matter whether arenas points to a
-                * wholly up-to-date vector when pymalloc free checks it in
-                * this case, because the only legal (and that even this is
-                * legal is debatable) way to call PyMem_{Del, etc} while not
-                * holding the GIL is if the memory being released is not
-                * object memory, i.e. if the address check in pymalloc free
-                * is supposed to fail.  Having an incomplete vector can't
-                * make a supposed-to-fail case succeed by mistake (it could
-                * only make a supposed-to-succeed case fail by mistake).
-                *
-                * In addition, without a lock we can't know for sure when
-                * an old vector is no longer referenced, so we simply let
-                * old vectors leak.
-                *
-                * And on top of that, since narenas and arenas can't be
-                * changed as-a-pair atomically without a lock, we're also
-                * careful to declare them volatile and ensure that we change
-                * arenas first.  This prevents another thread from picking
-                * up an narenas value too large for the arenas value it
-                * reads up (arenas never shrinks).
-                *
-                * Read the above 50 times before changing anything in this
-                * block.
+
+       /* Take the next available arena object off the head of the list. */
+       assert(unused_arena_objects != NULL);
+       arenaobj = unused_arena_objects;
+       unused_arena_objects = arenaobj->nextarena;
+       assert(arenaobj->address == 0);
+       arenaobj->address = (uptr)malloc(ARENA_SIZE);
+       if (arenaobj->address == 0) {
+               /* The allocation failed: return NULL after putting the
+                * arenaobj back.
                 */
-               uptr *p;
-               uint newmax = maxarenas << 1;
-               if (newmax <= maxarenas)        /* overflow */
-                       goto error;
-               p = (uptr *)malloc(newmax * sizeof(*arenas));
-               if (p == NULL)
-                       goto error;
-               memcpy(p, arenas, narenas * sizeof(*arenas));
-               arenas = p;     /* old arenas deliberately leaked */
-               maxarenas = newmax;
+               arenaobj->nextarena = unused_arena_objects;
+               unused_arena_objects = arenaobj;
+               return NULL;
        }
 
-       /* Append the new arena address to arenas. */
-       assert(narenas < maxarenas);
-       arenas[narenas] = (uptr)bp;
-       ++narenas;      /* can't overflow, since narenas < maxarenas before */
-       return bp;
+       ++narenas_currently_allocated;
+#ifdef PYMALLOC_DEBUG
+       ++ntimes_arena_allocated;
+       if (narenas_currently_allocated > narenas_highwater)
+               narenas_highwater = narenas_currently_allocated;
+#endif
+       arenaobj->freepools = NULL;
+       /* pool_address <- first pool-aligned address in the arena
+          nfreepools <- number of whole pools that fit after alignment */
+       arenaobj->pool_address = (block*)arenaobj->address;
+       arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
+       assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
+       excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
+       if (excess != 0) {
+               --arenaobj->nfreepools;
+               arenaobj->pool_address += POOL_SIZE - excess;
+       }
+       arenaobj->ntotalpools = arenaobj->nfreepools;
 
-error:
-       free(bp);
-       nfreepools = 0;
-       return NULL;
+       return arenaobj;
 }
 
-/* Return true if and only if P is an address that was allocated by
- * pymalloc.  I must be the index into arenas that the address claims
- * to come from.
- *
- * Tricky:  Letting B be the arena base address in arenas[I], P belongs to the
- * arena if and only if
- *     B <= P < B + ARENA_SIZE
- * Subtracting B throughout, this is true iff
- *     0 <= P-B < ARENA_SIZE
- * By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
- *
- * Obscure:  A PyMem "free memory" function can call the pymalloc free or
- * realloc before the first arena has been allocated.  arenas is still
- * NULL in that case.  We're relying on that narenas is also 0 in that case,
- * so the (I) < narenas must be false, saving us from trying to index into
- * a NULL arenas.
- */
-#define Py_ADDRESS_IN_RANGE(P, POOL)   \
-       ((POOL)->arenaindex < narenas &&                \
-        (uptr)(P) - arenas[(POOL)->arenaindex] < (uptr)ARENA_SIZE)
+/*
+Py_ADDRESS_IN_RANGE(P, POOL)
+
+Return true if and only if P is an address that was allocated by pymalloc.
+POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
+(the caller is asked to compute this because the macro expands POOL more than
+once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
+variable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
+called on every alloc/realloc/free, micro-efficiency is important here).
+
+Tricky:  Let B be the arena base address associated with the pool, B =
+arenas[(POOL)->arenaindex].address.  Then P belongs to the arena if and only if
+
+       B <= P < B + ARENA_SIZE
+
+Subtracting B throughout, this is true iff
+
+       0 <= P-B < ARENA_SIZE
+
+By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
+
+Obscure:  A PyMem "free memory" function can call the pymalloc free or realloc
+before the first arena has been allocated.  `arenas` is still NULL in that
+case.  We're relying on that maxarenas is also 0 in that case, so that
+(POOL)->arenaindex < maxarenas  must be false, saving us from trying to index
+into a NULL arenas.
+
+Details:  given P and POOL, the arena_object corresponding to P is AO =
+arenas[(POOL)->arenaindex].  Suppose obmalloc controls P.  Then (barring wild
+stores, etc), POOL is the correct address of P's pool, AO.address is the
+correct base address of the pool's arena, and P must be within ARENA_SIZE of
+AO.address.  In addition, AO.address is not 0 (no arena can start at address 0
+(NULL)).  Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
+controls P.
+
+Now suppose obmalloc does not control P (e.g., P was obtained via a direct
+call to the system malloc() or realloc()).  (POOL)->arenaindex may be anything
+in this case -- it may even be uninitialized trash.  If the trash arenaindex
+is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
+control P.
+
+Else arenaindex is < maxarena, and AO is read up.  If AO corresponds to an
+allocated arena, obmalloc controls all the memory in slice AO.address :
+AO.address+ARENA_SIZE.  By case assumption, P is not controlled by obmalloc,
+so P doesn't lie in that slice, so the macro correctly reports that P is not
+controlled by obmalloc.
+
+Finally, if P is not controlled by obmalloc and AO corresponds to an unused
+arena_object (one not currently associated with an allocated arena),
+AO.address is 0, and the second test in the macro reduces to:
+
+       P < ARENA_SIZE
+
+If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
+that P is not controlled by obmalloc.  However, if P < ARENA_SIZE, this part
+of the test still passes, and the third clause (AO.address != 0) is necessary
+to get the correct result:  AO.address is 0 in this case, so the macro
+correctly reports that P is not controlled by obmalloc (despite that P lies in
+slice AO.address : AO.address + ARENA_SIZE).
+
+Note:  The third (AO.address != 0) clause was added in Python 2.5.  Before
+2.5, arenas were never free()'ed, and an arenaindex < maxarena always
+corresponded to a currently-allocated arena, so the "P is not controlled by
+obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
+was impossible.
+
+Note that the logic is excruciating, and reading up possibly uninitialized
+memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
+creates problems for some memory debuggers.  The overwhelming advantage is
+that this test determines whether an arbitrary address is controlled by
+obmalloc in a small constant time, independent of the number of arenas
+obmalloc controls.  Since this test is needed at every entry point, it's
+extremely desirable that it be this fast.
+*/
+#define Py_ADDRESS_IN_RANGE(P, POOL)                   \
+       ((POOL)->arenaindex < maxarenas &&              \
+        (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \
+        arenas[(POOL)->arenaindex].address != 0)
+
 
 /* This is only useful when running memory debuggers such as
  * Purify or Valgrind.  Uncomment to use.
@@ -599,7 +733,7 @@ PyObject_Malloc(size_t nbytes)
                /*
                 * Most frequent paths first
                 */
-               size = (uint )(nbytes - 1) >> ALIGNMENT_SHIFT;
+               size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
                pool = usedpools[size + size];
                if (pool != pool->nextpool) {
                        /*
@@ -614,22 +748,18 @@ PyObject_Malloc(size_t nbytes)
                                return (void *)bp;
                        }
                        /*
-                        * Reached the end of the free list, try to extend it
+                        * Reached the end of the free list, try to extend it.
                         */
                        if (pool->nextoffset <= pool->maxnextoffset) {
-                               /*
-                                * There is room for another block
-                                */
-                               pool->freeblock = (block *)pool +
+                               /* There is room for another block. */
+                               pool->freeblock = (block*)pool +
                                                  pool->nextoffset;
                                pool->nextoffset += INDEX2SIZE(size);
                                *(block **)(pool->freeblock) = NULL;
                                UNLOCK();
                                return (void *)bp;
                        }
-                       /*
-                        * Pool is full, unlink from used pools
-                        */
+                       /* Pool is full, unlink from used pools. */
                        next = pool->nextpool;
                        pool = pool->prevpool;
                        next->prevpool = pool;
@@ -637,19 +767,68 @@ PyObject_Malloc(size_t nbytes)
                        UNLOCK();
                        return (void *)bp;
                }
-               /*
-                * Try to get a cached free pool
+
+               /* There isn't a pool of the right size class immediately
+                * available:  use a free pool.
                 */
-               pool = freepools;
+               if (usable_arenas == NULL) {
+                       /* No arena has a free pool:  allocate a new arena. */
+#ifdef WITH_MEMORY_LIMITS
+                       if (narenas_currently_allocated >= MAX_ARENAS) {
+                               UNLOCK();
+                               goto redirect;
+                       }
+#endif
+                       usable_arenas = new_arena();
+                       if (usable_arenas == NULL) {
+                               UNLOCK();
+                               goto redirect;
+                       }
+                       usable_arenas->nextarena =
+                               usable_arenas->prevarena = NULL;
+               }
+               assert(usable_arenas->address != 0);
+
+               /* Try to get a cached free pool. */
+               pool = usable_arenas->freepools;
                if (pool != NULL) {
-                       /*
-                        * Unlink from cached pools
+                       /* Unlink from cached pools. */
+                       usable_arenas->freepools = pool->nextpool;
+
+                       /* This arena already had the smallest nfreepools
+                        * value, so decreasing nfreepools doesn't change
+                        * that, and we don't need to rearrange the
+                        * usable_arenas list.  However, if the arena has
+                        * become wholly allocated, we need to remove its
+                        * arena_object from usable_arenas.
                         */
-                       freepools = pool->nextpool;
+                       --usable_arenas->nfreepools;
+                       if (usable_arenas->nfreepools == 0) {
+                               /* Wholly allocated:  remove. */
+                               assert(usable_arenas->freepools == NULL);
+                               assert(usable_arenas->nextarena == NULL ||
+                                      usable_arenas->nextarena->prevarena ==
+                                          usable_arenas);
+
+                               usable_arenas = usable_arenas->nextarena;
+                               if (usable_arenas != NULL) {
+                                       usable_arenas->prevarena = NULL;
+                                       assert(usable_arenas->address != 0);
+                               }
+                       }
+                       else {
+                               /* nfreepools > 0:  it must be that freepools
+                                * isn't NULL, or that we haven't yet carved
+                                * off all the arena's pools for the first
+                                * time.
+                                */
+                               assert(usable_arenas->freepools != NULL ||
+                                      usable_arenas->pool_address <=
+                                          (block*)usable_arenas->address +
+                                              ARENA_SIZE - POOL_SIZE);
+                       }
                init_pool:
-                       /*
-                        * Frontlink to used pools
-                        */
+                       /* Frontlink to used pools. */
                        next = usedpools[size + size]; /* == prev */
                        pool->nextpool = next;
                        pool->prevpool = next;
@@ -657,8 +836,7 @@ PyObject_Malloc(size_t nbytes)
                        next->prevpool = pool;
                        pool->ref.count = 1;
                        if (pool->szidx == size) {
-                               /*
-                                * Luckily, this pool last contained blocks
+                               /* Luckily, this pool last contained blocks
                                 * of the same size class, so its header
                                 * and free list are already initialized.
                                 */
@@ -682,39 +860,38 @@ PyObject_Malloc(size_t nbytes)
                        UNLOCK();
                        return (void *)bp;
                }
-               /*
-                * Allocate new pool
-                */
-               if (nfreepools) {
-               commit_pool:
-                       --nfreepools;
-                       pool = (poolp)arenabase;
-                       arenabase += POOL_SIZE;
-                       pool->arenaindex = narenas - 1;
-                       pool->szidx = DUMMY_SIZE_IDX;
-                       goto init_pool;
-               }
-               /*
-                * Allocate new arena
-                */
-#ifdef WITH_MEMORY_LIMITS
-               if (!(narenas < MAX_ARENAS)) {
-                       UNLOCK();
-                       goto redirect;
+
+               /* Carve off a new pool. */
+               assert(usable_arenas->nfreepools > 0);
+               assert(usable_arenas->freepools == NULL);
+               pool = (poolp)usable_arenas->pool_address;
+               assert((block*)pool <= (block*)usable_arenas->address +
+                                      ARENA_SIZE - POOL_SIZE);
+               pool->arenaindex = usable_arenas - arenas;
+               assert(&arenas[pool->arenaindex] == usable_arenas);
+               pool->szidx = DUMMY_SIZE_IDX;
+               usable_arenas->pool_address += POOL_SIZE;
+               --usable_arenas->nfreepools;
+
+               if (usable_arenas->nfreepools == 0) {
+                       assert(usable_arenas->nextarena == NULL ||
+                              usable_arenas->nextarena->prevarena ==
+                                  usable_arenas);
+                       /* Unlink the arena:  it is completely allocated. */
+                       usable_arenas = usable_arenas->nextarena;
+                       if (usable_arenas != NULL) {
+                               usable_arenas->prevarena = NULL;
+                               assert(usable_arenas->address != 0);
+                       }
                }
-#endif
-               bp = new_arena();
-               if (bp != NULL)
-                       goto commit_pool;
-               UNLOCK();
-               goto redirect;
+
+               goto init_pool;
        }
 
         /* The small block allocator ends here. */
 
 redirect:
-       /*
-        * Redirect the original request to the underlying (libc) allocator.
+       /* Redirect the original request to the underlying (libc) allocator.
         * We jump here on bigger requests, on error in the code above (as a
         * last chance to serve the request) or when the max memory limit
         * has been reached.
@@ -742,8 +919,7 @@ PyObject_Free(void *p)
        if (Py_ADDRESS_IN_RANGE(p, pool)) {
                /* We allocated this address. */
                LOCK();
-               /*
-                * Link p to the start of the pool's freeblock list.  Since
+               /* Link p to the start of the pool's freeblock list.  Since
                 * the pool had at least the p block outstanding, the pool
                 * wasn't empty (so it's already in a usedpools[] list, or
                 * was full and is in no list -- it's not in the freeblocks
@@ -753,8 +929,10 @@ PyObject_Free(void *p)
                *(block **)p = lastfree = pool->freeblock;
                pool->freeblock = (block *)p;
                if (lastfree) {
-                       /*
-                        * freeblock wasn't NULL, so the pool wasn't full,
+                       struct arena_object* ao;
+                       uint nf;  /* ao->nfreepools */
+
+                       /* freeblock wasn't NULL, so the pool wasn't full,
                         * and the pool is in a usedpools[] list.
                         */
                        if (--pool->ref.count != 0) {
@@ -762,8 +940,7 @@ PyObject_Free(void *p)
                                UNLOCK();
                                return;
                        }
-                       /*
-                        * Pool is now empty:  unlink from usedpools, and
+                       /* Pool is now empty:  unlink from usedpools, and
                         * link to the front of freepools.  This ensures that
                         * previously freed pools will be allocated later
                         * (being not referenced, they are perhaps paged out).
@@ -772,16 +949,147 @@ PyObject_Free(void *p)
                        prev = pool->prevpool;
                        next->prevpool = prev;
                        prev->nextpool = next;
-                       /* Link to freepools.  This is a singly-linked list,
-                        * and pool->prevpool isn't used there.
+
+                       /* Link the pool to freepools.  This is a singly-linked
+                        * list, and pool->prevpool isn't used there.
+                        */
+                       ao = &arenas[pool->arenaindex];
+                       pool->nextpool = ao->freepools;
+                       ao->freepools = pool;
+                       nf = ++ao->nfreepools;
+
+                       /* All the rest is arena management.  We just freed
+                        * a pool, and there are 4 cases for arena mgmt:
+                        * 1. If all the pools are free, return the arena to
+                        *    the system free().
+                        * 2. If this is the only free pool in the arena,
+                        *    add the arena back to the `usable_arenas` list.
+                        * 3. If the "next" arena has a smaller count of free
+                        *    pools, we have to "slide this arena right" to
+                        *    restore that usable_arenas is sorted in order of
+                        *    nfreepools.
+                        * 4. Else there's nothing more to do.
+                        */
+                       if (nf == ao->ntotalpools) {
+                               /* Case 1.  First unlink ao from usable_arenas.
+                                */
+                               assert(ao->prevarena == NULL ||
+                                      ao->prevarena->address != 0);
+                               assert(ao ->nextarena == NULL ||
+                                      ao->nextarena->address != 0);
+
+                               /* Fix the pointer in the prevarena, or the
+                                * usable_arenas pointer.
+                                */
+                               if (ao->prevarena == NULL) {
+                                       usable_arenas = ao->nextarena;
+                                       assert(usable_arenas == NULL ||
+                                              usable_arenas->address != 0);
+                               }
+                               else {
+                                       assert(ao->prevarena->nextarena == ao);
+                                       ao->prevarena->nextarena =
+                                               ao->nextarena;
+                               }
+                               /* Fix the pointer in the nextarena. */
+                               if (ao->nextarena != NULL) {
+                                       assert(ao->nextarena->prevarena == ao);
+                                       ao->nextarena->prevarena =
+                                               ao->prevarena;
+                               }
+                               /* Record that this arena_object slot is
+                                * available to be reused.
+                                */
+                               ao->nextarena = unused_arena_objects;
+                               unused_arena_objects = ao;
+
+                               /* Free the entire arena. */
+                               free((void *)ao->address);
+                               ao->address = 0;        /* mark unassociated */
+                               --narenas_currently_allocated;
+
+                               UNLOCK();
+                               return;
+                       }
+                       if (nf == 1) {
+                               /* Case 2.  Put ao at the head of
+                                * usable_arenas.  Note that because
+                                * ao->nfreepools was 0 before, ao isn't
+                                * currently on the usable_arenas list.
+                                */
+                               ao->nextarena = usable_arenas;
+                               ao->prevarena = NULL;
+                               if (usable_arenas)
+                                       usable_arenas->prevarena = ao;
+                               usable_arenas = ao;
+                               assert(usable_arenas->address != 0);
+
+                               UNLOCK();
+                               return;
+                       }
+                       /* If this arena is now out of order, we need to keep
+                        * the list sorted.  The list is kept sorted so that
+                        * the "most full" arenas are used first, which allows
+                        * the nearly empty arenas to be completely freed.  In
+                        * a few un-scientific tests, it seems like this
+                        * approach allowed a lot more memory to be freed.
+                        */
+                       if (ao->nextarena == NULL ||
+                                    nf <= ao->nextarena->nfreepools) {
+                               /* Case 4.  Nothing to do. */
+                               UNLOCK();
+                               return;
+                       }
+                       /* Case 3:  We have to move the arena towards the end
+                        * of the list, because it has more free pools than
+                        * the arena to its right.
+                        * First unlink ao from usable_arenas.
                         */
-                       pool->nextpool = freepools;
-                       freepools = pool;
+                       if (ao->prevarena != NULL) {
+                               /* ao isn't at the head of the list */
+                               assert(ao->prevarena->nextarena == ao);
+                               ao->prevarena->nextarena = ao->nextarena;
+                       }
+                       else {
+                               /* ao is at the head of the list */
+                               assert(usable_arenas == ao);
+                               usable_arenas = ao->nextarena;
+                       }
+                       ao->nextarena->prevarena = ao->prevarena;
+
+                       /* Locate the new insertion point by iterating over
+                        * the list, using our nextarena pointer.
+                        */
+                       while (ao->nextarena != NULL &&
+                                       nf > ao->nextarena->nfreepools) {
+                               ao->prevarena = ao->nextarena;
+                               ao->nextarena = ao->nextarena->nextarena;
+                       }
+
+                       /* Insert ao at this point. */
+                       assert(ao->nextarena == NULL ||
+                               ao->prevarena == ao->nextarena->prevarena);
+                       assert(ao->prevarena->nextarena == ao->nextarena);
+
+                       ao->prevarena->nextarena = ao;
+                       if (ao->nextarena != NULL)
+                               ao->nextarena->prevarena = ao;
+
+                       /* Verify that the swaps worked. */
+                       assert(ao->nextarena == NULL ||
+                                 nf <= ao->nextarena->nfreepools);
+                       assert(ao->prevarena == NULL ||
+                                 nf > ao->prevarena->nfreepools);
+                       assert(ao->nextarena == NULL ||
+                               ao->nextarena->prevarena == ao);
+                       assert((usable_arenas == ao &&
+                               ao->prevarena == NULL) ||
+                               ao->prevarena->nextarena == ao);
+
                        UNLOCK();
                        return;
                }
-               /*
-                * Pool was full, so doesn't currently live in any list:
+               /* Pool was full, so doesn't currently live in any list:
                 * link it to the front of the appropriate usedpools[] list.
                 * This mimics LRU pool usage for new allocations and
                 * targets optimal filling when several pools contain
@@ -1302,6 +1610,8 @@ _PyObject_DebugMallocStats(void)
         * full pools.
         */
        ulong quantization = 0;
+       /* # of arenas actually allocated. */
+       ulong narenas = 0;
        /* running total -- should equal narenas * ARENA_SIZE */
        ulong total;
        char buf[128];
@@ -1316,36 +1626,38 @@ _PyObject_DebugMallocStats(void)
         * to march over all the arenas.  If we're lucky, most of the memory
         * will be living in full pools -- would be a shame to miss them.
         */
-       for (i = 0; i < narenas; ++i) {
+       for (i = 0; i < maxarenas; ++i) {
                uint poolsinarena;
                uint j;
-               uptr base = arenas[i];
+               uptr base = arenas[i].address;
+
+               /* Skip arenas which are not allocated. */
+               if (arenas[i].address == (uptr)NULL)
+                       continue;
+               narenas += 1;
+
+               poolsinarena = arenas[i].ntotalpools;
+               numfreepools += arenas[i].nfreepools;
 
                /* round up to pool alignment */
-               poolsinarena = ARENA_SIZE / POOL_SIZE;
                if (base & (uptr)POOL_SIZE_MASK) {
-                       --poolsinarena;
                        arena_alignment += POOL_SIZE;
                        base &= ~(uptr)POOL_SIZE_MASK;
                        base += POOL_SIZE;
                }
 
-               if (i == narenas - 1) {
-                       /* current arena may have raw memory at the end */
-                       numfreepools += nfreepools;
-                       poolsinarena -= nfreepools;
-               }
-
                /* visit every pool in the arena */
-               for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
+               assert(base <= (uptr) arenas[i].pool_address);
+               for (j = 0;
+                           base < (uptr) arenas[i].pool_address;
+                           ++j, base += POOL_SIZE) {
                        poolp p = (poolp)base;
                        const uint sz = p->szidx;
                        uint freeblocks;
 
                        if (p->ref.count == 0) {
                                /* currently unused */
-                               ++numfreepools;
-                               assert(pool_is_in_list(p, freepools));
+                               assert(pool_is_in_list(p, arenas[i].freepools));
                                continue;
                        }
                        ++numpools[sz];
@@ -1358,6 +1670,7 @@ _PyObject_DebugMallocStats(void)
 #endif
                }
        }
+       assert(narenas == narenas_currently_allocated);
 
        fputc('\n', stderr);
        fputs("class   size   num pools   blocks in use  avail blocks\n"
@@ -1383,9 +1696,14 @@ _PyObject_DebugMallocStats(void)
        fputc('\n', stderr);
        (void)printone("# times object malloc called", serialno);
 
+       (void)printone("# arenas allocated total", ntimes_arena_allocated);
+       (void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
+       (void)printone("# arenas highwater mark", narenas_highwater);
+       (void)printone("# arenas allocated current", narenas);
+
        PyOS_snprintf(buf, sizeof(buf),
-               "%u arenas * %d bytes/arena", narenas, ARENA_SIZE);
-       (void)printone(buf, (ulong)narenas * ARENA_SIZE);
+               "%lu arenas * %d bytes/arena", narenas, ARENA_SIZE);
+       (void)printone(buf, narenas * ARENA_SIZE);
 
        fputc('\n', stderr);
 
@@ -1405,12 +1723,14 @@ _PyObject_DebugMallocStats(void)
 #endif /* PYMALLOC_DEBUG */
 
 #ifdef Py_USING_MEMORY_DEBUGGER
-/* Make this function last so gcc won't inline it
-   since the definition is after the reference. */
+/* Make this function last so gcc won't inline it since the definition is
+ * after the reference.
+ */
 int
 Py_ADDRESS_IN_RANGE(void *P, poolp pool)
 {
-       return ((pool->arenaindex) < narenas &&
-               (uptr)(P) - arenas[pool->arenaindex] < (uptr)ARENA_SIZE);
+       return pool->arenaindex < maxarenas &&
+              (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE &&
+              arenas[pool->arenaindex].address != 0;
 }
 #endif
index 253bc393260d385af191d697ba417e1f710fda6f..0e8c37498077466c65fa183bd4a6d7958ef9085b 100644 (file)
@@ -260,6 +260,56 @@ PyObject *PyCodec_Decoder(const char *encoding)
     return NULL;
 }
 
+PyObject *PyCodec_IncrementalEncoder(const char *encoding,
+                                    const char *errors)
+{
+    PyObject *codecs, *ret, *encoder;
+
+    codecs = _PyCodec_Lookup(encoding);
+    if (codecs == NULL)
+       goto onError;
+    encoder = PyObject_GetAttrString(codecs, "incrementalencoder");
+    if (encoder == NULL) {
+       Py_DECREF(codecs);
+       return NULL;
+    }
+    if (errors)
+       ret = PyObject_CallFunction(encoder, "O", errors);
+    else
+       ret = PyObject_CallFunction(encoder, NULL);
+    Py_DECREF(encoder);
+    Py_DECREF(codecs);
+    return ret;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyCodec_IncrementalDecoder(const char *encoding,
+                                    const char *errors)
+{
+    PyObject *codecs, *ret, *decoder;
+
+    codecs = _PyCodec_Lookup(encoding);
+    if (codecs == NULL)
+       goto onError;
+    decoder = PyObject_GetAttrString(codecs, "incrementaldecoder");
+    if (decoder == NULL) {
+       Py_DECREF(codecs);
+       return NULL;
+    }
+    if (errors)
+       ret = PyObject_CallFunction(decoder, "O", errors);
+    else
+       ret = PyObject_CallFunction(decoder, NULL);
+    Py_DECREF(decoder);
+    Py_DECREF(codecs);
+    return ret;
+
+ onError:
+    return NULL;
+}
+
 PyObject *PyCodec_StreamReader(const char *encoding,
                               PyObject *stream,
                               const char *errors)
index d28262e43c26f4769d37f51db4ac56ac791e77a1..4b949225d183bb0932359fda218140d8bcf2e598 100644 (file)
@@ -1,3 +1,6 @@
 @rem Used by the buildbot "clean" step.
 call "%VS71COMNTOOLS%vsvars32.bat"
-devenv.com /clean Debug PCbuild\pcbuild.sln
+cd PCbuild
+@echo Deleting .pyc/.pyo files ...
+python_d.exe rmpyc.py
+devenv.com /clean Debug pcbuild.sln
index 34a9df989bb7b8cca5f16ee205503874de2fb122..f266d4d218346e008fd58c12852f5ca091d137df 100644 (file)
@@ -44,11 +44,11 @@ windows:    build/
        $(RM) -f build/readme.*
 
 iso:   build/
-       $(PYTHON) gencodec.py MAPPINGS/ISO8859/ build/iso
+       $(PYTHON) gencodec.py MAPPINGS/ISO8859/ build/ iso
        $(RM) -f build/isoreadme.*
 
 apple: build/
-       $(PYTHON) gencodec.py MAPPINGS/VENDORS/APPLE/ build/mac_
+       $(PYTHON) gencodec.py MAPPINGS/VENDORS/APPLE/ build/ mac_
        $(RM) build/mac_dingbats.*
        $(RM) build/mac_japanese.*
        $(RM) build/mac_chin*
index 494164a6908ace515734c206ece77c1034c85bc5..bb1c9da5f0c9d030ef3abce5d98fa278d55c1fe1 100644 (file)
@@ -248,7 +248,7 @@ def python_tabledef_code(varname, map, comments=1, key_precision=2):
     append(')')
     return l
 
-def codegen(name, map, comments=1):
+def codegen(name, map, encodingname, comments=1):
 
     """ Returns Python source for the given map.
 
@@ -272,7 +272,7 @@ def codegen(name, map, comments=1):
 
     l = [
         '''\
-""" Python Character Mapping Codec generated from '%s' with gencodec.py.
+""" Python Character Mapping Codec %s generated from '%s' with gencodec.py.
 
 """#"
 
@@ -283,11 +283,9 @@ import codecs
 class Codec(codecs.Codec):
 
     def encode(self,input,errors='strict'):
-
         return codecs.charmap_encode(input,errors,encoding_map)
 
-    def decode(self,input,errors='strict'):
-''' % name
+    def decode(self,input,errors='strict'):''' % (encodingname, name)
         ]
     if decoding_table_code:
         l.append('''\
@@ -296,6 +294,20 @@ class Codec(codecs.Codec):
         l.append('''\
         return codecs.charmap_decode(input,errors,decoding_map)''')
 
+    l.append('''
+class IncrementalEncoder(codecs.IncrementalEncoder):
+    def encode(self, input, final=False):
+        return codecs.charmap_encode(input,self.errors,encoding_map)[0]
+
+class IncrementalDecoder(codecs.IncrementalDecoder):
+    def decode(self, input, final=False):''')
+    if decoding_table_code:
+        l.append('''\
+        return codecs.charmap_decode(input,self.errors,decoding_table)[0]''')
+    else:
+        l.append('''\
+        return codecs.charmap_decode(input,self.errors,decoding_map)[0]''')
+
     l.append('''
 class StreamWriter(Codec,codecs.StreamWriter):
     pass
@@ -306,9 +318,16 @@ class StreamReader(Codec,codecs.StreamReader):
 ### encodings module API
 
 def getregentry():
-
-    return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
-''')
+    return codecs.CodecInfo((
+        name=%r,
+        Codec().encode,
+        Codec().decode,
+        streamwriter=StreamWriter,
+        streamreader=StreamReader,
+        incrementalencoder=IncrementalEncoder,
+        incrementaldecoder=IncrementalDecoder,
+    ))
+''' % encodingname.replace('_', '-'))
 
     # Add decoding table or map (with preference to the table)
     if not decoding_table_code:
@@ -331,11 +350,11 @@ def getregentry():
     # Final new-line
     l.append('\n')
 
-    return '\n'.join(l)
+    return '\n'.join(l).expandtabs()
 
-def pymap(name,map,pyfile,comments=1):
+def pymap(name,map,pyfile,encodingname,comments=1):
 
-    code = codegen(name,map,comments)
+    code = codegen(name,map,encodingname,comments)
     f = open(pyfile,'w')
     f.write(code)
     f.close()
@@ -349,7 +368,7 @@ def marshalmap(name,map,marshalfile):
     marshal.dump(d,f)
     f.close()
 
-def convertdir(dir,prefix='',comments=1):
+def convertdir(dir, dirprefix='', nameprefix='', comments=1):
 
     mapnames = os.listdir(dir)
     for mapname in mapnames:
@@ -360,38 +379,40 @@ def convertdir(dir,prefix='',comments=1):
         name = name.replace('-','_')
         name = name.split('.')[0]
         name = name.lower()
+        name = nameprefix + name
         codefile = name + '.py'
         marshalfile = name + '.mapping'
         print 'converting %s to %s and %s' % (mapname,
-                                              prefix + codefile,
-                                              prefix + marshalfile)
+                                              dirprefix + codefile,
+                                              dirprefix + marshalfile)
         try:
             map = readmap(os.path.join(dir,mapname))
             if not map:
                 print '* map is empty; skipping'
             else:
-                pymap(mappathname, map, prefix + codefile,comments)
-                marshalmap(mappathname, map, prefix + marshalfile)
+                pymap(mappathname, map, dirprefix + codefile,name,comments)
+                marshalmap(mappathname, map, dirprefix + marshalfile)
         except ValueError, why:
             print '* conversion failed: %s' % why
             raise
 
-def rewritepythondir(dir,prefix='',comments=1):
+def rewritepythondir(dir, dirprefix='', comments=1):
 
     mapnames = os.listdir(dir)
     for mapname in mapnames:
         if not mapname.endswith('.mapping'):
             continue
-        codefile = mapname[:-len('.mapping')] + '.py'
+        name = mapname[:-len('.mapping')]
+        codefile = name + '.py'
         print 'converting %s to %s' % (mapname,
-                                       prefix + codefile)
+                                       dirprefix + codefile)
         try:
             map = marshal.load(open(os.path.join(dir,mapname),
                                'rb'))
             if not map:
                 print '* map is empty; skipping'
             else:
-                pymap(mapname, map, prefix + codefile,comments)
+                pymap(mapname, map, dirprefix + codefile,name,comments)
         except ValueError, why:
             print '* conversion failed: %s' % why