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

Detached instance error at cleanup of location fixture #114

Open
monotasker opened this issue Feb 20, 2025 · 0 comments
Open

Detached instance error at cleanup of location fixture #114

monotasker opened this issue Feb 20, 2025 · 0 comments
Labels

Comments

@monotasker
Copy link

monotasker commented Feb 20, 2025

Package version: 2.2.1 (seems also with 3.0.0)

Describe the bug

When tearing down the location fixture I get a DetachedInstanceError:

sqlalchemy.orm.exc.DetachedInstanceError: Instance <Location at 0x124d10130> is not bound to a Session; attribute refresh operation cannot proceed

The error is triggered by the teardown of the temporary location in the last line of the fixture:

shutil.rmtree(location_obj.uri)

The cause seems to be that location_obj is detached from the session by the database.session.commit() call a few lines above. So attempting to access that object's uri property raises the error.

I believe the same uri value is available as a local variable (uri) that can be accessed directly. So we don't need to access the value from the (now detached) location object. In my tests it works to simply change that line to

shutil.rmtree(uri)

I'm happy to submit a pull request with that change if I'm right about this.

Steps to Reproduce

  1. Use the location fixture in a test
  2. Clean up fixture after last test has run
  3. Receive error

Additional context

The full pytest error output in case it's helpful:

database = <SQLAlchemy engine=None>

    @pytest.yield_fixture(scope="module")
    def location(database):
        """Creates a simple default location for a test.
    
        Scope: function
    
        Use this fixture if your test requires a `files location <https://invenio-
        files-rest.readthedocs.io/en/latest/api.html#invenio_files_rest.models.
        Location>`_. The location will be a default location with the name
        ``pytest-location``.
        """
        from invenio_files_rest.models import Location
    
        uri = tempfile.mkdtemp()
        location_obj = Location(name="pytest-location", uri=uri, default=True)
    
        database.session.add(location_obj)
        database.session.commit()
    
        yield location_obj
    
>       shutil.rmtree(location_obj.uri)

tests/conftest.py:217: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.local/share/virtualenvs/knowledge-commons-works-2Z_360jm/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py:487: in __get__
    return self.impl.get(state, dict_)
../../../.local/share/virtualenvs/knowledge-commons-works-2Z_360jm/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py:959: in get
    value = self._fire_loader_callables(state, key, passive)
../../../.local/share/virtualenvs/knowledge-commons-works-2Z_360jm/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py:990: in _fire_loader_callables
    return state._load_expired(state, passive)
../../../.local/share/virtualenvs/knowledge-commons-works-2Z_360jm/lib/python3.9/site-packages/sqlalchemy/orm/state.py:712: in _load_expired
    self.manager.expired_attribute_loader(self, toload, passive)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

mapper = <Mapper at 0x11487cfa0; Location>
state = <sqlalchemy.orm.state.InstanceState object at 0x1439b17c0>
attribute_names = {'buckets', 'created', 'default', 'id', 'name', 'updated', ...}
passive = symbol('PASSIVE_OFF')

    def load_scalar_attributes(mapper, state, attribute_names, passive):
        """initiate a column-based attribute refresh operation."""
    
        # assert mapper is _state_mapper(state)
        session = state.session
        if not session:
>           raise orm_exc.DetachedInstanceError(
                "Instance %s is not bound to a Session; "
                "attribute refresh operation cannot proceed" % (state_str(state))
            )
E           sqlalchemy.orm.exc.DetachedInstanceError: Instance <Location at 0x124d10130> is not bound to a Session; attribute refresh operation cannot proceed (Background on this error at: https://sqlalche.me/e/14/bhk3)
@monotasker monotasker added the bug label Feb 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant