Browse Source

Modernize Python 2 code to prepare for Python 3

pull/373/head
cclauss 7 years ago
parent
commit
158add8eb6
14 changed files with 76 additions and 43 deletions
  1. +8
    -2
      .travis.yml
  2. +5
    -3
      octodns/cmds/report.py
  3. +4
    -4
      octodns/manager.py
  4. +3
    -1
      octodns/provider/base.py
  5. +1
    -1
      octodns/provider/cloudflare.py
  6. +4
    -2
      octodns/provider/ns1.py
  7. +10
    -8
      octodns/provider/plan.py
  8. +10
    -3
      octodns/provider/route53.py
  9. +13
    -5
      octodns/record/__init__.py
  10. +3
    -1
      octodns/zone.py
  11. +2
    -2
      requirements.txt
  12. +9
    -7
      tests/test_octodns_provider_base.py
  13. +3
    -3
      tests/test_octodns_provider_cloudflare.py
  14. +1
    -1
      tests/test_octodns_provider_googlecloud.py

+ 8
- 2
.travis.yml View File

@ -1,6 +1,12 @@
language: python language: python
python:
- 2.7
matrix:
include:
- python: 2.7
- python: 3.7
dist: xenial # required for Python >= 3.7 on Travis CI
allow_failures:
- python: 3.7
before_install: pip install --upgrade pip
script: ./script/cibuild script: ./script/cibuild
notifications: notifications:
email: email:


+ 5
- 3
octodns/cmds/report.py View File

@ -13,6 +13,8 @@ from logging import getLogger
from sys import stdout from sys import stdout
import re import re
from six import text_type
from octodns.cmds.args import ArgumentParser from octodns.cmds.args import ArgumentParser
from octodns.manager import Manager from octodns.manager import Manager
from octodns.zone import Zone from octodns.zone import Zone
@ -65,7 +67,7 @@ def main():
resolver = AsyncResolver(configure=False, resolver = AsyncResolver(configure=False,
num_workers=int(args.num_workers)) num_workers=int(args.num_workers))
if not ip_addr_re.match(server): if not ip_addr_re.match(server):
server = unicode(query(server, 'A')[0])
server = text_type(query(server, 'A')[0])
log.info('server=%s', server) log.info('server=%s', server)
resolver.nameservers = [server] resolver.nameservers = [server]
resolver.lifetime = int(args.timeout) resolver.lifetime = int(args.timeout)
@ -81,12 +83,12 @@ def main():
stdout.write(',') stdout.write(',')
stdout.write(record._type) stdout.write(record._type)
stdout.write(',') stdout.write(',')
stdout.write(unicode(record.ttl))
stdout.write(text_type(record.ttl))
compare = {} compare = {}
for future in futures: for future in futures:
stdout.write(',') stdout.write(',')
try: try:
answers = [unicode(r) for r in future.result()]
answers = [text_type(r) for r in future.result()]
except (NoAnswer, NoNameservers): except (NoAnswer, NoNameservers):
answers = ['*no answer*'] answers = ['*no answer*']
except NXDOMAIN: except NXDOMAIN:


+ 4
- 4
octodns/manager.py View File

@ -276,9 +276,9 @@ class Manager(object):
try: try:
sources = [self.providers[source] for source in sources] sources = [self.providers[source] for source in sources]
except KeyError:
except KeyError as e:
raise Exception('Zone {}, unknown source: {}'.format(zone_name, raise Exception('Zone {}, unknown source: {}'.format(zone_name,
source))
e))
try: try:
trgs = [] trgs = []
@ -397,9 +397,9 @@ class Manager(object):
try: try:
sources = [self.providers[source] for source in sources] sources = [self.providers[source] for source in sources]
except KeyError:
except KeyError as e:
raise Exception('Zone {}, unknown source: {}'.format(zone_name, raise Exception('Zone {}, unknown source: {}'.format(zone_name,
source))
e))
for source in sources: for source in sources:
if isinstance(source, YamlProvider): if isinstance(source, YamlProvider):


+ 3
- 1
octodns/provider/base.py View File

@ -5,6 +5,8 @@
from __future__ import absolute_import, division, print_function, \ from __future__ import absolute_import, division, print_function, \
unicode_literals unicode_literals
from six import text_type
from ..source.base import BaseSource from ..source.base import BaseSource
from ..zone import Zone from ..zone import Zone
from .plan import Plan from .plan import Plan
@ -68,7 +70,7 @@ class BaseProvider(BaseSource):
changes=changes) changes=changes)
if extra: if extra:
self.log.info('plan: extra changes\n %s', '\n ' self.log.info('plan: extra changes\n %s', '\n '
.join([unicode(c) for c in extra]))
.join([text_type(c) for c in extra]))
changes += extra changes += extra
if changes: if changes:


