From 71c9b81bb7e8c0488c495e62ad2e7d6d98bde57d Mon Sep 17 00:00:00 2001 From: eevel Date: Mon, 24 Oct 2022 21:21:37 -0500 Subject: [PATCH] remove twisted.protocols.dict --- src/twisted/newsfragments/11725.removal | 1 + src/twisted/protocols/__init__.py | 11 - src/twisted/protocols/dict.py | 388 ------------------------ src/twisted/test/test_dict.py | 55 ---- 4 files changed, 1 insertion(+), 454 deletions(-) create mode 100644 src/twisted/newsfragments/11725.removal delete mode 100644 src/twisted/protocols/dict.py delete mode 100644 src/twisted/test/test_dict.py diff --git a/src/twisted/newsfragments/11725.removal b/src/twisted/newsfragments/11725.removal new file mode 100644 index 00000000000..c682b5626f3 --- /dev/null +++ b/src/twisted/newsfragments/11725.removal @@ -0,0 +1 @@ +twisted.protocol.dict, which was deprecated in 17.9, was now removed. diff --git a/src/twisted/protocols/__init__.py b/src/twisted/protocols/__init__.py index 0c879b2ba5d..d5286f79592 100644 --- a/src/twisted/protocols/__init__.py +++ b/src/twisted/protocols/__init__.py @@ -4,14 +4,3 @@ """ Twisted Protocols: A collection of internet protocol implementations. """ - -from incremental import Version - -from twisted.python.deprecate import deprecatedModuleAttribute - -deprecatedModuleAttribute( - Version("Twisted", 17, 9, 0), - "There is no replacement for this module.", - "twisted.protocols", - "dict", -) diff --git a/src/twisted/protocols/dict.py b/src/twisted/protocols/dict.py deleted file mode 100644 index f92737682af..00000000000 --- a/src/twisted/protocols/dict.py +++ /dev/null @@ -1,388 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - - -""" -Dict client protocol implementation. - -@author: Pavel Pergamenshchik -""" - -from io import BytesIO - -from twisted.internet import defer, protocol -from twisted.protocols import basic -from twisted.python import log - - -def parseParam(line): - """Chew one dqstring or atom from beginning of line and return (param, remaningline)""" - if line == b"": - return (None, b"") - elif line[0:1] != b'"': # atom - mode = 1 - else: # dqstring - mode = 2 - res = b"" - io = BytesIO(line) - if mode == 2: # skip the opening quote - io.read(1) - while 1: - a = io.read(1) - if a == b'"': - if mode == 2: - io.read(1) # skip the separating space - return (res, io.read()) - elif a == b"\\": - a = io.read(1) - if a == b"": - return (None, line) # unexpected end of string - elif a == b"": - if mode == 1: - return (res, io.read()) - else: - return (None, line) # unexpected end of string - elif a == b" ": - if mode == 1: - return (res, io.read()) - res += a - - -def makeAtom(line): - """Munch a string into an 'atom'""" - # FIXME: proper quoting - return filter(lambda x: not (x in map(chr, range(33) + [34, 39, 92])), line) - - -def makeWord(s): - mustquote = range(33) + [34, 39, 92] - result = [] - for c in s: - if ord(c) in mustquote: - result.append(b"\\") - result.append(c) - s = b"".join(result) - return s - - -def parseText(line): - if len(line) == 1 and line == b".": - return None - else: - if len(line) > 1 and line[0:2] == b"..": - line = line[1:] - return line - - -class Definition: - """A word definition""" - - def __init__(self, name, db, dbdesc, text): - self.name = name - self.db = db - self.dbdesc = dbdesc - self.text = text # list of strings not terminated by newline - - -class DictClient(basic.LineReceiver): - """dict (RFC2229) client""" - - data = None # multiline data - MAX_LENGTH = 1024 - state = None - mode = None - result = None - factory = None - - def __init__(self): - self.data = None - self.result = None - - def connectionMade(self): - self.state = "conn" - self.mode = "command" - - def sendLine(self, line): - """Throw up if the line is longer than 1022 characters""" - if len(line) > self.MAX_LENGTH - 2: - raise ValueError("DictClient tried to send a too long line") - basic.LineReceiver.sendLine(self, line) - - def lineReceived(self, line): - try: - line = line.decode("utf-8") - except UnicodeError: # garbage received, skip - return - if self.mode == "text": # we are receiving textual data - code = "text" - else: - if len(line) < 4: - log.msg("DictClient got invalid line from server -- %s" % line) - self.protocolError("Invalid line from server") - self.transport.LoseConnection() - return - code = int(line[:3]) - line = line[4:] - method = getattr(self, f"dictCode_{code}_{self.state}", self.dictCode_default) - method(line) - - def dictCode_default(self, line): - """Unknown message""" - log.msg("DictClient got unexpected message from server -- %s" % line) - self.protocolError("Unexpected server message") - self.transport.loseConnection() - - def dictCode_221_ready(self, line): - """We are about to get kicked off, do nothing""" - pass - - def dictCode_220_conn(self, line): - """Greeting message""" - self.state = "ready" - self.dictConnected() - - def dictCode_530_conn(self): - self.protocolError("Access denied") - self.transport.loseConnection() - - def dictCode_420_conn(self): - self.protocolError("Server temporarily unavailable") - self.transport.loseConnection() - - def dictCode_421_conn(self): - self.protocolError("Server shutting down at operator request") - self.transport.loseConnection() - - def sendDefine(self, database, word): - """Send a dict DEFINE command""" - assert ( - self.state == "ready" - ), "DictClient.sendDefine called when not in ready state" - self.result = ( - None # these two are just in case. In "ready" state, result and data - ) - self.data = None # should be None - self.state = "define" - command = "DEFINE {} {}".format( - makeAtom(database.encode("UTF-8")), - makeWord(word.encode("UTF-8")), - ) - self.sendLine(command) - - def sendMatch(self, database, strategy, word): - """Send a dict MATCH command""" - assert ( - self.state == "ready" - ), "DictClient.sendMatch called when not in ready state" - self.result = None - self.data = None - self.state = "match" - command = "MATCH {} {} {}".format( - makeAtom(database), - makeAtom(strategy), - makeAtom(word), - ) - self.sendLine(command.encode("UTF-8")) - - def dictCode_550_define(self, line): - """Invalid database""" - self.mode = "ready" - self.defineFailed("Invalid database") - - def dictCode_550_match(self, line): - """Invalid database""" - self.mode = "ready" - self.matchFailed("Invalid database") - - def dictCode_551_match(self, line): - """Invalid strategy""" - self.mode = "ready" - self.matchFailed("Invalid strategy") - - def dictCode_552_define(self, line): - """No match""" - self.mode = "ready" - self.defineFailed("No match") - - def dictCode_552_match(self, line): - """No match""" - self.mode = "ready" - self.matchFailed("No match") - - def dictCode_150_define(self, line): - """n definitions retrieved""" - self.result = [] - - def dictCode_151_define(self, line): - """Definition text follows""" - self.mode = "text" - (word, line) = parseParam(line) - (db, line) = parseParam(line) - (dbdesc, line) = parseParam(line) - if not (word and db and dbdesc): - self.protocolError("Invalid server response") - self.transport.loseConnection() - else: - self.result.append(Definition(word, db, dbdesc, [])) - self.data = [] - - def dictCode_152_match(self, line): - """n matches found, text follows""" - self.mode = "text" - self.result = [] - self.data = [] - - def dictCode_text_define(self, line): - """A line of definition text received""" - res = parseText(line) - if res == None: - self.mode = "command" - self.result[-1].text = self.data - self.data = None - else: - self.data.append(line) - - def dictCode_text_match(self, line): - """One line of match text received""" - - def l(s): - p1, t = parseParam(s) - p2, t = parseParam(t) - return (p1, p2) - - res = parseText(line) - if res == None: - self.mode = "command" - self.result = map(l, self.data) - self.data = None - else: - self.data.append(line) - - def dictCode_250_define(self, line): - """ok""" - t = self.result - self.result = None - self.state = "ready" - self.defineDone(t) - - def dictCode_250_match(self, line): - """ok""" - t = self.result - self.result = None - self.state = "ready" - self.matchDone(t) - - def protocolError(self, reason): - """override to catch unexpected dict protocol conditions""" - pass - - def dictConnected(self): - """override to be notified when the server is ready to accept commands""" - pass - - def defineFailed(self, reason): - """override to catch reasonable failure responses to DEFINE""" - pass - - def defineDone(self, result): - """override to catch successful DEFINE""" - pass - - def matchFailed(self, reason): - """override to catch reasonable failure responses to MATCH""" - pass - - def matchDone(self, result): - """override to catch successful MATCH""" - pass - - -class InvalidResponse(Exception): - pass - - -class DictLookup(DictClient): - """Utility class for a single dict transaction. To be used with DictLookupFactory""" - - def protocolError(self, reason): - if not self.factory.done: - self.factory.d.errback(InvalidResponse(reason)) - self.factory.clientDone() - - def dictConnected(self): - if self.factory.queryType == "define": - self.sendDefine(*self.factory.param) - elif self.factory.queryType == "match": - self.sendMatch(*self.factory.param) - - def defineFailed(self, reason): - self.factory.d.callback([]) - self.factory.clientDone() - self.transport.loseConnection() - - def defineDone(self, result): - self.factory.d.callback(result) - self.factory.clientDone() - self.transport.loseConnection() - - def matchFailed(self, reason): - self.factory.d.callback([]) - self.factory.clientDone() - self.transport.loseConnection() - - def matchDone(self, result): - self.factory.d.callback(result) - self.factory.clientDone() - self.transport.loseConnection() - - -class DictLookupFactory(protocol.ClientFactory): - """Utility factory for a single dict transaction""" - - protocol = DictLookup - done = None - - def __init__(self, queryType, param, d): - self.queryType = queryType - self.param = param - self.d = d - self.done = 0 - - def clientDone(self): - """Called by client when done.""" - self.done = 1 - del self.d - - def clientConnectionFailed(self, connector, error): - self.d.errback(error) - - def clientConnectionLost(self, connector, error): - if not self.done: - self.d.errback(error) - - def buildProtocol(self, addr): - p = self.protocol() - p.factory = self - return p - - -def define(host, port, database, word): - """Look up a word using a dict server""" - d = defer.Deferred() - factory = DictLookupFactory("define", (database, word), d) - - from twisted.internet import reactor - - reactor.connectTCP(host, port, factory) - return d - - -def match(host, port, database, strategy, word): - """Match a word using a dict server""" - d = defer.Deferred() - factory = DictLookupFactory("match", (database, strategy, word), d) - - from twisted.internet import reactor - - reactor.connectTCP(host, port, factory) - return d diff --git a/src/twisted/test/test_dict.py b/src/twisted/test/test_dict.py deleted file mode 100644 index 7ba28526d1a..00000000000 --- a/src/twisted/test/test_dict.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - - -from twisted.protocols import dict -from twisted.trial import unittest -from twisted.trial.unittest import SynchronousTestCase - -paramString = b'"This is a dqstring \\w\\i\\t\\h boring stuff like: \\"" and t\\hes\\"e are a\\to\\ms' -goodparams = [ - b'This is a dqstring with boring stuff like: "', - b"and", - b'thes"e', - b"are", - b"atoms", -] - - -class ParamTests(unittest.TestCase): - def testParseParam(self): - """Testing command response handling""" - params = [] - rest = paramString - while 1: - (param, rest) = dict.parseParam(rest) - if param == None: - break - params.append(param) - self.assertEqual( - params, goodparams - ) # , "DictClient.parseParam returns unexpected results") - - -class DictDeprecationTests(SynchronousTestCase): - """ - L{twisted.protocols.dict} is deprecated. - """ - - def test_dictDeprecation(self): - """ - L{twisted.protocols.dict} is deprecated since Twisted 17.9.0. - """ - from twisted.protocols import dict - - dict - - warningsShown = self.flushWarnings([self.test_dictDeprecation]) - self.assertEqual(1, len(warningsShown)) - self.assertEqual( - ( - "twisted.protocols.dict was deprecated in Twisted 17.9.0:" - " There is no replacement for this module." - ), - warningsShown[0]["message"], - )