Browse Source

Add idna encode/decode helpers

pull/903/head
Ross McFarland 4 years ago
parent
commit
044d8561ed
No known key found for this signature in database GPG Key ID: 943B179E15D3B22A
7 changed files with 89 additions and 15 deletions
  1. +4
    -0
      CHANGELOG.md
  2. +26
    -0
      octodns/idna.py
  3. +1
    -1
      octodns/record/__init__.py
  4. +13
    -14
      requirements-dev.txt
  5. +1
    -0
      requirements.txt
  6. +1
    -0
      setup.py
  7. +43
    -0
      tests/test_octodns_idna.py

+ 4
- 0
CHANGELOG.md View File

@ -1,3 +1,7 @@
## v0.9.18 - 2022-??-?? - Internationalization
* Added octodns.idna idna_encode/idna_decode helpers
## v0.9.17 - 2022-04-02 - Registration required
#### Noteworthy changes


+ 26
- 0
octodns/idna.py View File

@ -0,0 +1,26 @@
#
#
#
from idna import decode as _decode, encode as _encode
def idna_encode(name):
if not name:
# idna.encode doesn't handle ''
return name
elif name.startswith('*'):
# idna.encode doesn't like the *
name = _encode(name[2:]).decode('utf-8')
return f'*.{name}'
return _encode(name).decode('utf-8')
def idna_decode(name):
if not name:
# idna.decode doesn't handle ''
return name
elif name.startswith('*'):
# idna.decode doesn't like the *
return f'*.{_decode(name[2:])}'
return _decode(name)

+ 1
- 1
octodns/record/__init__.py View File

@ -100,7 +100,7 @@ class Record(EqualityTupleMixin):
@classmethod
def new(cls, zone, name, data, source=None, lenient=False):
name = str(name)
name = str(name).lower()
fqdn = f'{name}.{zone.name}' if name else zone.name
try:
_type = data['type']


+ 13
- 14
requirements-dev.txt View File

@ -1,16 +1,15 @@
Pygments==2.11.2
Pygments==2.12.0
attrs==21.4.0
bleach==4.1.0
bleach==5.0.0
build==0.7.0
certifi==2021.10.8
certifi==2022.5.18.1
cffi==1.15.0
charset-normalizer==2.0.12
cmarkgfm==0.8.0
colorama==0.4.4
coverage==6.3.2
commonmark==0.9.1
coverage==6.3.3
docutils==0.18.1
idna==3.3
importlib-metadata==4.11.2
importlib-metadata==4.11.3
iniconfig==1.1.1
keyring==23.5.0
packaging==21.3
@ -24,19 +23,19 @@ pycountry-convert==0.7.2
pycountry==22.3.5
pycparser==2.21
pyflakes==2.4.0
pyparsing==3.0.7
pyparsing==3.0.9
pytest-cov==3.0.0
pytest-mock==3.7.0
pytest-network==0.0.1
pytest==7.0.1
readme-renderer==33.0
pytest==7.1.2
readme-renderer==35.0
repoze.lru==0.7
requests-toolbelt==0.9.1
requests==2.27.1
rfc3986==2.0.0
rich==12.4.1
tomli==2.0.1
tqdm==4.63.0
twine==3.8.0
urllib3==1.26.8
twine==4.0.0
urllib3==1.26.9
webencodings==0.5.1
zipp==3.7.0
zipp==3.8.0

+ 1
- 0
requirements.txt View File

@ -1,6 +1,7 @@
PyYAML==6.0
dnspython==2.2.1
fqdn==1.5.1
idna==3.3
natsort==8.1.0
python-dateutil==2.8.2
six==1.16.0

+ 1
- 0
setup.py View File

@ -96,6 +96,7 @@ setup(
'PyYaml>=4.2b1',
'dnspython>=1.15.0',
'fqdn>=1.5.0',
'idna>=3.3',
'natsort>=5.5.0',
'python-dateutil>=2.8.1',
),


+ 43
- 0
tests/test_octodns_idna.py View File

@ -0,0 +1,43 @@
#
#
#
from __future__ import absolute_import, division, print_function, \
unicode_literals
from unittest import TestCase
from octodns.idna import idna_decode, idna_encode
class TestIdna(TestCase):
def assertIdna(self, value, expected):
got = idna_encode(value)
self.assertEqual(expected, got)
# round tripped
self.assertEqual(value, idna_decode(value))
def test_noops(self):
# empty
self.assertIdna('', '')
# noop
self.assertIdna('unit.tests.', 'unit.tests.')
# wildcard noop
self.assertIdna('*.unit.tests.', '*.unit.tests.')
def test_unicode(self):
# encoded
self.assertIdna('zajęzyk.pl.', 'xn--zajzyk-y4a.pl.')
# encoded with wildcard
self.assertIdna('*.zajęzyk.pl.', '*.xn--zajzyk-y4a.pl.')
# encoded with simple name
self.assertIdna('noop.zajęzyk.pl.', 'noop.xn--zajzyk-y4a.pl.')
# encoded with encoded name
self.assertIdna('zajęzyk.zajęzyk.pl.',
'xn--zajzyk-y4a.xn--zajzyk-y4a.pl.')

Loading…
Cancel
Save