snowflake-connector-python 4.1.0__tar.gz → 4.1.1__tar.gz

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 (261) hide show
  1. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/DESCRIPTION.md +5 -0
  2. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/PKG-INFO +9 -2
  3. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/setup.cfg +3 -1
  4. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/connection.py +18 -0
  5. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/crl.py +131 -6
  6. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/crl_cache.py +113 -22
  7. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/network.py +3 -0
  8. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/result_batch.py +1 -1
  9. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/session_manager.py +14 -8
  10. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/version.py +1 -1
  11. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/PKG-INFO +9 -2
  12. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/requires.txt +9 -1
  13. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/CONTRIBUTING.md +0 -0
  14. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/LICENSE.txt +0 -0
  15. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/MANIFEST.in +0 -0
  16. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/NOTICE +0 -0
  17. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/README.md +0 -0
  18. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/SECURITY.md +0 -0
  19. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/pyproject.toml +0 -0
  20. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/setup.py +0 -0
  21. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/__init__.py +0 -0
  22. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/_query_context_cache.py +0 -0
  23. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/_sql_util.py +0 -0
  24. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/_utils.py +0 -0
  25. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/arrow_context.py +0 -0
  26. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/__init__.py +0 -0
  27. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/_auth.py +0 -0
  28. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/_http_server.py +0 -0
  29. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/_oauth_base.py +0 -0
  30. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/by_plugin.py +0 -0
  31. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/default.py +0 -0
  32. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/idtoken.py +0 -0
  33. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/keypair.py +0 -0
  34. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/no_auth.py +0 -0
  35. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/oauth.py +0 -0
  36. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/oauth_code.py +0 -0
  37. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/oauth_credentials.py +0 -0
  38. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/okta.py +0 -0
  39. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/pat.py +0 -0
  40. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/usrpwdmfa.py +0 -0
  41. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/webbrowser.py +0 -0
  42. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/auth/workload_identity.py +0 -0
  43. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/azure_storage_client.py +0 -0
  44. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/backoff_policies.py +0 -0
  45. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/bind_upload_agent.py +0 -0
  46. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/cache.py +0 -0
  47. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/compat.py +0 -0
  48. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/config_manager.py +0 -0
  49. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/connection_diagnostic.py +0 -0
  50. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/constants.py +0 -0
  51. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/converter.py +0 -0
  52. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/converter_issue23517.py +0 -0
  53. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/converter_null.py +0 -0
  54. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/converter_snowsql.py +0 -0
  55. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/cursor.py +0 -0
  56. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/dbapi.py +0 -0
  57. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/description.py +0 -0
  58. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/direct_file_operation_utils.py +0 -0
  59. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/encryption_util.py +0 -0
  60. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/errorcode.py +0 -0
  61. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/errors.py +0 -0
  62. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/externals_utils/__init__.py +0 -0
  63. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/externals_utils/externals_setup.py +0 -0
  64. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/feature.py +0 -0
  65. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/file_compression_type.py +0 -0
  66. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/file_lock.py +0 -0
  67. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/file_transfer_agent.py +0 -0
  68. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/file_util.py +0 -0
  69. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/gcs_storage_client.py +0 -0
  70. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/gzip_decoder.py +0 -0
  71. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/interval_util.py +0 -0
  72. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/local_storage_client.py +0 -0
  73. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/log_configuration.py +0 -0
  74. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/logging_utils/__init__.py +0 -0
  75. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/logging_utils/filters.py +0 -0
  76. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +0 -0
  77. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +0 -0
  78. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +0 -0
  79. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +0 -0
  80. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +0 -0
  81. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +0 -0
  82. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +0 -0
  83. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +0 -0
  84. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +0 -0
  85. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +0 -0
  86. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +0 -0
  87. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +0 -0
  88. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +0 -0
  89. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +0 -0
  90. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +0 -0
  91. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +0 -0
  92. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +0 -0
  93. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +0 -0
  94. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +0 -0
  95. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +0 -0
  96. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +0 -0
  97. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +0 -0
  98. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +0 -0
  99. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +0 -0
  100. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +0 -0
  101. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +0 -0
  102. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +0 -0
  103. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +0 -0
  104. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +0 -0
  105. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +0 -0
  106. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +0 -0
  107. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +0 -0
  108. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +0 -0
  109. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +0 -0
  110. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +0 -0
  111. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +0 -0
  112. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +0 -0
  113. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +0 -0
  114. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +0 -0
  115. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +0 -0
  116. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +0 -0
  117. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +0 -0
  118. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +0 -0
  119. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +0 -0
  120. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +0 -0
  121. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +0 -0
  122. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +0 -0
  123. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +0 -0
  124. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +0 -0
  125. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +0 -0
  126. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +0 -0
  127. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +0 -0
  128. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +0 -0
  129. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +0 -0
  130. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +0 -0
  131. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +0 -0
  132. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +0 -0
  133. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +0 -0
  134. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +0 -0
  135. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +0 -0
  136. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +0 -0
  137. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +0 -0
  138. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +0 -0
  139. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +0 -0
  140. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +0 -0
  141. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +0 -0
  142. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +0 -0
  143. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +0 -0
  144. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +0 -0
  145. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +0 -0
  146. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +0 -0
  147. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +0 -0
  148. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +0 -0
  149. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +0 -0
  150. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +0 -0
  151. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +0 -0
  152. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +0 -0
  153. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +0 -0
  154. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +0 -0
  155. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +0 -0
  156. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +0 -0
  157. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +0 -0
  158. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +0 -0
  159. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +0 -0
  160. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +0 -0
  161. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +0 -0
  162. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +0 -0
  163. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +0 -0
  164. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +0 -0
  165. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +0 -0
  166. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +0 -0
  167. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/ocsp_asn1crypto.py +0 -0
  168. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/ocsp_snowflake.py +0 -0
  169. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/options.py +0 -0
  170. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/pandas_tools.py +0 -0
  171. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/platform_detection.py +0 -0
  172. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/proxy.py +0 -0
  173. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/py.typed +0 -0
  174. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/result_set.py +0 -0
  175. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/s3_storage_client.py +0 -0
  176. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/secret_detector.py +0 -0
  177. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/sf_dirs.py +0 -0
  178. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/sfbinaryformat.py +0 -0
  179. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/sfdatetime.py +0 -0
  180. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/snow_logging.py +0 -0
  181. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/sqlstate.py +0 -0
  182. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/ssd_internal_keys.py +0 -0
  183. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/ssl_wrap_socket.py +0 -0
  184. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/storage_client.py +0 -0
  185. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/telemetry.py +0 -0
  186. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/telemetry_oob.py +0 -0
  187. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/test_util.py +0 -0
  188. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/time_util.py +0 -0
  189. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/token_cache.py +0 -0
  190. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/tool/__init__.py +0 -0
  191. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/tool/dump_certs.py +0 -0
  192. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/tool/dump_ocsp_response.py +0 -0
  193. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/tool/dump_ocsp_response_cache.py +0 -0
  194. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/tool/probe_connection.py +0 -0
  195. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/url_util.py +0 -0
  196. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/util_text.py +0 -0
  197. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/__init__.py +0 -0
  198. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/LICENSE +0 -0
  199. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/__init__.py +0 -0
  200. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/__version__.py +0 -0
  201. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/_internal_utils.py +0 -0
  202. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/adapters.py +0 -0
  203. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/api.py +0 -0
  204. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/auth.py +0 -0
  205. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/certs.py +0 -0
  206. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/compat.py +0 -0
  207. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/cookies.py +0 -0
  208. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/exceptions.py +0 -0
  209. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/help.py +0 -0
  210. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/hooks.py +0 -0
  211. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/models.py +0 -0
  212. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/packages.py +0 -0
  213. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/sessions.py +0 -0
  214. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/status_codes.py +0 -0
  215. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/structures.py +0 -0
  216. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/requests/utils.py +0 -0
  217. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/LICENSE.txt +0 -0
  218. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/__init__.py +0 -0
  219. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/_base_connection.py +0 -0
  220. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/_collections.py +0 -0
  221. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/_request_methods.py +0 -0
  222. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/_version.py +0 -0
  223. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/connection.py +0 -0
  224. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/connectionpool.py +0 -0
  225. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  226. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/__init__.py +0 -0
  227. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/connection.py +0 -0
  228. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/emscripten_fetch_worker.js +0 -0
  229. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/fetch.py +0 -0
  230. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/request.py +0 -0
  231. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/response.py +0 -0
  232. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +0 -0
  233. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/contrib/socks.py +0 -0
  234. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/exceptions.py +0 -0
  235. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/fields.py +0 -0
  236. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/filepost.py +0 -0
  237. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/http2/__init__.py +0 -0
  238. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/http2/connection.py +0 -0
  239. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/http2/probe.py +0 -0
  240. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/poolmanager.py +0 -0
  241. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/py.typed +0 -0
  242. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/response.py +0 -0
  243. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/__init__.py +0 -0
  244. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/connection.py +0 -0
  245. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/proxy.py +0 -0
  246. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/request.py +0 -0
  247. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/response.py +0 -0
  248. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/retry.py +0 -0
  249. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/ssl_.py +0 -0
  250. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +0 -0
  251. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/ssltransport.py +0 -0
  252. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/timeout.py +0 -0
  253. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/url.py +0 -0
  254. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/util.py +0 -0
  255. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/vendored/urllib3/util/wait.py +0 -0
  256. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake/connector/wif_util.py +0 -0
  257. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/SOURCES.txt +0 -0
  258. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/dependency_links.txt +0 -0
  259. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/entry_points.txt +0 -0
  260. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/not-zip-safe +0 -0
  261. {snowflake_connector_python-4.1.0 → snowflake_connector_python-4.1.1}/src/snowflake_connector_python.egg-info/top_level.txt +0 -0
