fix error namespace for ComponentXMPP
in SlixTest, if mode=="component", restore jabber:client namespace afterwards Fixes #3476 Fixes #3474
This commit is contained in:
parent
4fa068da54
commit
e16f72d32d
@ -9,13 +9,14 @@
|
|||||||
import logging
|
import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
from slixmpp import Message, Iq, Presence
|
||||||
from slixmpp.basexmpp import BaseXMPP
|
from slixmpp.basexmpp import BaseXMPP
|
||||||
from slixmpp.stanza import Handshake
|
from slixmpp.stanza import Handshake
|
||||||
|
from slixmpp.stanza.error import Error
|
||||||
from slixmpp.xmlstream import XMLStream
|
from slixmpp.xmlstream import XMLStream
|
||||||
from slixmpp.xmlstream import ET
|
|
||||||
from slixmpp.xmlstream.matcher import MatchXPath
|
from slixmpp.xmlstream.matcher import MatchXPath
|
||||||
from slixmpp.xmlstream.handler import Callback
|
from slixmpp.xmlstream.handler import Callback
|
||||||
|
from slixmpp.xmlstream.stanzabase import register_stanza_plugin
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -39,9 +40,17 @@ class ComponentXMPP(BaseXMPP):
|
|||||||
should be used instead of the standard
|
should be used instead of the standard
|
||||||
``'jabber:component:accept'`` namespace.
|
``'jabber:component:accept'`` namespace.
|
||||||
Defaults to ``False``.
|
Defaults to ``False``.
|
||||||
|
:param fix_error_ns: Fix the namespace of error stanzas.
|
||||||
|
If you use ``use_jc_ns`` namespace, you probably want that, but
|
||||||
|
it can be a problem if you use both a ClientXMPP and a ComponentXMPP
|
||||||
|
in the same interpreter. This is ``False`` by default for backwards
|
||||||
|
compatibility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, jid, secret, host=None, port=None, plugin_config=None, plugin_whitelist=None, use_jc_ns=False):
|
def __init__(self, jid, secret,
|
||||||
|
host=None, port=None, plugin_config=None,
|
||||||
|
plugin_whitelist=None, use_jc_ns=False,
|
||||||
|
fix_error_ns=False):
|
||||||
|
|
||||||
if not plugin_whitelist:
|
if not plugin_whitelist:
|
||||||
plugin_whitelist = []
|
plugin_whitelist = []
|
||||||
@ -52,6 +61,8 @@ class ComponentXMPP(BaseXMPP):
|
|||||||
default_ns = 'jabber:client'
|
default_ns = 'jabber:client'
|
||||||
else:
|
else:
|
||||||
default_ns = 'jabber:component:accept'
|
default_ns = 'jabber:component:accept'
|
||||||
|
if fix_error_ns:
|
||||||
|
self._fix_error_ns()
|
||||||
BaseXMPP.__init__(self, jid, default_ns)
|
BaseXMPP.__init__(self, jid, default_ns)
|
||||||
|
|
||||||
self.auto_authorize = None
|
self.auto_authorize = None
|
||||||
@ -77,6 +88,11 @@ class ComponentXMPP(BaseXMPP):
|
|||||||
self.add_event_handler('presence_probe',
|
self.add_event_handler('presence_probe',
|
||||||
self._handle_probe)
|
self._handle_probe)
|
||||||
|
|
||||||
|
def _fix_error_ns(self):
|
||||||
|
Error.namespace = self.default_ns
|
||||||
|
for st in Message, Iq, Presence:
|
||||||
|
register_stanza_plugin(st, Error)
|
||||||
|
|
||||||
def connect(self, host=None, port=None, use_ssl=False):
|
def connect(self, host=None, port=None, use_ssl=False):
|
||||||
"""Connect to the server.
|
"""Connect to the server.
|
||||||
|
|
||||||
|
@ -10,11 +10,13 @@ from xml.parsers.expat import ExpatError
|
|||||||
from slixmpp.test import TestTransport
|
from slixmpp.test import TestTransport
|
||||||
from slixmpp import ClientXMPP, ComponentXMPP
|
from slixmpp import ClientXMPP, ComponentXMPP
|
||||||
from slixmpp.stanza import Message, Iq, Presence
|
from slixmpp.stanza import Message, Iq, Presence
|
||||||
|
from slixmpp.stanza.error import Error
|
||||||
from slixmpp.xmlstream import ET
|
from slixmpp.xmlstream import ET
|
||||||
from slixmpp.xmlstream import ElementBase
|
from slixmpp.xmlstream import ElementBase
|
||||||
from slixmpp.xmlstream.tostring import tostring, highlight
|
from slixmpp.xmlstream.tostring import tostring, highlight
|
||||||
from slixmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender
|
from slixmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender
|
||||||
from slixmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
|
from slixmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
|
||||||
|
from slixmpp.xmlstream.stanzabase import register_stanza_plugin
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
@ -322,6 +324,7 @@ class SlixTest(unittest.TestCase):
|
|||||||
if not plugin_config:
|
if not plugin_config:
|
||||||
plugin_config = {}
|
plugin_config = {}
|
||||||
|
|
||||||
|
self.mode = mode
|
||||||
if mode == 'client':
|
if mode == 'client':
|
||||||
self.xmpp = ClientXMPP(jid, password,
|
self.xmpp = ClientXMPP(jid, password,
|
||||||
sasl_mech=sasl_mech,
|
sasl_mech=sasl_mech,
|
||||||
@ -740,3 +743,10 @@ class SlixTest(unittest.TestCase):
|
|||||||
|
|
||||||
# Everything matches
|
# Everything matches
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.stream_close()
|
||||||
|
if getattr(self, "mode", None) == "component":
|
||||||
|
Error.namespace = 'jabber:client'
|
||||||
|
for st in Message, Iq, Presence:
|
||||||
|
register_stanza_plugin(st, Error)
|
||||||
|
@ -8,9 +8,6 @@ class TestLiveStream(SlixTest):
|
|||||||
Test that we can test a live stanza stream.
|
Test that we can test a live stanza stream.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testClientConnection(self):
|
def testClientConnection(self):
|
||||||
"""Test that we can interact with a live ClientXMPP instance."""
|
"""Test that we can interact with a live ClientXMPP instance."""
|
||||||
self.stream_start(mode='client',
|
self.stream_start(mode='client',
|
||||||
|
@ -8,9 +8,6 @@ class TestEvents(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start()
|
self.stream_start()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testEventHappening(self):
|
def testEventHappening(self):
|
||||||
"""Test handler working"""
|
"""Test handler working"""
|
||||||
happened = []
|
happened = []
|
||||||
|
@ -5,10 +5,6 @@ from slixmpp.xmlstream.stanzabase import ET
|
|||||||
|
|
||||||
class TestIqStanzas(SlixTest):
|
class TestIqStanzas(SlixTest):
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""Shutdown the XML stream after testing."""
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testSetup(self):
|
def testSetup(self):
|
||||||
"""Test initializing default Iq values."""
|
"""Test initializing default Iq values."""
|
||||||
iq = self.Iq()
|
iq = self.Iq()
|
||||||
|
@ -8,9 +8,6 @@ class TestStreamTester(SlixTest):
|
|||||||
Test that we can simulate and test a stanza stream.
|
Test that we can simulate and test a stanza stream.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testClientEcho(self):
|
def testClientEcho(self):
|
||||||
"""Test that we can interact with a ClientXMPP instance."""
|
"""Test that we can interact with a ClientXMPP instance."""
|
||||||
self.stream_start(mode='client')
|
self.stream_start(mode='client')
|
||||||
|
@ -10,9 +10,6 @@ class TestStreamExceptions(SlixTest):
|
|||||||
Test handling roster updates.
|
Test handling roster updates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testExceptionContinueWorking(self):
|
def testExceptionContinueWorking(self):
|
||||||
"""Test that Slixmpp continues to respond after an XMPPError is raised."""
|
"""Test that Slixmpp continues to respond after an XMPPError is raised."""
|
||||||
|
|
||||||
|
@ -14,9 +14,6 @@ class TestFilters(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start()
|
self.stream_start()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testIncoming(self):
|
def testIncoming(self):
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
@ -15,9 +15,6 @@ class TestHandlers(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start()
|
self.stream_start()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testCallback(self):
|
def testCallback(self):
|
||||||
"""Test using stream callback handlers."""
|
"""Test using stream callback handlers."""
|
||||||
|
|
||||||
|
@ -11,9 +11,6 @@ class TestStreamPresence(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start(jid='tester@localhost', plugins=[])
|
self.stream_start(jid='tester@localhost', plugins=[])
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testInitialUnavailablePresences(self):
|
def testInitialUnavailablePresences(self):
|
||||||
"""
|
"""
|
||||||
Test receiving unavailable presences from JIDs that
|
Test receiving unavailable presences from JIDs that
|
||||||
|
@ -13,9 +13,6 @@ class TestStreamRoster(SlixTest):
|
|||||||
Test handling roster updates.
|
Test handling roster updates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testGetRoster(self):
|
def testGetRoster(self):
|
||||||
"""Test handling roster requests."""
|
"""Test handling roster requests."""
|
||||||
self.stream_start(mode='client', jid='tester@localhost')
|
self.stream_start(mode='client', jid='tester@localhost')
|
||||||
|
@ -11,9 +11,6 @@ class TestStreamDisco(SlixTest):
|
|||||||
Test using the XEP-0030 plugin.
|
Test using the XEP-0030 plugin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testInfoEmptyDefaultNode(self):
|
def testInfoEmptyDefaultNode(self):
|
||||||
"""
|
"""
|
||||||
Info query result from an entity MUST have at least one identity
|
Info query result from an entity MUST have at least one identity
|
||||||
|
@ -11,9 +11,6 @@ class TestInBandByteStreams(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start(plugins=['xep_0047', 'xep_0030'])
|
self.stream_start(plugins=['xep_0047', 'xep_0030'])
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testOpenStream(self):
|
def testOpenStream(self):
|
||||||
"""Test requesting a stream, successfully"""
|
"""Test requesting a stream, successfully"""
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@ class TestAdHocCommands(SlixTest):
|
|||||||
# a dummy value.
|
# a dummy value.
|
||||||
self.xmpp['xep_0050'].new_session = lambda: '_sessionid_'
|
self.xmpp['xep_0050'].new_session = lambda: '_sessionid_'
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testInitialPayloadCommand(self):
|
def testInitialPayloadCommand(self):
|
||||||
"""Test a command with an initial payload."""
|
"""Test a command with an initial payload."""
|
||||||
|
|
||||||
|
@ -19,9 +19,6 @@ class TestJabberSearch(SlixTest):
|
|||||||
self.xmpp["xep_0055"].api.register(get_results, "search_query")
|
self.xmpp["xep_0055"].api.register(get_results, "search_query")
|
||||||
self.xmpp["xep_0055"].api.register(get_results, "search_query")
|
self.xmpp["xep_0055"].api.register(get_results, "search_query")
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testRequestingSearchFields(self):
|
def testRequestingSearchFields(self):
|
||||||
self.recv(
|
self.recv(
|
||||||
"""
|
"""
|
||||||
|
@ -15,9 +15,6 @@ class TestStreamPubsub(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start()
|
self.stream_start()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testCreateInstantNode(self):
|
def testCreateInstantNode(self):
|
||||||
"""Test creating an instant node"""
|
"""Test creating an instant node"""
|
||||||
self.xmpp['xep_0060'].create_node('pubsub.example.com', None)
|
self.xmpp['xep_0060'].create_node('pubsub.example.com', None)
|
||||||
|
@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
|
|||||||
|
|
||||||
class TestOOB(SlixTest):
|
class TestOOB(SlixTest):
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testSendOOB(self):
|
def testSendOOB(self):
|
||||||
"""Test sending an OOB transfer request."""
|
"""Test sending an OOB transfer request."""
|
||||||
self.stream_start(plugins=['xep_0066', 'xep_0030'])
|
self.stream_start(plugins=['xep_0066', 'xep_0030'])
|
||||||
|
@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
|
|||||||
|
|
||||||
class TestStreamChatStates(SlixTest):
|
class TestStreamChatStates(SlixTest):
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testChatStates(self):
|
def testChatStates(self):
|
||||||
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0085'])
|
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0085'])
|
||||||
|
|
||||||
|
@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
|
|||||||
|
|
||||||
class TestStreamSet(SlixTest):
|
class TestStreamSet(SlixTest):
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testHandleSoftwareVersionRequest(self):
|
def testHandleSoftwareVersionRequest(self):
|
||||||
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])
|
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class TestStreamGateway(SlixTest):
|
|||||||
"xep_0100": {"component_name": "AIM Gateway", "type": "aim"}
|
"xep_0100": {"component_name": "AIM Gateway", "type": "aim"}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self.xmpp._fix_error_ns()
|
||||||
|
|
||||||
def next_sent(self):
|
def next_sent(self):
|
||||||
self.wait_for_send_queue()
|
self.wait_for_send_queue()
|
||||||
@ -160,7 +161,6 @@ class TestStreamGateway(SlixTest):
|
|||||||
</iq>
|
</iq>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
# xmlns="jabber:client" in error substanza, bug in XEP-0077 plugin or OK?
|
|
||||||
self.send(
|
self.send(
|
||||||
"""
|
"""
|
||||||
<iq type='error'
|
<iq type='error'
|
||||||
@ -171,7 +171,7 @@ class TestStreamGateway(SlixTest):
|
|||||||
<username>RomeoMyRomeo</username>
|
<username>RomeoMyRomeo</username>
|
||||||
<password>ILoveJuliet</password>
|
<password>ILoveJuliet</password>
|
||||||
</query>
|
</query>
|
||||||
<error code='406' type='modify' xmlns="jabber:client">
|
<error code='406' type='modify'>
|
||||||
<not-acceptable
|
<not-acceptable
|
||||||
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||||
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Not good</text>
|
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Not good</text>
|
||||||
|
@ -8,9 +8,6 @@ class TestStreamExtendedDisco(SlixTest):
|
|||||||
Test using the XEP-0128 plugin.
|
Test using the XEP-0128 plugin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testUsingExtendedInfo(self):
|
def testUsingExtendedInfo(self):
|
||||||
self.stream_start(mode='client',
|
self.stream_start(mode='client',
|
||||||
jid='tester@localhost',
|
jid='tester@localhost',
|
||||||
|
@ -10,9 +10,6 @@ class TestStreamDirectInvite(SlixTest):
|
|||||||
Test using the XEP-0249 plugin.
|
Test using the XEP-0249 plugin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testReceiveInvite(self):
|
def testReceiveInvite(self):
|
||||||
self.stream_start(mode='client',
|
self.stream_start(mode='client',
|
||||||
plugins=['xep_0030',
|
plugins=['xep_0030',
|
||||||
|
@ -9,9 +9,6 @@ class TestMAM(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start(plugins=['xep_0313'])
|
self.stream_start(plugins=['xep_0313'])
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testRetrieveSimple(self):
|
def testRetrieveSimple(self):
|
||||||
"""Test requesting MAM messages without RSM"""
|
"""Test requesting MAM messages without RSM"""
|
||||||
|
|
||||||
|
@ -24,9 +24,6 @@ class TestStreamSensorData(SlixTest):
|
|||||||
def _time_now(self):
|
def _time_now(self):
|
||||||
return datetime.datetime.now().replace(microsecond=0).isoformat()
|
return datetime.datetime.now().replace(microsecond=0).isoformat()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testRequestAccept(self):
|
def testRequestAccept(self):
|
||||||
self.stream_start(mode='component',
|
self.stream_start(mode='component',
|
||||||
plugins=['xep_0030',
|
plugins=['xep_0030',
|
||||||
|
@ -30,9 +30,6 @@ class TestStreamControl(SlixTest):
|
|||||||
def _time_now(self):
|
def _time_now(self):
|
||||||
return datetime.datetime.now().replace(microsecond=0).isoformat()
|
return datetime.datetime.now().replace(microsecond=0).isoformat()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testRequestSetOk(self):
|
def testRequestSetOk(self):
|
||||||
self.stream_start(mode='component',
|
self.stream_start(mode='component',
|
||||||
plugins=['xep_0030',
|
plugins=['xep_0030',
|
||||||
|
@ -14,9 +14,6 @@ class TestSIMS(SlixTest):
|
|||||||
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0385"}
|
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0385"}
|
||||||
)
|
)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def test_set_file(self):
|
def test_set_file(self):
|
||||||
with NamedTemporaryFile("wb+") as f:
|
with NamedTemporaryFile("wb+") as f:
|
||||||
n = 10
|
n = 10
|
||||||
|
@ -8,9 +8,6 @@ class TestMIXPAM(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start(plugins=['xep_0405'])
|
self.stream_start(plugins=['xep_0405'])
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testGetRosterEmpty(self):
|
def testGetRosterEmpty(self):
|
||||||
"""Test requesting an empty annotated roster"""
|
"""Test requesting an empty annotated roster"""
|
||||||
|
|
||||||
|
@ -15,8 +15,6 @@ class TestStatelessFileSharing(SlixTest):
|
|||||||
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0447"}
|
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0447"}
|
||||||
)
|
)
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def test_set_file(self):
|
def test_set_file(self):
|
||||||
with NamedTemporaryFile("wb+") as f:
|
with NamedTemporaryFile("wb+") as f:
|
||||||
|
@ -7,9 +7,6 @@ class TestReply(SlixTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream_start(plugins=["xep_0461"])
|
self.stream_start(plugins=["xep_0461"])
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def testFallBackBody(self):
|
def testFallBackBody(self):
|
||||||
async def on_reply(msg):
|
async def on_reply(msg):
|
||||||
start = msg["feature_fallback"]["fallback_body"]["start"]
|
start = msg["feature_fallback"]["fallback_body"]["start"]
|
||||||
|
@ -10,9 +10,6 @@ class TestToString(SlixTest):
|
|||||||
Test the implementation of slixmpp.xmlstream.tostring
|
Test the implementation of slixmpp.xmlstream.tostring
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.stream_close()
|
|
||||||
|
|
||||||
def tryTostring(self, original='', expected=None, message='', **kwargs):
|
def tryTostring(self, original='', expected=None, message='', **kwargs):
|
||||||
"""
|
"""
|
||||||
Compare the result of calling tostring against an
|
Compare the result of calling tostring against an
|
||||||
|
Loading…
x
Reference in New Issue
Block a user