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.
Files changed (204) hide show
  1. snowflake/connector/__init__.py +148 -0
  2. snowflake/connector/_common/__init__.py +0 -0
  3. snowflake/connector/_common/extras.py +134 -0
  4. snowflake/connector/_common/telemetry.py +221 -0
  5. snowflake/connector/_common/wif_util.py +92 -0
  6. snowflake/connector/_core/sf_core_python.cp315-win_amd64.pyd +0 -0
  7. snowflake/connector/_core/sf_core_python.pyi +79 -0
  8. snowflake/connector/_internal/__init__.py +6 -0
  9. snowflake/connector/_internal/_private_key_helper.py +31 -0
  10. snowflake/connector/_internal/api_client/__init__.py +93 -0
  11. snowflake/connector/_internal/api_client/bridge.py +41 -0
  12. snowflake/connector/_internal/api_client/client_api.py +976 -0
  13. snowflake/connector/_internal/arrow.py +47 -0
  14. snowflake/connector/_internal/arrow_context.py +240 -0
  15. snowflake/connector/_internal/arrow_stream_async.py +266 -0
  16. snowflake/connector/_internal/arrow_stream_iterator.cp311-win_amd64.pyd +0 -0
  17. snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
  18. snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
  19. snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
  20. snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
  21. snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +0 -0
  22. snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
  23. snowflake/connector/_internal/arrow_stream_utils.py +171 -0
  24. snowflake/connector/_internal/authenticator_type.py +53 -0
  25. snowflake/connector/_internal/backward_compatibility.py +245 -0
  26. snowflake/connector/_internal/binding_converters.py +741 -0
  27. snowflake/connector/_internal/config_utils.py +71 -0
  28. snowflake/connector/_internal/connection/__init__.py +39 -0
  29. snowflake/connector/_internal/connection/connection.py +616 -0
  30. snowflake/connector/_internal/connection/connection_types.py +13 -0
  31. snowflake/connector/_internal/connection/constants.py +25 -0
  32. snowflake/connector/_internal/connection/decorators.py +31 -0
  33. snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
  34. snowflake/connector/_internal/connection/queries.py +10 -0
  35. snowflake/connector/_internal/connection_config_mixin.py +755 -0
  36. snowflake/connector/_internal/cursor/__init__.py +25 -0
  37. snowflake/connector/_internal/cursor/base.py +732 -0
  38. snowflake/connector/_internal/cursor/cursor_types.py +13 -0
  39. snowflake/connector/_internal/cursor/decorators.py +56 -0
  40. snowflake/connector/_internal/cursor/query_result.py +202 -0
  41. snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
  42. snowflake/connector/_internal/cursor/result_metadata.py +255 -0
  43. snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
  44. snowflake/connector/_internal/decorators.py +539 -0
  45. snowflake/connector/_internal/error_kinds.py +111 -0
  46. snowflake/connector/_internal/errorcode.py +35 -0
  47. snowflake/connector/_internal/errorhandler.py +278 -0
  48. snowflake/connector/_internal/fips.py +28 -0
  49. snowflake/connector/_internal/logging/__init__.py +52 -0
  50. snowflake/connector/_internal/logging/config.py +134 -0
  51. snowflake/connector/_internal/logging/core_logger.py +218 -0
  52. snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
  53. snowflake/connector/_internal/logout_config_mapping.py +187 -0
  54. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
  55. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  56. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
  57. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
  58. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
  59. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  60. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  61. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  62. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
  63. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
  64. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
  65. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
  66. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
  67. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
  68. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
  69. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
  70. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
  71. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  72. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
  73. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  74. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
  75. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
  76. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
  77. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  78. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
  79. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  80. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  81. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  82. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
  83. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
  84. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
  85. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  86. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
  87. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  88. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
  89. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  90. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  91. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
  92. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
  93. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
  94. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
  95. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  96. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
  97. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  98. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
  99. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  100. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
  101. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
  102. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  103. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  104. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  105. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13278 -0
  106. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
  107. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
  108. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
  109. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  110. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
  111. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
  112. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
  113. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  114. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
  115. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
  116. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  117. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  118. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  119. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
  120. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
  121. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
  122. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  123. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
  124. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
  125. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
  126. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  127. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  128. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
  129. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
  130. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  131. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  132. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  133. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  134. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  135. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
  136. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
  137. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
  138. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  139. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  140. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
  141. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
  142. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
  143. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
  144. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
  145. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
  146. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
  147. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
  148. snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
  149. snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
  150. snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
  151. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
  152. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
  153. snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
  154. snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
  155. snowflake/connector/_internal/result_batch.py +150 -0
  156. snowflake/connector/_internal/snowflake_restful.py +222 -0
  157. snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
  158. snowflake/connector/_internal/sqlstate.py +11 -0
  159. snowflake/connector/_internal/statement_utils.py +207 -0
  160. snowflake/connector/_internal/text_utils.py +112 -0
  161. snowflake/connector/_internal/type_codes.py +139 -0
  162. snowflake/connector/_internal/utils.py +65 -0
  163. snowflake/connector/_internal/write_pandas_operation.py +657 -0
  164. snowflake/connector/aio/README.md +168 -0
  165. snowflake/connector/aio/__init__.py +37 -0
  166. snowflake/connector/aio/connection/__init__.py +17 -0
  167. snowflake/connector/aio/connection/_connection.py +506 -0
  168. snowflake/connector/aio/cursor/__init__.py +35 -0
  169. snowflake/connector/aio/cursor/_base.py +1034 -0
  170. snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
  171. snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
  172. snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
  173. snowflake/connector/aio/pandas_tools.py +279 -0
  174. snowflake/connector/aio/result_batch.py +165 -0
  175. snowflake/connector/auth/__init__.py +0 -0
  176. snowflake/connector/auth/workload_identity.py +5 -0
  177. snowflake/connector/compat.py +22 -0
  178. snowflake/connector/config_manager.py +392 -0
  179. snowflake/connector/connection/__init__.py +30 -0
  180. snowflake/connector/connection/_connection.py +641 -0
  181. snowflake/connector/connection_config.py +517 -0
  182. snowflake/connector/constants.py +52 -0
  183. snowflake/connector/cursor/__init__.py +37 -0
  184. snowflake/connector/cursor/_base.py +1169 -0
  185. snowflake/connector/cursor/_chunked_download_reader.py +75 -0
  186. snowflake/connector/cursor/_dict_cursor.py +78 -0
  187. snowflake/connector/cursor/_result_set_wrapper.py +35 -0
  188. snowflake/connector/cursor/_snowflake_cursor.py +72 -0
  189. snowflake/connector/description.py +7 -0
  190. snowflake/connector/errors.py +492 -0
  191. snowflake/connector/network.py +71 -0
  192. snowflake/connector/pandas_tools.py +191 -0
  193. snowflake/connector/py.typed +0 -0
  194. snowflake/connector/result_batch.py +216 -0
  195. snowflake/connector/telemetry.py +40 -0
  196. snowflake/connector/time_util.py +11 -0
  197. snowflake/connector/types.py +134 -0
  198. snowflake/connector/util_text.py +3 -0
  199. snowflake/connector/version.py +23 -0
  200. snowflake_connector_python-5.2.0.dist-info/DELVEWHEEL +2 -0
  201. snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
  202. snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
  203. snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
  204. snowflake_connector_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
