Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/pandas/core/internals/api.py: 28%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

58 statements  

1""" 

2This is a pseudo-public API for downstream libraries. We ask that downstream 

3authors 

4 

51) Try to avoid using internals directly altogether, and failing that, 

62) Use only functions exposed here (or in core.internals) 

7 

8""" 

9from __future__ import annotations 

10 

11from typing import TYPE_CHECKING 

12 

13import numpy as np 

14 

15from pandas._libs.internals import BlockPlacement 

16 

17from pandas.core.dtypes.common import pandas_dtype 

18from pandas.core.dtypes.dtypes import ( 

19 DatetimeTZDtype, 

20 PeriodDtype, 

21) 

22 

23from pandas.core.arrays import DatetimeArray 

24from pandas.core.construction import extract_array 

25from pandas.core.internals.blocks import ( 

26 check_ndim, 

27 ensure_block_shape, 

28 extract_pandas_array, 

29 get_block_type, 

30 maybe_coerce_values, 

31) 

32 

33if TYPE_CHECKING: 

34 from pandas._typing import Dtype 

35 

36 from pandas.core.internals.blocks import Block 

37 

38 

39def make_block( 

40 values, placement, klass=None, ndim=None, dtype: Dtype | None = None 

41) -> Block: 

42 """ 

43 This is a pseudo-public analogue to blocks.new_block. 

44 

45 We ask that downstream libraries use this rather than any fully-internal 

46 APIs, including but not limited to: 

47 

48 - core.internals.blocks.make_block 

49 - Block.make_block 

50 - Block.make_block_same_class 

51 - Block.__init__ 

52 """ 

53 if dtype is not None: 

54 dtype = pandas_dtype(dtype) 

55 

56 values, dtype = extract_pandas_array(values, dtype, ndim) 

57 

58 from pandas.core.internals.blocks import ( 

59 DatetimeTZBlock, 

60 ExtensionBlock, 

61 ) 

62 

63 if klass is ExtensionBlock and isinstance(values.dtype, PeriodDtype): 

64 # GH-44681 changed PeriodArray to be stored in the 2D 

65 # NDArrayBackedExtensionBlock instead of ExtensionBlock 

66 # -> still allow ExtensionBlock to be passed in this case for back compat 

67 klass = None 

68 

69 if klass is None: 

70 dtype = dtype or values.dtype 

71 klass = get_block_type(dtype) 

72 

73 elif klass is DatetimeTZBlock and not isinstance(values.dtype, DatetimeTZDtype): 

74 # pyarrow calls get here 

75 values = DatetimeArray._simple_new( 

76 # error: Argument "dtype" to "_simple_new" of "DatetimeArray" has 

77 # incompatible type "Union[ExtensionDtype, dtype[Any], None]"; 

78 # expected "Union[dtype[datetime64], DatetimeTZDtype]" 

79 values, 

80 dtype=dtype, # type: ignore[arg-type] 

81 ) 

82 

83 if not isinstance(placement, BlockPlacement): 

84 placement = BlockPlacement(placement) 

85 

86 ndim = maybe_infer_ndim(values, placement, ndim) 

87 if isinstance(values.dtype, (PeriodDtype, DatetimeTZDtype)): 

88 # GH#41168 ensure we can pass 1D dt64tz values 

89 # More generally, any EA dtype that isn't is_1d_only_ea_dtype 

90 values = extract_array(values, extract_numpy=True) 

91 values = ensure_block_shape(values, ndim) 

92 

93 check_ndim(values, placement, ndim) 

94 values = maybe_coerce_values(values) 

95 return klass(values, ndim=ndim, placement=placement) 

96 

97 

98def maybe_infer_ndim(values, placement: BlockPlacement, ndim: int | None) -> int: 

99 """ 

100 If `ndim` is not provided, infer it from placement and values. 

101 """ 

102 if ndim is None: 

103 # GH#38134 Block constructor now assumes ndim is not None 

104 if not isinstance(values.dtype, np.dtype): 

105 if len(placement) != 1: 

106 ndim = 1 

107 else: 

108 ndim = 2 

109 else: 

110 ndim = values.ndim 

111 return ndim 

112 

113 

114def __getattr__(name: str): 

115 # GH#55139 

116 import warnings 

117 

118 if name in [ 

119 "Block", 

120 "ExtensionBlock", 

121 "DatetimeTZBlock", 

122 "create_block_manager_from_blocks", 

123 ]: 

124 # GH#33892 

125 warnings.warn( 

126 f"{name} is deprecated and will be removed in a future version. " 

127 "Use public APIs instead.", 

128 DeprecationWarning, 

129 # https://github.com/pandas-dev/pandas/pull/55139#pullrequestreview-1720690758 

130 # on hard-coding stacklevel 

131 stacklevel=2, 

132 ) 

133 

134 if name == "create_block_manager_from_blocks": 

135 from pandas.core.internals.managers import create_block_manager_from_blocks 

136 

137 return create_block_manager_from_blocks 

138 

139 elif name == "Block": 

140 from pandas.core.internals.blocks import Block 

141 

142 return Block 

143 

144 elif name == "DatetimeTZBlock": 

145 from pandas.core.internals.blocks import DatetimeTZBlock 

146 

147 return DatetimeTZBlock 

148 

149 elif name == "ExtensionBlock": 

150 from pandas.core.internals.blocks import ExtensionBlock 

151 

152 return ExtensionBlock 

153 

154 raise AttributeError( 

155 f"module 'pandas.core.internals.api' has no attribute '{name}'" 

156 )