test_api.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from __future__ import annotations
  2. import pytest
  3. import pandas as pd
  4. from pandas import api
  5. import pandas._testing as tm
  6. class Base:
  7. def check(self, namespace, expected, ignored=None):
  8. # see which names are in the namespace, minus optional
  9. # ignored ones
  10. # compare vs the expected
  11. result = sorted(
  12. f for f in dir(namespace) if not f.startswith("__") and f != "annotations"
  13. )
  14. if ignored is not None:
  15. result = sorted(set(result) - set(ignored))
  16. expected = sorted(expected)
  17. tm.assert_almost_equal(result, expected)
  18. class TestPDApi(Base):
  19. # these are optionally imported based on testing
  20. # & need to be ignored
  21. ignored = ["tests", "locale", "conftest"]
  22. # top-level sub-packages
  23. public_lib = [
  24. "api",
  25. "arrays",
  26. "options",
  27. "test",
  28. "testing",
  29. "errors",
  30. "plotting",
  31. "io",
  32. "tseries",
  33. ]
  34. private_lib = ["compat", "core", "pandas", "util"]
  35. # misc
  36. misc = ["IndexSlice", "NaT", "NA"]
  37. # top-level classes
  38. classes = [
  39. "ArrowDtype",
  40. "Categorical",
  41. "CategoricalIndex",
  42. "DataFrame",
  43. "DateOffset",
  44. "DatetimeIndex",
  45. "ExcelFile",
  46. "ExcelWriter",
  47. "Flags",
  48. "Grouper",
  49. "HDFStore",
  50. "Index",
  51. "MultiIndex",
  52. "Period",
  53. "PeriodIndex",
  54. "RangeIndex",
  55. "Series",
  56. "SparseDtype",
  57. "StringDtype",
  58. "Timedelta",
  59. "TimedeltaIndex",
  60. "Timestamp",
  61. "Interval",
  62. "IntervalIndex",
  63. "CategoricalDtype",
  64. "PeriodDtype",
  65. "IntervalDtype",
  66. "DatetimeTZDtype",
  67. "BooleanDtype",
  68. "Int8Dtype",
  69. "Int16Dtype",
  70. "Int32Dtype",
  71. "Int64Dtype",
  72. "UInt8Dtype",
  73. "UInt16Dtype",
  74. "UInt32Dtype",
  75. "UInt64Dtype",
  76. "Float32Dtype",
  77. "Float64Dtype",
  78. "NamedAgg",
  79. ]
  80. # these are already deprecated; awaiting removal
  81. deprecated_classes: list[str] = []
  82. # external modules exposed in pandas namespace
  83. modules: list[str] = []
  84. # top-level functions
  85. funcs = [
  86. "array",
  87. "bdate_range",
  88. "concat",
  89. "crosstab",
  90. "cut",
  91. "date_range",
  92. "interval_range",
  93. "eval",
  94. "factorize",
  95. "get_dummies",
  96. "from_dummies",
  97. "infer_freq",
  98. "isna",
  99. "isnull",
  100. "lreshape",
  101. "melt",
  102. "notna",
  103. "notnull",
  104. "offsets",
  105. "merge",
  106. "merge_ordered",
  107. "merge_asof",
  108. "period_range",
  109. "pivot",
  110. "pivot_table",
  111. "qcut",
  112. "show_versions",
  113. "timedelta_range",
  114. "unique",
  115. "value_counts",
  116. "wide_to_long",
  117. ]
  118. # top-level option funcs
  119. funcs_option = [
  120. "reset_option",
  121. "describe_option",
  122. "get_option",
  123. "option_context",
  124. "set_option",
  125. "set_eng_float_format",
  126. ]
  127. # top-level read_* funcs
  128. funcs_read = [
  129. "read_clipboard",
  130. "read_csv",
  131. "read_excel",
  132. "read_fwf",
  133. "read_gbq",
  134. "read_hdf",
  135. "read_html",
  136. "read_xml",
  137. "read_json",
  138. "read_pickle",
  139. "read_sas",
  140. "read_sql",
  141. "read_sql_query",
  142. "read_sql_table",
  143. "read_stata",
  144. "read_table",
  145. "read_feather",
  146. "read_parquet",
  147. "read_orc",
  148. "read_spss",
  149. ]
  150. # top-level json funcs
  151. funcs_json = ["json_normalize"]
  152. # top-level to_* funcs
  153. funcs_to = ["to_datetime", "to_numeric", "to_pickle", "to_timedelta"]
  154. # top-level to deprecate in the future
  155. deprecated_funcs_in_future: list[str] = []
  156. # these are already deprecated; awaiting removal
  157. deprecated_funcs: list[str] = []
  158. # private modules in pandas namespace
  159. private_modules = [
  160. "_config",
  161. "_libs",
  162. "_is_numpy_dev",
  163. "_testing",
  164. "_typing",
  165. "_version",
  166. ]
  167. def test_api(self):
  168. checkthese = (
  169. self.public_lib
  170. + self.private_lib
  171. + self.misc
  172. + self.modules
  173. + self.classes
  174. + self.funcs
  175. + self.funcs_option
  176. + self.funcs_read
  177. + self.funcs_json
  178. + self.funcs_to
  179. + self.private_modules
  180. )
  181. self.check(namespace=pd, expected=checkthese, ignored=self.ignored)
  182. def test_api_all(self):
  183. expected = set(
  184. self.public_lib
  185. + self.misc
  186. + self.modules
  187. + self.classes
  188. + self.funcs
  189. + self.funcs_option
  190. + self.funcs_read
  191. + self.funcs_json
  192. + self.funcs_to
  193. ) - set(self.deprecated_classes)
  194. actual = set(pd.__all__)
  195. extraneous = actual - expected
  196. assert not extraneous
  197. missing = expected - actual
  198. assert not missing
  199. def test_depr(self):
  200. deprecated_list = (
  201. self.deprecated_classes
  202. + self.deprecated_funcs
  203. + self.deprecated_funcs_in_future
  204. )
  205. for depr in deprecated_list:
  206. with tm.assert_produces_warning(FutureWarning):
  207. _ = getattr(pd, depr)
  208. class TestApi(Base):
  209. allowed = ["types", "extensions", "indexers", "interchange"]
  210. def test_api(self):
  211. self.check(api, self.allowed)
  212. class TestTesting(Base):
  213. funcs = [
  214. "assert_frame_equal",
  215. "assert_series_equal",
  216. "assert_index_equal",
  217. "assert_extension_array_equal",
  218. ]
  219. def test_testing(self):
  220. from pandas import testing
  221. self.check(testing, self.funcs)
  222. def test_util_in_top_level(self):
  223. with pytest.raises(AttributeError, match="foo"):
  224. pd.util.foo