+ 1
- 1
octodns/provider/cloudflare.py View File

@ -442,7 +442,7 @@ class CloudflareProvider(BaseProvider):
# Round trip the single value through a record to contents flow # Round trip the single value through a record to contents flow
# to get a consistent _gen_data result that matches what # to get a consistent _gen_data result that matches what
# went in to new_contents # went in to new_contents
data = self._gen_data(r).next()
data = next(self._gen_data(r))
# Record the record_id and data for this existing record # Record the record_id and data for this existing record
key = self._gen_key(data) key = self._gen_key(data)


+ 4
- 2
octodns/provider/ns1.py View File

@ -13,6 +13,8 @@ from nsone.rest.errors import RateLimitException, ResourceException
from incf.countryutils import transformations from incf.countryutils import transformations
from time import sleep from time import sleep
from six import text_type
from ..record import Record from ..record import Record
from .base import BaseProvider from .base import BaseProvider
@ -76,9 +78,9 @@ class Ns1Provider(BaseProvider):
else: else:
values.extend(answer['answer']) values.extend(answer['answer'])
codes.append([]) codes.append([])
values = [unicode(x) for x in values]
values = [text_type(x) for x in values]
geo = OrderedDict( geo = OrderedDict(
{unicode(k): [unicode(x) for x in v] for k, v in geo.items()}
{text_type(k): [text_type(x) for x in v] for k, v in geo.items()}
) )
data['values'] = values data['values'] = values
data['geo'] = geo data['geo'] = geo


+ 10
- 8
octodns/provider/plan.py View File

@ -9,6 +9,8 @@ from StringIO import StringIO
from logging import DEBUG, ERROR, INFO, WARN, getLogger from logging import DEBUG, ERROR, INFO, WARN, getLogger
from sys import stdout from sys import stdout
from six import text_type
class UnsafePlan(Exception): class UnsafePlan(Exception):
pass pass
@ -147,11 +149,11 @@ class PlanLogger(_PlanOutput):
def _value_stringifier(record, sep): def _value_stringifier(record, sep):
try: try:
values = [unicode(v) for v in record.values]
values = [text_type(v) for v in record.values]
except AttributeError: except AttributeError:
values = [record.value] values = [record.value]
for code, gv in sorted(getattr(record, 'geo', {}).items()): for code, gv in sorted(getattr(record, 'geo', {}).items()):
vs = ', '.join([unicode(v) for v in gv.values])
vs = ', '.join([text_type(v) for v in gv.values])
values.append('{}: {}'.format(code, vs)) values.append('{}: {}'.format(code, vs))
return sep.join(values) return sep.join(values)
@ -193,7 +195,7 @@ class PlanMarkdown(_PlanOutput):
fh.write(' | ') fh.write(' | ')
# TTL # TTL
if existing: if existing:
fh.write(unicode(existing.ttl))
fh.write(text_type(existing.ttl))
fh.write(' | ') fh.write(' | ')
fh.write(_value_stringifier(existing, '; ')) fh.write(_value_stringifier(existing, '; '))
fh.write(' | |\n') fh.write(' | |\n')
@ -201,7 +203,7 @@ class PlanMarkdown(_PlanOutput):
fh.write('| | | | ') fh.write('| | | | ')
if new: if new:
fh.write(unicode(new.ttl))
fh.write(text_type(new.ttl))
fh.write(' | ') fh.write(' | ')
fh.write(_value_stringifier(new, '; ')) fh.write(_value_stringifier(new, '; '))
fh.write(' | ') fh.write(' | ')
@ -210,7 +212,7 @@ class PlanMarkdown(_PlanOutput):
fh.write(' |\n') fh.write(' |\n')
fh.write('\nSummary: ') fh.write('\nSummary: ')
fh.write(unicode(plan))
fh.write(text_type(plan))
fh.write('\n\n') fh.write('\n\n')
else: else:
fh.write('## No changes were planned\n') fh.write('## No changes were planned\n')
@ -261,7 +263,7 @@ class PlanHtml(_PlanOutput):
# TTL # TTL
if existing: if existing:
fh.write(' <td>') fh.write(' <td>')
fh.write(unicode(existing.ttl))
fh.write(text_type(existing.ttl))
fh.write('</td>\n <td>') fh.write('</td>\n <td>')
fh.write(_value_stringifier(existing, '<br/>')) fh.write(_value_stringifier(existing, '<br/>'))
fh.write('</td>\n <td></td>\n </tr>\n') fh.write('</td>\n <td></td>\n </tr>\n')
@ -270,7 +272,7 @@ class PlanHtml(_PlanOutput):
if new: if new:
fh.write(' <td>') fh.write(' <td>')
fh.write(unicode(new.ttl))
fh.write(text_type(new.ttl))
fh.write('</td>\n <td>') fh.write('</td>\n <td>')
fh.write(_value_stringifier(new, '<br/>')) fh.write(_value_stringifier(new, '<br/>'))
fh.write('</td>\n <td>') fh.write('</td>\n <td>')
@ -279,7 +281,7 @@ class PlanHtml(_PlanOutput):
fh.write('</td>\n </tr>\n') fh.write('</td>\n </tr>\n')
fh.write(' <tr>\n <td colspan=6>Summary: ') fh.write(' <tr>\n <td colspan=6>Summary: ')
fh.write(unicode(plan))
fh.write(text_type(plan))
fh.write('</td>\n </tr>\n</table>\n') fh.write('</td>\n </tr>\n</table>\n')
else: else:
fh.write('<b>No changes were planned</b>') fh.write('<b>No changes were planned</b>')

