From d3343cb8a1bae607541ae0b567eecccefbf0051b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 12 May 2008 03:18:21 +0000 Subject: Remove the multifile module as deprecated by PEP 4. --- Doc/library/multifile.rst | 191 ---------------------------------------------- Doc/library/netdata.rst | 1 - Lib/multifile.py | 158 -------------------------------------- Misc/NEWS | 2 + 4 files changed, 2 insertions(+), 350 deletions(-) delete mode 100644 Doc/library/multifile.rst delete mode 100644 Lib/multifile.py diff --git a/Doc/library/multifile.rst b/Doc/library/multifile.rst deleted file mode 100644 index 0614b86..0000000 --- a/Doc/library/multifile.rst +++ /dev/null @@ -1,191 +0,0 @@ - -:mod:`multifile` --- Support for files containing distinct parts -================================================================ - -.. module:: multifile - :synopsis: Support for reading files which contain distinct parts, such as some MIME data. - :deprecated: -.. sectionauthor:: Eric S. Raymond - - -.. deprecated:: 2.5 - The :mod:`email` package should be used in preference to the :mod:`multifile` - module. This module is present only to maintain backward compatibility. - -The :class:`MultiFile` object enables you to treat sections of a text file as -file-like input objects, with ``''`` being returned by :meth:`readline` when a -given delimiter pattern is encountered. The defaults of this class are designed -to make it useful for parsing MIME multipart messages, but by subclassing it and -overriding methods it can be easily adapted for more general use. - - -.. class:: MultiFile(fp[, seekable]) - - Create a multi-file. You must instantiate this class with an input object - argument for the :class:`MultiFile` instance to get lines from, such as a file - object returned by :func:`open`. - - :class:`MultiFile` only ever looks at the input object's :meth:`readline`, - :meth:`seek` and :meth:`tell` methods, and the latter two are only needed if you - want random access to the individual MIME parts. To use :class:`MultiFile` on a - non-seekable stream object, set the optional *seekable* argument to false; this - will prevent using the input object's :meth:`seek` and :meth:`tell` methods. - -It will be useful to know that in :class:`MultiFile`'s view of the world, text -is composed of three kinds of lines: data, section-dividers, and end-markers. -MultiFile is designed to support parsing of messages that may have multiple -nested message parts, each with its own pattern for section-divider and -end-marker lines. - - -.. seealso:: - - Module :mod:`email` - Comprehensive email handling package; supersedes the :mod:`multifile` module. - - -.. _multifile-objects: - -MultiFile Objects ------------------ - -A :class:`MultiFile` instance has the following methods: - - -.. method:: MultiFile.readline(str) - - Read a line. If the line is data (not a section-divider or end-marker or real - EOF) return it. If the line matches the most-recently-stacked boundary, return - ``''`` and set ``self.last`` to 1 or 0 according as the match is or is not an - end-marker. If the line matches any other stacked boundary, raise an error. On - encountering end-of-file on the underlying stream object, the method raises - :exc:`Error` unless all boundaries have been popped. - - -.. method:: MultiFile.readlines(str) - - Return all lines remaining in this part as a list of strings. - - -.. method:: MultiFile.read() - - Read all lines, up to the next section. Return them as a single (multiline) - string. Note that this doesn't take a size argument! - - -.. method:: MultiFile.seek(pos[, whence]) - - Seek. Seek indices are relative to the start of the current section. The *pos* - and *whence* arguments are interpreted as for a file seek. - - -.. method:: MultiFile.tell() - - Return the file position relative to the start of the current section. - - -.. method:: MultiFile.next() - - Skip lines to the next section (that is, read lines until a section-divider or - end-marker has been consumed). Return true if there is such a section, false if - an end-marker is seen. Re-enable the most-recently-pushed boundary. - - -.. method:: MultiFile.is_data(str) - - Return true if *str* is data and false if it might be a section boundary. As - written, it tests for a prefix other than ``'-``\ ``-'`` at start of line (which - all MIME boundaries have) but it is declared so it can be overridden in derived - classes. - - Note that this test is used intended as a fast guard for the real boundary - tests; if it always returns false it will merely slow processing, not cause it - to fail. - - -.. method:: MultiFile.push(str) - - Push a boundary string. When a decorated version of this boundary is found as - an input line, it will be interpreted as a section-divider or end-marker - (depending on the decoration, see :rfc:`2045`). All subsequent reads will - return the empty string to indicate end-of-file, until a call to :meth:`pop` - removes the boundary a or :meth:`next` call reenables it. - - It is possible to push more than one boundary. Encountering the - most-recently-pushed boundary will return EOF; encountering any other - boundary will raise an error. - - -.. method:: MultiFile.pop() - - Pop a section boundary. This boundary will no longer be interpreted as EOF. - - -.. method:: MultiFile.section_divider(str) - - Turn a boundary into a section-divider line. By default, this method - prepends ``'--'`` (which MIME section boundaries have) but it is declared so - it can be overridden in derived classes. This method need not append LF or - CR-LF, as comparison with the result ignores trailing whitespace. - - -.. method:: MultiFile.end_marker(str) - - Turn a boundary string into an end-marker line. By default, this method - prepends ``'--'`` and appends ``'--'`` (like a MIME-multipart end-of-message - marker) but it is declared so it can be overridden in derived classes. This - method need not append LF or CR-LF, as comparison with the result ignores - trailing whitespace. - -Finally, :class:`MultiFile` instances have two public instance variables: - - -.. attribute:: MultiFile.level - - Nesting depth of the current part. - - -.. attribute:: MultiFile.last - - True if the last end-of-file was for an end-of-message marker. - - -.. _multifile-example: - -:class:`MultiFile` Example --------------------------- - -.. sectionauthor:: Skip Montanaro - - -:: - - import mimetools - import multifile - import StringIO - - def extract_mime_part_matching(stream, mimetype): - """Return the first element in a multipart MIME message on stream - matching mimetype.""" - - msg = mimetools.Message(stream) - msgtype = msg.gettype() - params = msg.getplist() - - data = StringIO.StringIO() - if msgtype[:10] == "multipart/": - - file = multifile.MultiFile(stream) - file.push(msg.getparam("boundary")) - while file.next(): - submsg = mimetools.Message(file) - try: - data = StringIO.StringIO() - mimetools.decode(file, data, submsg.getencoding()) - except ValueError: - continue - if submsg.gettype() == mimetype: - break - file.pop() - return data.getvalue() - diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index b331e24..076c214 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -17,7 +17,6 @@ on the Internet. mailbox.rst mimetools.rst mimetypes.rst - multifile.rst rfc822.rst base64.rst binhex.rst diff --git a/Lib/multifile.py b/Lib/multifile.py deleted file mode 100644 index c94d06b..0000000 --- a/Lib/multifile.py +++ /dev/null @@ -1,158 +0,0 @@ -"""A readline()-style interface to the parts of a multipart message. - -The MultiFile class makes each part of a multipart message "feel" like -an ordinary file, as long as you use fp.readline(). Allows recursive -use, for nested multipart messages. Probably best used together -with module mimetools. - -Suggested use: - -real_fp = open(...) -fp = MultiFile(real_fp) - -"read some lines from fp" -fp.push(separator) -while 1: - "read lines from fp until it returns an empty string" (A) - if not fp.next(): break -fp.pop() -"read remaining lines from fp until it returns an empty string" - -The latter sequence may be used recursively at (A). -It is also allowed to use multiple push()...pop() sequences. - -If seekable is given as 0, the class code will not do the bookkeeping -it normally attempts in order to make seeks relative to the beginning of the -current file part. This may be useful when using MultiFile with a non- -seekable stream object. -""" - -__all__ = ["MultiFile","Error"] - -class Error(Exception): - pass - -class MultiFile: - - seekable = 0 - - def __init__(self, fp, seekable=1): - self.fp = fp - self.stack = [] - self.level = 0 - self.last = 0 - if seekable: - self.seekable = 1 - self.start = self.fp.tell() - self.posstack = [] - - def tell(self): - if self.level > 0: - return self.lastpos - return self.fp.tell() - self.start - - def seek(self, pos, whence=0): - here = self.tell() - if whence: - if whence == 1: - pos = pos + here - elif whence == 2: - if self.level > 0: - pos = pos + self.lastpos - else: - raise Error("can't use whence=2 yet") - if not 0 <= pos <= here or \ - self.level > 0 and pos > self.lastpos: - raise Error('bad MultiFile.seek() call') - self.fp.seek(pos + self.start) - self.level = 0 - self.last = 0 - - def readline(self): - if self.level > 0: - return '' - line = self.fp.readline() - # Real EOF? - if not line: - self.level = len(self.stack) - self.last = (self.level > 0) - if self.last: - raise Error('sudden EOF in MultiFile.readline()') - return '' - assert self.level == 0 - # Fast check to see if this is just data - if self.is_data(line): - return line - else: - # Ignore trailing whitespace on marker lines - marker = line.rstrip() - # No? OK, try to match a boundary. - # Return the line (unstripped) if we don't. - for i, sep in enumerate(reversed(self.stack)): - if marker == self.section_divider(sep): - self.last = 0 - break - elif marker == self.end_marker(sep): - self.last = 1 - break - else: - return line - # We only get here if we see a section divider or EOM line - if self.seekable: - self.lastpos = self.tell() - len(line) - self.level = i+1 - if self.level > 1: - raise Error('Missing endmarker in MultiFile.readline()') - return '' - - def readlines(self): - list = [] - while 1: - line = self.readline() - if not line: break - list.append(line) - return list - - def read(self): # Note: no size argument -- read until EOF only! - return ''.join(self.readlines()) - - def next(self): - while self.readline(): pass - if self.level > 1 or self.last: - return 0 - self.level = 0 - self.last = 0 - if self.seekable: - self.start = self.fp.tell() - return 1 - - def push(self, sep): - if self.level > 0: - raise Error('bad MultiFile.push() call') - self.stack.append(sep) - if self.seekable: - self.posstack.append(self.start) - self.start = self.fp.tell() - - def pop(self): - if self.stack == []: - raise Error('bad MultiFile.pop() call') - if self.level <= 1: - self.last = 0 - else: - abslastpos = self.lastpos + self.start - self.level = max(0, self.level - 1) - self.stack.pop() - if self.seekable: - self.start = self.posstack.pop() - if self.level > 0: - self.lastpos = abslastpos - self.start - - def is_data(self, line): - return line[:2] != '--' - - def section_divider(self, str): - return "--" + str - - def end_marker(self, str): - return "--" + str + "--" diff --git a/Misc/NEWS b/Misc/NEWS index cfd3770..0af5a10 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -21,6 +21,8 @@ Extension Modules Library ------- +- The multifile module has been removed. + - The SocketServer module has been renamed to socketserver. - Fix the __all__ setting on 'collections' to include UserList and UserString. -- cgit v0.12