Skip to content

Commit

Permalink
Use tomli/tomli-w instead of unmaintained toml
Browse files Browse the repository at this point in the history
Replace the `toml` dependency that is unmaintained (last release
in 2020) and does not implement TOML 1.0 with more modern `tomli`
and `tomli-w` packages.

Co-authored-by: Maksim Beliaev <beliaev.m.s@gmail.com>
  • Loading branch information
mgorny and beliaev-maksim committed Oct 12, 2022
1 parent 27cb0c7 commit cdc131b
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 14 deletions.
5 changes: 3 additions & 2 deletions responses/__init__.py
Expand Up @@ -25,7 +25,8 @@
from typing import overload
from warnings import warn

import toml as _toml
import tomli as _toml

from requests.adapters import HTTPAdapter
from requests.adapters import MaxRetryError
from requests.exceptions import ConnectionError
Expand Down Expand Up @@ -770,7 +771,7 @@ def add(
put = partialmethod(add, PUT)

def _add_from_file(self, file_path: "Union[str, bytes, os.PathLike[Any]]") -> None:
with open(file_path) as file:
with open(file_path, "rb") as file:
data = _toml.load(file)

for rsp in data["responses"]:
Expand Down
18 changes: 13 additions & 5 deletions responses/_recorder.py
Expand Up @@ -2,10 +2,10 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING: # pragma: no cover
import io
import os

from typing import Any
from typing import BinaryIO
from typing import Callable
from typing import Dict
from typing import List
Expand All @@ -18,15 +18,23 @@
from responses import _F
from responses import BaseResponse

import toml as _toml
import tomli_w as _toml

from responses import RequestsMock
from responses import Response
from responses import _real_send
from responses.registries import OrderedRegistry


def _dump(registered: "List[BaseResponse]", destination: "io.IOBase") -> None:
def _remove_nones(d: "Any") -> "Any":
if isinstance(d, dict):
return {k: _remove_nones(v) for k, v in d.items() if v is not None}
if isinstance(d, list):
return [_remove_nones(i) for i in d]
return d


def _dump(registered: "List[BaseResponse]", destination: "BinaryIO") -> None:
data: Dict[str, Any] = {"responses": []}
for rsp in registered:
try:
Expand All @@ -49,7 +57,7 @@ def _dump(registered: "List[BaseResponse]", destination: "io.IOBase") -> None:
"Cannot dump response object."
"Probably you use custom Response object that is missing required attributes"
) from exc
_toml.dump(data, destination)
_toml.dump(_remove_nones(data), destination)


class Recorder(RequestsMock):
Expand All @@ -71,7 +79,7 @@ def deco_record(function: "_F") -> "Callable[..., Any]":
def wrapper(*args: "Any", **kwargs: "Any") -> "Any": # type: ignore[misc]
with self:
ret = function(*args, **kwargs)
with open(file_path, "w") as file:
with open(file_path, "wb") as file:
_dump(self.get_registry().registered, file)

return ret
Expand Down
11 changes: 6 additions & 5 deletions responses/tests/test_recorder.py
@@ -1,7 +1,8 @@
from pathlib import Path

import requests
import toml
import tomli_w
import tomli as _toml

import responses
from responses import _recorder
Expand Down Expand Up @@ -94,8 +95,8 @@ def run():

run()

with open(self.out_file) as file:
data = toml.load(file)
with open(self.out_file, "rb") as file:
data = _toml.load(file)

assert data == get_data(httpserver.host, httpserver.port)

Expand All @@ -109,8 +110,8 @@ def teardown(self):
assert not out_file.exists()

def test_add_from_file(self):
with open("out.toml", "w") as file:
toml.dump(get_data("example.com", "8080"), file)
with open("out.toml", "wb") as file:
tomli_w.dump(get_data("example.com", "8080"), file)

@responses.activate
def run():
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -19,8 +19,8 @@
install_requires = [
"requests>=2.22.0,<3.0",
"urllib3>=1.25.10",
"toml",
"types-toml",
"tomli",
"tomli-w",
"typing_extensions; python_version < '3.8'",
]

Expand Down

0 comments on commit cdc131b

Please sign in to comment.