summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--lib/extras.py9
-rwxr-xr-xtests/test_extras_dictcursor.py9
3 files changed, 16 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 09b19e5..a264c90 100644
--- a/NEWS
+++ b/NEWS
@@ -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