Skip to content

Commit

Permalink
Merge 8926-rem-strportparse: Remove twisted.application.strports.parse
Browse files Browse the repository at this point in the history
Author: hawkowl
Reviewer: moshez
Fixes: twisted#8926
  • Loading branch information
hawkowl authored Nov 29, 2016
2 parents 889a4db + 3915b41 commit 160ecab
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 221 deletions.
73 changes: 19 additions & 54 deletions src/twisted/application/strports.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,95 +11,60 @@

from __future__ import absolute_import, division

import warnings

from incremental import Version

from twisted.application.internet import StreamServerEndpointService
from twisted.internet import endpoints
from twisted.python.deprecate import deprecatedModuleAttribute



def parse(description, factory, default='tcp'):
"""
This function is deprecated as of Twisted 10.2.
@see: L{twisted.internet.endpoints.serverFromString}
"""
return endpoints._parseServer(description, factory, default)

deprecatedModuleAttribute(
Version("Twisted", 10, 2, 0),
"in favor of twisted.internet.endpoints.serverFromString",
__name__, "parse")



_DEFAULT = object()

def service(description, factory, default=_DEFAULT, reactor=None):
def service(description, factory, reactor=None):
"""
Return the service corresponding to a description.
@param description: The description of the listening port, in the syntax
described by L{twisted.internet.endpoints.serverFromString}.
@type description: C{str}
@param factory: The protocol factory which will build protocols for
connections to this service.
@type factory: L{twisted.internet.interfaces.IProtocolFactory}
@type default: C{str} or L{None}
@param default: Do not use this parameter. It has been deprecated since
Twisted 10.2.0.
@rtype: C{twisted.application.service.IService}
@return: the service corresponding to a description of a reliable
stream server.
@return: the service corresponding to a description of a reliable stream
server.
@see: L{twisted.internet.endpoints.serverFromString}
"""
if reactor is None:
from twisted.internet import reactor
if default is _DEFAULT:
default = None
else:
message = "The 'default' parameter was deprecated in Twisted 10.2.0."
if default is not None:
message += (
" Use qualified endpoint descriptions; for example, "
"'tcp:%s'." % (description,))
warnings.warn(
message=message, category=DeprecationWarning, stacklevel=2)

svc = StreamServerEndpointService(
endpoints._serverFromStringLegacy(reactor, description, default),
factory)
endpoints.serverFromString(reactor, description), factory)
svc._raiseSynchronously = True
return svc



def listen(description, factory, default=None):
"""Listen on a port corresponding to a description
def listen(description, factory):
"""
Listen on a port corresponding to a description.
@param description: The description of the connecting port, in the syntax
described by L{twisted.internet.endpoints.serverFromString}.
@type description: L{str}
@param factory: The protocol factory which will build protocols on
connection.
@type factory: L{twisted.internet.interfaces.IProtocolFactory}
@type default: L{str} or L{None}
@rtype: L{twisted.internet.interfaces.IListeningPort}
@return: the port corresponding to a description of a reliable
virtual circuit server.
@return: the port corresponding to a description of a reliable virtual
circuit server.
@see: L{twisted.internet.endpoints.serverFromString}
"""
from twisted.internet import reactor
name, args, kw = endpoints._parseServer(description, factory, default)
return getattr(reactor, 'listen'+name)(*args, **kw)
name, args, kw = endpoints._parseServer(description, factory)
return getattr(reactor, 'listen' + name)(*args, **kw)



__all__ = ['parse', 'service', 'listen']
__all__ = ['service', 'listen']
6 changes: 3 additions & 3 deletions src/twisted/conch/test/test_manhole_tap.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_telnetPort(self):
L{manhole_tap.makeService} will make a telnet service on the port
defined by C{--telnetPort}. It will not make a SSH service.
"""
self.options.parseOptions(["--telnetPort", "222"])
self.options.parseOptions(["--telnetPort", "tcp:222"])
service = manhole_tap.makeService(self.options)
self.assertIsInstance(service, MultiService)
self.assertEqual(len(service.services), 1)
Expand All @@ -92,7 +92,7 @@ def test_sshPort(self):
# which will never be used in a temp directory.
self.options.parseOptions(["--sshKeyDir", self.mktemp(),
"--sshKeySize", "512",
"--sshPort", "223"])
"--sshPort", "tcp:223"])
service = manhole_tap.makeService(self.options)
self.assertIsInstance(service, MultiService)
self.assertEqual(len(service.services), 1)
Expand All @@ -106,7 +106,7 @@ def test_passwd(self):
"""
The C{--passwd} command-line option will load a passwd-like file.
"""
self.options.parseOptions(['--telnetPort', '22',
self.options.parseOptions(['--telnetPort', 'tcp:22',
'--passwd', self.filename])
service = manhole_tap.makeService(self.options)
portal = service.services[0].factory.protocol.portal
Expand Down
54 changes: 10 additions & 44 deletions src/twisted/internet/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import os
import re
import socket
import warnings

from constantly import NamedConstant, Names

Expand Down Expand Up @@ -1377,9 +1376,7 @@ def add(sofar):
}


_NO_DEFAULT = object()

def _parseServer(description, factory, default=None):
def _parseServer(description, factory):
"""
Parse a strports description into a 2-tuple of arguments and keyword
values.
Expand All @@ -1392,28 +1389,9 @@ def _parseServer(description, factory, default=None):
twisted.application.strports, it's not really used.
@type factory: L{IProtocolFactory} or L{None}
@param default: Deprecated argument, specifying the default parser mode to
use for unqualified description strings (those which do not have a ':'
and prefix).
@type default: C{str} or L{None}
@return: a 3-tuple of (plugin or name, arguments, keyword arguments)
"""
args, kw = _parse(description)
if not args or (len(args) == 1 and not kw):
deprecationMessage = (
"Unqualified strport description passed to 'service'."
"Use qualified endpoint descriptions; for example, 'tcp:%s'."
% (description,))
if default is None:
default = 'tcp'
warnings.warn(
deprecationMessage, category=DeprecationWarning, stacklevel=4)
elif default is _NO_DEFAULT:
raise ValueError(deprecationMessage)
# If the default has been otherwise specified, the user has already
# been warned.
args[0:0] = [default]
endpointType = args[0]
parser = _serverParsers.get(endpointType)
if parser is None:
Expand All @@ -1427,23 +1405,6 @@ def _parseServer(description, factory, default=None):



def _serverFromStringLegacy(reactor, description, default):
"""
Underlying implementation of L{serverFromString} which avoids exposing the
deprecated 'default' argument to anything but L{strports.service}.
"""
nameOrPlugin, args, kw = _parseServer(description, None, default)
if type(nameOrPlugin) is not str:
plugin = nameOrPlugin
return plugin.parseStreamServer(reactor, *args, **kw)
else:
name = nameOrPlugin
# Chop out the factory.
args = args[:1] + args[2:]
return _endpointServerFactories[name](reactor, *args, **kw)



def _matchPluginToPrefix(plugins, endpointType):
"""
Match plugin to prefix.
Expand Down Expand Up @@ -1519,7 +1480,15 @@ def serverFromString(reactor, description):
@since: 10.2
"""
return _serverFromStringLegacy(reactor, description, _NO_DEFAULT)
nameOrPlugin, args, kw = _parseServer(description, None)
if type(nameOrPlugin) is not str:
plugin = nameOrPlugin
return plugin.parseStreamServer(reactor, *args, **kw)
else:
name = nameOrPlugin
# Chop out the factory.
args = args[:1] + args[2:]
return _endpointServerFactories[name](reactor, *args, **kw)



Expand Down Expand Up @@ -2050,6 +2019,3 @@ def parseStreamClient(reactor, *args, **kwargs):
@rtype: L{IStreamClientEndpoint}
"""
return _parseClientTLS(reactor, *args, **kwargs)



29 changes: 0 additions & 29 deletions src/twisted/internet/test/test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2450,18 +2450,6 @@ def test_impliedEscape(self):
{'mode': 0o666, 'backlog': 50, 'wantPID': True}))


def test_nonstandardDefault(self):
"""
For compatibility with the old L{twisted.application.strports.parse},
the third 'mode' argument may be specified to L{endpoints.parse} to
indicate a default other than TCP.
"""
self.assertEqual(
self.parse('filename', self.f, 'unix'),
('UNIX', ('filename', self.f),
{'mode': 0o666, 'backlog': 50, 'wantPID': True}))


def test_unknownType(self):
"""
L{strports.parse} raises C{ValueError} when given an unknown endpoint
Expand Down Expand Up @@ -2633,23 +2621,6 @@ def test_unix(self):
self.assertTrue(endpoint._wantPID)


def test_implicitDefaultNotAllowed(self):
"""
The older service-based API (L{twisted.internet.strports.service})
allowed an implicit default of 'tcp' so that TCP ports could be
specified as a simple integer, but we've since decided that's a bad
idea, and the new API does not accept an implicit default argument; you
have to say 'tcp:' now. If you try passing an old implicit port number
to the new API, you'll get a C{ValueError}.
"""
value = self.assertRaises(
ValueError, endpoints.serverFromString, None, "4321")
self.assertEqual(
str(value),
"Unqualified strport description passed to 'service'."
"Use qualified endpoint descriptions; for example, 'tcp:4321'.")


def test_unknownType(self):
"""
L{endpoints.serverFromString} raises C{ValueError} when given an
Expand Down
91 changes: 2 additions & 89 deletions src/twisted/test/test_strports.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,8 @@
from twisted.trial.unittest import TestCase
from twisted.application import strports
from twisted.application import internet
from twisted.internet.test.test_endpoints import ParserTests
from twisted.internet.protocol import Factory
from twisted.internet.endpoints import TCP4ServerEndpoint, UNIXServerEndpoint
from twisted.python.compat import _PY3



class DeprecatedParseTests(ParserTests):
"""
L{strports.parse} is deprecated. It's an alias for a method that is now
private in L{twisted.internet.endpoints}.
"""

def parse(self, *a, **kw):
result = strports.parse(*a, **kw)
warnings = self.flushWarnings([self.parse])
self.assertEqual(len(warnings), 1)
self.assertEqual(
warnings[0]['message'],
"twisted.application.strports.parse was deprecated "
"in Twisted 10.2.0: in favor of "
"twisted.internet.endpoints.serverFromString")
return result


def test_simpleNumeric(self):
"""
Base numeric ports should be parsed as TCP.
"""
self.assertEqual(self.parse('80', self.f),
('TCP', (80, self.f), {'interface':'', 'backlog':50}))


def test_allKeywords(self):
"""
A collection of keyword arguments with no prefixed type, like 'port=80',
will be parsed as keyword arguments to 'tcp'.
"""
self.assertEqual(self.parse('port=80', self.f),
('TCP', (80, self.f), {'interface':'', 'backlog':50}))

from twisted.internet.endpoints import TCP4ServerEndpoint


class ServiceTests(TestCase):
Expand All @@ -68,7 +29,7 @@ def test_service(self):
aFactory = Factory()
aGoodPort = 1337
svc = strports.service(
'tcp:'+str(aGoodPort), aFactory, reactor=reactor)
'tcp:' + str(aGoodPort), aFactory, reactor=reactor)
self.assertIsInstance(svc, internet.StreamServerEndpointService)

# See twisted.application.test.test_internet.EndpointServiceTests.
Expand All @@ -89,51 +50,3 @@ def test_serviceDefaultReactor(self):
from twisted.internet import reactor as globalReactor
aService = strports.service("tcp:80", None)
self.assertIs(aService.endpoint._reactor, globalReactor)


def test_serviceDeprecatedDefault(self):
"""
L{strports.service} still accepts a 'default' argument, which will
affect the parsing of 'default' (i.e. 'not containing a colon')
endpoint descriptions, but this behavior is deprecated.
"""
svc = strports.service("8080", None, "unix")
self.assertIsInstance(svc.endpoint, UNIXServerEndpoint)
warnings = self.flushWarnings([self.test_serviceDeprecatedDefault])
self.assertEqual(warnings[0]['category'], DeprecationWarning)
self.assertEqual(
warnings[0]['message'],
"The 'default' parameter was deprecated in Twisted 10.2.0. "
"Use qualified endpoint descriptions; for example, 'tcp:8080'.")
self.assertEqual(len(warnings), 1)

# Almost the same case, but slightly tricky - explicitly passing the
# old default value, None, also must trigger a deprecation warning.
svc = strports.service("tcp:8080", None, None)
self.assertIsInstance(svc.endpoint, TCP4ServerEndpoint)
warnings = self.flushWarnings([self.test_serviceDeprecatedDefault])
self.assertEqual(warnings[0]['category'], DeprecationWarning)
self.assertEqual(
warnings[0]['message'],
"The 'default' parameter was deprecated in Twisted 10.2.0.")
self.assertEqual(len(warnings), 1)


def test_serviceDeprecatedUnqualified(self):
"""
Unqualified strport descriptions, i.e. "8080", are deprecated.
"""
svc = strports.service("8080", None)
self.assertIsInstance(svc.endpoint, TCP4ServerEndpoint)
warnings = self.flushWarnings(
[self.test_serviceDeprecatedUnqualified])
self.assertEqual(warnings[0]['category'], DeprecationWarning)
self.assertEqual(
warnings[0]['message'],
"Unqualified strport description passed to 'service'."
"Use qualified endpoint descriptions; for example, 'tcp:8080'.")
self.assertEqual(len(warnings), 1)


if _PY3:
del DeprecatedParseTests
1 change: 1 addition & 0 deletions src/twisted/topfiles/8926.removal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
twisted.application.strports.parse, as well as the deprecated default arguments in strports.service/listen, deprecated since Twisted 10.2, has been removed.
Loading

0 comments on commit 160ecab

Please sign in to comment.