summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2021-10-10 12:33:21 -0500
committerJordan Cook <jordan.cook@pioneer.com>2021-10-10 12:43:52 -0500
commit9f8027f658c9dbc57742ce75ed8f30d62daffbf9 (patch)
tree12c9d72e739b8fad2dfe997fc8f5aacd58053438
parente9f425d4631c9da8b49f598d4a82e6f6b729dd73 (diff)
downloadrequests-cache-9f8027f658c9dbc57742ce75ed8f30d62daffbf9.tar.gz
Add better error message if parent path exists but isn't a directory
-rw-r--r--HISTORY.md1
-rw-r--r--requests_cache/backends/sqlite.py17
-rw-r--r--tests/integration/test_sqlite.py11
3 files changed, 22 insertions, 7 deletions
diff --git a/HISTORY.md b/HISTORY.md
index 79839a9..f86478f 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -3,6 +3,7 @@
## 0.8.2 (Unreleased)
* Use `Cache-Control` **request** headers by default
* Support `expire_after` param for `CachedSession.send()`
+* Filesystem and SQLite backends: Add better error message if parent path exists but isn't a directory
* Make per-request expiration thread-safe for both `CachedSession.request()` and `CachedSession.send()`
* Handle some additional corner cases when normalizing request data
* Some micro-optimizations for request matching
diff --git a/requests_cache/backends/sqlite.py b/requests_cache/backends/sqlite.py
index def6c13..aa7f4d4 100644
--- a/requests_cache/backends/sqlite.py
+++ b/requests_cache/backends/sqlite.py
@@ -145,14 +145,13 @@ class SQLiteDict(BaseStorage):
**kwargs,
):
super().__init__(**kwargs)
+ self._can_commit = True
+ self._local_context = threading.local()
+ self._lock = threading.RLock()
self.connection_kwargs = get_valid_kwargs(sqlite_template, kwargs)
self.db_path = _get_sqlite_cache_path(db_path, use_cache_dir, use_temp, use_memory)
self.fast_save = fast_save
self.table_name = table_name
-
- self._lock = threading.RLock()
- self._can_commit = True
- self._local_context = threading.local()
self.init_db()
def init_db(self):
@@ -312,9 +311,15 @@ def get_cache_path(db_path: AnyPath, use_cache_dir: bool = False, use_temp: bool
elif use_temp and not db_path.is_absolute():
db_path = Path(gettempdir()) / db_path
- # Expand relative and user paths (~/*), and make sure parent dirs exist
+ # Expand relative and user paths (~), make parent dir(s), and better error if parent is a file
db_path = db_path.absolute().expanduser()
- db_path.parent.mkdir(parents=True, exist_ok=True)
+ try:
+ db_path.parent.mkdir(parents=True, exist_ok=True)
+ except FileExistsError:
+ raise FileExistsError(
+ f'Parent path exists and is not a directory: {db_path.parent}.'
+ 'Please either delete the file or choose a different path.'
+ )
return db_path
diff --git a/tests/integration/test_sqlite.py b/tests/integration/test_sqlite.py
index 67ab7a8..1840a78 100644
--- a/tests/integration/test_sqlite.py
+++ b/tests/integration/test_sqlite.py
@@ -1,8 +1,10 @@
import os
-from tempfile import gettempdir
+from os.path import join
+from tempfile import NamedTemporaryFile, gettempdir
from threading import Thread
from unittest.mock import patch
+import pytest
from appdirs import user_cache_dir
from requests_cache.backends.base import BaseCache
@@ -51,6 +53,13 @@ class SQLiteTestCase(BaseStorageTest):
def test_use_memory__uri(self):
self.init_cache(':memory:').db_path == ':memory:'
+ def test_non_dir_parent_exists(self):
+ """Expect a custom error message if a parent path already exists but isn't a directory"""
+ with NamedTemporaryFile() as tmp:
+ with pytest.raises(FileExistsError) as exc_info:
+ self.storage_class(join(tmp.name, 'invalid_path'))
+ assert 'not a directory' in str(exc_info.value)
+
def test_bulk_commit(self):
cache = self.init_cache()
with cache.bulk_commit():