@@ -7,6 +7,11 @@ https://docs.snowflake.com/
7
7
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
8
8
 
9
9
  # Release Notes
10
+ - v4.1.1(TBD)
11
+ - Relaxed pandas dependency requirements for Python below 3.12.
12
+ - Changed CRL cache cleanup background task to daemon to avoid blocking main thread.
13
+ - Fixed NO_PROXY issues with PUT operations
14
+
10
15
  - v4.1.0(November 18,2025)
11
16
  - Added the `SNOWFLAKE_AUTH_FORCE_SERVER` environment variable to force the use of the local-listening server when using the `externalbrowser` auth method.
12
17
  - This allows headless environments (like Docker or Airflow) running locally to auth via a browser URL.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-connector-python
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: Snowflake Connector for Python
5
5
  Home-page: https://www.snowflake.com/
6
6
  Author: Snowflake, Inc
@@ -62,6 +62,7 @@ Requires-Dist: botocore>=1.24; extra == "boto"
62
62
  Provides-Extra: development
63
63
  Requires-Dist: Cython; extra == "development"
64
64
  Requires-Dist: coverage; extra == "development"
65
+ Requires-Dist: mitmproxy>=6.0.0; python_version >= "3.10" and extra == "development"
65
66
  Requires-Dist: more-itertools; extra == "development"