@@ -0,0 +1,278 @@
1
+ """PEP 249 error-handler routing via ``ErrorHandlerMixin``.
2
+
3
+ How to raise errors in the driver:
4
+ - Classes (Connection, Cursor, ResultBatch): inherit ``ErrorHandlerMixin``.
5
+ Public methods are wrapped automatically via ``__init_subclass__``.
6
+ Then use plain ``raise``.
7
+ - Free functions with a ``conn`` argument (e.g. ``write_pandas``): wrap the body
8
+ in ``try/except Error`` and call ``route_exception(conn, None, exc)``.
9
+
10
+ This wrapping is also where ``wrapper_error`` telemetry is collected (see
11
+ ``_report_wrapper_error`` / ``_report_wrapper_error_async``): every wrapped
12
+ call that catches an exception reports it, tagged with its own method name,
13
+ but only the outermost frame in a call chain hands the error to the PEP 249
14
+ errorhandler, so PEP 249 routing still fires exactly once.
15
+
16
+ Hot-path methods may use ``@simplified_error_handling`` instead of the mixin wrap:
17
+ failures still go through ``_reraise_via_errorhandler``, but the success path
18
+ skips the ContextVar round-trip.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import functools
24
+ import inspect
25
+
26
+ from collections.abc import Callable
27
+ from contextvars import ContextVar
28
+ from typing import TYPE_CHECKING, Any, NoReturn, TypeVar, cast
29
+
30
+ from ..errors import Error, ErrorDetails
31
+ from .decorators import _schedule_async_telemetry, _telemetry_client_if_enabled
32
+ from .logging import get_logger
33
+
34
+
35
+ if TYPE_CHECKING:
36
+ from ..aio.connection import Connection as AsyncConnection
37
+ from ..aio.cursor import SnowflakeCursorBase as AsyncSnowflakeCursorBase
38
+ from ..connection import Connection
39
+ from ..cursor import SnowflakeCursorBase
40
+
41
+ logger = get_logger(__name__)
42
+
43
+ F = TypeVar("F", bound=Callable[..., Any])
44
+
45
+ # Set on an Error that has already been through ``route_exception`` / the
46
+ # default handler, so a @simplified_error_handling hot path does not PEP 249-route
47
+ # twice when an inner wrapped method already did.
48
+ _ROUTED_ATTR = "_sf_errorhandler_routed"
49
+ _SIMPLIFIED_ERROR_HANDLING_ATTR = "_simplified_error_handling"
50
+
51
+
52
+ def simplified_error_handling(func: F) -> F:
53
+ """Route failures without the mixin ContextVar round-trip on the success path.
54
+
55
+ Skips ``ErrorHandlerMixin`` auto-wrapping and installs a cheap ``try/except``
56
+ that calls ``_reraise_via_errorhandler`` (PEP 249 routing + ``wrapper_error`` telemetry).
57
+ """
58
+ if inspect.iscoroutinefunction(func):
59
+
60
+ @functools.wraps(func)
61
+ async def async_wrapper(self: ErrorHandlerMixin, *args: Any, **kwargs: Any) -> Any:
62
+ try:
63
+ return await func(self, *args, **kwargs)
64
+ except Exception as exc:
65
+ await self._reraise_via_errorhandler_async(func, exc)
66
+
67
+ wrapper: Callable[..., Any] = async_wrapper
68
+ else:
69
+
70
+ @functools.wraps(func)
71
+ def sync_wrapper(self: ErrorHandlerMixin, *args: Any, **kwargs: Any) -> Any:
72
+ try:
73
+ return func(self, *args, **kwargs)
74
+ except Exception as exc:
75
+ self._reraise_via_errorhandler(func, exc)
76
+
77
+ wrapper = sync_wrapper
78
+
79
+ setattr(wrapper, _SIMPLIFIED_ERROR_HANDLING_ATTR, True)
80
+ return cast(F, wrapper)
81
+
82
+
83
+ def _mark_errorhandler_routed(exc: BaseException) -> None:
84
+ setattr(exc, _ROUTED_ATTR, True)
85
+
86
+
87
+ def route_exception(
88
+ connection: Connection | AsyncConnection | None,
89
+ cursor: SnowflakeCursorBase | AsyncSnowflakeCursorBase | None,
90
+ exc: Error,
91
+ ) -> NoReturn:
92
+ """Route an ``Error`` through the PEP 249 errorhandler chain, then re-raise.
93
+
94
+ The handler may observe, log, or replace the error (by raising a different
95
+ exception), but it cannot suppress it — the original is always re-raised.
96
+ """
97
+ _mark_errorhandler_routed(exc)
98
+ error_value = _error_to_value(exc)
99
+ Error.hand_to_other_handler(connection, cursor, type(exc), error_value)
100
+ raise exc
101
+
102
+
103
+ class ErrorHandlerMixin:
104
+ """Mixin that routes ``Error`` exceptions from public methods through PEP 249 errorhandler.
105
+
106
+ Inherit this class and override ``_errorhandler_connection`` and/or
107
+ ``_errorhandler_cursor`` to supply context. Public methods are wrapped
108
+ automatically at class creation time via ``__init_subclass__``.
109
+ """
110
+
111
+ def __init_subclass__(cls, **kwargs: Any) -> None:
112
+ super().__init_subclass__(**kwargs)
113
+ _apply_errorhandler(cls)
114
+
115
+ @property
116
+ def _errorhandler_connection(self) -> Connection | AsyncConnection | None:
117
+ return None
118
+
119
+ @property
120
+ def _errorhandler_cursor(self) -> SnowflakeCursorBase | AsyncSnowflakeCursorBase | None:
121
+ return None
122
+
123
+ def _reraise_via_errorhandler(self, method: Callable[..., Any], exc: BaseException) -> NoReturn:
124
+ """Report ``wrapper_error`` telemetry and PEP 249-route *exc* unless already routed.
125
+
126
+ Used by ``@simplified_error_handling`` instead of paying a ContextVar
127
+ round-trip on every successful call.
128
+ """
129
+ _report_wrapper_error(self, method, exc)
130
+ if isinstance(exc, Error) and not _errorhandler_active.get() and not getattr(exc, _ROUTED_ATTR, False):
131
+ route_exception(self._errorhandler_connection, self._errorhandler_cursor, exc)
132
+ raise exc
133
+
134
+ async def _reraise_via_errorhandler_async(self, method: Callable[..., Any], exc: BaseException) -> NoReturn:
135
+ """Async counterpart of :meth:`_reraise_via_errorhandler`."""
136
+ await _report_wrapper_error_async(self, method, exc)
137
+ if isinstance(exc, Error) and not _errorhandler_active.get() and not getattr(exc, _ROUTED_ATTR, False):
138
+ route_exception(self._errorhandler_connection, self._errorhandler_cursor, exc)
139
+ raise exc
140
+
141
+
142
+ def _apply_errorhandler(cls: type) -> None:
143
+ """Wrap public methods of *cls* with error-handler routing."""
144
+ for name in list(vars(cls)):
145
+ # private/dunder — not part of the public API surface
146
+ if name.startswith("_"):
147
+ continue
148
+ attr = vars(cls)[name]
149
+ if getattr(attr, _SIMPLIFIED_ERROR_HANDLING_ATTR, False):
150
+ continue
151
+ # descriptors — not regular instance methods
152
+ if isinstance(attr, (property, classmethod, staticmethod)):
153
+ continue
154
+ # class-level constants or non-callable attributes
155
+ if not callable(attr):
156
+ continue
157
+ # generators/async generators yield lazily; errors surface at iteration
158
+ # time, not call time — the inner calls they drive are wrapped individually.
159
+ if inspect.isgeneratorfunction(attr) or inspect.isasyncgenfunction(attr):
160
+ continue
161
+ if inspect.iscoroutinefunction(attr):
162
+ setattr(cls, name, _wrap_async_method(attr))
163
+ else:
164
+ setattr(cls, name, _wrap_method(attr))
165
+
166
+
167
+ # Prevents double-routing when a wrapped public method calls another.
168
+ # Global (not per-object):
169
+ # if conn A's method somehow triggers conn B's method in the same context, conn B's errors won't be routed.
170
+ # This is acceptable because a connection method should never call into another connection
171
+ # and per-object tracking would add overhead on every call for a scenario that should not occur.
172
+ _errorhandler_active: ContextVar[bool] = ContextVar("_errorhandler_active", default=False)
173
+
174
+
175
+ def _report_wrapper_error(self: Any, method: Callable[..., Any], exc: BaseException) -> None:
176
+ """Send ``wrapper_error`` telemetry for *exc*."""
177
+ try:
178
+ # circular-import: telemetry.py imports errorhandler helpers; defer this import
179
+ # to call time so the module-level import graph doesn't cycle.
180
+ from .._common.telemetry import AsyncTelemetryClient
181
+
182
+ error_source = f"{type(self).__name__}.{method.__name__}"
183
+ client = _telemetry_client_if_enabled(self)
184
+ if client is None:
185
+ return
186
+ if isinstance(client, AsyncTelemetryClient):
187
+ # A sync method on an async-flavored class (e.g. a non-coroutine method on
188
+ # AsyncConnection/AsyncCursorBase) still carries an AsyncTelemetryClient.
189
+ _schedule_async_telemetry(client.send_wrapper_error(type(exc).__name__, error_source))
190
+ else:
191
+ client.send_wrapper_error(type(exc).__name__, error_source)
192
+ except Exception:
193
+ logger.debug("Failed to send wrapper_error telemetry")
194
+
195
+
196
+ async def _report_wrapper_error_async(self: Any, method: Callable[..., Any], exc: BaseException) -> None:
197
+ """Async counterpart of :func:`_report_wrapper_error`."""
198
+ try:
199
+ # circular-import: telemetry.py imports errorhandler helpers; defer this import
200
+ # to call time so the module-level import graph doesn't cycle.
201
+ from .._common.telemetry import AsyncTelemetryClient
202
+
203
+ error_source = f"{type(self).__name__}.{method.__name__}"
204
+ client = _telemetry_client_if_enabled(self)
205
+ if client is None:
206
+ return
207
+ if isinstance(client, AsyncTelemetryClient):
208
+ await client.send_wrapper_error(type(exc).__name__, error_source)
209
+ else:
210
+ client.send_wrapper_error(type(exc).__name__, error_source)
211
+ except Exception:
212
+ logger.debug("Failed to send wrapper_error telemetry")
213
+
214
+
215
+ def _wrap_method(method: Callable) -> Callable:
216
+ """Wrap a method to report ``wrapper_error`` telemetry and route ``Error`` through the errorhandler chain."""
217
+
218
+ @functools.wraps(method)
219
+ def wrapper(self: ErrorHandlerMixin, *args: Any, **kwargs: Any) -> Any:
220
+ nested = _errorhandler_active.get()
221
+ if not nested:
222
+ token = _errorhandler_active.set(True)
223
+ try:
224
+ return method(self, *args, **kwargs)
225
+ except Exception as exc:
226
+ _report_wrapper_error(self, method, exc)
227
+ if not nested and isinstance(exc, Error):
228
+ route_exception(
229
+ self._errorhandler_connection,
230
+ self._errorhandler_cursor,
231
+ exc,
232
+ )
233
+ raise
234
+ finally:
235
+ if not nested:
236
+ _errorhandler_active.reset(token)
237
+
238
+ return wrapper
239
+
240
+
241
+ def _wrap_async_method(method: Callable) -> Callable:
242
+ """Async counterpart of :func:`_wrap_method`."""
243
+
244
+ @functools.wraps(method)
245
+ async def wrapper(self: ErrorHandlerMixin, *args: Any, **kwargs: Any) -> Any:
246
+ nested = _errorhandler_active.get()
247
+ if not nested:
248
+ token = _errorhandler_active.set(True)
249
+ try:
250
+ return await method(self, *args, **kwargs)
251
+ except Exception as exc:
252
+ await _report_wrapper_error_async(self, method, exc)
253
+ if not nested and isinstance(exc, Error):
254
+ route_exception(
255
+ self._errorhandler_connection,
256
+ self._errorhandler_cursor,
257
+ exc,
258
+ )
259
+ raise
260
+ finally:
261
+ if not nested:
262
+ _errorhandler_active.reset(token)
263
+
264
+ return wrapper
265
+
266
+
267
+ def _error_to_value(exc: Error) -> ErrorDetails:
268
+ """Deconstruct an ``Error`` into the dict expected by ``hand_to_other_handler``."""
269
+ return {
270
+ "msg": exc.raw_msg,
271
+ "errno": exc.errno,
272
+ "sqlstate": exc.sqlstate,
273
+ "sfqid": exc.sfqid,
274
+ "query": exc.query,
275
+ "request_id": exc.request_id,
276
+ "parameter": exc.parameter,
277
+ "validation_code": exc.validation_code,
278
+ }
@@ -0,0 +1,28 @@
1
+ """FIPS status for this process.
2
+
3
+ ``snowflake.connector`` re-exports :class:`FipsStatus` and :func:`get_fips_status`.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import NamedTuple
9
+
10
+ from .api_client.client_api import core_driver
11
+ from .decorators import pep249
12
+
13
+
14
+ class FipsStatus(NamedTuple):
15
+ """Whether this process is the FIPS driver.
16
+
17
+ ``is_fips`` is true when this binary was built with ``fips`` and its linked
18
+ TLS provider is in FIPS mode. A standard build returns false.
19
+ """
20
+
21
+ is_fips: bool
22
+
23
+
24
+ @pep249
25
+ def get_fips_status() -> FipsStatus:
26
+ """Report whether this process is the FIPS driver without opening a connection."""
27
+ response = core_driver.driver_get_fips_status()
28
+ return FipsStatus(is_fips=response.is_fips)
@@ -0,0 +1,52 @@
1
+ """Logging for the snowflake.connector module.
2
+
3
+ This package owns **configuration** of the ``snowflake.connector`` and
4
+ ``snowflake.connector._core`` stdlib loggers (``setup_logging`` and the internal
5
+ ``_get_*_stdlib_logger`` accessors), including the ``sf_core`` FFI callback
6
+ logger, plus the public :func:`get_logger` entry point that wrapper code uses.
7
+
8
+ Round-trip logging (:class:`.core_logger.CoreLogger`, which sends wrapper logs
9
+ to sf_core over a direct FFI call and receives them back through the FFI
10
+ callback) lives in :mod:`.core_logger` so its FFI import stays off this
11
+ module's load path. See ``docs/logging/logging-architecture.md``.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import functools
17
+
18
+ from typing import TYPE_CHECKING
19
+
20
+ from .config import (
21
+ CONNECTOR_LOGGER_NAME,
22
+ SF_CORE_LOGGER_NAME,
23
+ _get_connector_stdlib_logger,
24
+ _get_sf_core_stdlib_logger,
25
+ _needs_handler,
26
+ setup_logging,
27
+ )
28
+ from .native_extension_logger import NativeExtensionLogger, get_native_extension_logger
29
+
30
+
31
+ if TYPE_CHECKING:
32
+ from .core_logger import CoreLogger
33
+
34
+
35
+ @functools.cache
36
+ def get_logger(name: str) -> CoreLogger:
37
+ from .core_logger import CoreLogger
38
+
39
+ return CoreLogger(name)
40
+
41
+
42
+ __all__ = [
43
+ "CONNECTOR_LOGGER_NAME",
44
+ "SF_CORE_LOGGER_NAME",
45
+ "NativeExtensionLogger",
46
+ "_get_connector_stdlib_logger",
47
+ "_get_sf_core_stdlib_logger",
48
+ "_needs_handler",
49
+ "get_logger",
50
+ "get_native_extension_logger",
51
+ "setup_logging",
52
+ ]
@@ -0,0 +1,134 @@
1
+ """Logging configuration for snowflake.connector."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+
7
+
8
+ # Logger names
9
+ CONNECTOR_LOGGER_NAME = "snowflake.connector"
10
+ SF_CORE_LOGGER_NAME = "snowflake.connector._core"
11
+
12
+ # Set up loggers once at module load with NullHandler (standard library practice
13
+ # per https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library).
14
+ # Propagation is left ON so that external log capture (e.g. pytest caplog, root-level
15
+ # handlers configured by the application) works out of the box -- matching
16
+ # the behavior of snowflake-connector-python.
17
+ # When setup_logging() is called explicitly, propagation is turned OFF on the
18
+ # loggers that receive a dedicated handler to prevent duplicate output.
19
+ _sf_core_logger = logging.getLogger(SF_CORE_LOGGER_NAME)
20
+ _sf_core_logger.addHandler(logging.NullHandler())
21
+
22
+ _connector_logger = logging.getLogger(CONNECTOR_LOGGER_NAME)
23
+ _connector_logger.addHandler(logging.NullHandler())
24
+
25
+
26
+ def _needs_handler(logger: logging.Logger) -> bool:
27
+ """Return True if the logger has no handlers or only NullHandler(s)."""
28
+ if not logger.handlers:
29
+ return True
30
+ return all(isinstance(h, logging.NullHandler) for h in logger.handlers)
31
+
32
+
33
+ def setup_logging(
34
+ level: int = logging.INFO,
35
+ sf_core_level: int = logging.INFO,
36
+ format_string: str | None = None,
37
+ stream: object | None = None,
38
+ ) -> None:
39
+ """Configure basic logging for the snowflake.connector module.
40
+
41
+ Propagation behaviour
42
+ ---------------------
43
+ By default (before this function is called) both loggers have
44
+ ``propagate=True``. This means log records bubble up to the root
45
+ logger so that application-level handlers and test frameworks such as
46
+ ``pytest caplog`` capture connector output without any extra
47
+ configuration.
48
+
49
+ When this function adds a dedicated StreamHandler to a logger it also
50
+ sets ``propagate=False`` on that logger to prevent every message from
51
+ appearing twice — once via the dedicated handler and once via the root
52
+ handler chain.
53
+
54
+ **The propagate flag is only changed when a handler is actually added.**
55
+ If the logger already has a non-NullHandler (meaning the caller has
56
+ configured it themselves), this function leaves ``propagate`` and the
57
+ existing handler untouched and only updates the logger's *level*.
58
+ This respects application-level logging configuration while still
59
+ honouring the requested verbosity.
60
+
61
+ Summary:
62
+ * No prior handler → adds StreamHandler, sets propagate=False.
63
+ * Prior non-Null handler exists → updates level only, propagate unchanged.
64
+ * Called multiple times with no prior handler → second call is a no-op
65
+ for handler/propagation (handler already present from the first call).
66
+
67
+ Args:
68
+ level: Logging level for the snowflake.connector logger.
69
+ Defaults to logging.INFO.
70
+ sf_core_level: Logging level for the sf_core logger.
71
+ Defaults to logging.INFO.
72
+ format_string: Custom format string for log messages.
73
+ If None, uses a default format.
74
+ stream: Stream to write logs to. If None, uses sys.stderr.
75
+
76
+ Example:
77
+ >>> from snowflake.connector._internal.logging import setup_logging
78
+ >>> import logging
79
+ >>> setup_logging(level=logging.DEBUG, sf_core_level=logging.DEBUG)
80
+ """
81
+ if format_string is None:
82
+ format_string = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
83
+
84
+ formatter = logging.Formatter(format_string)
85
+ handler = logging.StreamHandler(stream) # type: ignore [arg-type]
86
+ handler.setFormatter(formatter)
87
+
88
+ _connector_logger.setLevel(level)
89
+ if _needs_handler(_connector_logger):
90
+ _connector_logger.addHandler(handler)
91
+ _connector_logger.propagate = False
92
+
93
+ _sf_core_logger.setLevel(sf_core_level)
94
+ if _needs_handler(_sf_core_logger):
95
+ _sf_core_logger.addHandler(handler)
96
+ _sf_core_logger.propagate = False
97
+
98
+
99
+ def _get_connector_stdlib_logger() -> logging.Logger:
100
+ """Return the package stdlib logger used by logging infrastructure.
101
+
102
+ Internal — not for wrapper contributor use. Call :func:`logging.get_logger`
103
+ to obtain a :class:`~.core_logger.CoreLogger` for module logging.
104
+ """
105
+ return _connector_logger
106
+
107
+
108
+ def _get_sf_core_stdlib_logger() -> logging.Logger:
109
+ """Return the stdlib logger that receives core-originated FFI callback events.
110
+
111
+ Internal — used by :mod:`~.api_client` callback dispatch only.
112
+ Wrapper code should use :func:`logging.get_logger` instead.
113
+ """
114
+ return _sf_core_logger
115
+
116
+
117
+ class LoggingConfiguration:
118
+ """Process-wide logging knobs — currently just troubleshooting mode."""
119
+
120
+ _instance: LoggingConfiguration | None = None
121
+
122
+ def __init__(self, *, troubleshooting_enabled: bool) -> None:
123
+ self._troubleshooting_enabled = troubleshooting_enabled
124
+
125
+ @classmethod
126
+ def initialize(cls, *, troubleshooting_enabled: bool) -> LoggingConfiguration:
127
+ """Create the process-wide instance. Call once after ``sf_core_python.init``."""
128
+ if cls._instance is None:
129
+ cls._instance = cls(troubleshooting_enabled=troubleshooting_enabled)
130
+ return cls._instance
131
+
132
+ def is_troubleshooting_enabled(self) -> bool:
133
+ """Return whether wrapper logs should bypass the ``CoreLogger`` pre-filter."""
134
+ return self._troubleshooting_enabled