snowflake-connector-python 5.2.0__cp315-cp315-win_amd64.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.
- snowflake/connector/__init__.py +148 -0
- snowflake/connector/_common/__init__.py +0 -0
- snowflake/connector/_common/extras.py +134 -0
- snowflake/connector/_common/telemetry.py +221 -0
- snowflake/connector/_common/wif_util.py +92 -0
- snowflake/connector/_core/sf_core_python.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_core/sf_core_python.pyi +79 -0
- snowflake/connector/_internal/__init__.py +6 -0
- snowflake/connector/_internal/_private_key_helper.py +31 -0
- snowflake/connector/_internal/api_client/__init__.py +93 -0
- snowflake/connector/_internal/api_client/bridge.py +41 -0
- snowflake/connector/_internal/api_client/client_api.py +976 -0
- snowflake/connector/_internal/arrow.py +47 -0
- snowflake/connector/_internal/arrow_context.py +240 -0
- snowflake/connector/_internal/arrow_stream_async.py +266 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp311-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
- snowflake/connector/_internal/arrow_stream_utils.py +171 -0
- snowflake/connector/_internal/authenticator_type.py +53 -0
- snowflake/connector/_internal/backward_compatibility.py +245 -0
- snowflake/connector/_internal/binding_converters.py +741 -0
- snowflake/connector/_internal/config_utils.py +71 -0
- snowflake/connector/_internal/connection/__init__.py +39 -0
- snowflake/connector/_internal/connection/connection.py +616 -0
- snowflake/connector/_internal/connection/connection_types.py +13 -0
- snowflake/connector/_internal/connection/constants.py +25 -0
- snowflake/connector/_internal/connection/decorators.py +31 -0
- snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
- snowflake/connector/_internal/connection/queries.py +10 -0
- snowflake/connector/_internal/connection_config_mixin.py +755 -0
- snowflake/connector/_internal/cursor/__init__.py +25 -0
- snowflake/connector/_internal/cursor/base.py +732 -0
- snowflake/connector/_internal/cursor/cursor_types.py +13 -0
- snowflake/connector/_internal/cursor/decorators.py +56 -0
- snowflake/connector/_internal/cursor/query_result.py +202 -0
- snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
- snowflake/connector/_internal/cursor/result_metadata.py +255 -0
- snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
- snowflake/connector/_internal/decorators.py +539 -0
- snowflake/connector/_internal/error_kinds.py +111 -0
- snowflake/connector/_internal/errorcode.py +35 -0
- snowflake/connector/_internal/errorhandler.py +278 -0
- snowflake/connector/_internal/fips.py +28 -0
- snowflake/connector/_internal/logging/__init__.py +52 -0
- snowflake/connector/_internal/logging/config.py +134 -0
- snowflake/connector/_internal/logging/core_logger.py +218 -0
- snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
- snowflake/connector/_internal/logout_config_mapping.py +187 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13278 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
- snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
- snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
- snowflake/connector/_internal/result_batch.py +150 -0
- snowflake/connector/_internal/snowflake_restful.py +222 -0
- snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
- snowflake/connector/_internal/sqlstate.py +11 -0
- snowflake/connector/_internal/statement_utils.py +207 -0
- snowflake/connector/_internal/text_utils.py +112 -0
- snowflake/connector/_internal/type_codes.py +139 -0
- snowflake/connector/_internal/utils.py +65 -0
- snowflake/connector/_internal/write_pandas_operation.py +657 -0
- snowflake/connector/aio/README.md +168 -0
- snowflake/connector/aio/__init__.py +37 -0
- snowflake/connector/aio/connection/__init__.py +17 -0
- snowflake/connector/aio/connection/_connection.py +506 -0
- snowflake/connector/aio/cursor/__init__.py +35 -0
- snowflake/connector/aio/cursor/_base.py +1034 -0
- snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
- snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/aio/pandas_tools.py +279 -0
- snowflake/connector/aio/result_batch.py +165 -0
- snowflake/connector/auth/__init__.py +0 -0
- snowflake/connector/auth/workload_identity.py +5 -0
- snowflake/connector/compat.py +22 -0
- snowflake/connector/config_manager.py +392 -0
- snowflake/connector/connection/__init__.py +30 -0
- snowflake/connector/connection/_connection.py +641 -0
- snowflake/connector/connection_config.py +517 -0
- snowflake/connector/constants.py +52 -0
- snowflake/connector/cursor/__init__.py +37 -0
- snowflake/connector/cursor/_base.py +1169 -0
- snowflake/connector/cursor/_chunked_download_reader.py +75 -0
- snowflake/connector/cursor/_dict_cursor.py +78 -0
- snowflake/connector/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/description.py +7 -0
- snowflake/connector/errors.py +492 -0
- snowflake/connector/network.py +71 -0
- snowflake/connector/pandas_tools.py +191 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +216 -0
- snowflake/connector/telemetry.py +40 -0
- snowflake/connector/time_util.py +11 -0
- snowflake/connector/types.py +134 -0
- snowflake/connector/util_text.py +3 -0
- snowflake/connector/version.py +23 -0
- snowflake_connector_python-5.2.0.dist-info/DELVEWHEEL +2 -0
- snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
- snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
- snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
- snowflake_connector_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import TYPE_CHECKING, cast
|
|
5
|
+
|
|
6
|
+
from snowflake.connector._core import sf_core_python
|
|
7
|
+
from snowflake.connector.errors import InternalError
|
|
8
|
+
|
|
9
|
+
from .._common.extras import pyarrow
|
|
10
|
+
from .arrow_context import ArrowConverterContext
|
|
11
|
+
from .arrow_stream_iterator import ArrowStreamIterator as CythonArrowStreamIterator
|
|
12
|
+
from .arrow_stream_iterator import ArrowStreamTableIterator as CythonArrowStreamTableIterator
|
|
13
|
+
from .type_codes import FIXED
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from pyarrow import Schema, Table
|
|
18
|
+
|
|
19
|
+
from .arrow import ArrowRowIterator, ArrowTableIterator
|
|
20
|
+
from .cursor.result_metadata import ResultMetadata
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _missing_native_class(name: str) -> InternalError:
|
|
24
|
+
return InternalError(
|
|
25
|
+
msg=f"sf_core_python.{name} is unavailable; rebuild with --features native-arrow / SF_NATIVE_ARROW=1",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def release_arrow_stream(stream_ptr: int | None) -> None:
|
|
30
|
+
"""Release an ArrowArrayStream pointer to prevent memory leaks.
|
|
31
|
+
|
|
32
|
+
Works by creating a throwaway ArrowStreamIterator whose C++ destructor
|
|
33
|
+
calls ``stream->release(stream)`` when it goes out of scope. This is
|
|
34
|
+
indirect — the C++ from_stream() factory also reads the schema — but it
|
|
35
|
+
is the only release path currently exposed to Python.
|
|
36
|
+
|
|
37
|
+
If the stream is in a bad state (already released, corrupt), the
|
|
38
|
+
ArrowStreamIterator constructor will fail. We catch that to avoid
|
|
39
|
+
propagating errors into callers that are doing best-effort cleanup
|
|
40
|
+
(e.g. from_prepare_result cleanup).
|
|
41
|
+
"""
|
|
42
|
+
if not stream_ptr:
|
|
43
|
+
return
|
|
44
|
+
try:
|
|
45
|
+
_ = CythonArrowStreamIterator(stream_ptr, ArrowConverterContext())
|
|
46
|
+
except Exception:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def create_row_iterator(
|
|
51
|
+
stream_ptr: int,
|
|
52
|
+
*,
|
|
53
|
+
context: ArrowConverterContext,
|
|
54
|
+
use_dict_result: bool = False,
|
|
55
|
+
use_numpy: bool = False,
|
|
56
|
+
use_core_arrow: bool = False,
|
|
57
|
+
) -> ArrowRowIterator:
|
|
58
|
+
"""Build a sync row iterator that yields one row at a time.
|
|
59
|
+
|
|
60
|
+
When ``use_core_arrow`` is true and ``sf_core_python`` is built with the
|
|
61
|
+
``native-arrow`` feature, returns the PyO3 ``ArrowStreamIterator`` directly.
|
|
62
|
+
Otherwise uses the Cython nanoarrow iterator.
|
|
63
|
+
"""
|
|
64
|
+
if use_core_arrow and sf_core_python.native_arrow_enabled():
|
|
65
|
+
# Class is only exported when built with ``native-arrow``; stub_gen
|
|
66
|
+
# emits ``#[pyfunction]``s only, so do not attribute-access it on the stub.
|
|
67
|
+
iterator_cls = getattr(sf_core_python, "ArrowStreamIterator", None)
|
|
68
|
+
if iterator_cls is None:
|
|
69
|
+
release_arrow_stream(stream_ptr)
|
|
70
|
+
raise _missing_native_class("ArrowStreamIterator")
|
|
71
|
+
return cast(
|
|
72
|
+
"ArrowRowIterator",
|
|
73
|
+
iterator_cls(
|
|
74
|
+
stream_ptr,
|
|
75
|
+
session_timezone=context.timezone,
|
|
76
|
+
use_dict_result=use_dict_result,
|
|
77
|
+
use_numpy=use_numpy,
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
return CythonArrowStreamIterator(
|
|
81
|
+
stream_ptr,
|
|
82
|
+
context,
|
|
83
|
+
use_dict_result=use_dict_result,
|
|
84
|
+
use_numpy=use_numpy,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def create_table_iterator(
|
|
89
|
+
stream_ptr: int,
|
|
90
|
+
*,
|
|
91
|
+
context: ArrowConverterContext,
|
|
92
|
+
number_to_decimal: bool = False,
|
|
93
|
+
force_microsecond_precision: bool = False,
|
|
94
|
+
use_core_arrow: bool = False,
|
|
95
|
+
) -> ArrowTableIterator:
|
|
96
|
+
"""Build a table iterator that yields one RecordBatch at a time.
|
|
97
|
+
|
|
98
|
+
When ``use_core_arrow`` is true and ``sf_core_python`` is built with the
|
|
99
|
+
``native-arrow`` feature, returns the PyO3 ``ArrowStreamTableIterator``.
|
|
100
|
+
Otherwise uses the Cython nanoarrow iterator.
|
|
101
|
+
"""
|
|
102
|
+
if use_core_arrow and sf_core_python.native_arrow_enabled():
|
|
103
|
+
# Class is only exported when built with ``native-arrow``; stub_gen
|
|
104
|
+
# emits ``#[pyfunction]``s only, so do not attribute-access it on the stub.
|
|
105
|
+
iterator_cls = getattr(sf_core_python, "ArrowStreamTableIterator", None)
|
|
106
|
+
if iterator_cls is None:
|
|
107
|
+
release_arrow_stream(stream_ptr)
|
|
108
|
+
raise _missing_native_class("ArrowStreamTableIterator")
|
|
109
|
+
return cast(
|
|
110
|
+
"ArrowTableIterator",
|
|
111
|
+
iterator_cls(
|
|
112
|
+
stream_ptr,
|
|
113
|
+
session_timezone=context.timezone,
|
|
114
|
+
number_to_decimal=number_to_decimal,
|
|
115
|
+
force_microsecond_precision=force_microsecond_precision,
|
|
116
|
+
),
|
|
117
|
+
)
|
|
118
|
+
return CythonArrowStreamTableIterator(
|
|
119
|
+
stream_ptr,
|
|
120
|
+
context,
|
|
121
|
+
number_to_decimal=number_to_decimal,
|
|
122
|
+
force_microsecond_precision=force_microsecond_precision,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def normalize_fixed_column_types(
|
|
127
|
+
schema: Schema,
|
|
128
|
+
description: Sequence[ResultMetadata],
|
|
129
|
+
) -> Schema:
|
|
130
|
+
"""Rewrite FIXED columns in an Arrow schema to int64 for backward compatibility.
|
|
131
|
+
|
|
132
|
+
When the result set has zero rows, sf-core may choose a narrower integer
|
|
133
|
+
type (e.g. int8) for NUMBER columns. The old driver always exposed int64,
|
|
134
|
+
so we normalize here to keep behavior consistent.
|
|
135
|
+
"""
|
|
136
|
+
new_fields = []
|
|
137
|
+
changed = False
|
|
138
|
+
for field, metadata in zip(schema, description, strict=False):
|
|
139
|
+
if metadata.type_code == FIXED and field.type != pyarrow.int64():
|
|
140
|
+
new_fields.append(field.with_type(pyarrow.int64()))
|
|
141
|
+
changed = True
|
|
142
|
+
else:
|
|
143
|
+
new_fields.append(field)
|
|
144
|
+
return pyarrow.schema(new_fields) if changed else schema
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def collect_arrow_table(
|
|
148
|
+
table_iterator: ArrowTableIterator,
|
|
149
|
+
columns_metadata: Sequence[ResultMetadata] | None = None,
|
|
150
|
+
force_return_table: bool = False,
|
|
151
|
+
) -> Table | None:
|
|
152
|
+
"""Collect all RecordBatches from *table_iterator* into a single Arrow Table.
|
|
153
|
+
|
|
154
|
+
When *force_return_table* is ``True`` an empty result set produces a
|
|
155
|
+
properly-typed empty table. When ``False`` (the default), an empty result
|
|
156
|
+
set returns ``None``.
|
|
157
|
+
|
|
158
|
+
When *columns_metadata* is provided the empty-table schema is normalized via
|
|
159
|
+
:func:`normalize_fixed_column_types` so that FIXED columns are int64.
|
|
160
|
+
"""
|
|
161
|
+
batches = list(table_iterator)
|
|
162
|
+
if batches:
|
|
163
|
+
return pyarrow.Table.from_batches(batches)
|
|
164
|
+
|
|
165
|
+
if not force_return_table:
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
schema = table_iterator.get_converted_schema()
|
|
169
|
+
if columns_metadata:
|
|
170
|
+
schema = normalize_fixed_column_types(schema, columns_metadata)
|
|
171
|
+
return schema.empty_table()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""The ``AuthenticatorType`` enum: one member per authenticator the driver accepts.
|
|
2
|
+
|
|
3
|
+
DEPRECATED. Retained only for backward compatibility with
|
|
4
|
+
snowflake-connector-python, whose callers imported these values to pass to
|
|
5
|
+
``authenticator=``. The Universal Driver itself never reads this enum — it only
|
|
6
|
+
needs the raw string. New code should pass the string directly (e.g.
|
|
7
|
+
``authenticator="OAUTH"``); this exists so existing code keeps working.
|
|
8
|
+
|
|
9
|
+
MUST BE KEPT IN SYNC WITH THE RUST CORE. Every value below has to be a spelling
|
|
10
|
+
the core's connection-config parser accepts, because callers read a value from
|
|
11
|
+
here and hand it straight back as ``authenticator=`` — a value listed here but
|
|
12
|
+
rejected by the core is a broken round trip. Nothing generates this file, so the
|
|
13
|
+
guard is a test on the Rust side:
|
|
14
|
+
``sf_core::config::connection_config``'s
|
|
15
|
+
``recognises_every_authenticator_spelling_exposed_to_python``. It reads *this
|
|
16
|
+
file* and runs the real parser over every value, so adding a member here that
|
|
17
|
+
the core does not accept fails the Rust test suite. If you add one, add the
|
|
18
|
+
matching arm in ``sf_core/src/config/connection_config.rs`` too.
|
|
19
|
+
|
|
20
|
+
The reverse does not hold, deliberately: the core accepts spellings this enum
|
|
21
|
+
does not list (``""`` and ``"SNOWFLAKE_PASSWORD"`` for password auth,
|
|
22
|
+
``https://`` URLs for native Okta SSO). Only listing something the core rejects
|
|
23
|
+
is a bug.
|
|
24
|
+
|
|
25
|
+
Re-exported by :mod:`snowflake.connector.constants`. Unlike the flat
|
|
26
|
+
``*_AUTHENTICATOR`` constants in :mod:`snowflake.connector.network`, this enum
|
|
27
|
+
does not emit a deprecation warning on access: it's re-exported from two
|
|
28
|
+
modules, and the shared warn-once machinery only lets a single defining module
|
|
29
|
+
warn, so there's no clean way to fire exactly one warning across both re-export
|
|
30
|
+
paths.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
from enum import StrEnum
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AuthenticatorType(StrEnum):
|
|
39
|
+
"""Authenticator types accepted by the Universal Driver's ``authenticator=`` connection parameter."""
|
|
40
|
+
|
|
41
|
+
DEFAULT = "SNOWFLAKE"
|
|
42
|
+
EXTERNAL_BROWSER = "EXTERNALBROWSER"
|
|
43
|
+
KEY_PAIR = "SNOWFLAKE_JWT"
|
|
44
|
+
OAUTH = "OAUTH"
|
|
45
|
+
OAUTH_AUTHORIZATION_CODE = "OAUTH_AUTHORIZATION_CODE"
|
|
46
|
+
OAUTH_CLIENT_CREDENTIALS = "OAUTH_CLIENT_CREDENTIALS"
|
|
47
|
+
USERNAME_PASSWORD_MFA = "USERNAME_PASSWORD_MFA"
|
|
48
|
+
PROGRAMMATIC_ACCESS_TOKEN = "PROGRAMMATIC_ACCESS_TOKEN"
|
|
49
|
+
PAT_WITH_EXTERNAL_SESSION = "PAT_WITH_EXTERNAL_SESSION"
|
|
50
|
+
WORKLOAD_IDENTITY = "WORKLOAD_IDENTITY"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
__all__ = ["AuthenticatorType"]
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"""Runtime machinery backing the ``@backward_compatibility`` decorator.
|
|
2
|
+
|
|
3
|
+
The public decorator itself lives in :mod:`.decorators` for discoverability;
|
|
4
|
+
everything that supports it — the call-time wrapper, the module-level
|
|
5
|
+
``__getattr__`` installer, the dedup state, and the caller-origin check —
|
|
6
|
+
lives here so ``decorators.py`` stays a thin file of marker/annotation
|
|
7
|
+
decorators.
|
|
8
|
+
|
|
9
|
+
Three collaborators form the public surface of this module:
|
|
10
|
+
|
|
11
|
+
* :func:`apply_backward_compatibility` — used by the decorator in
|
|
12
|
+
:mod:`.decorators`; never called directly by user code.
|
|
13
|
+
* :func:`install_backward_compatibility_getattr` — called at the bottom of
|
|
14
|
+
modules that export ``@backward_compatibility``-decorated classes, to wire
|
|
15
|
+
up the PEP 562 ``__getattr__`` that warns on first attribute access.
|
|
16
|
+
* :data:`_BACKWARD_COMPAT_WARNED` — process-wide dedup set; exported for
|
|
17
|
+
tests only.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import functools
|
|
23
|
+
import inspect
|
|
24
|
+
import sys
|
|
25
|
+
import warnings
|
|
26
|
+
|
|
27
|
+
from collections.abc import Callable
|
|
28
|
+
from typing import Any, TypeVar
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
F = TypeVar("F", bound=Callable)
|
|
32
|
+
T = TypeVar("T")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Callers whose module name starts with any of these prefixes are considered
|
|
36
|
+
# internal and will NOT trigger a backward-compatibility warning. This keeps
|
|
37
|
+
# internal uses (e.g. ``self.populate_data(...)`` called from elsewhere in the
|
|
38
|
+
# driver) silent so the dedup slot remains available for the first external use.
|
|
39
|
+
_INTERNAL_CALLER_PREFIX = "snowflake.connector"
|
|
40
|
+
|
|
41
|
+
# (module, qualname) pairs that have already emitted a deprecation warning.
|
|
42
|
+
# Used to enforce once-per-process dedup across both the ``__getattr__`` and
|
|
43
|
+
# call-wrapper paths.
|
|
44
|
+
_BACKWARD_COMPAT_WARNED: set[tuple[str, str]] = set()
|
|
45
|
+
|
|
46
|
+
# Registry of objects processed by ``@backward_compatibility``. We track
|
|
47
|
+
# membership here rather than stamping the decorated object with a marker
|
|
48
|
+
# attribute: (a) descriptors such as ``property`` reject arbitrary attribute
|
|
49
|
+
# assignment, so the marker approach silently failed for them, and (b) the
|
|
50
|
+
# decorator stays non-invasive — the decorated object is never mutated.
|
|
51
|
+
# Classes, functions, and stdlib descriptors are held by identity under the
|
|
52
|
+
# default hash. Plain values (e.g. module-level string constants) hash and
|
|
53
|
+
# compare by *value* instead, so two unrelated constants with the same value
|
|
54
|
+
# would collide here; harmless today (no such collision exists), but a
|
|
55
|
+
# byte-for-byte identical string added elsewhere would be swept in too.
|
|
56
|
+
_MARKED_BACKWARD_COMPAT: set[Any] = set()
|
|
57
|
+
|
|
58
|
+
_DEPRECATION_WARNING_MSG_SUFFIX = (
|
|
59
|
+
"is retained only for backward compatibility and is not used by the new driver; "
|
|
60
|
+
"it may be removed in a future release."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def apply_backward_compatibility(obj: T, *, recommendation: str | None = None) -> T:
|
|
65
|
+
"""Implement the ``@backward_compatibility`` decorator.
|
|
66
|
+
|
|
67
|
+
Plain functions are wrapped so the first *external* call emits a warning.
|
|
68
|
+
Classes, descriptors (property, staticmethod, classmethod, etc.), and
|
|
69
|
+
plain values (e.g. module-level string constants) are passed through
|
|
70
|
+
unchanged; for those, the module-level ``__getattr__`` installed by
|
|
71
|
+
:func:`install_backward_compatibility_getattr` turns registry membership
|
|
72
|
+
into a warn-on-first-access behavior.
|
|
73
|
+
|
|
74
|
+
``recommendation``, if given, is appended to the emitted warning to name
|
|
75
|
+
the replacement API. Only takes effect for the wrapped-function path;
|
|
76
|
+
classes ignore it since they never reach :func:`_wrap_fn_with_warning`.
|
|
77
|
+
|
|
78
|
+
The returned object is recorded in :data:`_MARKED_BACKWARD_COMPAT` so
|
|
79
|
+
:func:`install_backward_compatibility_getattr` can later identify which
|
|
80
|
+
module globals to stash, and so repeated ``@backward_compatibility``
|
|
81
|
+
decoration is a no-op.
|
|
82
|
+
"""
|
|
83
|
+
if _is_marked_backward_compat(obj):
|
|
84
|
+
return obj # idempotent re-decoration
|
|
85
|
+
|
|
86
|
+
result = _wrap_fn_with_warning(obj, recommendation=recommendation) if inspect.isfunction(obj) else obj
|
|
87
|
+
_mark_backward_compat(result)
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def install_backward_compatibility_getattr(module_name: str) -> None:
|
|
92
|
+
"""Install a module-level ``__getattr__`` that warns on first access of
|
|
93
|
+
each ``@backward_compatibility``-decorated top-level **class or
|
|
94
|
+
module-level constant**.
|
|
95
|
+
|
|
96
|
+
Must be called at the *bottom* of the target module, after all decorated
|
|
97
|
+
names have been defined. The tagged names are removed from the module's
|
|
98
|
+
globals and stashed privately so PEP 562 ``__getattr__`` is invoked on
|
|
99
|
+
access — which is what lets us distinguish "someone imported this name"
|
|
100
|
+
from mere module import.
|
|
101
|
+
|
|
102
|
+
Top-level functions decorated with ``@backward_compatibility`` are NOT
|
|
103
|
+
moved here; they already emit a warning on first external call via the
|
|
104
|
+
call-time wrapper installed by :func:`apply_backward_compatibility`.
|
|
105
|
+
"""
|
|
106
|
+
module = sys.modules[module_name]
|
|
107
|
+
stash: dict[str, Any] = {}
|
|
108
|
+
|
|
109
|
+
for name, value in list(vars(module).items()):
|
|
110
|
+
if name.startswith("_"):
|
|
111
|
+
continue
|
|
112
|
+
# Functions self-warn via the call-time wrapper installed by
|
|
113
|
+
# ``apply_backward_compatibility``; never stash them here.
|
|
114
|
+
if inspect.isfunction(value):
|
|
115
|
+
continue
|
|
116
|
+
# ``value`` may be an unhashable module global (e.g. a dict/list),
|
|
117
|
+
# which can never be a registry member. Probe defensively so the
|
|
118
|
+
# membership test can't raise TypeError on those globals.
|
|
119
|
+
try:
|
|
120
|
+
marked = _is_marked_backward_compat(value)
|
|
121
|
+
except TypeError:
|
|
122
|
+
continue
|
|
123
|
+
if not marked:
|
|
124
|
+
continue
|
|
125
|
+
# Classes: only stash those DEFINED in this module, not re-exports.
|
|
126
|
+
# Non-class marked values (module-level constants) carry no meaningful
|
|
127
|
+
# ``__module__``, so this re-export guard is scoped to classes.
|
|
128
|
+
if inspect.isclass(value) and getattr(value, "__module__", None) != module_name:
|
|
129
|
+
continue
|
|
130
|
+
stash[name] = value
|
|
131
|
+
delattr(module, name)
|
|
132
|
+
|
|
133
|
+
if not stash:
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
existing_getattr: Callable[[str], Any] | None = module.__dict__.get("__getattr__")
|
|
137
|
+
module.__getattr__ = _module_getattr_with_warning( # type: ignore[method-assign]
|
|
138
|
+
module_name, stash, existing_getattr
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _mark_backward_compat(obj: Any) -> None:
|
|
143
|
+
_MARKED_BACKWARD_COMPAT.add(obj)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _is_marked_backward_compat(obj: Any) -> bool:
|
|
147
|
+
return obj in _MARKED_BACKWARD_COMPAT
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _wrap_fn_with_warning(obj: F, *, recommendation: str | None = None) -> F:
|
|
151
|
+
module = getattr(obj, "__module__", None) or ""
|
|
152
|
+
# Prefer __qualname__ so method warnings read "Class.method" rather than just "method".
|
|
153
|
+
name = getattr(obj, "__qualname__", None) or getattr(obj, "__name__", None) or ""
|
|
154
|
+
|
|
155
|
+
@functools.wraps(obj)
|
|
156
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
157
|
+
if _is_caller_external():
|
|
158
|
+
_emit_backward_compatibility_warning(module, name, recommendation=recommendation)
|
|
159
|
+
return obj(*args, **kwargs)
|
|
160
|
+
|
|
161
|
+
return wrapper # type: ignore[return-value]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _is_caller_external() -> bool:
|
|
165
|
+
"""Return ``True`` when the frame that invoked our direct caller is NOT
|
|
166
|
+
part of the ``snowflake.connector`` package tree.
|
|
167
|
+
|
|
168
|
+
Used from both the call-time wrapper (:func:`_wrap_fn_with_warning`) and
|
|
169
|
+
the PEP 562 ``__getattr__`` installed by
|
|
170
|
+
:func:`install_backward_compatibility_getattr` to suppress warnings for
|
|
171
|
+
accesses originating inside ``snowflake.connector.*`` — driver-internal
|
|
172
|
+
use must never consume the once-per-process dedup slot before a customer
|
|
173
|
+
does. Both call sites sit exactly one Python frame below the caller we
|
|
174
|
+
care about, which is why the skip count below is fixed at 2.
|
|
175
|
+
"""
|
|
176
|
+
try:
|
|
177
|
+
frame = sys._getframe(2) # skip: this helper + our direct caller
|
|
178
|
+
except ValueError:
|
|
179
|
+
return True
|
|
180
|
+
caller_module = frame.f_globals.get("__name__") or ""
|
|
181
|
+
return not caller_module.startswith(_INTERNAL_CALLER_PREFIX)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _module_getattr_with_warning(
|
|
185
|
+
module_name: str,
|
|
186
|
+
stash: dict[str, Any],
|
|
187
|
+
existing_getattr: Callable[[str], Any] | None,
|
|
188
|
+
) -> Callable[[str], Any]:
|
|
189
|
+
"""Build the PEP 562 ``__getattr__`` that emits a warning on first access
|
|
190
|
+
of a stashed backward-compat name and delegates unknown names to any
|
|
191
|
+
pre-existing module ``__getattr__``.
|
|
192
|
+
|
|
193
|
+
Internal accesses (from within ``snowflake.connector.*``) bypass the
|
|
194
|
+
warning via :func:`_is_caller_external` — the value is still returned so
|
|
195
|
+
nothing breaks if a driver module does end up importing one of these
|
|
196
|
+
names, but the one-shot dedup slot stays available for the first real
|
|
197
|
+
user. A static test enforces that no such internal access exists today.
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __getattr__(name: str) -> Any:
|
|
201
|
+
if name in stash:
|
|
202
|
+
if _is_caller_external():
|
|
203
|
+
_emit_backward_compatibility_warning(module_name, name)
|
|
204
|
+
return stash[name]
|
|
205
|
+
if existing_getattr is not None:
|
|
206
|
+
return existing_getattr(name)
|
|
207
|
+
raise AttributeError(f"module {module_name!r} has no attribute {name!r}")
|
|
208
|
+
|
|
209
|
+
return __getattr__
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _emit_backward_compatibility_warning(module: str, name: str, *, recommendation: str | None = None) -> None:
|
|
213
|
+
"""Emit a ``DeprecationWarning`` the first time ``module.name`` is used.
|
|
214
|
+
|
|
215
|
+
Deduplication is done against an explicit set so the warning is emitted at
|
|
216
|
+
most once per process per ``(module, name)`` pair regardless of the user's
|
|
217
|
+
``warnings`` filter configuration, and regardless of whether the first use
|
|
218
|
+
was an import (module ``__getattr__``) or a call (wrapped callable).
|
|
219
|
+
|
|
220
|
+
``recommendation``, if given, is appended verbatim to name the replacement
|
|
221
|
+
API for this specific symbol.
|
|
222
|
+
|
|
223
|
+
Concurrency: the check-then-add is not locked. Two threads racing on the
|
|
224
|
+
same key may each see it as absent and both emit the warning once — an
|
|
225
|
+
acceptable trade-off vs. taking a lock on every call.
|
|
226
|
+
|
|
227
|
+
Stack-level invariant: this function must be called from exactly one
|
|
228
|
+
Python frame below the user — i.e. from the wrapped-callable wrapper or
|
|
229
|
+
from the module ``__getattr__``, and nowhere else. Given that, the two
|
|
230
|
+
call chains are ``user -> wrapper -> _emit -> warn`` and
|
|
231
|
+
``user -> __getattr__ -> _emit -> warn``, so ``stacklevel=3`` puts the
|
|
232
|
+
reported source at the user's frame in both cases. If you add a third
|
|
233
|
+
call site, keep this invariant or this helper's stacklevel must grow a
|
|
234
|
+
parameter.
|
|
235
|
+
"""
|
|
236
|
+
key = (module, name)
|
|
237
|
+
if key in _BACKWARD_COMPAT_WARNED:
|
|
238
|
+
return
|
|
239
|
+
_BACKWARD_COMPAT_WARNED.add(key)
|
|
240
|
+
suffix = f" {recommendation}" if recommendation else ""
|
|
241
|
+
warnings.warn(
|
|
242
|
+
f"'{module}.{name}' {_DEPRECATION_WARNING_MSG_SUFFIX}{suffix}",
|
|
243
|
+
DeprecationWarning,
|
|
244
|
+
stacklevel=3,
|
|
245
|
+
)
|