diff --git a/radicale/config.py b/radicale/config.py
index d1b66251a..1ed2fae32 100644
--- a/radicale/config.py
+++ b/radicale/config.py
@@ -349,7 +349,7 @@ def load(paths: Optional[Iterable[Tuple[str, bool]]] = None
config_source = "config file %r" % path
config: types.CONFIG
try:
- with open(path, "r") as f:
+ with open(path) as f:
parser.read_file(f)
config = {s: {o: parser[s][o] for o in parser.options(s)}
for s in parser.sections()}
diff --git a/radicale/server.py b/radicale/server.py
index 600a31ac2..2f03837cf 100644
--- a/radicale/server.py
+++ b/radicale/server.py
@@ -176,7 +176,7 @@ def server_bind(self) -> None:
if name == "certificate_authority" and not filename:
continue
try:
- open(filename, "r").close()
+ open(filename).close()
except OSError as e:
raise RuntimeError(
"Invalid %s value for option %r in section %r in %s: %r "
diff --git a/radicale/types.py b/radicale/types.py
index c7e1904a2..6899a7553 100644
--- a/radicale/types.py
+++ b/radicale/types.py
@@ -15,9 +15,9 @@
# along with Radicale. If not, see .
import contextlib
-import sys
from typing import (Any, Callable, ContextManager, Iterator, List, Mapping,
- MutableMapping, Sequence, Tuple, TypeVar, Union)
+ MutableMapping, Protocol, Sequence, Tuple, TypeVar, Union,
+ runtime_checkable)
WSGIResponseHeaders = Union[Mapping[str, str], Sequence[Tuple[str, str]]]
WSGIResponse = Tuple[int, WSGIResponseHeaders, Union[None, str, bytes]]
@@ -41,20 +41,17 @@ def contextmanager(func: Callable[..., Iterator[_T]]
return result
-if sys.version_info >= (3, 8):
- from typing import Protocol, runtime_checkable
+@runtime_checkable
+class InputStream(Protocol):
+ def read(self, size: int = ...) -> bytes: ...
- @runtime_checkable
- class InputStream(Protocol):
- def read(self, size: int = ...) -> bytes: ...
- @runtime_checkable
- class ErrorStream(Protocol):
- def flush(self) -> object: ...
- def write(self, s: str) -> object: ...
-else:
- ErrorStream = Any
- InputStream = Any
+@runtime_checkable
+class ErrorStream(Protocol):
+ def flush(self) -> object: ...
+
+ def write(self, s: str) -> object: ...
+
from radicale import item, storage # noqa:E402 isort:skip
diff --git a/radicale/utils.py b/radicale/utils.py
index 6125792a5..a65126464 100644
--- a/radicale/utils.py
+++ b/radicale/utils.py
@@ -16,18 +16,12 @@
# You should have received a copy of the GNU General Public License
# along with Radicale. If not, see .
-import sys
-from importlib import import_module
+from importlib import import_module, metadata
from typing import Callable, Sequence, Type, TypeVar, Union
from radicale import config
from radicale.log import logger
-if sys.version_info < (3, 8):
- import pkg_resources
-else:
- from importlib import metadata
-
_T_co = TypeVar("_T_co", covariant=True)
@@ -52,6 +46,4 @@ def load_plugin(internal_types: Sequence[str], module_name: str,
def package_version(name):
- if sys.version_info < (3, 8):
- return pkg_resources.get_distribution(name).version
return metadata.version(name)