From aa493a8f0af953c313352bb6aa8a1f99540d4a6d Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 3 Jul 2016 02:25:19 +0200 Subject: [PATCH] Fix encoding errors zone.to_file() From the code it looks like the only 'wb' mode is supported after migration to py3. I fixed py3 with 'wb'. Both textual and binary modes should be supported now. --- dns/zone.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/dns/zone.py b/dns/zone.py index 4a73e1e4..1b5dca2f 100644 --- a/dns/zone.py +++ b/dns/zone.py @@ -19,6 +19,7 @@ from __future__ import generators import sys import re +import os from io import BytesIO import dns.exception @@ -498,18 +499,27 @@ class Zone(object): @type nl: string or None """ - str_type = string_types + if isinstance(f, string_types): + f = open(f, 'wb') + want_close = True + else: + want_close = False + + # must be in this way, f.encoding may contain None, or even attribute + # may not be there + file_enc = getattr(f, 'encoding', None) + if file_enc is None: + file_enc = 'utf-8' if nl is None: - opts = 'wb' + nl_b = os.linesep.encode(file_enc) # binary mode, '\n' is not enough + nl = u'\n' + elif isinstance(nl, string_types): + nl_b = nl.encode(file_enc) else: - opts = 'wb' + nl_b = nl + nl = nl.decode() - if isinstance(f, str_type): - f = open(f, opts) - want_close = True - else: - want_close = False try: if sorted: names = list(self.keys()) @@ -520,11 +530,15 @@ class Zone(object): l = self[n].to_text(n, origin=self.origin, relativize=relativize) if isinstance(l, text_type): - l = l.encode() - if nl is None: - f.write(l) - f.write('\n') + l_b = l.encode(file_enc) else: + l_b = l + l = l.decode() + + try: + f.write(l_b) + f.write(nl_b) + except TypeError: # textual mode f.write(l) f.write(nl) finally: -- 2.47.3