66
67
  Requires-Dist: numpy<=2.2.4; extra == "development"
67
68
  Requires-Dist: pendulum!=2.1.1; extra == "development"
@@ -74,7 +75,8 @@ Requires-Dist: pytest-xdist; extra == "development"
74
75
  Requires-Dist: pytzdata; extra == "development"
75
76
  Requires-Dist: responses; extra == "development"
76
77
  Provides-Extra: pandas
77
- Requires-Dist: pandas<3.0.0,>=2.1.2; extra == "pandas"
78
+ Requires-Dist: pandas<3.0.0,>=1.0.0; python_version < "3.13" and extra == "pandas"
79
+ Requires-Dist: pandas<3.0.0,>=2.1.2; python_version >= "3.13" and extra == "pandas"
78
80
  Requires-Dist: pyarrow>=14.0.1; extra == "pandas"
79
81
  Provides-Extra: secure-local-storage
80
82
  Requires-Dist: keyring<26.0.0,>=23.1.0; extra == "secure-local-storage"
@@ -90,6 +92,11 @@ https://docs.snowflake.com/
90
92
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
91
93
 
92
94
  # Release Notes
95
+ - v4.1.1(TBD)
96
+ - Relaxed pandas dependency requirements for Python below 3.12.
97
+ - Changed CRL cache cleanup background task to daemon to avoid blocking main thread.
98
+ - Fixed NO_PROXY issues with PUT operations
99
+
93
100
  - v4.1.0(November 18,2025)
94
101
  - Added the `SNOWFLAKE_AUTH_FORCE_SERVER` environment variable to force the use of the local-listening server when using the `externalbrowser` auth method.
95
102
  - This allows headless environments (like Docker or Airflow) running locally to auth via a browser URL.
@@ -82,6 +82,7 @@ boto =
82
82
  development =
83
83
  Cython
84
84
  coverage
85
+ mitmproxy>=6.0.0; python_version >= '3.10'
85
86
  more-itertools
86
87
  numpy<=2.2.4
87
88
  pendulum!=2.1.1
@@ -94,7 +95,8 @@ development =
94
95
  pytzdata
95
96
  responses
96
97
  pandas =
97
- pandas>=2.1.2,<3.0.0
98
+ pandas>=1.0.0,<3.0.0; python_version < '3.13'
99
+ pandas>=2.1.2,<3.0.0; python_version >= '3.13'
98
100
  pyarrow>=14.0.1
99
101
  secure-local-storage =
100
102
  keyring>=23.1.0,<26.0.0
@@ -476,6 +476,10 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
476
476
  None,
477
477
  (type(None), bool),
478
478
  ), # Run CRL cache cleanup in the background
479
+ "crl_download_max_size": (
480
+ None,
481
+ (type(None), int),
482
+ ), # Maximum CRL file size in bytes
479
483
  }
480
484
 
481
485
  APPLICATION_RE = re.compile(r"[\w\d_]+")
@@ -786,6 +790,20 @@ class SnowflakeConnection:
786
790
  return self._crl_cache_start_cleanup
787
791
  return self._crl_config.crl_cache_start_cleanup
788
792
 
793
+ @property
794
+ def crl_download_max_size(self) -> int | None:
795
+ """Maximum CRL file size in bytes."""
796
+ if not self._crl_config:
797
+ return self._crl_download_max_size
798
+ return self._crl_config.crl_download_max_size
799
+
800
+ @property
801
+ def skip_file_permissions_check(self) -> bool | None:
802
+ """Whether to skip file permission checks for CRL cache files."""
803
+ if not self._crl_config:
804
+ return self._skip_file_permissions_check
805
+ return self._crl_config.skip_file_permissions_check
806
+
789
807
  @property
790
808
  def session_id(self) -> int:
791
809
  return self._session_id
@@ -64,6 +64,8 @@ class CRLConfig:
64
64
  crl_cache_removal_delay_days: int = 7
65
65
  crl_cache_cleanup_interval_hours: int = 1
66
66
  crl_cache_start_cleanup: bool = False
67
+ crl_download_max_size: int = 200 * 1024 * 1024 # 200 MB
68
+ unsafe_skip_file_permissions_check: bool = False
67
69
 
