Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'Module' object has no attribute '_obj' #386

Closed
aklaver opened this issue Aug 25, 2016 · 9 comments
Closed

AttributeError: 'Module' object has no attribute '_obj' #386

aklaver opened this issue Aug 25, 2016 · 9 comments

Comments

@aklaver
Copy link

aklaver commented Aug 25, 2016

Django 1.8.14
pytest==3.0.1
pytest-django-3.0.0

This code(a simplified version of real code):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pytest
import hplc_app.views as vw


class testClass(object):
    pass


def testStr():
    print('test')

Gives this Traceback

../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/_pytest/python.py:209: in fget
    return self._obj
E   AttributeError: 'Module' object has no attribute '_obj'

During handling of the above exception, another exception occurred:
tests/test_test_views.py:6: in <module>
    import hplc_app.views as vw
hplc_app/views.py:24: in <module>
    import hplc_app.forms as forms
hplc_app/forms.py:17: in <module>
    class DistrictForm(forms.Form):
hplc_app/forms.py:20: in DistrictForm
    district_list = [(d.district_id, d.district_short_name) for d in districts]
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:162: in __iter__
    self._fetch_all()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:965: in _fetch_all
    self._result_cache = list(self.iterator())
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/sql/compiler.py:838: in execute_sql
    cursor = self.connection.cursor()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/backends/base/base.py:162: in cursor
    cursor = self.make_debug_cursor(self._cursor())
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/backends/base/base.py:135: in _cursor
    self.ensure_connection()
E   Failed: Database access not allowed, use the "django_db" mark to enable it.

The above combination of software works on other test files. Using pytest-django==2.9.1 also works

@blueyed
Copy link
Contributor

blueyed commented Aug 25, 2016

You are accessing the DB when defining your form already (during import):

district_list = [(d.district_id, d.district_short_name) for d in districts]

That is probably not what you want, since then the list is (probably) stale.

The AttributeError from pytest appears to only be a cache miss: https://github.com/pytest-dev/pytest/blob/86ec3f37afbf3238a437b92d30115d87a9cf3141/_pytest/python.py#L207-L211

@blueyed
Copy link
Contributor

blueyed commented Aug 25, 2016

In pytest-django the DB blocker is more strict, and I'd say that it probably found some issue in your code.

I could imagine to handle this better in this specific case, so that not the AttributeError would be in the spotlight.

@blueyed
Copy link
Contributor

blueyed commented Aug 25, 2016

Can you post the full output from pytest, please?
So it can be seen if it's an error during setup or the test itself.
FWIW, pytest.fail(), which we're using here throws Failed(OutcomeException), which I could imagine could be handled after/with the AttributeError. That would be an issue for pytest though.

@aklaver
Copy link
Author

aklaver commented Aug 25, 2016

The issue seems to be tied to pytest-django not pytest
The full output, also output further below from when I run with pytest-django==2.9.1 and same version of pytest:

(hplc_dj18_py3) aklaver@panda:~/py_virt/hplc_dj18_py3/hplc_site> pytest -v -s tests/test_test_views.py 
==================================================================== test session starts ====================================================================
platform linux -- Python 3.4.5, pytest-3.0.1, py-1.4.31, pluggy-0.3.1 -- /home/aklaver/py_virt/hplc_dj18_py3/bin/python3.4
cachedir: .cache
Django settings: hplc_site.dev_settings (from environment variable)
rootdir: /home/aklaver/software_projects/hplc_app/hplc_site, inifile: pytest.ini
plugins: cov-2.3.1, django-3.0.0
collected 0 items / 1 errors 

========================================================================== ERRORS ===========================================================================
_________________________________________________________ ERROR collecting tests/test_test_views.py _________________________________________________________
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/_pytest/python.py:209: in fget
    return self._obj
E   AttributeError: 'Module' object has no attribute '_obj'

During handling of the above exception, another exception occurred:
tests/test_test_views.py:5: in <module>
    import hplc_app.views as vw
hplc_app/views.py:24: in <module>
    import hplc_app.forms as forms
hplc_app/forms.py:17: in <module>
    class DistrictForm(forms.Form):
hplc_app/forms.py:20: in DistrictForm
    district_list = [(d.district_id, d.district_short_name) for d in districts]
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:162: in __iter__
    self._fetch_all()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:965: in _fetch_all
    self._result_cache = list(self.iterator())
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/query.py:238: in iterator
    results = compiler.execute_sql()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/models/sql/compiler.py:838: in execute_sql
    cursor = self.connection.cursor()
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/backends/base/base.py:162: in cursor
    cursor = self.make_debug_cursor(self._cursor())
../../../py_virt/hplc_dj18_py3/lib/python3.4/site-packages/django/db/backends/base/base.py:135: in _cursor
    self.ensure_connection()
E   Failed: Database access not allowed, use the "django_db" mark to enable it.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(hplc_dj18_py3) aklaver@panda:~/py_virt/hplc_dj18_py3/hplc_site> pytest -v -s tests/test_test_views.py 
==================================================================== test session starts ====================================================================
platform linux -- Python 3.4.5, pytest-3.0.1, py-1.4.31, pluggy-0.3.1 -- /home/aklaver/py_virt/hplc_dj18_py3/bin/python3.4
cachedir: .cache
django settings: hplc_site.dev_settings (from environment variable)
rootdir: /home/aklaver/software_projects/hplc_app/hplc_site, inifile: pytest.ini
plugins: cov-2.3.1, django-2.9.1
collected 1 items 

tests/test_test_views.py::testStr test
PASSED

@aklaver
Copy link
Author

aklaver commented Aug 25, 2016

I use --reuse-db and if I where to hazard a guess the issue is coming from here:

e540ace

in pytest_django/db_reuse.py

I will need to do some more digging to verify.

@blueyed
Copy link
Contributor

blueyed commented Aug 26, 2016

The issue seems to be tied to pytest-django not pytest

It is more strict now. This is expected to happen.

But the error should not be about the AssertionError: I guess pytest.fail is not properly handled / meant to be used in that phase.

Let's wait for @pelme to chime in.

@pelme
Copy link
Member

pelme commented Aug 28, 2016

@aklaver Your code does not do what you expect. As @blueyed pointed out, the line district_list = [(d.district_id, d.district_short_name) for d in districts] is triggering a database query at the import time of your forms module. That is not allowed, the database is not necessarily available to service queries at import time (test collection time with pytest-django).

The code does not do what you intend it to do. district_list will be created when you start your web server. This means that new districts that are added to the databse will not show up in your forms until your server is restarted.

pytest-django was buggy and accidentally did not throw an error prior to 3.0.0. You need to change your code to have the query run at a later time (at the time of a request). If you need help, provide the full code of your form class and I can suggest how you can change it.


E   AttributeError: 'Module' object has no attribute '_obj'

looks like an issue with pytest. Let's create a pytest issue for that error and then we can close this issue.

@aklaver
Copy link
Author

aklaver commented Aug 28, 2016

Per @blueyed and your (@pelme ) suggestions I moved the choice generation into the init
of the forms and the tests run. Thanks for the heads up. As to filing an issue with pytest I think it would be better if you do that as I am still not sure exactly what the error message is saying. If you do not have the time I can do it.

@bluetech
Copy link
Member

bluetech commented Oct 9, 2020

Seems to be fixed in pytest.

@bluetech bluetech closed this as completed Oct 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants