Python3.4 help() not compatible w/ SQLAlchemy mapped classes

Issue #3361 closed
EirN created an issue

I have project with SQLAlchemy. Almost all my models are with documentation as described in documentation.

I want to use builtin help() to have some interactive help on my models but I have exception and don't know how to deal with.

Exception is: TypeError: Boolean value of this clause is not defined. After digging the code with pdb, I've found that it is caused with __table__ attribute and python 3.4 (py3k?) inspect changes.

This example works fine with Python 2.7, but I develop Python 3.4+ application and I really need it fixed.

Python version: 3.4.3

SQLAlchemy version: 0.9.9, 1.0.0b5

My model:

from sqlalchemy import Column, Integer, String, Unicode
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Model(Base):
    __tablename__ = 'model'

    id = Column(Integer, primary_key=True, doc='ID column for this model')
    data = Column(String(250), nullable=False, unique=True, doc='Some model data')


from sqlalchemy import Column, Integer, String, Unicode
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Category(Base):
    __tablename__ = 'category'

    id = Column(Integer, primary_key=True)
    slug = Column(String(250), nullable=False, unique=True)

Exception:

>>> help(model.Category)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/_sitebuiltins.py", line 103, in __call__
        return pydoc.help(*args, **kwds)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 1827, in __call__
        self.help(request)
   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 1877, in help
     else: doc(request, 'Help on %s:', output=self._output)
   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 1614, in doc
    pager(render_doc(thing, title, forceload))
   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 1607, in render_doc
     return title % desc + '\n\n' + renderer.document(object, name)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 372, in document
    if inspect.isclass(object): return self.docclass(*args)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 1272, in docclass
    for name, kind, cls, value in classify_class_attrs(object)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pydoc.py", line 205, in classify_class_attrs
    for (name, kind, cls, value) in inspect.classify_class_attrs(object):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/inspect.py", line 405, in classify_class_attrs
    obj = get_obj or dict_obj
  File "/Users/eirnym/venv/34/ens/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 538, in __bool__
    raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined

