Mike Bayer avatar Mike Bayer committed e3644ff

- Adjusted the __contains__() method of
a RowProxy result row such that no exception
throw is generated internally;
NoSuchColumnError() also will generate its
message regardless of whether or not the column
construct can be coerced to a string.
[ticket:2178].

Comments (0)

Files changed (5)

     break an ORM column_property() mapping against
     another column_property().  [ticket:2167].
 
+- engine
+  - Adjusted the __contains__() method of 
+    a RowProxy result row such that no exception
+    throw is generated internally;  
+    NoSuchColumnError() also will generate its 
+    message regardless of whether or not the column 
+    construct can be coerced to a string.  
+    [ticket:2178].
+
 - postgresql
 
   - Fixed bug affecting PG 9 whereby index reflection

lib/sqlalchemy/engine/base.py

             self.logger.debug(
                 "Col %r", tuple(x[0] for x in metadata))
 
-    def _key_fallback(self, key):
+    def _key_fallback(self, key, raiseerr=True):
         map = self._keymap
         result = None
         if isinstance(key, basestring):
             elif hasattr(key, 'name') and key.name.lower() in map:
                 result = map[key.name.lower()]
         if result is None:
-            raise exc.NoSuchColumnError(
-                "Could not locate column in row for column '%s'" % key)
+            if raiseerr:
+                raise exc.NoSuchColumnError(
+                    "Could not locate column in row for column '%s'" % 
+                        expression._string_or_unprintable(key))
+            else:
+                return None
         else:
             map[key] = result
         return result
         if key in self._keymap:
             return True
         else:
-            try:
-                self._key_fallback(key)
-                return True
-            except exc.NoSuchColumnError:
-                return False
+            return self._key_fallback(key, False) is not None
 
     def __len__(self):
         return len(self.keys)

lib/sqlalchemy/sql/expression.py

     else:
         return x.replace('%', '%%')
 
+def _string_or_unprintable(element):
+    if isinstance(element, basestring):
+        return element
+    else:
+        try:
+            return str(element)
+        except:
+            return "unprintable element %r" % element
+
 def _clone(element):
     return element._clone()
 

test/aaa_profiling/test_resultset.py

                                    '2.6+cextension': 409, '2.7+cextension':409})
     def test_unicode(self):
         [tuple(row) for row in t2.select().execute().fetchall()]
+
+    def test_contains_doesnt_compile(self):
+        row = t.select().execute().first()
+        c1 = Column('some column', Integer) + Column("some other column", Integer)
+        @profiling.function_call_count(9)
+        def go():
+            c1 in row
+        go()

test/sql/test_query.py

                 assert_raises(exc.NoSuchColumnError, lambda: result[0]['fake key'])
                 assert_raises(exc.NoSuchColumnError, lambda: result[0][addresses.c.address_id])
 
+    def test_column_error_printing(self):
+        row = testing.db.execute(select([1])).first()
+        class unprintable(object):
+            def __str__(self):
+                raise ValueError("nope")
+
+        msg = r"Could not locate column in row for column '%s'"
+
+        for accessor, repl in [
+            ("x", "x"),
+            (Column("q", Integer), "q"),
+            (Column("q", Integer) + 12, r"q \+ :q_1"),
+            (unprintable(), "unprintable element.*"),
+        ]:
+            assert_raises_message(
+                exc.NoSuchColumnError, 
+                msg % repl,
+                lambda: row[accessor]
+            )
 
 
     @testing.requires.boolean_col_expressions
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.