From 1c247d0903ee533212e733cb1f9c4815e342aca3 Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 18:54:26 +0200 Subject: [PATCH 1/6] fix: prevent shared state mutation in MockAPIResponse --- multi_api_mocker/definitions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/multi_api_mocker/definitions.py b/multi_api_mocker/definitions.py index efc259f..5aa20c1 100644 --- a/multi_api_mocker/definitions.py +++ b/multi_api_mocker/definitions.py @@ -41,13 +41,13 @@ class MockAPIResponse: customizations. """ - url: Union[str, re.Pattern] = None + url: str | re.Pattern = None method: str = None endpoint_name: str = None default_status_code: Optional[int] = None - default_json: Optional[Any] = None - default_text: Optional[str] = None - default_exc: Optional[Union[Exception, Type[Exception], None]] = None + default_json: Any | None = None + default_text: str | None = None + default_exc: Exception | type[Exception] | None = None def __init__( self, @@ -174,7 +174,7 @@ def exc(self): return self._exc or self.__class__.default_exc def _default_json(self, status_code): - return self.default_json + return self.default_json.copy() if self.default_json else None def _default_text(self, status_code): return self.default_text From 09156f56164bb58eaff89e74a4baac544d31a741 Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 19:01:47 +0200 Subject: [PATCH 2/6] remove python 3.8, add 3.11 and 3.12 --- .github/workflows/release.yml | 2 +- .github/workflows/validation.yml | 2 +- multi_api_mocker/definitions.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12be2f8..26740c6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v3 with: - python-version: '3.8' + python-version: '3.12' - name: Install build dependencies run: | diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 6e35223..d48b357 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 diff --git a/multi_api_mocker/definitions.py b/multi_api_mocker/definitions.py index 5aa20c1..0eab76b 100644 --- a/multi_api_mocker/definitions.py +++ b/multi_api_mocker/definitions.py @@ -1,6 +1,6 @@ import inspect import re -from typing import Union, Optional, Type, Any +from typing import Optional, Any class MockAPIResponse: @@ -44,7 +44,7 @@ class MockAPIResponse: url: str | re.Pattern = None method: str = None endpoint_name: str = None - default_status_code: Optional[int] = None + default_status_code: int | None = None default_json: Any | None = None default_text: str | None = None default_exc: Exception | type[Exception] | None = None From 8edb8bc33e45d0f6ed1bafce0c4b0c3504f4aa21 Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 19:02:53 +0200 Subject: [PATCH 3/6] remove optional import --- multi_api_mocker/definitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multi_api_mocker/definitions.py b/multi_api_mocker/definitions.py index 0eab76b..740d4db 100644 --- a/multi_api_mocker/definitions.py +++ b/multi_api_mocker/definitions.py @@ -1,6 +1,6 @@ import inspect import re -from typing import Optional, Any +from typing import Any class MockAPIResponse: From 78478b2ee72024411b79c26346b9130cf5b4e9ad Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 19:18:08 +0200 Subject: [PATCH 4/6] fix test comp with py312 --- multi_api_mocker/definitions.py | 10 +++++----- tests/test_definitions.py | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/multi_api_mocker/definitions.py b/multi_api_mocker/definitions.py index 740d4db..13b9860 100644 --- a/multi_api_mocker/definitions.py +++ b/multi_api_mocker/definitions.py @@ -130,9 +130,9 @@ def validate_class_attributes(cls): type_name = type(value).__name__ message = ( - f"The `{attr}` attribute in subclass `{cls.__name__}` " - f"must be of type `{', '.join(expected_type_names)}`, " - f"got `{type_name}`: `{value}`." + f"The {attr!r} attribute in subclass {cls.__name__!r} " + f"must be of type {', '.join(expected_type_names)!r}, " + f"got {type_name!r}: {value!r}." ) raise TypeError(message) @@ -144,9 +144,9 @@ def validate_class_attributes(cls): or isinstance(value, Exception) ): raise TypeError( - f"The `default_exc` attribute in subclass `{cls.__name__}` " + f"The 'default_exc' attribute in subclass {cls.__name__!r} " f"must be a subclass or instance of Exception or None, " - f"got `{type(value).__name__}`: `{value}`." + f"got {type(value).__name__!r}: {value!r}." ) @property diff --git a/tests/test_definitions.py b/tests/test_definitions.py index 71a2000..b4da775 100644 --- a/tests/test_definitions.py +++ b/tests/test_definitions.py @@ -119,8 +119,8 @@ def test_subclassing_with_invalid_url(self): assert ( str(exc_info.value) - == "The `url` attribute in subclass `MockAPIResponseSubclass` " - "must be of type `str, Pattern`, got `int`: `1`." + == "The 'url' attribute in subclass 'MockAPIResponseSubclass' " + "must be of type 'str, Pattern', got 'int': 1." ) @pytest.mark.parametrize( @@ -129,37 +129,37 @@ def test_subclassing_with_invalid_url(self): ( "method", 200, - "The `method` attribute in subclass `MockAPIResponseSubclass` " - "must be of type `str`, got `int`: `200`.", + "The 'method' attribute in subclass 'MockAPIResponseSubclass' " + "must be of type 'str', got 'int': 200.", ), ( "endpoint_name", False, ( - "The `endpoint_name` attribute in subclass " - "`MockAPIResponseSubclass` must be of type `str`, got `bool`: `False`." # noqa: E501 + "The 'endpoint_name' attribute in subclass " + "'MockAPIResponseSubclass' must be of type 'str', got 'bool': False." # noqa: E501 ), ), ( "default_status_code", "NotAnInt", ( - "The `default_status_code` attribute in subclass `MockAPIResponseSubclass` " # noqa: E501 - "must be of type `int, None`, got `str`: `NotAnInt`." + "The 'default_status_code' attribute in subclass 'MockAPIResponseSubclass' " # noqa: E501 + "must be of type 'int, None', got 'str': 'NotAnInt'." ), ), ( "default_text", 123, - "The `default_text` attribute in subclass `MockAPIResponseSubclass` " - "must be of type `str, None`, got `int`: `123`.", + "The 'default_text' attribute in subclass 'MockAPIResponseSubclass' " + "must be of type 'str, None', got 'int': 123.", ), ( "default_exc", "NotATypeOrNone", - "The `default_exc` attribute in subclass `MockAPIResponseSubclass` " - "must be a subclass or instance of Exception or None, got `str`: " - "`NotATypeOrNone`.", + "The 'default_exc' attribute in subclass 'MockAPIResponseSubclass' " + "must be a subclass or instance of Exception or None, got 'str': " + "'NotATypeOrNone'.", ), ], ids=[ From 5c40820d7863ec922269e1cbfdf3fec098bc3679 Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 19:20:47 +0200 Subject: [PATCH 5/6] remove 309 support --- .github/workflows/validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index d48b357..0a8d4f1 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] + python-version: ['3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 From 1b595749790795f42d788956cfa1ca979865c0cb Mon Sep 17 00:00:00 2001 From: Dacian Popute Date: Wed, 5 Feb 2025 19:26:26 +0200 Subject: [PATCH 6/6] chore: update changelog for 1.3.0 release --- CHANGELOG.md | 10 ++++++++++ multi_api_mocker/__init__.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2873ce..9211e9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog + +## [1.3.0] - 2024-02-05 + +### Changed +- Dropped support for Python 3.8 and 3.9 +- Added support for Python 3.12 + +### Fixed +- Fixed issue where `partial_json` modifications were mutating the class-level `default_json` attribute in `MockAPIResponse`, causing unexpected behavior in tests. + ## [1.2.1] - 2024-05-22 ### Changed diff --git a/multi_api_mocker/__init__.py b/multi_api_mocker/__init__.py index 595caea..527b705 100644 --- a/multi_api_mocker/__init__.py +++ b/multi_api_mocker/__init__.py @@ -2,4 +2,4 @@ __author__ = """Dacian Popute""" __email__ = "dacian@ottu.com" -__version__ = "1.2.2" +__version__ = "1.3.0" diff --git a/setup.cfg b/setup.cfg index 5d18995..5d1c1b7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.2.2 +current_version = 1.3.0 commit = False tag = True tag_name = v{new_version} diff --git a/setup.py b/setup.py index a4003da..c5502a5 100644 --- a/setup.py +++ b/setup.py @@ -51,6 +51,6 @@ test_suite="tests", tests_require=test_requirements, url="https://github.com/ottuco/multi_api_mocker", - version="1.2.2", + version="1.3.0", zip_safe=False, )