summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Kerr <chris.kerr@athion.de>2017-07-10 11:10:13 +0200
committerSergey Shepelev <temotor@gmail.com>2017-07-17 17:13:51 +0300
commitce72c4378b176cdb0d8b6039023e3ad0026becde (patch)
treed8870549e41ea0f62eab93ca81a957c1f11274ab
parentff4610d6d79139668abb7bdec243135805f5b12a (diff)
downloadeventlet-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.py26
-rw-r--r--tests/greendns_test.py15
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()