David Dyball
David Dyball

Reputation: 143

Python/SQLAlchemcy "or" functionality

I can't seem to find out why "or" is behaving the way it is. I'm using SQLAlchemy and WTForms.ext.sqlalchemy.QuerySelectField and QuerySelectField can have query_factory set, but if it's missing it should be falling back to the fields query method:

e.g.

class Form1(Form):
    fielda = QuerySelectField('Field A')

You can also set the query_factory argument like so:

class Form1(Form):
    fielda = QuerySelectField('Field A', query_factory=somefunction)

Then somewhere else you use the form like so:

form = Form1(request.form)
form.fielda.query = MyObjects.query.all()

What I'm seeing is that, if MyObjects.query.all() returns an empty list, I get a NoneType not callable exception on this line in the QuerySelectField _get_object_list() method:

query = self.query or self.query_factory()

Basically, no matter what the value of self.query, the or is still calling self.query_factory() even if it is assigned to None.

So, my question is, is this expected behaviour of or? It appears that it evaluates both and then it decides if it needs to use the second value if the first is None. Is this correct?

Upvotes: 1

Views: 231

Answers (3)

mgilson
mgilson

Reputation: 309821

You can succinctly state the behavior of or as:

if the left object is True-like, it returns the left object, otherwise it returns the right object.


In this case, left object is false-like (None), so it needs to call the function in order to get the right object to return.

Upvotes: 0

stonemetal
stonemetal

Reputation: 6208

That is correct None is false in a Boolean context. If self.query is None then the value is determined by self.query_factory()

Python docs on what is true and false

Upvotes: 1

Tim Pietzcker
Tim Pietzcker

Reputation: 336088

or short-circuits. This means that

query = self.query or self.query_factory()

is evaluated as follows:

  1. Check if self.query evaluates to False. If not, then the object referenced by self.query is bound to query. self.query_factory() is not called in this situation.
  2. If it is a Falsey value (including None), then self.query_factory() is called and its result bound to query.

Upvotes: 1

Related Questions