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: 'DbPickleDict' object has no attribute '_local_context' #433

Closed
glensc opened this issue Oct 10, 2021 · 6 comments · Fixed by #434
Closed

AttributeError: 'DbPickleDict' object has no attribute '_local_context' #433

glensc opened this issue Oct 10, 2021 · 6 comments · Fixed by #434
Labels
Milestone

Comments

@glensc
Copy link
Contributor

glensc commented Oct 10, 2021

The problem

requests cache can't load cache again:

  File "/Users/glen/MegaSync/scm/plex/PlexTraktSync/plex_trakt_sync/factory.py", line 44, in session
    session = CachedSession(trakt_cache)
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/session.py", line 45, in __init__
    self.cache = init_backend(backend, cache_name, **kwargs)
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/__init__.py", line 100, in init_backend
    return BACKEND_CLASSES[backend](*args, **kwargs)
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 38, in __init__
    self.responses = DbPickleDict(
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 90, in __init__
    self.db_path = _get_db_path(db_path, use_temp)
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 243, in _get_db_path
    makedirs(dirname(db_path), exist_ok=True)
  File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/os.py", line 225, in makedirs
    mkdir(name, mode)
FileExistsError: [Errno 17] File exists: '/Users/glen/.cache/PlexTraktSync'
Exception ignored in: <function DbDict.__del__ at 0x1105b4c10>
Traceback (most recent call last):
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 146, in __del__
    self.close()
  File "/Users/glen/.cache/direnv/PlexTraktSync/python-3.9.7/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 121, in close
    if getattr(self._local_context, 'con', None):
AttributeError: 'DbPickleDict' object has no attribute '_local_context'

Expected behavior

Catch or ignore error, do not throw.

Steps to reproduce the behavior

  1. install requests cache 0.8.0 (i guess)
  2. populate cache
  3. use same cache on requests cache 0.7.4

Workarounds

yes, nuke cache or upgrade package

Environment

  • requests-cache version: 0.7.4
  • Python version: 3.9.7
  • Platform: macOS
@glensc glensc added the bug label Oct 10, 2021
@glensc
Copy link
Contributor Author

glensc commented Oct 10, 2021

@JWCook I thought to report this, maybe you want to handle such errors gracefully again.

also, I see there mkdir EEXIST error, perhaps that should be handled too

@JWCook
Copy link
Member

JWCook commented Oct 10, 2021

I may need some more info to be able to reproduce this. Following those steps, it looks like the cached response just gets re-requested instead of raising an error. I'm not sure how DbPickleDict._local_context could be missing, since that's set in __init__(). Maybe something else is happening before it even gets to that?

As for the FileExistsError, an existing directory is already handled with makedirs("...", exist_ok=True), so I believe that can only fail if the path already exists and it's not a directory: https://github.com/python/cpython/blob/164dddf5f8c9c6b93f32c9f79b4301fc804576e9/Lib/os.py#L226-L230
In which case I don't think there's a good way to handle that automatically, since it requires deleting the file.

,..And I think I just answered my own question about _local_context. This error happens in __init__() before setting _local_context: https://github.com/reclosedev/requests-cache/blob/e9f425d4631c9da8b49f598d4a82e6f6b729dd73/requests_cache/backends/sqlite.py#L137-L156

When the class fails to initialize, python internally calls del on the partially initialized object, which then calls close(), which references self._local_context before it's created, which makes for a very confusing traceback. I'll get that fixed soon.

@glensc
Copy link
Contributor Author

glensc commented Oct 10, 2021

Looks like I can't reproduce this anymore either. But at least you got some ideas and some fixes out of this.

@glensc
Copy link
Contributor Author

glensc commented Oct 10, 2021

Also, /Users/glen/.cache/PlexTraktSync was a symlink pointing to a directory that did not exist.

@glensc
Copy link
Contributor Author

glensc commented Oct 10, 2021

Oh, that is the actual reason. cache file needs to point inside a "directory" which is a symlink to a path that does not exist.

in my case:

rm -rf /Users/glen/.cache/PlexTraktSync
ln -s /tmp/definitely-does-not-exist /Users/glen/.cache/PlexTraktSync

@JWCook
Copy link
Member

JWCook commented Oct 10, 2021

Fixed in the master branch. Now this will raise a less confusing error message. Thanks for the bug report!

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

Successfully merging a pull request may close this issue.

2 participants