Remove the gopherlib module. It has been raising a DeprecationWarning since

Python 2.5.

Also remove gopher support from urllib/urllib2.  As both imported gopherlib the
usage of the support would have raised a DeprecationWarning.
This commit is contained in:
Brett Cannon 2007-05-16 22:42:29 +00:00
parent b1a9b37aa8
commit d75f043c33
12 changed files with 10 additions and 347 deletions

View File

@ -187,7 +187,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
lib/liburllib2.tex \ lib/liburllib2.tex \
lib/libhttplib.tex \ lib/libhttplib.tex \
lib/libftplib.tex \ lib/libftplib.tex \
lib/libgopherlib.tex \
lib/libnntplib.tex \ lib/libnntplib.tex \
lib/liburlparse.tex \ lib/liburlparse.tex \
lib/libhtmlparser.tex \ lib/libhtmlparser.tex \

View File

@ -297,7 +297,6 @@ and how to embed it in other applications.
\input{liburllib2} \input{liburllib2}
\input{libhttplib} \input{libhttplib}
\input{libftplib} \input{libftplib}
\input{libgopherlib}
\input{libpoplib} \input{libpoplib}
\input{libimaplib} \input{libimaplib}
\input{libnntplib} \input{libnntplib}

View File

@ -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.

View File

@ -70,8 +70,8 @@ see the \function{urlencode()} function below.
The \function{urlopen()} function works transparently with proxies The \function{urlopen()} function works transparently with proxies
which do not require authentication. In a \UNIX{} or Windows which do not require authentication. In a \UNIX{} or Windows
environment, set the \envvar{http_proxy}, \envvar{ftp_proxy} or environment, set the \envvar{http_proxy}, or \envvar{ftp_proxy}
\envvar{gopher_proxy} environment variables to a URL that identifies environment variables to a URL that identifies
the proxy server before starting the Python interpreter. For example the proxy server before starting the Python interpreter. For example
(the \character{\%} is the command prompt): (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}}} \begin{classdesc}{URLopener}{\optional{proxies\optional{, **x509}}}
Base class for opening and reading URLs. Unless you need to support Base class for opening and reading URLs. Unless you need to support
opening objects using schemes other than \file{http:}, \file{ftp:}, 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}. \class{FancyURLopener}.
By default, the \class{URLopener} class sends a By default, the \class{URLopener} class sends a
@ -324,9 +324,8 @@ Restrictions:
\item \item
Currently, only the following protocols are supported: HTTP, (versions 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{HTTP}{protocol}
\indexii{Gopher}{protocol}
\indexii{FTP}{protocol} \indexii{FTP}{protocol}
\item \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 (such as an image), plain text or (for example) HTML\index{HTML}. The
HTTP\indexii{HTTP}{protocol} protocol provides type information in the HTTP\indexii{HTTP}{protocol} protocol provides type information in the
reply header, which can be inspected by looking at the reply header, which can be inspected by looking at the
\mailheader{Content-Type} header. For the \mailheader{Content-Type} header. If the
Gopher\indexii{Gopher}{protocol} protocol, type information is encoded
in the URL; there is currently no easy way to extract it. If the
returned data is HTML, you can use the module returned data is HTML, you can use the module
\refmodule{htmllib}\refstmodindex{htmllib} to parse it. \refmodule{htmllib}\refstmodindex{htmllib} to parse it.

View File

@ -86,11 +86,6 @@ non-exceptional file-like return value (the same thing that
HTTP errors, such as requests for authentication. HTTP errors, such as requests for authentication.
\end{excdesc} \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: The following classes are provided:
@ -241,10 +236,6 @@ Open FTP URLs, keeping a cache of open FTP connections to minimize
delays. delays.
\end{classdesc} \end{classdesc}
\begin{classdesc}{GopherHandler}{}
Open gopher URLs.
\end{classdesc}
\begin{classdesc}{UnknownHandler}{} \begin{classdesc}{UnknownHandler}{}
A catch-all class to handle unknown URLs. A catch-all class to handle unknown URLs.
\end{classdesc} \end{classdesc}
@ -744,13 +735,6 @@ Set maximum number of cached connections to \var{m}.
\end{methoddesc} \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}} \subsection{UnknownHandler Objects \label{unknown-handler-objects}}
\begin{methoddesc}[UnknownHandler]{unknown_open}{} \begin{methoddesc}[UnknownHandler]{unknown_open}{}

View File

@ -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()

View File

@ -3,10 +3,6 @@ from test.test_support import verbose, run_unittest
import sys import sys
import warnings import warnings
warnings.filterwarnings("ignore",
"the gopherlib module is deprecated",
DeprecationWarning,
"<string>")
warnings.filterwarnings("ignore", "the sets module is deprecated", warnings.filterwarnings("ignore", "the sets module is deprecated",
DeprecationWarning, "<string>") DeprecationWarning, "<string>")
warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*", warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*",
@ -84,7 +80,6 @@ class AllTest(unittest.TestCase):
self.check_all("getpass") self.check_all("getpass")
self.check_all("gettext") self.check_all("gettext")
self.check_all("glob") self.check_all("glob")
self.check_all("gopherlib")
self.check_all("gzip") self.check_all("gzip")
self.check_all("heapq") self.check_all("heapq")
self.check_all("htmllib") self.check_all("htmllib")

