Skip to content

Commit f2bd003

Browse files
committed
SNOW-2910128: improve decfloat tests
1 parent 3ea508b commit f2bd003

File tree

1 file changed

+62
-54
lines changed

1 file changed

+62
-54
lines changed

tests/test_decfloat.py

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,83 +25,84 @@ def _normalize_ddl(ddl: str) -> str:
2525
class TestDECFLOATType:
2626
"""Tests for DECFLOAT type support."""
2727

28+
@pytest.fixture(autouse=True)
29+
def reset_decfloat_state(self):
30+
"""Reset DECFLOAT warning flag and decimal precision before/after each test."""
31+
original_prec = decimal.getcontext().prec
32+
DECFLOAT._warned_precision = False
33+
yield
34+
decimal.getcontext().prec = original_prec
35+
DECFLOAT._warned_precision = False
36+
2837
def test_decfloat_type(self):
2938
"""Test DECFLOAT type instantiation."""
3039
decfloat_type = DECFLOAT()
3140
assert decfloat_type is not None
3241

3342
def test_decfloat_warns_on_low_precision_context(self):
3443
"""Test that DECFLOAT warns when decimal context precision is too low."""
35-
# Reset warning flag for clean test
36-
DECFLOAT._warned_precision = False
37-
original_prec = decimal.getcontext().prec
38-
39-
try:
40-
# Set precision below 38
41-
decimal.getcontext().prec = 28
44+
decimal.getcontext().prec = 28
4245

43-
decfloat_type = DECFLOAT()
44-
processor = decfloat_type.result_processor(None, None)
45-
46-
with warnings.catch_warnings(record=True) as w:
47-
warnings.simplefilter("always")
48-
processor(Decimal("123.456"))
46+
decfloat_type = DECFLOAT()
47+
processor = decfloat_type.result_processor(None, None)
4948

50-
assert len(w) == 1
51-
assert "decimal context precision (28)" in str(w[0].message)
52-
assert "DECFLOAT precision (38)" in str(w[0].message)
49+
with warnings.catch_warnings(record=True) as w:
50+
warnings.simplefilter("always")
51+
processor(Decimal("123.456")) # First call - should warn
52+
processor(Decimal("789.012")) # Second call - should not warn again
5353

54-
# Verify warning is only emitted once
55-
DECFLOAT._warned_precision = False # Reset for next assertion
56-
finally:
57-
decimal.getcontext().prec = original_prec
58-
DECFLOAT._warned_precision = False
54+
assert len(w) == 1, "Warning should only be emitted once"
55+
assert "decimal context precision (28)" in str(w[0].message)
56+
assert "DECFLOAT precision (38)" in str(w[0].message)
5957

6058
def test_decfloat_no_warning_when_precision_sufficient(self):
6159
"""Test that DECFLOAT does not warn when precision is >= 38."""
62-
DECFLOAT._warned_precision = False
63-
original_prec = decimal.getcontext().prec
60+
decimal.getcontext().prec = 38
6461

65-
try:
66-
decimal.getcontext().prec = 38
62+
decfloat_type = DECFLOAT()
63+
processor = decfloat_type.result_processor(None, None)
6764

68-
decfloat_type = DECFLOAT()
69-
processor = decfloat_type.result_processor(None, None)
65+
with warnings.catch_warnings(record=True) as w:
66+
warnings.simplefilter("always")
67+
processor(Decimal("123.456"))
7068

71-
with warnings.catch_warnings(record=True) as w:
72-
warnings.simplefilter("always")
73-
processor(Decimal("123.456"))
69+
assert len(w) == 0
7470

75-
assert len(w) == 0
76-
finally:
77-
decimal.getcontext().prec = original_prec
78-
DECFLOAT._warned_precision = False
71+
def test_decfloat_no_warning_when_precision_above_38(self):
72+
"""Test that DECFLOAT does not warn when precision is above 38.
73+
74+
When decimal context precision > 38, there's no risk of truncation.
75+
Python can hold all 38 DECFLOAT digits without loss.
76+
"""
77+
decimal.getcontext().prec = 50 # Above DECFLOAT's 38
78+
79+
decfloat_type = DECFLOAT()
80+
processor = decfloat_type.result_processor(None, None)
81+
82+
with warnings.catch_warnings(record=True) as w:
83+
warnings.simplefilter("always")
84+
processor(Decimal("123.456"))
85+
86+
assert len(w) == 0
7987

8088
def test_decfloat_no_warning_when_dialect_has_decfloat_enabled(self):
8189
"""Test that DECFLOAT does not warn when dialect has enable_decfloat set."""
82-
DECFLOAT._warned_precision = False
83-
original_prec = decimal.getcontext().prec
84-
85-
try:
86-
# Set low precision that would normally trigger warning
87-
decimal.getcontext().prec = 28
90+
# Set low precision that would normally trigger warning
91+
decimal.getcontext().prec = 28
8892

89-
# Create mock dialect with _enable_decfloat set
90-
class MockDialect:
91-
_enable_decfloat = True
93+
# Create mock dialect with _enable_decfloat set
94+
class MockDialect:
95+
_enable_decfloat = True
9296

93-
decfloat_type = DECFLOAT()
94-
processor = decfloat_type.result_processor(MockDialect(), None)
97+
decfloat_type = DECFLOAT()
98+
processor = decfloat_type.result_processor(MockDialect(), None)
9599

96-
with warnings.catch_warnings(record=True) as w:
97-
warnings.simplefilter("always")
98-
processor(Decimal("123.456"))
100+
with warnings.catch_warnings(record=True) as w:
101+
warnings.simplefilter("always")
102+
processor(Decimal("123.456"))
99103

100-
# No warning because dialect has DECFLOAT support enabled
101-
assert len(w) == 0
102-
finally:
103-
decimal.getcontext().prec = original_prec
104-
DECFLOAT._warned_precision = False
104+
# No warning because dialect has DECFLOAT support enabled
105+
assert len(w) == 0
105106

106107
def test_decfloat_visit_name(self):
107108
"""Test DECFLOAT has correct visit name."""
@@ -263,7 +264,14 @@ def test_create_table_with_decfloat(self, engine_testaccount):
263264
)
264265
metadata.create_all(engine_testaccount)
265266
try:
266-
assert test_table is not None
267+
inspector = inspect(engine_testaccount)
268+
assert inspector.has_table(
269+
table_name
270+
), f"Table {table_name} was not created"
271+
272+
columns = inspector.get_columns(table_name)
273+
value_col = next(c for c in columns if c["name"].lower() == "value")
274+
assert isinstance(value_col["type"], DECFLOAT)
267275
finally:
268276
test_table.drop(engine_testaccount)
269277

0 commit comments

Comments
 (0)