Skip to content

Weird behaviour using different variable names in select and filter function #203

@Limit64

Description

@Limit64

PonyORM raised an exception that didn't make any sense to me. After some hours of trying I found a solution for it, but I think it is a bug because imho the code should work.

from pony.orm import *

db = Database()

class Person(db.Entity):
    name = PrimaryKey(str)
    phone_numbers = Set("PhoneNumber")

class PhoneNumber(db.Entity):
    number = PrimaryKey(int)
    persons = Set(Person)

db.bind("sqlite", ":memory:")
db.generate_mapping(create_tables=True)

with db_session:
    persons = select(p for p in Person)
    persons = persons.filter(
        lambda pers: exists(pn for pn in PhoneNumber if pers in pn.persons)
    )

    print(persons[:])

This code leads to the following exception.

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    lambda pers: exists(pn for pn in PhoneNumber if pers in pn.persons)
  File "<string>", line 2, in filter
  File "/usr/lib/python3.5/site-packages/pony/utils.py", line 65, in cut_traceback
    return func(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 5332, in filter
    return query._process_lambda(func, globals, locals, order_by=False)
  File "/usr/lib/python3.5/site-packages/pony/orm/core.py", line 5296, in _process_lambda
    new_translator = prev_translator.apply_lambda(filter_num, order_by, func_ast, argnames, extractors, vartypes)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 598, in apply_lambda
    translator.dispatch(func_ast)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 79, in dispatch
    return ASTTranslator.dispatch(translator, node)  # default route
  File "/usr/lib/python3.5/site-packages/pony/orm/asttranslation.py", line 23, in dispatch
    stop = translator.call(pre_method, node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 129, in call
    reraise(exc_class, exc, tb)
  File "/usr/lib/python3.5/site-packages/pony/utils.py", line 92, in reraise
    try: raise exc.with_traceback(tb)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 119, in call
    try: monad = method(node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 708, in preCallFunc
    translator.dispatch(arg)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 79, in dispatch
    return ASTTranslator.dispatch(translator, node)  # default route
  File "/usr/lib/python3.5/site-packages/pony/orm/asttranslation.py", line 23, in dispatch
    stop = translator.call(pre_method, node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 129, in call
    reraise(exc_class, exc, tb)
  File "/usr/lib/python3.5/site-packages/pony/utils.py", line 92, in reraise
    try: raise exc.with_traceback(tb)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 119, in call
    try: monad = method(node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 622, in preGenExpr
    subtranslator = translator.__class__(inner_tree, translator.extractors, translator.vartypes, translator)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 263, in __init__
    translator.dispatch(if_)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 79, in dispatch
    return ASTTranslator.dispatch(translator, node)  # default route
  File "/usr/lib/python3.5/site-packages/pony/orm/asttranslation.py", line 28, in dispatch
    translator.dispatch(child)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 79, in dispatch
    return ASTTranslator.dispatch(translator, node)  # default route
  File "/usr/lib/python3.5/site-packages/pony/orm/asttranslation.py", line 23, in dispatch
    stop = translator.call(pre_method, node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 129, in call
    reraise(exc_class, exc, tb)
  File "/usr/lib/python3.5/site-packages/pony/utils.py", line 92, in reraise
    try: raise exc.with_traceback(tb)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 119, in call
    try: monad = method(node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 632, in preCompare
    translator.dispatch(left)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 79, in dispatch
    return ASTTranslator.dispatch(translator, node)  # default route
  File "/usr/lib/python3.5/site-packages/pony/orm/asttranslation.py", line 34, in dispatch
    translator.call(post_method, node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 129, in call
    reraise(exc_class, exc, tb)
  File "/usr/lib/python3.5/site-packages/pony/utils.py", line 92, in reraise
    try: raise exc.with_traceback(tb)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 119, in call
    try: monad = method(node)
  File "/usr/lib/python3.5/site-packages/pony/orm/sqltranslation.py", line 672, in postName
    else: assert False, name  # pragma: no cover
AssertionError: pers

If I use the same variable name in the select statement and for the lambdas it works as expected.

    persons = select(p for p in Person)
    persons = persons.filter(
        lambda p: exists(pn for pn in PhoneNumber if p in pn.persons)
    )

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions