1+ """
2+ Tests for iloc dictionary assignment bug fix.
3+
4+ Regression test for GH#62723: Series.iloc assignment with dtype="object"
5+ incorrectly converts dictionary values to Series.
6+ """
7+ import numpy as np
8+ import pytest
9+
10+ from pandas import (
11+ DataFrame ,
12+ Series ,
13+ )
14+ import pandas ._testing as tm
15+
16+
17+ class TestIlocDictionaryAssignment :
18+ """Tests for iloc dictionary assignment bug fix (GH#62723)."""
19+
20+ def test_iloc_preserves_dict_object_dtype (self ):
21+ """Test that iloc preserves dictionaries in object dtype Series."""
22+ # GH#62723
23+ s = Series (0 , dtype = "object" )
24+ test_dict = {}
25+
26+ # Assign dictionary via iloc
27+ s .iloc [0 ] = test_dict
28+
29+ # Verify dictionary is preserved
30+ assert s [0 ] == test_dict
31+ assert isinstance (s [0 ], dict )
32+
33+ def test_iloc_preserves_complex_dict_object_dtype (self ):
34+ """Test that iloc preserves complex dictionaries in object dtype Series."""
35+ s = Series (0 , dtype = "object" )
36+ test_dict = {
37+ 'a' : 1 ,
38+ 'b' : [1 , 2 , 3 ],
39+ 'c' : {'nested' : True },
40+ 'd' : None ,
41+ 'e' : 3.14
42+ }
43+
44+ s .iloc [0 ] = test_dict
45+
46+ assert s [0 ] == test_dict
47+ assert isinstance (s [0 ], dict )
48+ assert s [0 ]['a' ] == 1
49+ assert s [0 ]['b' ] == [1 , 2 , 3 ]
50+ assert s [0 ]['c' ] == {'nested' : True }
51+ assert s [0 ]['d' ] is None
52+ assert s [0 ]['e' ] == 3.14
53+
54+ def test_iloc_vs_loc_dict_assignment_consistency (self ):
55+ """Test that iloc and direct assignment behave consistently."""
56+ # Original bug: s[0] = {} works but s.iloc[0] = {} converts to Series
57+ s = Series (0 , dtype = "object" )
58+
59+ # Direct assignment should work (baseline)
60+ s [0 ] = {}
61+ assert s [0 ] == {}
62+ assert isinstance (s [0 ], dict )
63+
64+ # Reset and test iloc
65+ s = Series (0 , dtype = "object" )
66+ s .iloc [0 ] = {}
67+ assert s [0 ] == {}
68+ assert isinstance (s [0 ], dict )
69+
70+ def test_iloc_multiple_dict_assignments (self ):
71+ """Test iloc dictionary assignment to multiple positions."""
72+ s = Series ([0 , 1 , 2 ], dtype = "object" )
73+ dict1 = {'first' : 1 }
74+ dict2 = {'second' : 2 }
75+
76+ s .iloc [0 ] = dict1
77+ s .iloc [2 ] = dict2
78+
79+ assert s .iloc [0 ] == dict1
80+ assert isinstance (s .iloc [0 ], dict )
81+ assert s .iloc [1 ] == 1 # unchanged
82+ assert s .iloc [2 ] == dict2
83+ assert isinstance (s .iloc [2 ], dict )
84+
85+ def test_iloc_dict_assignment_non_object_dtype_fails (self ):
86+ """Test that iloc dict assignment to non-object dtypes fails as expected."""
87+ s = Series ([1 , 2 , 3 ], dtype = "int64" )
88+
89+ # This should fail for non-object dtypes
90+ with pytest .raises ((ValueError , TypeError )):
91+ s .iloc [0 ] = {'key' : 'value' }
92+
93+ def test_iloc_preserves_other_object_types (self ):
94+ """Test that iloc preserves other object types correctly."""
95+ s = Series ([None ] * 4 , dtype = "object" )
96+
97+ # Test various object types
98+ test_list = [1 , 2 , 3 ]
99+ test_tuple = (1 , 2 , 3 )
100+ test_set = {1 , 2 , 3 }
101+ test_str = "test string"
102+
103+ s .iloc [0 ] = test_list
104+ s .iloc [1 ] = test_tuple
105+ s .iloc [2 ] = test_set
106+ s .iloc [3 ] = test_str
107+
108+ assert s .iloc [0 ] == test_list
109+ assert isinstance (s .iloc [0 ], list )
110+ assert s .iloc [1 ] == test_tuple
111+ assert isinstance (s .iloc [1 ], tuple )
112+ assert s .iloc [2 ] == test_set
113+ assert isinstance (s .iloc [2 ], set )
114+ assert s .iloc [3 ] == test_str
115+ assert isinstance (s .iloc [3 ], str )
116+
117+ def test_dataframe_iloc_dict_assignment_unaffected (self ):
118+ """Test that the fix doesn't break DataFrame iloc dict assignment."""
119+ df = DataFrame ({'A' : [0 , 1 ], 'B' : [2 , 3 ]}, dtype = "object" )
120+ test_dict = {'frame' : 'test' }
121+
122+ # DataFrame iloc should still work correctly
123+ df .iloc [0 , 0 ] = test_dict
124+
125+ assert df .iloc [0 , 0 ] == test_dict
126+ assert isinstance (df .iloc [0 , 0 ], dict )
127+
128+ def test_nested_dict_assignment (self ):
129+ """Test iloc assignment with deeply nested dictionaries."""
130+ s = Series ([None ], dtype = "object" )
131+ nested_dict = {
132+ 'level1' : {
133+ 'level2' : {
134+ 'level3' : {
135+ 'deep' : 'value' ,
136+ 'list' : [1 , 2 , {'nested_in_list' : True }]
137+ }
138+ }
139+ },
140+ 'another_key' : [{'dict_in_list' : 'test' }]
141+ }
142+
143+ s .iloc [0 ] = nested_dict
144+
145+ assert s .iloc [0 ] == nested_dict
146+ assert isinstance (s .iloc [0 ], dict )
147+ assert s .iloc [0 ]['level1' ]['level2' ]['level3' ]['deep' ] == 'value'
148+ assert s .iloc [0 ]['another_key' ][0 ]['dict_in_list' ] == 'test'
149+
150+ def test_original_bug_reproduction (self ):
151+ """Direct test of the original bug report scenario."""
152+ # This is the exact code from the bug report
153+ s = Series (0 , dtype = "object" )
154+
155+ s [0 ] = {}
156+ assert s [0 ] == {} # This should pass
157+
158+ s .iloc [0 ] = {}
159+ assert s [0 ] == {} # This was failing before the fix
160+
161+ # Additional verification
162+ assert isinstance (s [0 ], dict )
163+ assert type (s [0 ]) == dict
0 commit comments