Allow non-ascii chars in namedtuple fields

They can be valid chars in Python 3. Or maybe not? In which case Python
will throw an exception, but that's fine.

Fix regression introduced fixing #211
This commit is contained in:
Daniele Varrazzo 2018-05-13 23:51:21 +01:00
parent 667079b209
commit 8ad39c2712
3 changed files with 17 additions and 4 deletions

2
NEWS
View File

@ -4,6 +4,8 @@ Current release
What's new in psycopg 2.7.5
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Allow non-ascii chars in namedtuple fields (regression introduced fixing
:ticket':`#211`).
- Fixed building on Solaris 11 and derivatives such as SmartOS and illumos
(:ticket:`#677`).
- Maybe fixed building on MSYS2 (as reported in :ticket:`#658`).

View File

@ -368,12 +368,15 @@ class NamedTupleCursor(_cursor):
raise self._exc
else:
def _make_nt(self, namedtuple=namedtuple):
# ascii except alnum and underscore
nochars = ' !"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~'
re_clean = _re.compile('[' + _re.escape(nochars) + ']')
def f(s):
# NOTE: Python 3 actually allows unicode chars in fields
s = _re.sub('[^a-zA-Z0-9_]', '_', s)
s = re_clean.sub('_', s)
# Python identifier cannot start with numbers, namedtuple fields
# cannot start with underscore. So...
if _re.match('^[0-9_]', s):
if s[0] == '_' or '0' <= s[0] <= '9':
s = 'f' + s
return s

View File

@ -19,7 +19,7 @@ from datetime import timedelta
import psycopg2
import psycopg2.extras
from testutils import unittest, ConnectingTestCase, skip_before_postgres
from testutils import skip_if_no_namedtuple
from testutils import skip_before_python, skip_if_no_namedtuple
class ExtrasDictCursorTests(ConnectingTestCase):
@ -391,6 +391,14 @@ class NamedTupleCursorTest(ConnectingTestCase):
self.assertEqual(rv.f_column_, 2)
self.assertEqual(rv.f3, 3)
@skip_before_python(3)
@skip_if_no_namedtuple
def test_nonascii_name(self):
curs = self.conn.cursor()
curs.execute('select 1 as \xe5h\xe9')
rv = curs.fetchone()
self.assertEqual(getattr(rv, '\xe5h\xe9'), 1)
@skip_if_no_namedtuple
def test_minimal_generation(self):
# Instrument the class to verify it gets called the minimum number of times.