68
70
  @classmethod
69
71
  def from_connection(cls, sf_connection) -> CRLConfig:
@@ -158,6 +160,15 @@ class CRLConfig:
158
160
  if sf_connection.crl_cache_start_cleanup is None
159
161
  else bool(sf_connection.crl_cache_start_cleanup)
160
162
  )
163
+ crl_download_max_size = (
164
+ cls.crl_download_max_size
165
+ if sf_connection.crl_download_max_size is None
166
+ else int(sf_connection.crl_download_max_size)
167
+ )
168
+ # Use the existing unsafe_skip_file_permissions_check flag from connection
169
+ unsafe_skip_file_permissions_check = bool(
170
+ sf_connection._unsafe_skip_file_permissions_check
171
+ )
161
172
 
162
173
  return cls(
163
174
  cert_revocation_check_mode=cert_revocation_check_mode,
@@ -171,6 +182,8 @@ class CRLConfig:
171
182
  crl_cache_removal_delay_days=crl_cache_removal_delay_days,
172
183
  crl_cache_cleanup_interval_hours=crl_cache_cleanup_interval_hours,
173
184
  crl_cache_start_cleanup=crl_cache_start_cleanup,
185
+ crl_download_max_size=crl_download_max_size,
186
+ unsafe_skip_file_permissions_check=unsafe_skip_file_permissions_check,
174
187
  )
175
188
 
176
189
 
@@ -185,6 +198,7 @@ class CRLValidator:
185
198
  read_timeout_ms: int = CRLConfig.read_timeout_ms,
186
199
  cache_validity_time: timedelta = CRLConfig.cache_validity_time,
187
200
  cache_manager: CRLCacheManager | None = None,
201
+ crl_download_max_size: int = CRLConfig.crl_download_max_size,
188
202
  ):
189
203
  self._session_manager = session_manager
190
204
  self._cert_revocation_check_mode = cert_revocation_check_mode
@@ -193,6 +207,7 @@ class CRLValidator:
193
207
  self._read_timeout_ms = read_timeout_ms
194
208
  self._cache_validity_time = cache_validity_time
195
209
  self._cache_manager = cache_manager or CRLCacheManager.noop()
210
+ self._crl_download_max_size = crl_download_max_size
196
211
 
197
212
  # list of trusted CA and their certificates
198
213
  self._trusted_ca: dict[x509.Name, list[x509.Certificate]] = defaultdict(list)
@@ -237,7 +252,9 @@ class CRLValidator:
237
252
  if config.enable_crl_file_cache:
238
253
  removal_delay = timedelta(days=config.crl_cache_removal_delay_days)
239
254
  file_cache = CRLCacheFactory.get_file_cache(
240
- cache_dir=config.crl_cache_dir, removal_delay=removal_delay
255
+ cache_dir=config.crl_cache_dir,
256
+ removal_delay=removal_delay,
257
+ unsafe_skip_file_permissions_check=config.unsafe_skip_file_permissions_check,
241
258
  )
242
259
  else:
243
260
  from snowflake.connector.crl_cache import NoopCRLCache
@@ -268,6 +285,7 @@ class CRLValidator:
268
285
  read_timeout_ms=config.read_timeout_ms,
269
286
  cache_validity_time=config.cache_validity_time,
270
287
  cache_manager=cache_manager,
288
+ crl_download_max_size=config.crl_download_max_size,
271
289
  )
272
290
 
