google-cloud-bigquery 3.31.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. google/cloud/bigquery/__init__.py +249 -0
  2. google/cloud/bigquery/_helpers.py +1102 -0
  3. google/cloud/bigquery/_http.py +47 -0
  4. google/cloud/bigquery/_job_helpers.py +600 -0
  5. google/cloud/bigquery/_pandas_helpers.py +1181 -0
  6. google/cloud/bigquery/_pyarrow_helpers.py +147 -0
  7. google/cloud/bigquery/_tqdm_helpers.py +137 -0
  8. google/cloud/bigquery/_versions_helpers.py +264 -0
  9. google/cloud/bigquery/client.py +4406 -0
  10. google/cloud/bigquery/dataset.py +1076 -0
  11. google/cloud/bigquery/dbapi/__init__.py +87 -0
  12. google/cloud/bigquery/dbapi/_helpers.py +522 -0
  13. google/cloud/bigquery/dbapi/connection.py +128 -0
  14. google/cloud/bigquery/dbapi/cursor.py +586 -0
  15. google/cloud/bigquery/dbapi/exceptions.py +58 -0
  16. google/cloud/bigquery/dbapi/types.py +96 -0
  17. google/cloud/bigquery/encryption_configuration.py +84 -0
  18. google/cloud/bigquery/enums.py +389 -0
  19. google/cloud/bigquery/exceptions.py +35 -0
  20. google/cloud/bigquery/external_config.py +1188 -0
  21. google/cloud/bigquery/format_options.py +147 -0
  22. google/cloud/bigquery/iam.py +38 -0
  23. google/cloud/bigquery/job/__init__.py +87 -0
  24. google/cloud/bigquery/job/base.py +1116 -0
  25. google/cloud/bigquery/job/copy_.py +282 -0
  26. google/cloud/bigquery/job/extract.py +271 -0
  27. google/cloud/bigquery/job/load.py +985 -0
  28. google/cloud/bigquery/job/query.py +2498 -0
  29. google/cloud/bigquery/magics/__init__.py +20 -0
  30. google/cloud/bigquery/magics/line_arg_parser/__init__.py +34 -0
  31. google/cloud/bigquery/magics/line_arg_parser/exceptions.py +25 -0
  32. google/cloud/bigquery/magics/line_arg_parser/lexer.py +200 -0
  33. google/cloud/bigquery/magics/line_arg_parser/parser.py +484 -0
  34. google/cloud/bigquery/magics/line_arg_parser/visitors.py +159 -0
  35. google/cloud/bigquery/magics/magics.py +776 -0
  36. google/cloud/bigquery/model.py +517 -0
  37. google/cloud/bigquery/opentelemetry_tracing.py +164 -0
  38. google/cloud/bigquery/py.typed +2 -0
  39. google/cloud/bigquery/query.py +1344 -0
  40. google/cloud/bigquery/retry.py +207 -0
  41. google/cloud/bigquery/routine/__init__.py +33 -0
  42. google/cloud/bigquery/routine/routine.py +744 -0
  43. google/cloud/bigquery/schema.py +896 -0
  44. google/cloud/bigquery/standard_sql.py +389 -0
  45. google/cloud/bigquery/table.py +3594 -0
  46. google/cloud/bigquery/version.py +15 -0
  47. google/cloud/bigquery_v2/__init__.py +56 -0
  48. google/cloud/bigquery_v2/types/__init__.py +54 -0
  49. google/cloud/bigquery_v2/types/encryption_config.py +48 -0
  50. google/cloud/bigquery_v2/types/model.py +1994 -0
  51. google/cloud/bigquery_v2/types/model_reference.py +57 -0
  52. google/cloud/bigquery_v2/types/standard_sql.py +156 -0
  53. google/cloud/bigquery_v2/types/table_reference.py +80 -0
  54. google_cloud_bigquery-3.31.0.dist-info/LICENSE +202 -0
  55. google_cloud_bigquery-3.31.0.dist-info/METADATA +203 -0
  56. google_cloud_bigquery-3.31.0.dist-info/RECORD +58 -0
  57. google_cloud_bigquery-3.31.0.dist-info/WHEEL +5 -0
  58. google_cloud_bigquery-3.31.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,147 @@
