Coveragepy: Coverage thinks there are additional files with Pony ORM queries

Created on 18 Mar 2021  路  7Comments  路  Source: nedbat/coveragepy

Describe the bug
When a Pony ORM query is run by the test code, Coverage thinks that one of the query parameters is another file being tested.

To Reproduce

  1. What version of Python are you using? Python 3.8.3
  2. What version of coverage.py are you using? The output of coverage debug sys is helpful.
> coverage debug sys
-- sys -------------------------------------------------------
                        version: 5.5
                       coverage: /home/jpyams/test2/.venv/lib/python3.8/site-packages/coverage/__init__.py
                         tracer: -none-
                        CTracer: available
           plugins.file_tracers: -none-
            plugins.configurers: -none-
      plugins.context_switchers: -none-
              configs_attempted: .coveragerc
                                 setup.cfg
                                 tox.ini
                                 pyproject.toml
                   configs_read: -none-
                    config_file: None
                config_contents: -none-
                      data_file: -none-
                         python: 3.8.3 (default, May 19 2020, 18:47:26) [GCC 7.3.0]
                       platform: Linux-3.10.0-1127.19.1.el7.x86_64-x86_64-with-glibc2.10
                 implementation: CPython
                     executable: /home/jpyams/test2/.venv/bin/python3
                   def_encoding: utf-8
                    fs_encoding: utf-8
                            pid: 24221
                            cwd: /home/jpyams/test2
                           path: /home/jpyams/test2/.venv/bin
                                 /path/python/3.8.3/lib/python38.zip
                                 /path/python/3.8.3/lib/python3.8
                                 /path/python/3.8.3/lib/python3.8/lib-dynload
                                 /home/jpyams/test2/.venv/lib/python3.8/site-packages
                    environment: CDS_NVIDIA_XCOPYPLANE_FIX = 1
                                 PYTHONDONTWRITEBYTECODE = 1
                   command_line: /home/jpyams/test2/.venv/bin/coverage debug sys
                sqlite3_version: 2.6.0
         sqlite3_sqlite_version: 3.32.3
             sqlite3_temp_store: 0
        sqlite3_compile_options: COMPILER=gcc-7.3.0
                                 ENABLE_COLUMN_METADATA
                                 ENABLE_DBSTAT_VTAB
                                 ENABLE_FTS3
                                 ENABLE_FTS3_TOKENIZER
                                 ENABLE_FTS4
                                 ENABLE_FTS5
                                 ENABLE_GEOPOLY
                                 ENABLE_JSON1
                                 ENABLE_RTREE
                                 ENABLE_UNLOCK_NOTIFY
                                 MAX_DEFAULT_PAGE_SIZE=32768
                                 MAX_EXPR_DEPTH=10000
                                 MAX_VARIABLE_NUMBER=250000
                                 SECURE_DELETE
                                 THREADSAFE=1
  1. What versions of what packages do you have installed? The output of pip freeze is helpful.
attrs==20.3.0
coverage==5.5
iniconfig==1.1.1
packaging==20.9
pluggy==0.13.1
pony==0.7.14
py==1.10.0
pyparsing==2.4.7
pytest==6.2.2
toml==0.10.2
  1. What code are you running? Give us a specific commit of a specific repo that we can check out.
from pony import orm

db = orm.Database()


class Table(db.Entity):
    user = orm.Required(str)


def query(user):
    Table.select(lambda r: r.user == user)


def test_query():
    query('a')
  1. What commands did you run?
$ coverage run --source=app -m pytest app.py
$ coverage debug data
-- data ------------------------------------------------------
path: /home/jpyams/test2/.coverage
has_arcs: False

2 files:
/home/jpyams/test2/app.py: 8 lines
/home/jpyams/test2/user: 1 lines

Expected behavior
Expected output:

-- data ------------------------------------------------------
path: /home/jpyams/test2/.coverage
has_arcs: False

2 files:
/home/jpyams/test2/app.py: 8 lines

Additional context
This bug prevents the coverage reports from showing the source code and line-by-line breakdown of coverage in the XML report.

Trying variations of Pony's select() did not affect the output.

bug not-our-bug

Most helpful comment

All 7 comments

@jpyams Thanks for the details, but I think there's a step missing. I'm sorry, I've never used Pony. When I run your program, I get this:

$ coverage run --source=app -m pytest app.py
================================================== test session starts ===================================================
platform darwin -- Python 3.8.6, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /src/foo/bug1136
collected 1 item

app.py F                                                                                                           [100%]

======================================================== FAILURES ========================================================
_______________________________________________________ test_query _______________________________________________________

    def test_query():
>       query('a')

app.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
app.py:11: in query
    Table.select(lambda r: r.user == user)
/usr/local/virtualenvs/tmp-588bd07b744c67f2/lib/python3.8/site-packages/pony/orm/core.py:4034: in select
    if args: query = entity._query_from_args_(args, kwargs, frame_depth=cut_traceback_depth+1)
/usr/local/virtualenvs/tmp-588bd07b744c67f2/lib/python3.8/site-packages/pony/orm/core.py:4407: in _query_from_args_
    return Query(code_key, inner_expr, globals, locals, cells)
/usr/local/virtualenvs/tmp-588bd07b744c67f2/lib/python3.8/site-packages/pony/orm/core.py:5712: in __init__
    if database.schema is None: throw(ERDiagramError, 'Mapping is not generated for entity %r' % origin.__name__)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

exc_type = <class 'pony.orm.core.ERDiagramError'>, args = ("Mapping is not generated for entity 'Table'",), kwargs = {}

    def throw(exc_type, *args, **kwargs):
        if isinstance(exc_type, Exception):
            assert not args and not kwargs
            exc = exc_type
        else: exc = exc_type(*args, **kwargs)
        exc.__cause__ = None
        try:
            if not (pony.MODE == 'INTERACTIVE' and options.CUT_TRACEBACK):
>               raise exc
E               pony.orm.core.ERDiagramError: Mapping is not generated for entity 'Table'

/usr/local/virtualenvs/tmp-588bd07b744c67f2/lib/python3.8/site-packages/pony/utils/utils.py:106: ERDiagramError
================================================ short test summary info =================================================
FAILED app.py::test_query - pony.orm.core.ERDiagramError: Mapping is not generated for entity 'Table'
=================================================== 1 failed in 0.80s ====================================================

That's correct, sorry for the confusion, I didn't want to clutter the issue with error output. The tests fail (since this is minimum reproduceable). After running the tests, run

coverage debug data

And that gives the rest of the output that shows the file, app.py, and an extra 'user' file which doesn't exist. Changing the name of the variable in the select() changes the name of the ghost file.

Ah, OK! Well, PonyORM does something very strange: it compiles code at runtime to evaluate queries, which isn't the odd part. The odd part is that it does it like this:

code = compile(src, src, 'eval')

Which means it compiles your expression (user in this case), but also use the source of the expression as the "filename" of the code.

If I change app.py to this:

Table.select(lambda r: r.user == len("xyzzy"))

then coverage debug data shows this!:

/src/foo/bug1136/app.py: 8 lines
/src/foo/bug1136/len('xyzzy'): 1 lines

I'm going to write an issue and maybe a pull request for Pony.

@jpyams In the meantime, coverage xml -i will ignore errors, so you can generate an XML report.

Thank you very much!

Was this page helpful?
0 / 5 - 0 ratings