273
291
  def validate_certificate_chain(
@@ -550,15 +568,99 @@ class CRLValidator:
550
568
  try:
551
569
  logger.debug("Trying to download CRL from: %s", crl_url)
552
570
  response = self._session_manager.get(
553
- crl_url, timeout=(self._connection_timeout_ms, self._read_timeout_ms)
571
+ crl_url,
572
+ timeout=(self._connection_timeout_ms, self._read_timeout_ms),
573
+ stream=True,
554
574
  )
555
575
  response.raise_for_status()
556
- return response.content
576
+
577
+ # Check Content-Length header first if available
578
+ content_length = response.headers.get("Content-Length")
579
+ if content_length:
580
+ try:
581
+ size = int(content_length)
582
+ if size > self._crl_download_max_size:
583
+ logger.warning(
584
+ "CRL from %s exceeds maximum size limit (%d bytes > %d bytes)",
585
+ crl_url,
586
+ size,
587
+ self._crl_download_max_size,
588
+ )
589
+ return None
590
+ except ValueError:
591
+ logger.debug(
592
+ "Invalid Content-Length header for %s: %s",
593
+ crl_url,
594
+ content_length,
595
+ )
596
+
597
+ # Stream the content and check size as we download
598
+ chunks = []
599
+ total_size = 0
600
+ for chunk in response.iter_content(chunk_size=8192):
601
+ if not chunk:
602
+ continue
603
+ total_size += len(chunk)
604
+ if total_size > self._crl_download_max_size:
605
+ logger.warning(
606
+ "CRL from %s exceeded maximum size limit during download (%d bytes)",
607
+ crl_url,
608
+ self._crl_download_max_size,
609
+ )
610
+ return None
611
+ chunks.append(chunk)
612
+
613
+ return b"".join(chunks)
557
614
  except Exception:
558
615
  # CRL fetch or parsing failed
559
616
  logger.exception("Failed to download CRL from %s", crl_url)
560
617
  return None
561
618
 
619
+ def _get_crl_last_update(
620
+ self, crl: x509.CertificateRevocationList
621
+ ) -> datetime | None:
622
+ """
623
+ Get the last_update timestamp from a CRL.
624
+
625
+ Args:
626
+ crl: The CRL to extract the timestamp from
627
+
628
+ Returns:
629
+ The last_update timestamp, or None if not available
630
+ """
631
+ try:
632
+ return crl.last_update_utc
633
+ except AttributeError:
634
+ return getattr(crl, "last_update", None)
635
+
636
+ def _is_crl_more_recent(
637
+ self,
638
+ new_crl: x509.CertificateRevocationList,
639
+ cached_crl: x509.CertificateRevocationList,
640
+ ) -> bool:
641
+ """
642
+ Check if a newly downloaded CRL is more recent than a cached CRL.
643
+
644
+ Args:
645
+ new_crl: The newly downloaded CRL
646
+ cached_crl: The cached CRL
647
+
648
+ Returns:
649
+ True if new_crl is more recent (has a later last_update), False otherwise
650
+ """
651
+ new_last_update = self._get_crl_last_update(new_crl)
652
+ cached_last_update = self._get_crl_last_update(cached_crl)
653
+
654
+ if new_last_update is None:
655
+ logger.warning("New CRL has no last_update timestamp")
656
+ return False
657
+
658
+ if cached_last_update is None:
659
+ logger.warning("Cached CRL has no last_update timestamp")
660
+ return True
661
+
662
+ return new_last_update > cached_last_update
663
+
562
664
  def _download_crl(
563
665
  self, crl_url: str
564
666
  ) -> tuple[x509.CertificateRevocationList | None, datetime | None]:
@@ -572,7 +674,12 @@ class CRLValidator:
572
674
  except AttributeError:
573
675
  next_update = crl.next_update
574
676
 
575
- if next_update and now > next_update:
677
+ if not next_update:
678
+ # reject CRL as lack of next_update timestamp is a violation of both the RFC and the governing policy documents.
679
+ logger.warning("CRL from %s has no next_update timestamp", crl_url)
680
+ return None, None
681
+
682
+ if now > next_update:
576
683
  logger.warning(
577
684
  "The CRL from %s was expired on %s", crl_url, next_update
578
685
  )
@@ -595,9 +702,27 @@ class CRLValidator:
595
702
  or cached_crl.is_crl_expired_by(now)
596
703
  or cached_crl.is_evicted_by(now, self._cache_validity_time)
597
704
  ):
705
+ logger.debug("Cached CRL is None/expired/evicted, downloading new CRL")
598
706
  crl, ts = self._download_crl(crl_url)
599
- if crl and ts:
600
- self._put_crl_to_cache(crl_url, crl, ts)
707
+ if crl is not None and ts is not None:
708
+ # Only cache the downloaded CRL if it's more recent than the cached one
709
+ is_more_recent = cached_crl is None or self._is_crl_more_recent(
710
+ crl, cached_crl.crl
711
+ )
712
+ logger.debug(
713
+ "Is downloaded CRL more recent? cached_crl is None=%s, is_more_recent=%s",
714
+ cached_crl is None,
715
+ is_more_recent,
716
+ )
717
+ if is_more_recent:
718
+ self._put_crl_to_cache(crl_url, crl, ts)
719
+ logger.debug("Cached newly downloaded CRL for %s", crl_url)
720
+ else:
721
+ logger.info(
722
+ "Downloaded CRL for %s is not more recent than cached version, keeping cached CRL",
723
+ crl_url,
724
+ )
725
+ crl = cached_crl.crl
601
726
  else:
602
727
  crl = cached_crl.crl
603
728
 
@@ -6,9 +6,9 @@ import hashlib
6
6
  import logging
7
7
  import os
8
8
  import platform
9
+ import stat
9
10
  import threading
10
11
  from abc import ABC, abstractmethod
11
- from concurrent.futures import ThreadPoolExecutor
12
12
  from dataclasses import dataclass
13
13
  from datetime import datetime, timedelta, timezone
14
14
  from pathlib import Path
@@ -18,6 +18,8 @@ from cryptography.hazmat.backends import default_backend
18
18
  from cryptography.hazmat.primitives import serialization
19
19
  from filelock import BaseFileLock, FileLock
20
20
 
21
+ from .compat import IS_WINDOWS
22
+
21
23
  logger = logging.getLogger(__name__)
22
24
 
23
25
 
@@ -201,7 +203,10 @@ class CRLFileCache(CRLCache):
201
203
  """
202
204
 
203
205
  def __init__(
204
- self, cache_dir: Path | None = None, removal_delay: timedelta | None = None
206
+ self,
207
+ cache_dir: Path | None = None,
208
+ removal_delay: timedelta | None = None,
209
+ unsafe_skip_file_permissions_check: bool = False,
205
210
  ):
206
211
  """