+ 10
- 3
octodns/provider/route53.py View File

@ -14,10 +14,17 @@ from uuid import uuid4
import logging import logging
import re import re
from six import text_type
from ..record import Record, Update from ..record import Record, Update
from ..record.geo import GeoCodes from ..record.geo import GeoCodes
from .base import BaseProvider from .base import BaseProvider
try:
cmp
except NameError:
def cmp(x, y):
return (x > y) - (x < y)
octal_re = re.compile(r'\\(\d\d\d)') octal_re = re.compile(r'\\(\d\d\d)')
@ -1037,8 +1044,8 @@ class Route53Provider(BaseProvider):
# ip_address's returned object for equivalence # ip_address's returned object for equivalence
# E.g 2001:4860:4860::8842 -> 2001:4860:4860:0:0:0:0:8842 # E.g 2001:4860:4860::8842 -> 2001:4860:4860:0:0:0:0:8842
if value: if value:
value = ip_address(unicode(value))
config_ip_address = ip_address(unicode(config['IPAddress']))
value = ip_address(text_type(value))
config_ip_address = ip_address(text_type(config['IPAddress']))
else: else:
# No value so give this a None to match value's # No value so give this a None to match value's
config_ip_address = None config_ip_address = None
@ -1059,7 +1066,7 @@ class Route53Provider(BaseProvider):
fqdn, record._type, value) fqdn, record._type, value)
try: try:
ip_address(unicode(value))
ip_address(text_type(value))
# We're working with an IP, host is the Host header # We're working with an IP, host is the Host header
healthcheck_host = record.healthcheck_host healthcheck_host = record.healthcheck_host
except (AddressValueError, ValueError): except (AddressValueError, ValueError):


+ 13
- 5
octodns/record/__init__.py View File

