diff options
author | Chris Kerr <chris.kerr@athion.de> | 2017-07-10 11:10:13 +0200 |
---|---|---|
committer | Sergey Shepelev <temotor@gmail.com> | 2017-07-17 17:13:51 +0300 |
commit | ce72c4378b176cdb0d8b6039023e3ad0026becde (patch) | |
tree | d8870549e41ea0f62eab93ca81a957c1f11274ab | |
parent | ff4610d6d79139668abb7bdec243135805f5b12a (diff) | |
download | eventlet-ce72c4378b176cdb0d8b6039023e3ad0026becde.tar.gz |
dns: reading /etc/hosts raised DeprecationWarning for universal lines on Python 3.4+
Solved by always reading in binary mode with explicit decoding.
Plus: new hosts parser in regex, better comment handling.
-rw-r--r-- | eventlet/support/greendns.py | 26 | ||||
-rw-r--r-- | tests/greendns_test.py | 15 |
2 files changed, 30 insertions, 11 deletions
diff --git a/eventlet/support/greendns.py b/eventlet/support/greendns.py index ee9bc3d..ebdea2d 100644 --- a/eventlet/support/greendns.py +++ b/eventlet/support/greendns.py @@ -32,6 +32,7 @@ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import re import struct import sys @@ -154,10 +155,18 @@ class HostsResolver(object): :interval: The time between checking for hosts file modification """ + LINES_RE = re.compile(r""" + \s* # Leading space + ([^\r\n#]+?) # The actual match, non-greedy so as not to include trailing space + \s* # Trailing space + (?:[#][^\r\n]+)? # Comments + (?:$|[\r\n]+) # EOF or newline + """, re.VERBOSE) + def __init__(self, fname=None, interval=HOSTS_TTL): self._v4 = {} # name -> ipv4 self._v6 = {} # name -> ipv6 - self._aliases = {} # name -> cannonical_name + self._aliases = {} # name -> canonical_name self.interval = interval self.fname = fname if fname is None: @@ -178,16 +187,15 @@ class HostsResolver(object): Note that this performs disk I/O so can be blocking. """ - lines = [] try: - with open(self.fname, 'rU') as fp: - for line in fp: - line = line.strip() - if line and line[0] != '#': - lines.append(line) + with open(self.fname, 'rb') as fp: + fdata = fp.read() except (IOError, OSError): - pass - return lines + return [] + + udata = fdata.decode(errors='ignore') + + return self.LINES_RE.findall(udata) def _load(self): """Load hosts file diff --git a/tests/greendns_test.py b/tests/greendns_test.py index efdd628..4a47c5e 100644 --- a/tests/greendns_test.py +++ b/tests/greendns_test.py @@ -40,9 +40,20 @@ class TestHostsResolver(tests.LimitedTestCase): hr.hosts.write(b'line1\n') hr.hosts.flush() assert hr._readlines() == ['line0', 'line1'] + # Test reading of varied newline styles hr._last_stat = 0 - hr.hosts.write(b'#comment0\nline0\n #comment1\nline1') - assert hr._readlines() == ['line0', 'line1'] + hr.hosts.seek(0) + hr.hosts.truncate() + hr.hosts.write(b'\naa\r\nbb\r cc \n\n\tdd ee') + hr.hosts.flush() + assert hr._readlines() == ['aa', 'bb', 'cc', 'dd ee'] + # Test comments, including inline comments + hr._last_stat = 0 + hr.hosts.seek(0) + hr.hosts.truncate() + hr.hosts.write(b' line1\n#comment\nline2 # inline comment\n') + hr.hosts.flush() + assert hr._readlines() == ['line1', 'line2'] def test_readlines_missing_file(self): hr = _make_host_resolver() |