Skip to content

Commit

Permalink
feat: drop support of Python older than 3.7 (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Jun 8, 2023
1 parent 03d2ed5 commit d404a91
Show file tree
Hide file tree
Showing 27 changed files with 166 additions and 172 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ jobs:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
os: ["macos-latest", "windows-latest", "ubuntu-latest"]
include:
- python-version: "3.6"
os: "ubuntu-20.04"
- python-version: "3.6"
os: "windows-latest"

steps:
- uses: "actions/checkout@v3"
Expand Down
5 changes: 3 additions & 2 deletions cachecontrol/_cmd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-FileCopyrightText: 2015 Eric Larson
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations

import logging
from argparse import ArgumentParser
Expand Down Expand Up @@ -36,7 +37,7 @@ def get_session() -> requests.Session:
return sess


def get_args() -> "Namespace":
def get_args() -> Namespace:
parser = ArgumentParser()
parser.add_argument("url", help="The URL to try and cache")
return parser.parse_args()
Expand All @@ -53,7 +54,7 @@ def main() -> None:
setup_logging()

# try setting the cache
cache_controller: "CacheController" = (
cache_controller: CacheController = (
sess.cache_controller # type: ignore[attr-defined]
)
cache_controller.cache_response(resp.request, resp.raw)
Expand Down
51 changes: 23 additions & 28 deletions cachecontrol/adapter.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# SPDX-FileCopyrightText: 2015 Eric Larson
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations

import functools
import types
import zlib
from typing import TYPE_CHECKING, Any, Collection, Mapping, Optional, Tuple, Type, Union
from typing import TYPE_CHECKING, Any, Collection, Mapping

from requests.adapters import HTTPAdapter

Expand All @@ -27,16 +28,16 @@ class CacheControlAdapter(HTTPAdapter):

def __init__(
self,
cache: Optional["BaseCache"] = None,
cache: BaseCache | None = None,
cache_etags: bool = True,
controller_class: Optional[Type[CacheController]] = None,
serializer: Optional["Serializer"] = None,
heuristic: Optional["BaseHeuristic"] = None,
cacheable_methods: Optional[Collection[str]] = None,
controller_class: type[CacheController] | None = None,
serializer: Serializer | None = None,
heuristic: BaseHeuristic | None = None,
cacheable_methods: Collection[str] | None = None,
*args: Any,
**kw: Any,
) -> None:
super(CacheControlAdapter, self).__init__(*args, **kw)
super().__init__(*args, **kw)
self.cache = DictCache() if cache is None else cache
self.heuristic = heuristic
self.cacheable_methods = cacheable_methods or ("GET",)
Expand All @@ -48,16 +49,14 @@ def __init__(

def send(
self,
request: "PreparedRequest",
request: PreparedRequest,
stream: bool = False,
timeout: Union[None, float, Tuple[float, float], Tuple[float, None]] = None,
verify: Union[bool, str] = True,
cert: Union[
None, bytes, str, Tuple[Union[bytes, str], Union[bytes, str]]
] = None,
proxies: Optional[Mapping[str, str]] = None,
cacheable_methods: Optional[Collection[str]] = None,
) -> "Response":
timeout: None | float | tuple[float, float] | tuple[float, None] = None,
verify: bool | str = True,
cert: (None | bytes | str | tuple[bytes | str, bytes | str]) = None,
proxies: Mapping[str, str] | None = None,
cacheable_methods: Collection[str] | None = None,
) -> Response:
"""
Send a request. Use the request information to see if it
exists in the cache and cache the response if we need to and can.
Expand All @@ -74,19 +73,17 @@ def send(
# check for etags and add headers if appropriate
request.headers.update(self.controller.conditional_headers(request))

resp = super(CacheControlAdapter, self).send(
request, stream, timeout, verify, cert, proxies
)
resp = super().send(request, stream, timeout, verify, cert, proxies)

return resp

def build_response(
self,
request: "PreparedRequest",
response: "HTTPResponse",
request: PreparedRequest,
response: HTTPResponse,
from_cache: bool = False,
cacheable_methods: Optional[Collection[str]] = None,
) -> "Response":
cacheable_methods: Collection[str] | None = None,
) -> Response:
"""
Build a response by making a request or using the cache.
Expand Down Expand Up @@ -137,7 +134,7 @@ def build_response(
if response.chunked:
super_update_chunk_length = response._update_chunk_length # type: ignore[attr-defined]

def _update_chunk_length(self: "HTTPResponse") -> None:
def _update_chunk_length(self: HTTPResponse) -> None:
super_update_chunk_length()
if self.chunk_left == 0:
self._fp._close() # type: ignore[attr-defined]
Expand All @@ -146,9 +143,7 @@ def _update_chunk_length(self: "HTTPResponse") -> None:
_update_chunk_length, response
)

resp: "Response" = super( # type: ignore[no-untyped-call]
CacheControlAdapter, self
).build_response(request, response)
resp: Response = super().build_response(request, response) # type: ignore[no-untyped-call]

# See if we should invalidate the cache.
if request.method in self.invalidating_methods and resp.ok:
Expand All @@ -163,4 +158,4 @@ def _update_chunk_length(self: "HTTPResponse") -> None:

def close(self) -> None:
self.cache.close()
super(CacheControlAdapter, self).close() # type: ignore[no-untyped-call]
super().close() # type: ignore[no-untyped-call]
18 changes: 10 additions & 8 deletions cachecontrol/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
The cache object API for implementing caches. The default is a thread
safe in-memory dictionary.
"""
from __future__ import annotations

from threading import Lock
from typing import IO, TYPE_CHECKING, MutableMapping, Optional, Union
from typing import IO, TYPE_CHECKING, MutableMapping

if TYPE_CHECKING:
from datetime import datetime


class BaseCache(object):
def get(self, key: str) -> Optional[bytes]:
class BaseCache:
def get(self, key: str) -> bytes | None:
raise NotImplementedError()

def set(
self, key: str, value: bytes, expires: Optional[Union[int, "datetime"]] = None
self, key: str, value: bytes, expires: int | datetime | None = None
) -> None:
raise NotImplementedError()

Expand All @@ -30,15 +32,15 @@ def close(self) -> None:


class DictCache(BaseCache):
def __init__(self, init_dict: Optional[MutableMapping[str, bytes]] = None) -> None:
def __init__(self, init_dict: MutableMapping[str, bytes] | None = None) -> None:
self.lock = Lock()
self.data = init_dict or {}

def get(self, key: str) -> Optional[bytes]:
def get(self, key: str) -> bytes | None:
return self.data.get(key, None)

def set(
self, key: str, value: bytes, expires: Optional[Union[int, "datetime"]] = None
self, key: str, value: bytes, expires: int | datetime | None = None
) -> None:
with self.lock:
self.data.update({key: value})
Expand All @@ -65,7 +67,7 @@ class SeparateBodyBaseCache(BaseCache):
def set_body(self, key: str, body: bytes) -> None:
raise NotImplementedError()

def get_body(self, key: str) -> Optional["IO[bytes]"]:
def get_body(self, key: str) -> IO[bytes] | None:
"""
Return the body as file-like object.
"""
Expand Down
17 changes: 9 additions & 8 deletions cachecontrol/caches/file_cache.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# SPDX-FileCopyrightText: 2015 Eric Larson
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations

import hashlib
import os
from textwrap import dedent
from typing import IO, TYPE_CHECKING, Optional, Type, Union
from typing import IO, TYPE_CHECKING

from cachecontrol.cache import BaseCache, SeparateBodyBaseCache
from cachecontrol.controller import CacheController
Expand All @@ -16,7 +17,7 @@
from filelock import BaseFileLock


def _secure_open_write(filename: str, fmode: int) -> "IO[bytes]":
def _secure_open_write(filename: str, fmode: int) -> IO[bytes]:
# We only want to write to this file, so open it in write only mode
flags = os.O_WRONLY

Expand All @@ -39,7 +40,7 @@ def _secure_open_write(filename: str, fmode: int) -> "IO[bytes]":
# there
try:
os.remove(filename)
except (IOError, OSError):
except OSError:
# The file must not exist already, so we can just skip ahead to opening
pass

Expand All @@ -66,7 +67,7 @@ def __init__(
forever: bool = False,
filemode: int = 0o0600,
dirmode: int = 0o0700,
lock_class: Optional[Type["BaseFileLock"]] = None,
lock_class: type[BaseFileLock] | None = None,
) -> None:
try:
if lock_class is None:
Expand Down Expand Up @@ -100,7 +101,7 @@ def _fn(self, name: str) -> str:
parts = list(hashed[:5]) + [hashed]
return os.path.join(self.directory, *parts)

def get(self, key: str) -> Optional[bytes]:
def get(self, key: str) -> bytes | None:
name = self._fn(key)
try:
with open(name, "rb") as fh:
Expand All @@ -110,7 +111,7 @@ def get(self, key: str) -> Optional[bytes]:
return None

def set(
self, key: str, value: bytes, expires: Optional[Union[int, "datetime"]] = None
self, key: str, value: bytes, expires: int | datetime | None = None
) -> None:
name = self._fn(key)
self._write(name, value)
Expand All @@ -122,7 +123,7 @@ def _write(self, path: str, data: bytes) -> None:
# Make sure the directory exists
try:
os.makedirs(os.path.dirname(path), self.dirmode)
except (IOError, OSError):
except OSError:
pass

with self.lock_class(path + ".lock"):
Expand Down Expand Up @@ -155,7 +156,7 @@ class SeparateBodyFileCache(_FileCacheMixin, SeparateBodyBaseCache):
peak memory usage.
"""

def get_body(self, key: str) -> Optional["IO[bytes]"]:
def get_body(self, key: str) -> IO[bytes] | None:
name = self._fn(key) + ".body"
try:
return open(name, "rb")
Expand Down
10 changes: 5 additions & 5 deletions cachecontrol/caches/redis_cache.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# SPDX-FileCopyrightText: 2015 Eric Larson
#
# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations

from __future__ import division

from datetime import datetime, timezone
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING

from cachecontrol.cache import BaseCache

Expand All @@ -14,14 +14,14 @@


class RedisCache(BaseCache):
def __init__(self, conn: "Redis[bytes]") -> None:
def __init__(self, conn: Redis[bytes]) -> None:
self.conn = conn

def get(self, key: str) -> Optional[bytes]:
def get(self, key: str) -> bytes | None:
return self.conn.get(key)

def set(
self, key: str, value: bytes, expires: Optional[Union[int, datetime]] = None
self, key: str, value: bytes, expires: int | datetime | None = None
) -> None:
if not expires:
self.conn.set(key, value)
Expand Down
Loading

0 comments on commit d404a91

Please sign in to comment.