diff --git a/Doc/Makefile.deps b/Doc/Makefile.deps index c973d3496f5..1827ab3c320 100644 --- a/Doc/Makefile.deps +++ b/Doc/Makefile.deps @@ -187,7 +187,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ lib/liburllib2.tex \ lib/libhttplib.tex \ lib/libftplib.tex \ - lib/libgopherlib.tex \ lib/libnntplib.tex \ lib/liburlparse.tex \ lib/libhtmlparser.tex \ diff --git a/Doc/lib/lib.tex b/Doc/lib/lib.tex index addf91c26f5..30d05faa38a 100644 --- a/Doc/lib/lib.tex +++ b/Doc/lib/lib.tex @@ -297,7 +297,6 @@ and how to embed it in other applications. \input{liburllib2} \input{libhttplib} \input{libftplib} -\input{libgopherlib} \input{libpoplib} \input{libimaplib} \input{libnntplib} diff --git a/Doc/lib/libgopherlib.tex b/Doc/lib/libgopherlib.tex deleted file mode 100644 index 4b22605314a..00000000000 --- a/Doc/lib/libgopherlib.tex +++ /dev/null @@ -1,36 +0,0 @@ -\section{\module{gopherlib} --- - Gopher protocol client} - -\declaremodule{standard}{gopherlib} -\modulesynopsis{Gopher protocol client (requires sockets).} - -\deprecated{2.5}{The \code{gopher} protocol is not in active use - anymore.} - -\indexii{Gopher}{protocol} - -This module provides a minimal implementation of client side of the -Gopher protocol. It is used by the module \refmodule{urllib} to -handle URLs that use the Gopher protocol. - -The module defines the following functions: - -\begin{funcdesc}{send_selector}{selector, host\optional{, port}} -Send a \var{selector} string to the gopher server at \var{host} and -\var{port} (default \code{70}). Returns an open file object from -which the returned document can be read. -\end{funcdesc} - -\begin{funcdesc}{send_query}{selector, query, host\optional{, port}} -Send a \var{selector} string and a \var{query} string to a gopher -server at \var{host} and \var{port} (default \code{70}). Returns an -open file object from which the returned document can be read. -\end{funcdesc} - -Note that the data returned by the Gopher server can be of any type, -depending on the first character of the selector string. If the data -is text (first character of the selector is \samp{0}), lines are -terminated by CRLF, and the data is terminated by a line consisting of -a single \samp{.}, and a leading \samp{.} should be stripped from -lines that begin with \samp{..}. Directory listings (first character -of the selector is \samp{1}) are transferred using the same protocol. diff --git a/Doc/lib/liburllib.tex b/Doc/lib/liburllib.tex index 75ee310d512..77dfb8fac8e 100644 --- a/Doc/lib/liburllib.tex +++ b/Doc/lib/liburllib.tex @@ -70,8 +70,8 @@ see the \function{urlencode()} function below. The \function{urlopen()} function works transparently with proxies which do not require authentication. In a \UNIX{} or Windows -environment, set the \envvar{http_proxy}, \envvar{ftp_proxy} or -\envvar{gopher_proxy} environment variables to a URL that identifies +environment, set the \envvar{http_proxy}, or \envvar{ftp_proxy} +environment variables to a URL that identifies the proxy server before starting the Python interpreter. For example (the \character{\%} is the command prompt): @@ -253,7 +253,7 @@ function uses \function{unquote()} to decode \var{path}. \begin{classdesc}{URLopener}{\optional{proxies\optional{, **x509}}} Base class for opening and reading URLs. Unless you need to support opening objects using schemes other than \file{http:}, \file{ftp:}, -\file{gopher:} or \file{file:}, you probably want to use +or \file{file:}, you probably want to use \class{FancyURLopener}. By default, the \class{URLopener} class sends a @@ -324,9 +324,8 @@ Restrictions: \item Currently, only the following protocols are supported: HTTP, (versions -0.9 and 1.0), Gopher (but not Gopher-+), FTP, and local files. +0.9 and 1.0), FTP, and local files. \indexii{HTTP}{protocol} -\indexii{Gopher}{protocol} \indexii{FTP}{protocol} \item @@ -355,9 +354,7 @@ is the raw data returned by the server. This may be binary data (such as an image), plain text or (for example) HTML\index{HTML}. The HTTP\indexii{HTTP}{protocol} protocol provides type information in the reply header, which can be inspected by looking at the -\mailheader{Content-Type} header. For the -Gopher\indexii{Gopher}{protocol} protocol, type information is encoded -in the URL; there is currently no easy way to extract it. If the +\mailheader{Content-Type} header. If the returned data is HTML, you can use the module \refmodule{htmllib}\refstmodindex{htmllib} to parse it. diff --git a/Doc/lib/liburllib2.tex b/Doc/lib/liburllib2.tex index f6ff513e647..0df73859ba8 100644 --- a/Doc/lib/liburllib2.tex +++ b/Doc/lib/liburllib2.tex @@ -86,11 +86,6 @@ non-exceptional file-like return value (the same thing that HTTP errors, such as requests for authentication. \end{excdesc} -\begin{excdesc}{GopherError} -A subclass of \exception{URLError}, this is the error raised by the -Gopher handler. -\end{excdesc} - The following classes are provided: @@ -241,10 +236,6 @@ Open FTP URLs, keeping a cache of open FTP connections to minimize delays. \end{classdesc} -\begin{classdesc}{GopherHandler}{} -Open gopher URLs. -\end{classdesc} - \begin{classdesc}{UnknownHandler}{} A catch-all class to handle unknown URLs. \end{classdesc} @@ -744,13 +735,6 @@ Set maximum number of cached connections to \var{m}. \end{methoddesc} -\subsection{GopherHandler Objects \label{gopher-handler}} - -\begin{methoddesc}[GopherHandler]{gopher_open}{req} -Open the gopher resource indicated by \var{req}. -\end{methoddesc} - - \subsection{UnknownHandler Objects \label{unknown-handler-objects}} \begin{methoddesc}[UnknownHandler]{unknown_open}{} diff --git a/Lib/gopherlib.py b/Lib/gopherlib.py deleted file mode 100644 index d789161e60a..00000000000 --- a/Lib/gopherlib.py +++ /dev/null @@ -1,209 +0,0 @@ -"""Gopher protocol client interface.""" - -__all__ = ["send_selector","send_query"] - -import warnings -warnings.warn("the gopherlib module is deprecated", DeprecationWarning, - stacklevel=2) - -# Default selector, host and port -DEF_SELECTOR = '1/' -DEF_HOST = 'gopher.micro.umn.edu' -DEF_PORT = 70 - -# Recognized file types -A_TEXT = '0' -A_MENU = '1' -A_CSO = '2' -A_ERROR = '3' -A_MACBINHEX = '4' -A_PCBINHEX = '5' -A_UUENCODED = '6' -A_INDEX = '7' -A_TELNET = '8' -A_BINARY = '9' -A_DUPLICATE = '+' -A_SOUND = 's' -A_EVENT = 'e' -A_CALENDAR = 'c' -A_HTML = 'h' -A_TN3270 = 'T' -A_MIME = 'M' -A_IMAGE = 'I' -A_WHOIS = 'w' -A_QUERY = 'q' -A_GIF = 'g' -A_HTML = 'h' # HTML file -A_WWW = 'w' # WWW address -A_PLUS_IMAGE = ':' -A_PLUS_MOVIE = ';' -A_PLUS_SOUND = '<' - - -_names = dir() -_type_to_name_map = {} -def type_to_name(gtype): - """Map all file types to strings; unknown types become TYPE='x'.""" - global _type_to_name_map - if _type_to_name_map=={}: - for name in _names: - if name[:2] == 'A_': - _type_to_name_map[eval(name)] = name[2:] - if gtype in _type_to_name_map: - return _type_to_name_map[gtype] - return 'TYPE=%r' % (gtype,) - -# Names for characters and strings -CRLF = '\r\n' -TAB = '\t' - -def send_selector(selector, host, port = 0): - """Send a selector to a given host and port, return a file with the reply.""" - import socket - if not port: - i = host.find(':') - if i >= 0: - host, port = host[:i], int(host[i+1:]) - if not port: - port = DEF_PORT - elif type(port) == type(''): - port = int(port) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - s.sendall(selector + CRLF) - s.shutdown(1) - return s.makefile('rb') - -def send_query(selector, query, host, port = 0): - """Send a selector and a query string.""" - return send_selector(selector + '\t' + query, host, port) - -def path_to_selector(path): - """Takes a path as returned by urlparse and returns the appropriate selector.""" - if path=="/": - return "/" - else: - return path[2:] # Cuts initial slash and data type identifier - -def path_to_datatype_name(path): - """Takes a path as returned by urlparse and maps it to a string. - See section 3.4 of RFC 1738 for details.""" - if path=="/": - # No way to tell, although "INDEX" is likely - return "TYPE='unknown'" - else: - return type_to_name(path[1]) - -# The following functions interpret the data returned by the gopher -# server according to the expected type, e.g. textfile or directory - -def get_directory(f): - """Get a directory in the form of a list of entries.""" - entries = [] - while 1: - line = f.readline() - if not line: - print '(Unexpected EOF from server)' - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if not line: - print '(Empty line from server)' - continue - gtype = line[0] - parts = line[1:].split(TAB) - if len(parts) < 4: - print '(Bad line from server: %r)' % (line,) - continue - if len(parts) > 4: - if parts[4:] != ['+']: - print '(Extra info from server:', - print parts[4:], ')' - else: - parts.append('') - parts.insert(0, gtype) - entries.append(parts) - return entries - -def get_textfile(f): - """Get a text file as a list of lines, with trailing CRLF stripped.""" - lines = [] - get_alt_textfile(f, lines.append) - return lines - -def get_alt_textfile(f, func): - """Get a text file and pass each line to a function, with trailing CRLF stripped.""" - while 1: - line = f.readline() - if not line: - print '(Unexpected EOF from server)' - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if line[:2] == '..': - line = line[1:] - func(line) - -def get_binary(f): - """Get a binary file as one solid data block.""" - data = f.read() - return data - -def get_alt_binary(f, func, blocksize): - """Get a binary file and pass each block to a function.""" - while 1: - data = f.read(blocksize) - if not data: - break - func(data) - -def test(): - """Trivial test program.""" - import sys - import getopt - opts, args = getopt.getopt(sys.argv[1:], '') - selector = DEF_SELECTOR - type = selector[0] - host = DEF_HOST - if args: - host = args[0] - args = args[1:] - if args: - type = args[0] - args = args[1:] - if len(type) > 1: - type, selector = type[0], type - else: - selector = '' - if args: - selector = args[0] - args = args[1:] - query = '' - if args: - query = args[0] - args = args[1:] - if type == A_INDEX: - f = send_query(selector, query, host) - else: - f = send_selector(selector, host) - if type == A_TEXT: - lines = get_textfile(f) - for item in lines: print item - elif type in (A_MENU, A_INDEX): - entries = get_directory(f) - for item in entries: print item - else: - data = get_binary(f) - print 'binary data:', len(data), 'bytes:', repr(data[:100])[:40] - -# Run the test when run as script -if __name__ == '__main__': - test() diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 2b9f1dedea4..14795a6e603 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -3,10 +3,6 @@ from test.test_support import verbose, run_unittest import sys import warnings -warnings.filterwarnings("ignore", - "the gopherlib module is deprecated", - DeprecationWarning, - "") warnings.filterwarnings("ignore", "the sets module is deprecated", DeprecationWarning, "") warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*", @@ -84,7 +80,6 @@ class AllTest(unittest.TestCase): self.check_all("getpass") self.check_all("gettext") self.check_all("glob") - self.check_all("gopherlib") self.check_all("gzip") self.check_all("heapq") self.check_all("htmllib") diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index f19467c7672..42ee2574bb5 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -4,11 +4,6 @@ import warnings warnings.filterwarnings('ignore', r".*posixfile module", DeprecationWarning, 'posixfile$') -warnings.filterwarnings("ignore", - "the gopherlib module is deprecated", - DeprecationWarning, - ".*test_sundry") - from test.test_support import verbose import BaseHTTPServer @@ -27,7 +22,6 @@ import encodings import formatter import ftplib import getpass -import gopherlib import htmlentitydefs import ihooks import imghdr diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index 888a738901c..e76301e3e76 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -173,19 +173,6 @@ class OtherNetworkTests(unittest.TestCase): ] self._test_urls(urls, self._extra_handlers()) - def test_gopher(self): - import warnings - warnings.filterwarnings("ignore", - "the gopherlib module is deprecated", - DeprecationWarning, - "urllib2$") - urls = [ - # Thanks to Fred for finding these! - 'gopher://gopher.lib.ncsu.edu./11/library/stacks/Alex', - 'gopher://gopher.vt.edu.:10010/10/33', - ] - self._test_urls(urls, self._extra_handlers()) - def test_file(self): TESTFN = test_support.TESTFN f = open(TESTFN, 'w') @@ -274,8 +261,6 @@ class OtherNetworkTests(unittest.TestCase): def _extra_handlers(self): handlers = [] - handlers.append(urllib2.GopherHandler) - cfh = urllib2.CacheFTPHandler() cfh.setTimeout(1) handlers.append(cfh) diff --git a/Lib/urllib.py b/Lib/urllib.py index 7b2f1f74258..cecfbb0f0de 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -35,7 +35,7 @@ __all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve", "localhost", "thishost", "ftperrors", "basejoin", "unwrap", "splittype", "splithost", "splituser", "splitpasswd", "splitport", "splitnport", "splitquery", "splitattr", "splitvalue", - "splitgophertype", "getproxies"] + "getproxies"] __version__ = '1.17' # XXX This version is not always updated :-( @@ -433,24 +433,6 @@ class URLopener: return self.http_error(url, fp, errcode, errmsg, headers, data) - def open_gopher(self, url): - """Use Gopher protocol.""" - if not isinstance(url, str): - raise IOError, ('gopher error', 'proxy support for gopher protocol currently not implemented') - import gopherlib - host, selector = splithost(url) - if not host: raise IOError, ('gopher error', 'no host given') - host = unquote(host) - type, selector = splitgophertype(selector) - selector, query = splitquery(selector) - selector = unquote(selector) - if query: - query = unquote(query) - fp = gopherlib.send_query(selector, query, host) - else: - fp = gopherlib.send_selector(selector, host) - return addinfourl(fp, noheaders(), "gopher:" + url) - def open_file(self, url): """Use local file or FTP depending on form of URL.""" if not isinstance(url, str): @@ -981,7 +963,6 @@ class addinfourl(addbase): # splitattr('/path;attr1=value1;attr2=value2;...') -> # '/path', ['attr1=value1', 'attr2=value2', ...] # splitvalue('attr=value') --> 'attr', 'value' -# splitgophertype('/Xselector') --> 'X', 'selector' # unquote('abc%20def') -> 'abc def' # quote('abc def') -> 'abc%20def') @@ -1141,12 +1122,6 @@ def splitvalue(attr): if match: return match.group(1, 2) return attr, None -def splitgophertype(selector): - """splitgophertype('/Xselector') --> 'X', 'selector'.""" - if selector[:1] == '/' and selector[1:2]: - return selector[1], selector[2:] - return None, selector - _hextochr = dict(('%02x' % i, chr(i)) for i in range(256)) _hextochr.update(('%02X' % i, chr(i)) for i in range(256)) @@ -1482,7 +1457,6 @@ def test(args=[]): 'file:/etc/passwd', 'file://localhost/etc/passwd', 'ftp://ftp.gnu.org/pub/README', -## 'gopher://gopher.micro.umn.edu/1/', 'http://www.python.org/index.html', ] if hasattr(URLopener, "open_https"): diff --git a/Lib/urllib2.py b/Lib/urllib2.py index 6bfbc29772c..fe32b2d6520 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -107,7 +107,7 @@ except ImportError: from StringIO import StringIO from urllib import (unwrap, unquote, splittype, splithost, quote, - addinfourl, splitport, splitgophertype, splitquery, + addinfourl, splitport, splitquery, splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue) # support for FileHandler, proxies via environment variables @@ -164,9 +164,6 @@ class HTTPError(URLError, addinfourl): def __str__(self): return 'HTTP Error %s: %s' % (self.code, self.msg) -class GopherError(URLError): - pass - # copied from cookielib.py _cut_port_re = re.compile(r":\d+$") def request_host(request): @@ -1342,22 +1339,3 @@ class CacheFTPHandler(FTPHandler): del self.timeout[k] break self.soonest = min(self.timeout.values()) - -class GopherHandler(BaseHandler): - def gopher_open(self, req): - # XXX can raise socket.error - import gopherlib # this raises DeprecationWarning in 2.5 - host = req.get_host() - if not host: - raise GopherError('no host given') - host = unquote(host) - selector = req.get_selector() - type, selector = splitgophertype(selector) - selector, query = splitquery(selector) - selector = unquote(selector) - if query: - query = unquote(query) - fp = gopherlib.send_query(selector, query, host) - else: - fp = gopherlib.send_selector(selector, host) - return addinfourl(fp, noheaders(), req.get_full_url()) diff --git a/Misc/NEWS b/Misc/NEWS index eefa1816baf..fabd5f436db 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -207,6 +207,9 @@ Core and builtins Library ------- +- Remove the gopherlib module. This also leads to the removal of gopher + support in urllib/urllib2. + - Fix bug in marshal where bad data would cause a segfault due to lack of an infinite recursion check.