@@ -857,3 +857,55 @@ def test_dtype_representation(using_infer_string):
857
857
dtype = object ,
858
858
)
859
859
tm .assert_series_equal (result , expected )
860
+
861
+
862
+ def test_from_tuples_different_lengths_gh60695 ():
863
+ """
864
+ Test that MultiIndex.from_tuples properly handles tuples of different lengths.
865
+
866
+ GH#60695
867
+ """
868
+ # Test case 1: Original issue example
869
+ tuples = [("l1" ,), ("l1" , "l2" )]
870
+ result = pd .MultiIndex .from_tuples (tuples )
871
+ expected = pd .MultiIndex .from_tuples ([("l1" , np .nan ), ("l1" , "l2" )])
872
+ tm .assert_index_equal (result , expected )
873
+
874
+ # Test case 2: Series construction with tuple keys
875
+ s = pd .Series ({("l1" ,): "v1" , ("l1" , "l2" ): "v2" })
876
+ expected = pd .Series (
877
+ ["v1" , "v2" ],
878
+ index = pd .MultiIndex .from_tuples ([("l1" , np .nan ), ("l1" , "l2" )])
879
+ )
880
+ tm .assert_series_equal (s , expected )
881
+
882
+ # Test case 3: Multiple levels with None
883
+ data = {(1 , 1 , None ): - 1.0 }
884
+ result = pd .Series (data )
885
+ expected = pd .Series (
886
+ - 1.0 ,
887
+ index = pd .MultiIndex .from_tuples ([(1 , 1 , np .nan )]),
888
+ )
889
+ tm .assert_series_equal (result , expected )
890
+
891
+ # Test case 4: Mixed length tuples
892
+ tuples = [("a" ,), ("b" , "c" ), ("d" , "e" , "f" )]
893
+ result = pd .MultiIndex .from_tuples (tuples )
894
+ expected = pd .MultiIndex .from_tuples ([
895
+ ("a" , np .nan , np .nan ),
896
+ ("b" , "c" , np .nan ),
897
+ ("d" , "e" , "f" )
898
+ ])
899
+ tm .assert_index_equal (result , expected )
900
+
901
+ # Test case 5: DataFrame with tuple index
902
+ df = pd .DataFrame (
903
+ {"col" : ["v1" , "v2" ]},
904
+ index = pd .MultiIndex .from_tuples ([("l1" ,), ("l1" , "l2" )])
905
+ )
906
+ expected_index = pd .MultiIndex .from_tuples ([("l1" , np .nan ), ("l1" , "l2" )])
907
+ expected_df = pd .DataFrame (
908
+ {"col" : ["v1" , "v2" ]},
909
+ index = expected_index
910
+ )
911
+ tm .assert_frame_equal (df , expected_df )
0 commit comments