diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2018-05-13 23:51:21 +0100 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2018-05-18 12:15:50 +0100 |
commit | bc84b6233eaa1e7a6302b51f8ab8950534ff1813 (patch) | |
tree | 076031f0e5fec49835b25375963c6e042a8b1315 | |
parent | 548e28135023252ea79830e52521e2a8c1c0bd37 (diff) | |
download | psycopg2-bc84b6233eaa1e7a6302b51f8ab8950534ff1813.tar.gz |
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
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | lib/extras.py | 9 | ||||
-rwxr-xr-x | tests/test_extras_dictcursor.py | 9 |
3 files changed, 16 insertions, 4 deletions
@@ -17,6 +17,8 @@ Other changes: 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`). diff --git a/lib/extras.py b/lib/extras.py index 1f85d53..9c26ccb 100644 --- a/lib/extras.py +++ b/lib/extras.py @@ -363,12 +363,15 @@ class NamedTupleCursor(_cursor): return def _make_nt(self): + # 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 diff --git a/tests/test_extras_dictcursor.py b/tests/test_extras_dictcursor.py index 99bdeee..2a46fba 100755 --- a/tests/test_extras_dictcursor.py +++ b/tests/test_extras_dictcursor.py @@ -19,7 +19,7 @@ from datetime import timedelta import psycopg2 import psycopg2.extras import unittest -from .testutils import ConnectingTestCase, skip_before_postgres +from .testutils import ConnectingTestCase, skip_before_postgres, skip_before_python class ExtrasDictCursorTests(ConnectingTestCase): @@ -357,6 +357,13 @@ class NamedTupleCursorTest(ConnectingTestCase): self.assertEqual(rv.f_column_, 2) self.assertEqual(rv.f3, 3) + @skip_before_python(3) + 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) + def test_minimal_generation(self): # Instrument the class to verify it gets called the minimum number of times. from psycopg2.extras import NamedTupleCursor |