The problem is this:
News.label == None and f(News.title) == 'good'
Python does not allow overriding the behavior of logical operations operations and and or . You can influence them to some extent with __bool__ in Python 3 and __nonzero__ in Python 2, but all it does is that it determines the true value of your object .
If the objects in question did not implement __bool__ and did not __bool__ error, or the implementation did not give you, you could get quite cryptic errors due to the short circuit of and and or :
In [19]: (News.label == 'asdf') and True Out[19]: <sqlalchemy.sql.elements.BinaryExpression object at 0x7f62c416fa58> In [24]: (News.label == 'asdf') or True Out[24]: True
because
In [26]: bool(News.label == 'asdf') Out[26]: False
This can lead to hair loss in the form of incorrect SQL expressions:
In [28]: print(News.label == 'asdf' or News.author == 'NOT WHAT YOU EXPECTED') news.author = :author_1
Use the and_() , or_() and not_() sql functions, or binary & , | to create logical SQL statements. and ~ operator overloads:
# Parentheses required due to operator precedence filter((News.label == None) & (f(News.title) == 'good'))
or
filter(and_(News.label == None, f(News.title) == 'good'))
or pass in multiple criteria for calling Query.filter() :
filter(News.label == None, f(News.title) == 'good')
or combine several calls to filter() :
filter(News.label == None).filter(f(News.title) == 'good')