207
212
  Initialize the file cache.
@@ -209,6 +214,7 @@ class CRLFileCache(CRLCache):
209
214
  Args:
210
215
  cache_dir: Directory to store cached CRLs
211
216
  removal_delay: How long to wait before removing expired files
217
+ unsafe_skip_file_permissions_check: Skip file permission validation for security
212
218
 
213
219
  Raises:
214
220
  OSError: If cache directory cannot be created
@@ -216,14 +222,24 @@ class CRLFileCache(CRLCache):
216
222
  self._cache_file_lock_timeout = 5.0
217
223
  self._cache_dir = cache_dir or _get_default_crl_cache_path()
218
224
  self._removal_delay = removal_delay or timedelta(days=7)
225
+ self._unsafe_skip_file_permissions_check = unsafe_skip_file_permissions_check
219
226
 
220
227
  self._ensure_cache_directory_exists()
221
228
 
222
229
  def _ensure_cache_directory_exists(self) -> None:
223
- """Create the cache directory if it doesn't exist."""
230
+ """Create the cache directory if it doesn't exist with secure permissions."""
224
231
  try:
225
- self._cache_dir.mkdir(parents=True, exist_ok=True)
232
+ # Create directory with secure permissions (owner read/write/execute only)
233
+ self._cache_dir.mkdir(parents=True, exist_ok=True, mode=0o700)
234
+
235
+ # Verify directory permissions (if it already existed)
236
+ if not self._unsafe_skip_file_permissions_check:
237
+ self._check_permissions(self._cache_dir, "directory", "0o700")
238
+
226
239
  logger.debug(f"Cache directory created/verified: {self._cache_dir}")
240
+ except PermissionError:
241
+ # Re-raise permission errors as-is
242
+ raise
227
243
  except OSError as e:
228
244
  raise OSError(f"Failed to create cache directory {self._cache_dir}: {e}")
229
245
 
@@ -249,6 +265,44 @@ class CRLFileCache(CRLCache):
249
265
  timeout=self._cache_file_lock_timeout,
250
266
  )
251
267
 
268
+ def _check_permissions(
269
+ self, path: Path, resource_type: str, expected_perms: str
270
+ ) -> None:
271
+ """
272
+ Check that a CRL cache resource has secure permissions (owner-only access).
273
+
274
+ Note: This check is only performed on Unix-like systems. Windows file
275
+ permissions work differently and are not checked.
276
+
277
+ Args:
278
+ path: Path to the resource (file or directory) to check
279
+ resource_type: Description of the resource type (e.g., "file", "directory")
280
+ expected_perms: Description of expected permissions (e.g., "0o600 or 0o400", "0o700")
281
+
282
+ Raises:
283
+ PermissionError: If resource permissions are too wide
284
+ """
285
+ # Skip permission checks on Windows as they work differently
286
+ if IS_WINDOWS:
287
+ return
288
+
289
+ try:
290
+ stat_info = path.stat()
291
+ actual_permissions = stat.S_IMODE(stat_info.st_mode)
292
+
293
+ # Check that resource is accessible only by owner (no group/other permissions)
294
+ if (
295
+ actual_permissions & 0o077 != 0
296
+ ): # Check if group or others have any permission
297
+ raise PermissionError(
298
+ f"CRL cache {resource_type} {path} has insecure permissions: {oct(actual_permissions)}. "
299
+ f"{resource_type.capitalize()} must be accessible only by the owner ({expected_perms})."
300
+ )
301
+
302
+ except FileNotFoundError:
303
+ # Resource doesn't exist yet, this is fine
304
+ pass
305
+
252
306
  def get(self, crl_url: str) -> CRLCacheEntry | None:
253
307
  """
254
308
  Get a CRL cache entry from disk.
@@ -265,6 +319,14 @@ class CRLFileCache(CRLCache):
265
319
  if crl_file_path.exists():
266
320
  logger.debug(f"Found CRL on disk for {crl_file_path}")
267
321
 
322
+ # Check file permissions before reading
323
+ if not self._unsafe_skip_file_permissions_check:
324
+ self._check_permissions(crl_file_path, "file", "0o600 or 0o400")
325
+ else:
326
+ logger.warning(
327
+ f"Skipping file permissions check for {crl_file_path}"
328
+ )
329
+
268
330
  # Get file modification time as download time
269
331
  stat_info = crl_file_path.stat()
270
332
  download_time = datetime.fromtimestamp(
@@ -278,6 +340,11 @@ class CRLFileCache(CRLCache):
278
340
  crl = x509.load_der_x509_crl(crl_data, backend=default_backend())
279
341
  return CRLCacheEntry(crl, download_time)
280
342
 
343
+ except PermissionError as e:
344
+ logger.error(
345
+ f"Permission error reading CRL from disk cache for {crl_url}: {e}"
346
+ )
347
+ return None
281
348
  except Exception as e:
282
349
  logger.warning(f"Failed to read CRL from disk cache for {crl_url}: {e}")
283
350
 
@@ -297,9 +364,17 @@ class CRLFileCache(CRLCache):
297
364
  # Serialize the CRL to DER format
298
365
  crl_data = entry.crl.public_bytes(serialization.Encoding.DER)
299
366
 
300
- # Write to file
301
- with open(crl_file_path, "wb") as f:
302
- f.write(crl_data)
367
+ # Write to file with secure permissions (owner read/write only)
368
+ # Using os.open with 0o600 ensures the file is created with secure permissions
369
+ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
370
+ if IS_WINDOWS:
371
+ # flag necessary for writing binary data to file on Windows OS
372
+ flags |= os.O_BINARY
373
+ fd = os.open(crl_file_path, flags, 0o600)
374
+ try:
375
+ os.write(fd, crl_data)
376
+ finally:
377
+ os.close(fd)
303
378
 
304
379
  # Set file modification time to download time
305
380
  download_timestamp = entry.download_time.timestamp()
@@ -426,7 +501,7 @@ class CRLCacheFactory:
426
501
  _instance_lock = threading.RLock()
427
502
 
428
503
  # Cleanup management
429
- _cleanup_executor: ThreadPoolExecutor | None = None
504
+ _cleanup_thread: threading.Thread | None = None
430
505
  _cleanup_shutdown: threading.Event = threading.Event()
431
506
  _cleanup_interval: timedelta | None = None
432
507
  _atexit_registered: bool = False
@@ -454,7 +529,10 @@ class CRLCacheFactory:
454
529
 
455
530
  @classmethod
456
531
  def get_file_cache(
457
- cls, cache_dir: Path | None = None, removal_delay: timedelta | None = None
532
+ cls,
533
+ cache_dir: Path | None = None,
534
+ removal_delay: timedelta | None = None,
535
+ unsafe_skip_file_permissions_check: bool = False,
458
536
  ) -> CRLFileCache:
459
537
  """
460
538
  Get or create a singleton CRLFileCache instance.
@@ -462,17 +540,23 @@ class CRLCacheFactory:
462
540
  Args:
463
541
  cache_dir: Directory to store cached CRLs
464
542
  removal_delay: How long to wait before removing expired files
543
+ unsafe_skip_file_permissions_check: Skip file permission validation for security
465
544
 
466
545
  Returns:
467
546
  The singleton CRLFileCache instance