1
+ # Copyright 2023 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Shared helper functions for connecting BigQuery and pyarrow.
16
+
17
+ NOTE: This module is DEPRECATED. Please make updates in the pandas-gbq package,
18
+ instead. See: go/pandas-gbq-and-bigframes-redundancy,
19
+ https://github.com/googleapis/python-bigquery-pandas/blob/main/pandas_gbq/schema/bigquery_to_pyarrow.py
20
+ and
21
+ https://github.com/googleapis/python-bigquery-pandas/blob/main/pandas_gbq/schema/pyarrow_to_bigquery.py
22
+ """
23
+
24
+ from typing import Any
25
+
26
+ try:
27
+ import pyarrow # type: ignore
28
+ except ImportError:
29
+ pyarrow = None
30
+
31
+ try:
32
+ import db_dtypes # type: ignore
33
+
34
+ db_dtypes_import_exception = None
35
+ except ImportError as exc:
36
+ db_dtypes = None
37
+ db_dtypes_import_exception = exc
38
+
39
+
40
+ def pyarrow_datetime():
41
+ return pyarrow.timestamp("us", tz=None)
42
+
43
+
44
+ def pyarrow_numeric():
45
+ return pyarrow.decimal128(38, 9)
46
+
47
+
48
+ def pyarrow_bignumeric():
49
+ # 77th digit is partial.
50
+ # https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#decimal_types
51
+ return pyarrow.decimal256(76, 38)
52
+
53
+
54
+ def pyarrow_time():
55
+ return pyarrow.time64("us")
56
+
57
+
58
+ def pyarrow_timestamp():
59
+ return pyarrow.timestamp("us", tz="UTC")
60
+
61
+
62
+ _BQ_TO_ARROW_SCALARS = {}
63
+ _ARROW_SCALAR_IDS_TO_BQ = {}
64
+
65
+ if pyarrow:
66
+ # This dictionary is duplicated in bigquery_storage/test/unite/test_reader.py
67
+ # When modifying it be sure to update it there as well.
68
+ # Note(todo!!): type "BIGNUMERIC"'s matching pyarrow type is added in _pandas_helpers.py
69
+ _BQ_TO_ARROW_SCALARS = {
70
+ "BOOL": pyarrow.bool_,
71
+ "BOOLEAN": pyarrow.bool_,
72
+ "BYTES": pyarrow.binary,
73
+ "DATE": pyarrow.date32,
74
+ "DATETIME": pyarrow_datetime,
75
+ "FLOAT": pyarrow.float64,
76
+ "FLOAT64": pyarrow.float64,
77
+ "GEOGRAPHY": pyarrow.string,
78
+ "INT64": pyarrow.int64,
79
+ "INTEGER": pyarrow.int64,
80
+ # Normally, we'd prefer JSON type built-in to pyarrow (added in 19.0.0),
81
+ # but we'd like this to map as closely to the BQ Storage API as
82
+ # possible, which uses the string() dtype, as JSON support in Arrow
83
+ # predates JSON support in BigQuery by several years.
84
+ "JSON": pyarrow.string,
85
+ "NUMERIC": pyarrow_numeric,
86
+ "STRING": pyarrow.string,
87
+ "TIME": pyarrow_time,
88
+ "TIMESTAMP": pyarrow_timestamp,
89
+ }
90
+
91
+ # DEPRECATED: update pandas_gbq.schema.pyarrow_to_bigquery, instead.
92
+ _ARROW_SCALAR_IDS_TO_BQ = {
93
+ # https://arrow.apache.org/docs/python/api/datatypes.html#type-classes
94
+ pyarrow.bool_().id: "BOOL",
95
+ pyarrow.int8().id: "INT64",
96
+ pyarrow.int16().id: "INT64",
97
+ pyarrow.int32().id: "INT64",
98
+ pyarrow.int64().id: "INT64",
99
+ pyarrow.uint8().id: "INT64",
100
+ pyarrow.uint16().id: "INT64",
101
+ pyarrow.uint32().id: "INT64",
102
+ pyarrow.uint64().id: "INT64",
103
+ pyarrow.float16().id: "FLOAT64",
104
+ pyarrow.float32().id: "FLOAT64",
105
+ pyarrow.float64().id: "FLOAT64",
106
+ pyarrow.time32("ms").id: "TIME",
107
+ pyarrow.time64("ns").id: "TIME",
108
+ pyarrow.timestamp("ns").id: "TIMESTAMP",
109
+ pyarrow.date32().id: "DATE",
110
+ pyarrow.date64().id: "DATETIME", # because millisecond resolution
111
+ pyarrow.binary().id: "BYTES",
112
+ pyarrow.string().id: "STRING", # also alias for pyarrow.utf8()
113
+ pyarrow.large_string().id: "STRING",
114
+ # The exact scale and precision don't matter, see below.
115
+ pyarrow.decimal128(38, scale=9).id: "NUMERIC",
116
+ # NOTE: all extension types (e.g. json_, uuid, db_dtypes.JSONArrowType)
117
+ # have the same id (31 as of version 19.0.1), so these should not be
118
+ # matched by id.
119
+ }
120
+
121
+ _BQ_TO_ARROW_SCALARS["BIGNUMERIC"] = pyarrow_bignumeric
122
+ # The exact decimal's scale and precision are not important, as only
123
+ # the type ID matters, and it's the same for all decimal256 instances.
124
+ _ARROW_SCALAR_IDS_TO_BQ[pyarrow.decimal256(76, scale=38).id] = "BIGNUMERIC"
125
+
126
+
127
+ def bq_to_arrow_scalars(bq_scalar: str):
128
+ """
129
+ DEPRECATED: update pandas_gbq.schema.bigquery_to_pyarrow, instead, which is
130
+ to be added in https://github.com/googleapis/python-bigquery-pandas/pull/893.
131
+
132
+ Returns:
133
+ The Arrow scalar type that the input BigQuery scalar type maps to.
134
+ If it cannot find the BigQuery scalar, return None.
135
+ """
136
+ return _BQ_TO_ARROW_SCALARS.get(bq_scalar)
137
+
138
+
139
+ def arrow_scalar_ids_to_bq(arrow_scalar: Any):
140
+ """
141
+ DEPRECATED: update pandas_gbq.schema.pyarrow_to_bigquery, instead.
142
+
143
+ Returns:
144
+ The BigQuery scalar type that the input arrow scalar type maps to.
145
+ If it cannot find the arrow scalar, return None.
146
+ """
147
+ return _ARROW_SCALAR_IDS_TO_BQ.get(arrow_scalar)
@@ -0,0 +1,137 @@
1
+ # Copyright 2019 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Shared helper functions for tqdm progress bar."""
16
+
17
+ import concurrent.futures
18
+ import sys
19
+ import time
20
+ import typing
21
+ from typing import Optional
22
+ import warnings
23
+
24
+ try:
25
+ import tqdm # type: ignore
26
+ except ImportError:
27
+ tqdm = None
28
+
29
+ try:
30
+ import tqdm.notebook as tqdm_notebook # type: ignore
31
+ except ImportError:
32
+ tqdm_notebook = None
33
+
34
+ if typing.TYPE_CHECKING: # pragma: NO COVER
35
+ from google.cloud.bigquery import QueryJob
36
+ from google.cloud.bigquery.table import RowIterator
37
+
38
+ _NO_TQDM_ERROR = (
39
+ "A progress bar was requested, but there was an error loading the tqdm "
40
+ "library. Please install tqdm to use the progress bar functionality."
41
+ )
42
+
43
+ _PROGRESS_BAR_UPDATE_INTERVAL = 0.5
44
+
45
+
46
+ def get_progress_bar(progress_bar_type, description, total, unit):
47
+ """Construct a tqdm progress bar object, if tqdm is installed."""
48
+ if tqdm is None or tqdm_notebook is None and progress_bar_type == "tqdm_notebook":
49
+ if progress_bar_type is not None:
50
+ warnings.warn(_NO_TQDM_ERROR, UserWarning, stacklevel=3)
51
+ return None
52
+
53
+ try:
54
+ if progress_bar_type == "tqdm":
55
+ return tqdm.tqdm(
56
+ bar_format="{l_bar}{bar}|",
57
+ colour="green",
58
+ desc=description,
59
+ file=sys.stdout,
60
+ total=total,
61
+ unit=unit,
62
+ )
63
+ elif progress_bar_type == "tqdm_notebook":
64
+ return tqdm_notebook.tqdm(
65
+ bar_format="{l_bar}{bar}|",
66
+ desc=description,
67
+ file=sys.stdout,
68
+ total=total,
69
+ unit=unit,
70
+ )
71
+ elif progress_bar_type == "tqdm_gui":
72
+ return tqdm.tqdm_gui(desc=description, total=total, unit=unit)
73
+ except (KeyError, TypeError): # pragma: NO COVER
74
+ # Protect ourselves from any tqdm errors. In case of
75
+ # unexpected tqdm behavior, just fall back to showing
76
+ # no progress bar.
77
+ warnings.warn(_NO_TQDM_ERROR, UserWarning, stacklevel=3)
78
+ return None
79
+
80
+
81
+ def wait_for_query(
82
+ query_job: "QueryJob",
83
+ progress_bar_type: Optional[str] = None,
84
+ max_results: Optional[int] = None,
85
+ ) -> "RowIterator":
86
+ """Return query result and display a progress bar while the query running, if tqdm is installed.
87
+
88
+ Args:
89
+ query_job:
90
+ The job representing the execution of the query on the server.
91
+ progress_bar_type:
92
+ The type of progress bar to use to show query progress.
93
+ max_results:
94
+ The maximum number of rows the row iterator should return.
95
+
96
+ Returns:
97
+ A row iterator over the query results.
98
+ """
99
+ default_total = 1
100
+ current_stage = None
101
+ start_time = time.perf_counter()
102
+
103
+ progress_bar = get_progress_bar(
104
+ progress_bar_type, "Query is running", default_total, "query"
105
+ )
106
+ if progress_bar is None:
107
+ return query_job.result(max_results=max_results)
108
+
109
+ i = 0
110
+ while True:
111
+ if query_job.query_plan:
112
+ default_total = len(query_job.query_plan)
113
+ current_stage = query_job.query_plan[i]
114
+ progress_bar.total = len(query_job.query_plan)
115
+ progress_bar.set_description(
116
+ f"Query executing stage {current_stage.name} and status {current_stage.status} : {time.perf_counter() - start_time:.2f}s"
117
+ )
118
+ try:
119
+ query_result = query_job.result(
120
+ timeout=_PROGRESS_BAR_UPDATE_INTERVAL, max_results=max_results
121
+ )
122
+ progress_bar.update(default_total)
123
+ progress_bar.set_description(
124
+ f"Job ID {query_job.job_id} successfully executed",
125
+ )
126
+ break
127
+ except concurrent.futures.TimeoutError:
128
+ query_job.reload() # Refreshes the state via a GET request.
129
+ if current_stage:
130
+ if current_stage.status == "COMPLETE":
131
+ if i < default_total - 1:
132
+ progress_bar.update(i + 1)
133
+ i += 1
134
+ continue
135
+
136
+ progress_bar.close()
137
+ return query_result
@@ -0,0 +1,264 @@
1
+ # Copyright 2023 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Shared helper functions for verifying versions of installed modules."""
16
+
17
+ import sys
18
+ from typing import Any
19
+
20
+ import packaging.version
21
+
22
+ from google.cloud.bigquery import exceptions
23
+
24
+
25
+ _MIN_PYARROW_VERSION = packaging.version.Version("3.0.0")
26
+ _MIN_BQ_STORAGE_VERSION = packaging.version.Version("2.0.0")
27
+ _BQ_STORAGE_OPTIONAL_READ_SESSION_VERSION = packaging.version.Version("2.6.0")
28
+ _MIN_PANDAS_VERSION = packaging.version.Version("1.1.0")
29
+
30
+ _MIN_PANDAS_VERSION_RANGE = packaging.version.Version("1.5.0")
31
+ _MIN_PYARROW_VERSION_RANGE = packaging.version.Version("10.0.1")
32
+
33
+
34
+ class PyarrowVersions:
35
+ """Version comparisons for pyarrow package."""
36
+
37
+ def __init__(self):
38
+ self._installed_version = None
39
+
40
+ @property
41
+ def installed_version(self) -> packaging.version.Version:
42
+ """Return the parsed version of pyarrow."""
43
+ if self._installed_version is None:
44
+ import pyarrow # type: ignore
45
+
46
+ self._installed_version = packaging.version.parse(
47
+ # Use 0.0.0, since it is earlier than any released version.
48
+ # Legacy versions also have the same property, but
49
+ # creating a LegacyVersion has been deprecated.
50
+ # https://github.com/pypa/packaging/issues/321
51
+ getattr(pyarrow, "__version__", "0.0.0")
52
+ )
53
+
54
+ return self._installed_version
55
+
56
+ @property
57
+ def use_compliant_nested_type(self) -> bool:
58
+ return self.installed_version.major >= 4
59
+
60
+ def try_import(self, raise_if_error: bool = False) -> Any:
61
+ """Verifies that a recent enough version of pyarrow extra is installed.
62
+
63
+ The function assumes that pyarrow extra is installed, and should thus
64
+ be used in places where this assumption holds.
65
+
66
+ Because `pip` can install an outdated version of this extra despite
67
+ the constraints in `setup.py`, the calling code can use this helper
68
+ to verify the version compatibility at runtime.
69
+
70
+ Returns:
71
+ The ``pyarrow`` module or ``None``.
72
+
73
+ Raises:
74
+ exceptions.LegacyPyarrowError:
75
+ If the pyarrow package is outdated and ``raise_if_error`` is
76
+ ``True``.
77
+ """
78
+ try:
79
+ import pyarrow
80
+ except ImportError as exc:
81
+ if raise_if_error:
82
+ raise exceptions.LegacyPyarrowError(
83
+ "pyarrow package not found. Install pyarrow version >="
84
+ f" {_MIN_PYARROW_VERSION}."
85
+ ) from exc
86
+ return None
87
+
88
+ if self.installed_version < _MIN_PYARROW_VERSION:
89
+ if raise_if_error:
90
+ msg = (
91
+ "Dependency pyarrow is outdated, please upgrade"
92
+ f" it to version >= {_MIN_PYARROW_VERSION}"
93
+ f" (version found: {self.installed_version})."
94
+ )
95
+ raise exceptions.LegacyPyarrowError(msg)
96
+ return None
97
+
98
+ return pyarrow
99
+
100
+
101
+ PYARROW_VERSIONS = PyarrowVersions()
102
+
103
+
104
+ class BQStorageVersions:
105
+ """Version comparisons for google-cloud-bigqueyr-storage package."""
106
+
107
+ def __init__(self):
108
+ self._installed_version = None
109
+
110
+ @property
111
+ def installed_version(self) -> packaging.version.Version:
112
+ """Return the parsed version of google-cloud-bigquery-storage."""
113
+ if self._installed_version is None:
114
+ from google.cloud import bigquery_storage
115
+
116
+ self._installed_version = packaging.version.parse(
117
+ # Use 0.0.0, since it is earlier than any released version.
118
+ # Legacy versions also have the same property, but
119
+ # creating a LegacyVersion has been deprecated.
120
+ # https://github.com/pypa/packaging/issues/321
121
+ getattr(bigquery_storage, "__version__", "0.0.0")
122
+ )
123
+
124
+ return self._installed_version # type: ignore
125
+
126
+ @property
127
+ def is_read_session_optional(self) -> bool:
128
+ """True if read_session is optional to rows().
129
+
130
+ See: https://github.com/googleapis/python-bigquery-storage/pull/228
131
+ """
132
+ return self.installed_version >= _BQ_STORAGE_OPTIONAL_READ_SESSION_VERSION
133
+
134
+ def try_import(self, raise_if_error: bool = False) -> Any:
135
+ """Tries to import the bigquery_storage module, and returns results
136
+ accordingly. It also verifies the module version is recent enough.
137
+
138
+ If the import succeeds, returns the ``bigquery_storage`` module.
139
+
140
+ If the import fails,
141
+ returns ``None`` when ``raise_if_error == False``,
142
+ raises Error when ``raise_if_error == True``.
143
+
144
+ Returns:
145
+ The ``bigquery_storage`` module or ``None``.
146
+
147
+ Raises:
148
+ exceptions.BigQueryStorageNotFoundError:
149
+ If google-cloud-bigquery-storage is not installed
150
+ exceptions.LegacyBigQueryStorageError:
151
+ If google-cloud-bigquery-storage package is outdated
152
+ """
153
+ try:
154
+ from google.cloud import bigquery_storage # type: ignore
155
+ except ImportError:
156
+ if raise_if_error:
157
+ msg = (
158
+ "Package google-cloud-bigquery-storage not found. "
159
+ "Install google-cloud-bigquery-storage version >= "
160
+ f"{_MIN_BQ_STORAGE_VERSION}."
161
+ )
162
+ raise exceptions.BigQueryStorageNotFoundError(msg)
163
+ return None
164
+
165
+ if self.installed_version < _MIN_BQ_STORAGE_VERSION:
166
+ if raise_if_error:
167
+ msg = (
168
+ "Dependency google-cloud-bigquery-storage is outdated, "
169
+ f"please upgrade it to version >= {_MIN_BQ_STORAGE_VERSION} "
170
+ f"(version found: {self.installed_version})."
171
+ )
172
+ raise exceptions.LegacyBigQueryStorageError(msg)
173
+ return None
174
+
175
+ return bigquery_storage
176
+
177
+
178
+ BQ_STORAGE_VERSIONS = BQStorageVersions()
179
+
180
+
181
+ class PandasVersions:
182
+ """Version comparisons for pandas package."""
183
+
184
+ def __init__(self):
185
+ self._installed_version = None
186
+
187
+ @property
188
+ def installed_version(self) -> packaging.version.Version:
189
+ """Return the parsed version of pandas"""
190
+ if self._installed_version is None:
191
+ import pandas # type: ignore
192
+
193
+ self._installed_version = packaging.version.parse(
194
+ # Use 0.0.0, since it is earlier than any released version.
195
+ # Legacy versions also have the same property, but
196
+ # creating a LegacyVersion has been deprecated.
197
+ # https://github.com/pypa/packaging/issues/321
198
+ getattr(pandas, "__version__", "0.0.0")
199
+ )
200
+
201
+ return self._installed_version
202
+
203
+ def try_import(self, raise_if_error: bool = False) -> Any:
204
+ """Verify that a recent enough version of pandas extra is installed.
205
+ The function assumes that pandas extra is installed, and should thus
206
+ be used in places where this assumption holds.
207
+ Because `pip` can install an outdated version of this extra despite
208
+ the constraints in `setup.py`, the calling code can use this helper
209
+ to verify the version compatibility at runtime.
210
+ Returns:
211
+ The ``pandas`` module or ``None``.
212
+ Raises:
213
+ exceptions.LegacyPandasError:
214
+ If the pandas package is outdated and ``raise_if_error`` is
215
+ ``True``.
216
+ """
217
+ try:
218
+ import pandas
219
+ except ImportError as exc:
220
+ if raise_if_error:
221
+ raise exceptions.LegacyPandasError(
222
+ "pandas package not found. Install pandas version >="
223
+ f" {_MIN_PANDAS_VERSION}"
224
+ ) from exc
225
+ return None
226
+
227
+ if self.installed_version < _MIN_PANDAS_VERSION:
228
+ if raise_if_error:
229
+ msg = (
230
+ "Dependency pandas is outdated, please upgrade"
231
+ f" it to version >= {_MIN_PANDAS_VERSION}"
232
+ f" (version found: {self.installed_version})."
233
+ )
234
+ raise exceptions.LegacyPandasError(msg)
235
+ return None
236
+
237
+ return pandas
238
+
239
+
240
+ PANDAS_VERSIONS = PandasVersions()
241
+
242
+ # Since RANGE support in pandas requires specific versions
243
+ # of both pyarrow and pandas, we make this a separate
244
+ # constant instead of as a property of PANDAS_VERSIONS
245
+ # or PYARROW_VERSIONS.
246
+ SUPPORTS_RANGE_PYARROW = (
247
+ PANDAS_VERSIONS.try_import() is not None
248
+ and PANDAS_VERSIONS.installed_version >= _MIN_PANDAS_VERSION_RANGE
249
+ and PYARROW_VERSIONS.try_import() is not None
250
+ and PYARROW_VERSIONS.installed_version >= _MIN_PYARROW_VERSION_RANGE
251
+ )
252
+
253
+
254
+ def extract_runtime_version():
255
+ # Retrieve the version information
256
+ version_info = sys.version_info
257
+
258
+ # Extract the major, minor, and micro components
259
+ major = version_info.major
260
+ minor = version_info.minor
261
+ micro = version_info.micro
262
+
263
+ # Display the version number in a clear format
264
+ return major, minor, micro