@ -9,8 +9,16 @@ from ipaddress import IPv4Address, IPv6Address
from logging import getLogger from logging import getLogger
import re import re
from six import string_types, text_type
from .geo import GeoCodes from .geo import GeoCodes
try:
cmp
except NameError:
def cmp(x, y):
return (x > y) - (x < y)
class Change(object): class Change(object):
@ -130,7 +138,7 @@ class Record(object):
self.__class__.__name__, name) self.__class__.__name__, name)
self.zone = zone self.zone = zone
# force everything lower-case just to be safe # force everything lower-case just to be safe
self.name = unicode(name).lower() if name else name
self.name = text_type(name).lower() if name else name
self.source = source self.source = source
self.ttl = int(data['ttl']) self.ttl = int(data['ttl'])
@ -292,7 +300,7 @@ class _ValuesMixin(object):
return ret return ret
def __repr__(self): def __repr__(self):
values = "['{}']".format("', '".join([unicode(v)
values = "['{}']".format("', '".join([text_type(v)
for v in self.values])) for v in self.values]))
return '<{} {} {}, {}, {}>'.format(self.__class__.__name__, return '<{} {} {}, {}, {}>'.format(self.__class__.__name__,
self._type, self.ttl, self._type, self.ttl,
@ -574,7 +582,7 @@ class _DynamicMixin(object):
reasons.append('rule {} missing pool'.format(rule_num)) reasons.append('rule {} missing pool'.format(rule_num))
continue continue
if not isinstance(pool, basestring):
if not isinstance(pool, string_types):
reasons.append('rule {} invalid pool "{}"' reasons.append('rule {} invalid pool "{}"'
.format(rule_num, pool)) .format(rule_num, pool))
elif pool not in pools: elif pool not in pools:
@ -671,13 +679,13 @@ class _IpList(object):
return ['missing value(s)'] return ['missing value(s)']
reasons = [] reasons = []
for value in data: for value in data:
if value is '':
if value == '':
reasons.append('empty value') reasons.append('empty value')
elif value is None: elif value is None:
reasons.append('missing value(s)') reasons.append('missing value(s)')
else: else:
try: try:
cls._address_type(unicode(value))
cls._address_type(text_type(value))
except Exception: except Exception:
reasons.append('invalid {} address "{}"' reasons.append('invalid {} address "{}"'
.format(cls._address_name, value)) .format(cls._address_name, value))


+ 3
- 1
octodns/zone.py View File

@ -9,6 +9,8 @@ from collections import defaultdict
from logging import getLogger from logging import getLogger
import re import re
from six import text_type
from .record import Create, Delete from .record import Create, Delete
@ -38,7 +40,7 @@ class Zone(object):
raise Exception('Invalid zone name {}, missing ending dot' raise Exception('Invalid zone name {}, missing ending dot'
.format(name)) .format(name))
# Force everything to lowercase just to be safe # Force everything to lowercase just to be safe
self.name = unicode(name).lower() if name else name
self.name = text_type(name).lower() if name else name
self.sub_zones = sub_zones self.sub_zones = sub_zones
# We're grouping by node, it allows us to efficiently search for # We're grouping by node, it allows us to efficiently search for
# duplicates and detect when CNAMEs co-exist with other records # duplicates and detect when CNAMEs co-exist with other records


+ 2
- 2
requirements.txt View File

@ -6,7 +6,7 @@ botocore==1.10.5
dnspython==1.15.0 dnspython==1.15.0
docutils==0.14 docutils==0.14
dyn==1.8.1 dyn==1.8.1
futures==3.2.0
futures==3.2.0; python_version < '3.0'
google-cloud-core==0.28.1 google-cloud-core==0.28.1
google-cloud-dns==0.29.0 google-cloud-dns==0.29.0
incf.countryutils==1.0 incf.countryutils==1.0
@ -19,5 +19,5 @@ ovh==0.4.8
python-dateutil==2.6.1 python-dateutil==2.6.1
requests==2.20.0 requests==2.20.0
s3transfer==0.1.13 s3transfer==0.1.13
six==1.11.0
six==1.12.0
setuptools==38.5.2 setuptools==38.5.2

+ 9
- 7
tests/test_octodns_provider_base.py View File

@ -8,6 +8,8 @@ from __future__ import absolute_import, division, print_function, \
from logging import getLogger from logging import getLogger
from unittest import TestCase from unittest import TestCase
from six import text_type
from octodns.record import Create, Delete, Record, Update from octodns.record import Create, Delete, Record, Update
from octodns.provider.base import BaseProvider from octodns.provider.base import BaseProvider
from octodns.provider.plan import Plan, UnsafePlan from octodns.provider.plan import Plan, UnsafePlan
@ -193,7 +195,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -225,7 +227,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -251,7 +253,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -273,7 +275,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -299,7 +301,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -322,7 +324,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'
@ -350,7 +352,7 @@ class TestBaseProvider(TestCase):
}) })
for i in range(int(Plan.MIN_EXISTING_RECORDS)): for i in range(int(Plan.MIN_EXISTING_RECORDS)):
zone.add_record(Record.new(zone, unicode(i), {
zone.add_record(Record.new(zone, text_type(i), {
'ttl': 60, 'ttl': 60,
'type': 'A', 'type': 'A',
'value': '2.3.4.5' 'value': '2.3.4.5'


+ 3
- 3
tests/test_octodns_provider_cloudflare.py View File

@ -950,7 +950,7 @@ class TestCloudflareProvider(TestCase):
'value': 'ns1.unit.tests.' 'value': 'ns1.unit.tests.'
}) })
data = provider._gen_data(record).next()
data = next(provider._gen_data(record))
self.assertFalse('proxied' in data) self.assertFalse('proxied' in data)
@ -965,7 +965,7 @@ class TestCloudflareProvider(TestCase):
}), False }), False
) )
data = provider._gen_data(record).next()
data = next(provider._gen_data(record))
self.assertFalse(data['proxied']) self.assertFalse(data['proxied'])
@ -980,7 +980,7 @@ class TestCloudflareProvider(TestCase):
}), True }), True
) )
data = provider._gen_data(record).next()
data = next(provider._gen_data(record))
self.assertTrue(data['proxied']) self.assertTrue(data['proxied'])


+ 1
- 1
tests/test_octodns_provider_googlecloud.py View File

@ -194,7 +194,7 @@ class DummyIterator:
return self return self
def next(self): def next(self):
return self.iterable.next()
return next(self.iterable)
class TestGoogleCloudProvider(TestCase): class TestGoogleCloudProvider(TestCase):


Loading…
Cancel
Save