From ff4860d7ac405c7dfb82448fe9ab8d4447adc1de Mon Sep 17 00:00:00 2001 From: Vitaliy <160263432+vitalivo@users.noreply.github.com> Date: Sat, 12 Sep 2026 17:24:21 +0300 Subject: [PATCH] Require matching types when checking Literal values --- CHANGELOG.md | 4 +++- dacite/types.py | 2 +- tests/core/test_literal.py | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc82eed0..c2909446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -... +### Fixed + +- Require matching value types when checking `Literal` fields, distinguishing equal boolean, integer, and enum values. ## [1.9.2] - 2025-02-05 diff --git a/dacite/types.py b/dacite/types.py index 5cb1a5bd..d89470b6 100644 --- a/dacite/types.py +++ b/dacite/types.py @@ -171,7 +171,7 @@ def is_instance(value: Any, type_: Type) -> bool: if is_new_type(type_): return is_instance(value, extract_new_type(type_)) if is_literal(type_): - return value in extract_generic(type_) + return any(type(value) is type(literal) and value == literal for literal in extract_generic(type_)) if is_init_var(type_): return is_instance(value, extract_init_var(type_)) if is_type_generic(type_): diff --git a/tests/core/test_literal.py b/tests/core/test_literal.py index 922a6ac1..0765b39f 100644 --- a/tests/core/test_literal.py +++ b/tests/core/test_literal.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from enum import IntEnum from typing import Optional import pytest @@ -57,3 +58,26 @@ class X: result = from_dict(X, {"l": "A"}) assert result == X(l="A") + + +class Number(IntEnum): + ONE = 1 + + +@literal_support +@pytest.mark.parametrize( + "literal, value", [(1, True), (True, 1), (0, False), (False, 0), (1, 1.0), (Number.ONE, 1), (1, Number.ONE)] +) +def test_from_dict_with_equal_literal_of_wrong_type(literal, value): + from typing import Literal + + @dataclass + class X: + l: Literal[literal] + + with pytest.raises(WrongTypeError): + from_dict(X, {"l": value}) + + result = from_dict(X, {"l": literal}) + assert result.l == literal + assert type(result.l) is type(literal)