1+ #!/usr/bin/env python3
2+ """
3+ Test to verify the fix for the NDArrayBacked.__setstate__ issue with datetime64[ns] in MultiIndex.
4+ """
5+ import numpy as np
6+ import pandas as pd
7+ import pickle
8+ import sys
9+ from pandas ._libs .arrays import NDArrayBacked
10+
11+
12+ def test_ndarraybacked_setstate_with_tuple ():
13+ """Test that NDArrayBacked.__setstate__ handles 3-element tuple with (data, dtype, (dtype, array)) format."""
14+ # Create a mock NDArrayBacked instance to test the __setstate__ method directly
15+ class MockNDArrayBacked (NDArrayBacked ):
16+ def __init__ (self ):
17+ # We'll manually set _ndarray and _dtype when needed
18+ pass
19+
20+ # Test the problematic state format: a 3-element tuple where the third element
21+ # is another (dtype, array) tuple rather than an attributes dict
22+ arr = np .array (['2026-04-05T16:07:45.133961216' ], dtype = 'datetime64[ns]' )
23+ dtype = arr .dtype
24+ problematic_state = (arr , dtype , (dtype , arr ))
25+
26+ print (f"Testing state: { problematic_state } " )
27+
28+ try :
29+ obj = MockNDArrayBacked ()
30+ obj .__setstate__ (problematic_state )
31+ print ("SUCCESS: No NotImplementedError raised!" )
32+ return True
33+ except NotImplementedError as e :
34+ print (f"FAILED: NotImplementedError still raised: { e } " )
35+ return False
36+ except Exception as e :
37+ print (f"FAILED: Other exception raised: { e } " )
38+ return False
39+
40+
41+ def test_original_scenario ():
42+ """Test the original scenario that triggered the issue."""
43+ try :
44+ print ("Creating DataFrame with MultiIndex containing datetime64[ns]..." )
45+ df = pd .DataFrame ({
46+ 'date' : [np .datetime64 ("20110101" , 'ns' )],
47+ 'id' : [1 ],
48+ 'val' : [1 ]
49+ }).set_index (["date" , "id" ])
50+
51+ print ("DataFrame created successfully:" , df .index )
52+
53+ # Try to pickle and unpickle it (this mimics what joblib does internally)
54+ print ("Testing pickle/unpickle..." )
55+ pickled = pickle .dumps (df )
56+ unpickled_df = pickle .loads (pickled )
57+ print ("Pickle/unpickle successful:" , unpickled_df .index )
58+ return True
59+ except Exception as e :
60+ print (f"FAILED: Error in original scenario: { e } " )
61+ import traceback
62+ traceback .print_exc ()
63+ return False
64+
65+
66+ if __name__ == "__main__" :
67+ print ("Testing NDArrayBacked __setstate__ fix..." )
68+
69+ test1_result = test_ndarraybacked_setstate_with_tuple ()
70+ print ()
71+ test2_result = test_original_scenario ()
72+
73+ if test1_result and test2_result :
74+ print ("\n All tests passed! The fix should work." )
75+ sys .exit (0 )
76+ else :
77+ print ("\n Some tests failed. The fix needs more work." )
78+ sys .exit (1 )
0 commit comments