468
547
  """
469
548
  with cls._instance_lock:
470
549
  if cls._file_cache_instance is None:
471
- cls._file_cache_instance = CRLFileCache(cache_dir, removal_delay)
550
+ cls._file_cache_instance = CRLFileCache(
551
+ cache_dir, removal_delay, unsafe_skip_file_permissions_check
552
+ )
472
553
  else:
473
554
  # Check if parameters differ from existing instance
474
555
  existing_cache_dir = cls._file_cache_instance._cache_dir
475
556
  existing_removal_delay = cls._file_cache_instance._removal_delay
557
+ existing_skip_check = (
558
+ cls._file_cache_instance._unsafe_skip_file_permissions_check
559
+ )
476
560
  requested_cache_dir = cache_dir or _get_default_crl_cache_path()
477
561
  requested_removal_delay = removal_delay or timedelta(days=7)
478
562
 
@@ -486,6 +570,11 @@ class CRLCacheFactory:
486
570
  f"CRLs file cache has already been initialized with removal delay of {existing_removal_delay}, "
487
571
  f"ignoring new removal delay of {requested_removal_delay}"
488
572
  )
573
+ if existing_skip_check != unsafe_skip_file_permissions_check:
574
+ logger.warning(
575
+ f"CRLs file cache has already been initialized with unsafe_skip_file_permissions_check={existing_skip_check}, "
576
+ f"ignoring new value {unsafe_skip_file_permissions_check}"
577
+ )
489
578
  return cls._file_cache_instance
490
579
 
491
580
  @classmethod
@@ -504,8 +593,10 @@ class CRLCacheFactory:
504
593
  cls.stop_periodic_cleanup()
505
594
 
506
595
  cls._cleanup_interval = cleanup_interval
507
- cls._cleanup_executor = ThreadPoolExecutor(
508
- max_workers=1, thread_name_prefix="crl-cache-cleanup"
596
+ cls._cleanup_thread = threading.Thread(
597
+ target=cls._cleanup_loop,
598
+ name="crl-cache-cleanup",
599
+ daemon=True, # Make it a daemon thread so it doesn't block program exit
509
600
  )
510
601
 
511
602
  # Register atexit handler for graceful shutdown (only once)
@@ -513,8 +604,8 @@ class CRLCacheFactory:
513
604
  atexit.register(cls._atexit_cleanup_handler)
514
605
  cls._atexit_registered = True
515
606
 
516
- # Submit the cleanup task
517
- cls._cleanup_executor.submit(cls._cleanup_loop)
607
+ # Start the cleanup thread
608
+ cls._cleanup_thread.start()
518
609
 
519
610
  logger.debug(
520
611
  f"Scheduled CRL cache cleanup task to run every {cleanup_interval.total_seconds()} seconds."
@@ -523,29 +614,29 @@ class CRLCacheFactory:
523
614
  @classmethod
524
615
  def stop_periodic_cleanup(cls) -> None:
525
616
  """Stop the periodic cleanup task."""
526
- executor_to_shutdown = None
617
+ thread_to_join = None
527
618
 
528
619
  with cls._instance_lock:
529
- if cls._cleanup_executor is None or cls._cleanup_shutdown.is_set():
620
+ if cls._cleanup_thread is None or cls._cleanup_shutdown.is_set():
530
621
  return
531
622
 
532
623
  cls._cleanup_shutdown.set()
533
- executor_to_shutdown = cls._cleanup_executor
624
+ thread_to_join = cls._cleanup_thread
534
625
 
535
- # Shutdown outside of lock to avoid deadlock
536
- if executor_to_shutdown is not None:
537
- executor_to_shutdown.shutdown(wait=True)
626
+ # Join thread outside of lock to avoid deadlock
627
+ if thread_to_join is not None and thread_to_join.is_alive():
628
+ thread_to_join.join(timeout=5.0)
538
629
 
539
630
  with cls._instance_lock:
540
631
  cls._cleanup_shutdown.clear()
541
- cls._cleanup_executor = None
632
+ cls._cleanup_thread = None
542
633
  cls._cleanup_interval = None
543
634
 
544
635
  @classmethod
545
636
  def is_periodic_cleanup_running(cls) -> bool:
546
637
  """Check if periodic cleanup task is running."""
547
638
  with cls._instance_lock:
548
- return cls._cleanup_executor is not None
639
+ return cls._cleanup_thread is not None and cls._cleanup_thread.is_alive()
549
640
 
550
641
  @classmethod
551
642
  def _cleanup_loop(cls) -> None:
@@ -1222,3 +1222,6 @@ class SnowflakeRestful:
1222
1222
 
1223
1223
  def use_session(self, url: str | bytes) -> Generator[Session, Any, None]:
1224
1224
  return self.session_manager.use_session(url)
1225
+
1226
+ def use_requests_session(self, url: str | bytes) -> Generator[Session, Any, None]:
1227
+ return self.use_session(url)
@@ -360,7 +360,7 @@ class ResultBatch(abc.ABC):
360
360
  and connection.rest.session_manager is not None
361
361
  ):
362
362
  # If connection was explicitly passed and not closed yet - we can reuse SessionManager with session pooling
363
- with connection.rest.use_session(
363
+ with connection.rest.use_requests_session(
364
364
  request_data["url"]
365
365
  ) as session:
366
366
  logger.debug(
@@ -483,26 +483,32 @@ class SessionManager(_RequestVerbsUsingSessionMixin, _HttpConfigDirectAccessMixi
483
483
  self._mount_adapters(session)
484
484
  return session
485
485
 
486
+ @staticmethod
487
+ def _normalize_url(url: str | bytes | None) -> str:
488
+ """Normalize URL to string format (handles bytes from storage client)."""
489
+ return url.decode("utf-8") if isinstance(url, bytes) else url
490
+
486
491
  @contextlib.contextmanager
487
492
  @_propagate_session_manager_to_ocsp
488
493
  def use_session(
489
- self, url: str | bytes, use_pooling: bool | None = None
494
+ self, url: str | bytes | None, use_pooling: bool | None = None
490
495
  ) -> Generator[Session, Any, None]:
496
+ """Yield a session for the given URL (used for proxy handling and pooling).
497
+ The 'url' is an obligatory parameter due to the need for correct proxy handling (i.e. bypassing caused by no_proxy settings).
491
498
  """
492
- 'url' is an obligatory parameter due to the need for correct proxy handling (i.e. bypassing caused by no_proxy settings).
493
- """
499
+ url_str = self._normalize_url(url)
494
500
  use_pooling = use_pooling if use_pooling is not None else self.use_pooling
495
501
  if not use_pooling:
496
- session = self.make_session(url=url)
502
+ session = self.make_session(url=url_str)
497
503
  try:
498
504
  yield session
499
505
  finally:
500
506
  session.close()
501
507
  else:
502
- yield from self._yield_session_from_pool(url)
508
+ yield from self._yield_session_from_pool(url_str)
503
509
 
504
510
  def _yield_session_from_pool(
505
- self, url: str | bytes
511
+ self, url: str | None
506
512
  ) -> Generator[SessionT, Any, None]:
507
513
  hostname = self._get_pooling_key_from_url(url)
508
514
  pool = self._sessions_map[hostname]
@@ -635,8 +641,8 @@ class SessionManagerFactory:
635
641
  config: HttpConfig | None = None, **http_config_kwargs
636
642
  ) -> SessionManager:
637
643
  has_param_proxies = (
638
- hasattr(config, "proxy_host") or "proxies" in http_config_kwargs
639
- )
644
+ config and config.proxy_host is not None
645
+ ) or "proxies" in http_config_kwargs
640
646
  if has_param_proxies:
641
647
  return ProxySessionManager(config, **http_config_kwargs)
642
648
  else:
@@ -1,3 +1,3 @@
1
1
  # Update this for the versions
2
2
  # Don't change the forth version number from None
3
- VERSION = (4, 1, 0, None)
3
+ VERSION = (4, 1, 1, None)