Fix csvfile traceback on Python3 (#37625)

* Fix csvfile traceback on Python3

The csvfile lookup uses some custom iterators.  These needed to be
ported to handle the python3 iterator protocol.  In addition, the
csvfile module takes an iterator of byte strings in Python2 and an
iterator of text strings in Python3

Fixes #36808
This commit is contained in:
Toshio Kuratomi 2018-03-20 12:58:51 -07:00 committed by GitHub
commit 09325b619e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -53,6 +53,7 @@ from collections import MutableSequence
from ansible.errors import AnsibleError, AnsibleAssertionError from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.plugins.lookup import LookupBase from ansible.plugins.lookup import LookupBase
from ansible.module_utils.six import PY2
from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils._text import to_bytes, to_native, to_text
@ -66,8 +67,10 @@ class CSVRecoder:
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
return self.reader.next().encode("utf-8") return next(self.reader).encode("utf-8")
next = __next__ # For Python 2
class CSVReader: class CSVReader:
@ -77,13 +80,19 @@ class CSVReader:
""" """
def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds): def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds):
if PY2:
f = CSVRecoder(f, encoding) f = CSVRecoder(f, encoding)
else:
f = codecs.getreader(encoding)(f)
self.reader = csv.reader(f, dialect=dialect, **kwds) self.reader = csv.reader(f, dialect=dialect, **kwds)
def next(self): def __next__(self):
row = self.reader.next() row = next(self.reader)
return [to_text(s) for s in row] return [to_text(s) for s in row]
next = __next__ # For Python 2
def __iter__(self): def __iter__(self):
return self return self
@ -93,8 +102,8 @@ class LookupModule(LookupBase):
def read_csv(self, filename, key, delimiter, encoding='utf-8', dflt=None, col=1): def read_csv(self, filename, key, delimiter, encoding='utf-8', dflt=None, col=1):
try: try:
f = open(filename, 'r') f = open(filename, 'rb')
creader = CSVReader(f, delimiter=to_bytes(delimiter), encoding=encoding) creader = CSVReader(f, delimiter=to_native(delimiter), encoding=encoding)
for row in creader: for row in creader:
if row[0] == key: if row[0] == key: