From bd64a148341ca7f488552f25157d76cfe9d41bc0 Mon Sep 17 00:00:00 2001 From: Alexandr Shashkin Date: Mon, 13 Nov 2023 20:33:41 +0300 Subject: [PATCH] dirty_equals/_other.py: fix IsUrl for compatibility with Pydantic v2 Delete 'tld' for allowed attributes. See: https://docs.pydantic.dev/latest/api/networks/. Strip trailing '/' from parsed by pydantic url, if it isn't specified in other operand, because of it is always added after host due to Pydantic v2. See: https://github.com/pydantic/pydantic-settings/issues/104#issuecomment-1621630378 --- dirty_equals/_other.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dirty_equals/_other.py b/dirty_equals/_other.py index 7da1904..08ecda5 100644 --- a/dirty_equals/_other.py +++ b/dirty_equals/_other.py @@ -197,9 +197,13 @@ class IsUrl(DirtyEquals[str]): **expected_attributes: Expected values for url attributes ```py title="IsUrl" from dirty_equals import IsUrl + from pydantic import version assert 'https://example.com' == IsUrl - assert 'https://example.com' == IsUrl(tld='com') + if tuple(map(int, version.VERSION.split('.')))[0] == 1: + # tld isn't required when there is pydantic >= 2. + # See: https://docs.pydantic.dev/latest/api/networks/ + assert 'https://example.com' == IsUrl(tld='com') assert 'https://example.com' == IsUrl(scheme='https') assert 'https://example.com' != IsUrl(scheme='http') assert 'postgres://user:pass@localhost:5432/app' == IsUrl(postgres_dsn=True) @@ -245,6 +249,10 @@ class IsUrl(DirtyEquals[str]): url_types_sum = sum(url_type_mappings.values()) if url_types_sum > 1: raise ValueError('You can only check against one Pydantic url type at a time') + if self.pydantic_version[0] > 1 and "tld" in self.allowed_attribute_checks: + # tld isn't required when there is pydantic >= 2. + # See: https://docs.pydantic.dev/latest/api/networks/ + self.allowed_attribute_checks.remove("tld") for item in expected_attributes: if item not in self.allowed_attribute_checks: raise TypeError( @@ -268,7 +276,14 @@ class IsUrl(DirtyEquals[str]): if self.pydantic_version[0] == 1: # checking major version equal = parsed == other else: - equal = parsed.unicode_string() == other + # Trailing '/' is always added after host in Pydantic v2. Delete it + # if isn't specified in other. See: + # https://github.com/pydantic/pydantic-settings/issues/104#issuecomment-1621630378 + # And https://github.com/pydantic/pydantic/issues/7186 + if other[-1] != "/": + equal = parsed.unicode_string().rstrip("/") == other + else: + equal = parsed.unicode_string() == other if not self.attribute_checks: return equal -- 2.42.1