Skip to content

Commit 4ebeece

Browse files
committed
chore(internal): remove unused int/float conversion (#168)
1 parent 3cd2325 commit 4ebeece

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

src/finch/_models.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -313,16 +313,13 @@ def construct_type(*, value: object, type_: type) -> object:
313313
return [construct_type(value=entry, type_=inner_type) for entry in value]
314314

315315
if origin == float:
316-
try:
317-
return float(cast(Any, value))
318-
except Exception:
319-
return value
316+
if isinstance(value, int):
317+
coerced = float(value)
318+
if coerced != value:
319+
return value
320+
return coerced
320321

321-
if origin == int:
322-
try:
323-
return int(cast(Any, value))
324-
except Exception:
325-
return value
322+
return value
326323

327324
if type_ == datetime:
328325
try:

src/finch/pagination.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ def next_page_info(self) -> None:
4141
@classmethod
4242
def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseModelT: # noqa: ARG003
4343
return cls.construct(
44+
None,
4445
**{
4546
**(cast(Mapping[str, Any], data) if is_mapping(data) else {"items": data}),
46-
}
47+
},
4748
)
4849

4950

@@ -65,9 +66,10 @@ def next_page_info(self) -> None:
6566
@classmethod
6667
def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseModelT: # noqa: ARG003
6768
return cls.construct(
69+
None,
6870
**{
6971
**(cast(Mapping[str, Any], data) if is_mapping(data) else {"items": data}),
70-
}
72+
},
7173
)
7274

7375

tests/test_models.py

+20-9
Original file line numberDiff line numberDiff line change
@@ -439,21 +439,32 @@ class Model(BaseModel):
439439
assert model_json(model) == expected_json
440440

441441

442-
def test_coerces_int() -> None:
442+
def test_does_not_coerce_int() -> None:
443443
class Model(BaseModel):
444444
bar: int
445445

446446
assert Model.construct(bar=1).bar == 1
447-
assert Model.construct(bar=10.9).bar == 10
448-
assert Model.construct(bar="19").bar == 19
449-
assert Model.construct(bar=False).bar == 0
447+
assert Model.construct(bar=10.9).bar == 10.9
448+
assert Model.construct(bar="19").bar == "19" # type: ignore[comparison-overlap]
449+
assert Model.construct(bar=False).bar is False
450450

451-
# TODO: support this
452-
# assert Model.construct(bar="True").bar == 1
453451

454-
# mismatched types are left as-is
455-
m = Model.construct(bar={"foo": "bar"})
456-
assert m.bar == {"foo": "bar"} # type: ignore[comparison-overlap]
452+
def test_int_to_float_safe_conversion() -> None:
453+
class Model(BaseModel):
454+
float_field: float
455+
456+
m = Model.construct(float_field=10)
457+
assert m.float_field == 10.0
458+
assert isinstance(m.float_field, float)
459+
460+
m = Model.construct(float_field=10.12)
461+
assert m.float_field == 10.12
462+
assert isinstance(m.float_field, float)
463+
464+
# number too big
465+
m = Model.construct(float_field=2**53 + 1)
466+
assert m.float_field == 2**53 + 1
467+
assert isinstance(m.float_field, int)
457468

458469

459470
def test_deprecated_alias() -> None:

0 commit comments

Comments
 (0)