View File

@ -4,11 +4,6 @@ import warnings
warnings.filterwarnings('ignore', r".*posixfile module", warnings.filterwarnings('ignore', r".*posixfile module",
DeprecationWarning, 'posixfile$') DeprecationWarning, 'posixfile$')
warnings.filterwarnings("ignore",
"the gopherlib module is deprecated",
DeprecationWarning,
".*test_sundry")
from test.test_support import verbose from test.test_support import verbose
import BaseHTTPServer import BaseHTTPServer
@ -27,7 +22,6 @@ import encodings
import formatter import formatter
import ftplib import ftplib
import getpass import getpass
import gopherlib
import htmlentitydefs import htmlentitydefs
import ihooks import ihooks
import imghdr import imghdr

View File

@ -173,19 +173,6 @@ class OtherNetworkTests(unittest.TestCase):
] ]
self._test_urls(urls, self._extra_handlers()) 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): def test_file(self):
TESTFN = test_support.TESTFN TESTFN = test_support.TESTFN
f = open(TESTFN, 'w') f = open(TESTFN, 'w')
@ -274,8 +261,6 @@ class OtherNetworkTests(unittest.TestCase):
def _extra_handlers(self): def _extra_handlers(self):
handlers = [] handlers = []
handlers.append(urllib2.GopherHandler)
cfh = urllib2.CacheFTPHandler() cfh = urllib2.CacheFTPHandler()
cfh.setTimeout(1) cfh.setTimeout(1)
handlers.append(cfh) handlers.append(cfh)

View File

@ -35,7 +35,7 @@ __all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
"localhost", "thishost", "ftperrors", "basejoin", "unwrap", "localhost", "thishost", "ftperrors", "basejoin", "unwrap",
"splittype", "splithost", "splituser", "splitpasswd", "splitport", "splittype", "splithost", "splituser", "splitpasswd", "splitport",
"splitnport", "splitquery", "splitattr", "splitvalue", "splitnport", "splitquery", "splitattr", "splitvalue",
"splitgophertype", "getproxies"] "getproxies"]
__version__ = '1.17' # XXX This version is not always updated :-( __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, return self.http_error(url, fp, errcode, errmsg, headers,
data) 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): def open_file(self, url):
"""Use local file or FTP depending on form of URL.""" """Use local file or FTP depending on form of URL."""
if not isinstance(url, str): if not isinstance(url, str):
@ -981,7 +963,6 @@ class addinfourl(addbase):
# splitattr('/path;attr1=value1;attr2=value2;...') -> # splitattr('/path;attr1=value1;attr2=value2;...') ->
# '/path', ['attr1=value1', 'attr2=value2', ...] # '/path', ['attr1=value1', 'attr2=value2', ...]
# splitvalue('attr=value') --> 'attr', 'value' # splitvalue('attr=value') --> 'attr', 'value'
# splitgophertype('/Xselector') --> 'X', 'selector'
# unquote('abc%20def') -> 'abc def' # unquote('abc%20def') -> 'abc def'
# quote('abc def') -> 'abc%20def') # quote('abc def') -> 'abc%20def')
@ -1141,12 +1122,6 @@ def splitvalue(attr):
if match: return match.group(1, 2) if match: return match.group(1, 2)
return attr, None 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 = dict(('%02x' % i, chr(i)) for i in range(256))
_hextochr.update(('%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:/etc/passwd',
'file://localhost/etc/passwd', 'file://localhost/etc/passwd',
'ftp://ftp.gnu.org/pub/README', 'ftp://ftp.gnu.org/pub/README',
## 'gopher://gopher.micro.umn.edu/1/',
'http://www.python.org/index.html', 'http://www.python.org/index.html',
] ]
if hasattr(URLopener, "open_https"): if hasattr(URLopener, "open_https"):

View File

@ -107,7 +107,7 @@ except ImportError:
from StringIO import StringIO from StringIO import StringIO
from urllib import (unwrap, unquote, splittype, splithost, quote, from urllib import (unwrap, unquote, splittype, splithost, quote,
addinfourl, splitport, splitgophertype, splitquery, addinfourl, splitport, splitquery,
splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue) splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue)
# support for FileHandler, proxies via environment variables # support for FileHandler, proxies via environment variables
@ -164,9 +164,6 @@ class HTTPError(URLError, addinfourl):
def __str__(self): def __str__(self):
return 'HTTP Error %s: %s' % (self.code, self.msg) return 'HTTP Error %s: %s' % (self.code, self.msg)
class GopherError(URLError):
pass
# copied from cookielib.py # copied from cookielib.py
_cut_port_re = re.compile(r":\d+$") _cut_port_re = re.compile(r":\d+$")
def request_host(request): def request_host(request):
@ -1342,22 +1339,3 @@ class CacheFTPHandler(FTPHandler):
del self.timeout[k] del self.timeout[k]
break break
self.soonest = min(self.timeout.values()) 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())

View File

@ -207,6 +207,9 @@ Core and builtins
Library 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 - Fix bug in marshal where bad data would cause a segfault due to
lack of an infinite recursion check. lack of an infinite recursion check.