Comments (13)

  1. Mike Bayer repo owner

    This is unfortunately a bug in Python 3.4, I've reported it at http://bugs.python.org/issue23898. It is not present in Python 3.3.

    I've not heard of the help() function being used much these days, perhaps you need to write a quick script for now that just outputs the __doc__ attribute of the given object as well as the members of its __dict__.

    It might be worthwhile for SQLAlchemy to add test coverage for the help() function against a mapped class somehow.

  2. YuanZheCSYZ

    Hi,

    I got the same error when trying to merge the ORM objects. And I find this happens particularly on updating the geometry data. I'm using the Python 3.4.1 as well. Here is what I am trying to do.

    # gps is type of geometry in Postgresql
    db_obj.gps = "POINT (x y)" 
    

    Here is the stack track and hope it can help some.

     Traceback (most recent call last):
      File "my-python-program"
        session.merge(db_obj)
      File "/usr/local/python/lib/python3.4/site-packages/lmap/postgres/dbutil.py", line 33, in merge
        Session.merge(obj)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/scoping.py", line 150, in do
        return getattr(self.registry(), name)(*args, **kwargs)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 1689, in merge
        self._autoflush()
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 1282, in _autoflush
        self.flush()
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2004, in flush
        self._flush(objects)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2122, in _flush
        transaction.rollback(_capture_exception=True)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
        compat.reraise(exc_type, exc_value, exc_tb)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 182, in reraise
        raise value
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2086, in _flush
        flush_context.execute()
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", line 373, in execute
        rec.execute(self)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", line 532, in execute
        uow
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 170, in save_obj
        mapper, table, update)
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 613, in _emit_update_statements
        lambda rec: (
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 456, in _collect_update_commands
        value, state.committed_state[propkey]):
      File "/usr/local/python/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 2726, in __bool__
        raise TypeError("Boolean value of this clause is not defined")
    TypeError: Boolean value of this clause is not defined
    
  3. YuanZheCSYZ

    Hi Mike,

    Thanks for your reply.

    Recently I test my code on Python 3.3.6 and unfortunately the problem was still there whenever we tried to merge the updated gps data. Since we define our own Geometry data type using UserDefinedType, we think this might be the cause. Then we came across the GeoAlchemy and we tested replacing our code with it and surprisingly all the tests went through. Considering our code used to work fine with SqlAlchemy <= 0.99, I think in our case the program is mostly from the incorrectly defined geo type.

  4. Mike Bayer repo owner

    @nuwa - please provide a stack trace. the stack trace reported here should definitely be resolved with the patch.

  5. Mike Bayer repo owner

    @nuwa - With Python 3.4 + SQLA 0.99, I get the same stack trace as that in 1.0. No 1.0 regression is reported here. Please open a new issue, include full test case plus full stack trace, thanks.

  6. 曹忠

    I do not correctly patched? I was manually modified the inspect.py

    [E 150430 03:00:23 web:1421] Uncaught exception PUT /exchange/inv/check/docs/doc (192.168.3.108) HTTPServerRequest(protocol='http', host='192.168.3.101:8080', method='PUT', uri='/exchange/inv/check/docs/doc', version='HTTP/1.1', remote_ip='192.168.3.108', headers={'Accept-Encoding': 'gzip, deflate, sdch', 'Cookie': 'user_id="2|1:0|10:1430332609|7:user_id|8:MTY0MDI=|d282771e82bd94691417572995d4e09cd1ed4c24fba5528d30e43fce2942a0b6"', 'Dnt': '1', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', 'Content-Type': 'text/plain;charset=UTF-8', 'Content-Length': '266', 'Origin': 'http://192.168.3.101:8080', 'Accept': '/', 'Referer': 'http://192.168.3.101:8080/kingbar.html', 'Host': '192.168.3.101:8080', 'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4'}) Traceback (most recent call last): File "C:\Python34\lib\site-packages\tornado\web.py", line 1348, in _execute result = yield result File "C:\Python34\lib\site-packages\tornado\gen.py", line 807, in run value = future.result() File "C:\Python34\lib\site-packages\tornado\concurrent.py", line 209, in result raise_exc_info(self._exc_info) File "<string>", line 3, in raise_exc_info File "C:\Python34\lib\site-packages\tornado\gen.py", line 810, in run yielded = self.gen.throw(sys.exc_info()) File "./exchange/views.py", line 7018, in put File "C:\Python34\lib\site-packages\tornado\gen.py", line 807, in run value = future.result() File "C:\Python34\lib\concurrent\futures_base.py", line 395, in result return self.__get_result() File "C:\Python34\lib\concurrent\futures_base.py", line 354, in __get_result raise self._exception File "C:\Python34\lib\concurrent\futures\thread.py", line 54, in run result = self.fn(self.args, **self.kwargs) File "./exchange/views.py", line 7302, in update_inv_chk File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 790, in commit self.transaction.commit() File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 392, in commit self._prepare_impl() File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 372, in _prepare_impl self.session.flush() File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 2004, in flush self._flush(objects) File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 2122, in _flush transaction.rollback(_capture_exception=True) File "C:\Python34\lib\site-packages\sqlalchemy\util\langhelpers.py", line 60, in exit compat.reraise(exc_type, exc_value, exc_tb) File "C:\Python34\lib\site-packages\sqlalchemy\util\compat.py", line 182, in reraise raise value File "C:\Python34\lib\site-packages\sqlalchemy\orm\session.py", line 2086, in _flush flush_context.execute() File "C:\Python34\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 373, in execute rec.execute(self) File "C:\Python34\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 532, in execute uow File "C:\Python34\lib\site-packages\sqlalchemy\orm\persistence.py", line 170, in save_obj mapper, table, update) File "C:\Python34\lib\site-packages\sqlalchemy\orm\persistence.py", line 613, in _emit_update_statements lambda rec: ( File "C:\Python34\lib\site-packages\sqlalchemy\orm\persistence.py", line 456, in _collect_update_commands value, state.committed_state[propkey]): File "C:\Python34\lib\site-packages\sqlalchemy\sql\elements.py", line 2726, in bool raise TypeError("Boolean value of this clause is not defined") TypeError: Boolean value of this clause is not defined

  7. Mike Bayer repo owner

    @nuwa - OK yeah the formatting is off for your trace but I can see what's inside of it. That's a totally different issue, it's #3402 which is fixed and will be released tomorrow in 1.0.3.

  8. Log in to comment