mirror of https://github.com/python/cpython
asynchat: PEP8-ify the code
This commit is contained in:
parent
d9e810a870
commit
fd5d1b51d6
|
@ -49,22 +49,22 @@ import asyncore
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
class async_chat (asyncore.dispatcher):
|
class async_chat(asyncore.dispatcher):
|
||||||
"""This is an abstract class. You must derive from this class, and add
|
"""This is an abstract class. You must derive from this class, and add
|
||||||
the two methods collect_incoming_data() and found_terminator()"""
|
the two methods collect_incoming_data() and found_terminator()"""
|
||||||
|
|
||||||
# these are overridable defaults
|
# these are overridable defaults
|
||||||
|
|
||||||
ac_in_buffer_size = 65536
|
ac_in_buffer_size = 65536
|
||||||
ac_out_buffer_size = 65536
|
ac_out_buffer_size = 65536
|
||||||
|
|
||||||
# we don't want to enable the use of encoding by default, because that is a
|
# we don't want to enable the use of encoding by default, because that is a
|
||||||
# sign of an application bug that we don't want to pass silently
|
# sign of an application bug that we don't want to pass silently
|
||||||
|
|
||||||
use_encoding = 0
|
use_encoding = 0
|
||||||
encoding = 'latin-1'
|
encoding = 'latin-1'
|
||||||
|
|
||||||
def __init__ (self, sock=None, map=None):
|
def __init__(self, sock=None, map=None):
|
||||||
# for string terminator matching
|
# for string terminator matching
|
||||||
self.ac_in_buffer = b''
|
self.ac_in_buffer = b''
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ class async_chat (asyncore.dispatcher):
|
||||||
# we toss the use of the "simple producer" and replace it with
|
# we toss the use of the "simple producer" and replace it with
|
||||||
# a pure deque, which the original fifo was a wrapping of
|
# a pure deque, which the original fifo was a wrapping of
|
||||||
self.producer_fifo = deque()
|
self.producer_fifo = deque()
|
||||||
asyncore.dispatcher.__init__ (self, sock, map)
|
asyncore.dispatcher.__init__(self, sock, map)
|
||||||
|
|
||||||
def collect_incoming_data(self, data):
|
def collect_incoming_data(self, data):
|
||||||
raise NotImplementedError("must be implemented in subclass")
|
raise NotImplementedError("must be implemented in subclass")
|
||||||
|
@ -92,13 +92,16 @@ class async_chat (asyncore.dispatcher):
|
||||||
def found_terminator(self):
|
def found_terminator(self):
|
||||||
raise NotImplementedError("must be implemented in subclass")
|
raise NotImplementedError("must be implemented in subclass")
|
||||||
|
|
||||||
def set_terminator (self, term):
|
def set_terminator(self, term):
|
||||||
"Set the input delimiter. Can be a fixed string of any length, an integer, or None"
|
"""Set the input delimiter.
|
||||||
|
|
||||||
|
Can be a fixed string of any length, an integer, or None.
|
||||||
|
"""
|
||||||
if isinstance(term, str) and self.use_encoding:
|
if isinstance(term, str) and self.use_encoding:
|
||||||
term = bytes(term, self.encoding)
|
term = bytes(term, self.encoding)
|
||||||
self.terminator = term
|
self.terminator = term
|
||||||
|
|
||||||
def get_terminator (self):
|
def get_terminator(self):
|
||||||
return self.terminator
|
return self.terminator
|
||||||
|
|
||||||
# grab some more data from the socket,
|
# grab some more data from the socket,
|
||||||
|
@ -106,10 +109,10 @@ class async_chat (asyncore.dispatcher):
|
||||||
# check for the terminator,
|
# check for the terminator,
|
||||||
# if found, transition to the next state.
|
# if found, transition to the next state.
|
||||||
|
|
||||||
def handle_read (self):
|
def handle_read(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = self.recv (self.ac_in_buffer_size)
|
data = self.recv(self.ac_in_buffer_size)
|
||||||
except OSError as why:
|
except OSError as why:
|
||||||
self.handle_error()
|
self.handle_error()
|
||||||
return
|
return
|
||||||
|
@ -128,17 +131,17 @@ class async_chat (asyncore.dispatcher):
|
||||||
terminator = self.get_terminator()
|
terminator = self.get_terminator()
|
||||||
if not terminator:
|
if not terminator:
|
||||||
# no terminator, collect it all
|
# no terminator, collect it all
|
||||||
self.collect_incoming_data (self.ac_in_buffer)
|
self.collect_incoming_data(self.ac_in_buffer)
|
||||||
self.ac_in_buffer = b''
|
self.ac_in_buffer = b''
|
||||||
elif isinstance(terminator, int):
|
elif isinstance(terminator, int):
|
||||||
# numeric terminator
|
# numeric terminator
|
||||||
n = terminator
|
n = terminator
|
||||||
if lb < n:
|
if lb < n:
|
||||||
self.collect_incoming_data (self.ac_in_buffer)
|
self.collect_incoming_data(self.ac_in_buffer)
|
||||||
self.ac_in_buffer = b''
|
self.ac_in_buffer = b''
|
||||||
self.terminator = self.terminator - lb
|
self.terminator = self.terminator - lb
|
||||||
else:
|
else:
|
||||||
self.collect_incoming_data (self.ac_in_buffer[:n])
|
self.collect_incoming_data(self.ac_in_buffer[:n])
|
||||||
self.ac_in_buffer = self.ac_in_buffer[n:]
|
self.ac_in_buffer = self.ac_in_buffer[n:]
|
||||||
self.terminator = 0
|
self.terminator = 0
|
||||||
self.found_terminator()
|
self.found_terminator()
|
||||||
|
@ -155,32 +158,34 @@ class async_chat (asyncore.dispatcher):
|
||||||
if index != -1:
|
if index != -1:
|
||||||
# we found the terminator
|
# we found the terminator
|
||||||
if index > 0:
|
if index > 0:
|
||||||
# don't bother reporting the empty string (source of subtle bugs)
|
# don't bother reporting the empty string
|
||||||
self.collect_incoming_data (self.ac_in_buffer[:index])
|
# (source of subtle bugs)
|
||||||
|
self.collect_incoming_data(self.ac_in_buffer[:index])
|
||||||
self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
|
self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
|
||||||
# This does the Right Thing if the terminator is changed here.
|
# This does the Right Thing if the terminator
|
||||||
|
# is changed here.
|
||||||
self.found_terminator()
|
self.found_terminator()
|
||||||
else:
|
else:
|
||||||
# check for a prefix of the terminator
|
# check for a prefix of the terminator
|
||||||
index = find_prefix_at_end (self.ac_in_buffer, terminator)
|
index = find_prefix_at_end(self.ac_in_buffer, terminator)
|
||||||
if index:
|
if index:
|
||||||
if index != lb:
|
if index != lb:
|
||||||
# we found a prefix, collect up to the prefix
|
# we found a prefix, collect up to the prefix
|
||||||
self.collect_incoming_data (self.ac_in_buffer[:-index])
|
self.collect_incoming_data(self.ac_in_buffer[:-index])
|
||||||
self.ac_in_buffer = self.ac_in_buffer[-index:]
|
self.ac_in_buffer = self.ac_in_buffer[-index:]
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# no prefix, collect it all
|
# no prefix, collect it all
|
||||||
self.collect_incoming_data (self.ac_in_buffer)
|
self.collect_incoming_data(self.ac_in_buffer)
|
||||||
self.ac_in_buffer = b''
|
self.ac_in_buffer = b''
|
||||||
|
|
||||||
def handle_write (self):
|
def handle_write(self):
|
||||||
self.initiate_send()
|
self.initiate_send()
|
||||||
|
|
||||||
def handle_close (self):
|
def handle_close(self):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def push (self, data):
|
def push(self, data):
|
||||||
if not isinstance(data, (bytes, bytearray, memoryview)):
|
if not isinstance(data, (bytes, bytearray, memoryview)):
|
||||||
raise TypeError('data argument must be byte-ish (%r)',
|
raise TypeError('data argument must be byte-ish (%r)',
|
||||||
type(data))
|
type(data))
|
||||||
|
@ -192,11 +197,11 @@ class async_chat (asyncore.dispatcher):
|
||||||
self.producer_fifo.append(data)
|
self.producer_fifo.append(data)
|
||||||
self.initiate_send()
|
self.initiate_send()
|
||||||
|
|
||||||
def push_with_producer (self, producer):
|
def push_with_producer(self, producer):
|
||||||
self.producer_fifo.append(producer)
|
self.producer_fifo.append(producer)
|
||||||
self.initiate_send()
|
self.initiate_send()
|
||||||
|
|
||||||
def readable (self):
|
def readable(self):
|
||||||
"predicate for inclusion in the readable for select()"
|
"predicate for inclusion in the readable for select()"
|
||||||
# cannot use the old predicate, it violates the claim of the
|
# cannot use the old predicate, it violates the claim of the
|
||||||
# set_terminator method.
|
# set_terminator method.
|
||||||
|
@ -204,11 +209,11 @@ class async_chat (asyncore.dispatcher):
|
||||||
# return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
|
# return (len(self.ac_in_buffer) <= self.ac_in_buffer_size)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def writable (self):
|
def writable(self):
|
||||||
"predicate for inclusion in the writable for select()"
|
"predicate for inclusion in the writable for select()"
|
||||||
return self.producer_fifo or (not self.connected)
|
return self.producer_fifo or (not self.connected)
|
||||||
|
|
||||||
def close_when_done (self):
|
def close_when_done(self):
|
||||||
"automatically close this channel once the outgoing queue is empty"
|
"automatically close this channel once the outgoing queue is empty"
|
||||||
self.producer_fifo.append(None)
|
self.producer_fifo.append(None)
|
||||||
|
|
||||||
|
@ -219,10 +224,8 @@ class async_chat (asyncore.dispatcher):
|
||||||
if not first:
|
if not first:
|
||||||
del self.producer_fifo[0]
|
del self.producer_fifo[0]
|
||||||
if first is None:
|
if first is None:
|
||||||
## print("first is None")
|
|
||||||
self.handle_close()
|
self.handle_close()
|
||||||
return
|
return
|
||||||
## print("first is not None")
|
|
||||||
|
|
||||||
# handle classic producer behavior
|
# handle classic producer behavior
|
||||||
obs = self.ac_out_buffer_size
|
obs = self.ac_out_buffer_size
|
||||||
|
@ -254,20 +257,21 @@ class async_chat (asyncore.dispatcher):
|
||||||
# we tried to send some actual data
|
# we tried to send some actual data
|
||||||
return
|
return
|
||||||
|
|
||||||
def discard_buffers (self):
|
def discard_buffers(self):
|
||||||
# Emergencies only!
|
# Emergencies only!
|
||||||
self.ac_in_buffer = b''
|
self.ac_in_buffer = b''
|
||||||
del self.incoming[:]
|
del self.incoming[:]
|
||||||
self.producer_fifo.clear()
|
self.producer_fifo.clear()
|
||||||
|
|
||||||
|
|
||||||
class simple_producer:
|
class simple_producer:
|
||||||
|
|
||||||
def __init__ (self, data, buffer_size=512):
|
def __init__(self, data, buffer_size=512):
|
||||||
self.data = data
|
self.data = data
|
||||||
self.buffer_size = buffer_size
|
self.buffer_size = buffer_size
|
||||||
|
|
||||||
def more (self):
|
def more(self):
|
||||||
if len (self.data) > self.buffer_size:
|
if len(self.data) > self.buffer_size:
|
||||||
result = self.data[:self.buffer_size]
|
result = self.data[:self.buffer_size]
|
||||||
self.data = self.data[self.buffer_size:]
|
self.data = self.data[self.buffer_size:]
|
||||||
return result
|
return result
|
||||||
|
@ -276,38 +280,40 @@ class simple_producer:
|
||||||
self.data = b''
|
self.data = b''
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class fifo:
|
class fifo:
|
||||||
def __init__ (self, list=None):
|
def __init__(self, list=None):
|
||||||
if not list:
|
if not list:
|
||||||
self.list = deque()
|
self.list = deque()
|
||||||
else:
|
else:
|
||||||
self.list = deque(list)
|
self.list = deque(list)
|
||||||
|
|
||||||
def __len__ (self):
|
def __len__(self):
|
||||||
return len(self.list)
|
return len(self.list)
|
||||||
|
|
||||||
def is_empty (self):
|
def is_empty(self):
|
||||||
return not self.list
|
return not self.list
|
||||||
|
|
||||||
def first (self):
|
def first(self):
|
||||||
return self.list[0]
|
return self.list[0]
|
||||||
|
|
||||||
def push (self, data):
|
def push(self, data):
|
||||||
self.list.append(data)
|
self.list.append(data)
|
||||||
|
|
||||||
def pop (self):
|
def pop(self):
|
||||||
if self.list:
|
if self.list:
|
||||||
return (1, self.list.popleft())
|
return (1, self.list.popleft())
|
||||||
else:
|
else:
|
||||||
return (0, None)
|
return (0, None)
|
||||||
|
|
||||||
|
|
||||||
# Given 'haystack', see if any prefix of 'needle' is at its end. This
|
# Given 'haystack', see if any prefix of 'needle' is at its end. This
|
||||||
# assumes an exact match has already been checked. Return the number of
|
# assumes an exact match has already been checked. Return the number of
|
||||||
# characters matched.
|
# characters matched.
|
||||||
# for example:
|
# for example:
|
||||||
# f_p_a_e ("qwerty\r", "\r\n") => 1
|
# f_p_a_e("qwerty\r", "\r\n") => 1
|
||||||
# f_p_a_e ("qwertydkjf", "\r\n") => 0
|
# f_p_a_e("qwertydkjf", "\r\n") => 0
|
||||||
# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined>
|
# f_p_a_e("qwerty\r\n", "\r\n") => <undefined>
|
||||||
|
|
||||||
# this could maybe be made faster with a computed regex?
|
# this could maybe be made faster with a computed regex?
|
||||||
# [answer: no; circa Python-2.0, Jan 2001]
|
# [answer: no; circa Python-2.0, Jan 2001]
|
||||||
|
@ -316,7 +322,7 @@ class fifo:
|
||||||
# re: 12820/s
|
# re: 12820/s
|
||||||
# regex: 14035/s
|
# regex: 14035/s
|
||||||
|
|
||||||
def find_prefix_at_end (haystack, needle):
|
def find_prefix_at_end(haystack, needle):
|
||||||
l = len(needle) - 1
|
l = len(needle) - 1
|
||||||
while l and not haystack.endswith(needle[:l]):
|
while l and not haystack.endswith(needle[:l]):
|
||||||
l -= 1
|
l -= 1
|
||||||
|
|
|
@ -5,9 +5,12 @@ from test import support
|
||||||
# If this fails, the test will be skipped.
|
# If this fails, the test will be skipped.
|
||||||
thread = support.import_module('_thread')
|
thread = support.import_module('_thread')
|
||||||
|
|
||||||
import asyncore, asynchat, socket, time
|
import asynchat
|
||||||
import unittest
|
import asyncore
|
||||||
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
import unittest
|
||||||
try:
|
try:
|
||||||
import threading
|
import threading
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -28,8 +31,8 @@ if threading:
|
||||||
self.event = event
|
self.event = event
|
||||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.port = support.bind_port(self.sock)
|
self.port = support.bind_port(self.sock)
|
||||||
# This will be set if the client wants us to wait before echoing data
|
# This will be set if the client wants us to wait before echoing
|
||||||
# back.
|
# data back.
|
||||||
self.start_resend_event = None
|
self.start_resend_event = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -52,8 +55,8 @@ if threading:
|
||||||
|
|
||||||
# re-send entire set of collected data
|
# re-send entire set of collected data
|
||||||
try:
|
try:
|
||||||
# this may fail on some tests, such as test_close_when_done, since
|
# this may fail on some tests, such as test_close_when_done,
|
||||||
# the client closes the channel when it's done sending
|
# since the client closes the channel when it's done sending
|
||||||
while self.buffer:
|
while self.buffer:
|
||||||
n = conn.send(self.buffer[:self.chunk_size])
|
n = conn.send(self.buffer[:self.chunk_size])
|
||||||
time.sleep(0.001)
|
time.sleep(0.001)
|
||||||
|
@ -96,7 +99,7 @@ if threading:
|
||||||
s.start()
|
s.start()
|
||||||
event.wait()
|
event.wait()
|
||||||
event.clear()
|
event.clear()
|
||||||
time.sleep(0.01) # Give server time to start accepting.
|
time.sleep(0.01) # Give server time to start accepting.
|
||||||
return s, event
|
return s, event
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,10 +107,10 @@ if threading:
|
||||||
class TestAsynchat(unittest.TestCase):
|
class TestAsynchat(unittest.TestCase):
|
||||||
usepoll = False
|
usepoll = False
|
||||||
|
|
||||||
def setUp (self):
|
def setUp(self):
|
||||||
self._threads = support.threading_setup()
|
self._threads = support.threading_setup()
|
||||||
|
|
||||||
def tearDown (self):
|
def tearDown(self):
|
||||||
support.threading_cleanup(*self._threads)
|
support.threading_cleanup(*self._threads)
|
||||||
|
|
||||||
def line_terminator_check(self, term, server_chunk):
|
def line_terminator_check(self, term, server_chunk):
|
||||||
|
@ -117,7 +120,7 @@ class TestAsynchat(unittest.TestCase):
|
||||||
s.start()
|
s.start()
|
||||||
event.wait()
|
event.wait()
|
||||||
event.clear()
|
event.clear()
|
||||||
time.sleep(0.01) # Give server time to start accepting.
|
time.sleep(0.01) # Give server time to start accepting.
|
||||||
c = echo_client(term, s.port)
|
c = echo_client(term, s.port)
|
||||||
c.push(b"hello ")
|
c.push(b"hello ")
|
||||||
c.push(b"world" + term)
|
c.push(b"world" + term)
|
||||||
|
@ -136,17 +139,17 @@ class TestAsynchat(unittest.TestCase):
|
||||||
|
|
||||||
def test_line_terminator1(self):
|
def test_line_terminator1(self):
|
||||||
# test one-character terminator
|
# test one-character terminator
|
||||||
for l in (1,2,3):
|
for l in (1, 2, 3):
|
||||||
self.line_terminator_check(b'\n', l)
|
self.line_terminator_check(b'\n', l)
|
||||||
|
|
||||||
def test_line_terminator2(self):
|
def test_line_terminator2(self):
|
||||||
# test two-character terminator
|
# test two-character terminator
|
||||||
for l in (1,2,3):
|
for l in (1, 2, 3):
|
||||||
self.line_terminator_check(b'\r\n', l)
|
self.line_terminator_check(b'\r\n', l)
|
||||||
|
|
||||||
def test_line_terminator3(self):
|
def test_line_terminator3(self):
|
||||||
# test three-character terminator
|
# test three-character terminator
|
||||||
for l in (1,2,3):
|
for l in (1, 2, 3):
|
||||||
self.line_terminator_check(b'qqq', l)
|
self.line_terminator_check(b'qqq', l)
|
||||||
|
|
||||||
def numeric_terminator_check(self, termlen):
|
def numeric_terminator_check(self, termlen):
|
||||||
|
@ -269,11 +272,13 @@ class TestAsynchat(unittest.TestCase):
|
||||||
class TestAsynchat_WithPoll(TestAsynchat):
|
class TestAsynchat_WithPoll(TestAsynchat):
|
||||||
usepoll = True
|
usepoll = True
|
||||||
|
|
||||||
|
|
||||||
class TestHelperFunctions(unittest.TestCase):
|
class TestHelperFunctions(unittest.TestCase):
|
||||||
def test_find_prefix_at_end(self):
|
def test_find_prefix_at_end(self):
|
||||||
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
|
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
|
||||||
self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0)
|
self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0)
|
||||||
|
|
||||||
|
|
||||||
class TestFifo(unittest.TestCase):
|
class TestFifo(unittest.TestCase):
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
f = asynchat.fifo()
|
f = asynchat.fifo()
|
||||||
|
|
Loading…
Reference in New Issue