From d75d8d9717307c9c5129bc3f2e740fd81de1e520 Mon Sep 17 00:00:00 2001 From: nameexhaustion Date: Sat, 2 Nov 2024 01:23:02 +1100 Subject: [PATCH] fix: Do not attempt to load default credentials when `credential_provider` is given (#19589) --- crates/polars-io/src/cloud/options.rs | 21 +++++++++++++++--- .../unit/io/cloud/test_credential_provider.py | 22 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 py-polars/tests/unit/io/cloud/test_credential_provider.py diff --git a/crates/polars-io/src/cloud/options.rs b/crates/polars-io/src/cloud/options.rs index 9549b837f06d..ea5376b6865f 100644 --- a/crates/polars-io/src/cloud/options.rs +++ b/crates/polars-io/src/cloud/options.rs @@ -280,7 +280,14 @@ impl CloudOptions { pub async fn build_aws(&self, url: &str) -> PolarsResult { use super::credential_provider::IntoCredentialProvider; - let mut builder = AmazonS3Builder::from_env().with_url(url); + let mut builder = { + if self.credential_provider.is_none() { + AmazonS3Builder::from_env() + } else { + AmazonS3Builder::new() + } + } + .with_url(url); if let Some(options) = &self.config { let CloudConfig::Aws(options) = options else { panic!("impl error: cloud type mismatch") @@ -393,7 +400,11 @@ impl CloudOptions { pub fn build_azure(&self, url: &str) -> PolarsResult { use super::credential_provider::IntoCredentialProvider; - let mut builder = MicrosoftAzureBuilder::from_env(); + let mut builder = if self.credential_provider.is_none() { + MicrosoftAzureBuilder::from_env() + } else { + MicrosoftAzureBuilder::new() + }; if let Some(options) = &self.config { let CloudConfig::Azure(options) = options else { panic!("impl error: cloud type mismatch") @@ -434,7 +445,11 @@ impl CloudOptions { pub fn build_gcp(&self, url: &str) -> PolarsResult { use super::credential_provider::IntoCredentialProvider; - let mut builder = GoogleCloudStorageBuilder::from_env(); + let mut builder = if self.credential_provider.is_none() { + GoogleCloudStorageBuilder::from_env() + } else { + GoogleCloudStorageBuilder::new() + }; if let Some(options) = &self.config { let CloudConfig::Gcp(options) = options else { panic!("impl error: cloud type mismatch") diff --git a/py-polars/tests/unit/io/cloud/test_credential_provider.py b/py-polars/tests/unit/io/cloud/test_credential_provider.py new file mode 100644 index 000000000000..7c235c9d1a96 --- /dev/null +++ b/py-polars/tests/unit/io/cloud/test_credential_provider.py @@ -0,0 +1,22 @@ +import pytest + +import polars as pl +from polars.exceptions import ComputeError + + +def test_credential_provider_skips_config_autoload( + monkeypatch: pytest.MonkeyPatch, +) -> None: + monkeypatch.setenv("GOOGLE_SERVICE_ACCOUNT_PATH", "__non_existent") + + with pytest.raises(ComputeError, match="__non_existent"): + pl.scan_parquet("gs://.../...", credential_provider=None).collect() + + err_magic = "err_magic_3" + + def raises() -> pl.CredentialProviderFunctionReturn: + raise AssertionError(err_magic) + + # We should get a different error raised by our `raises()` function. + with pytest.raises(ComputeError, match=err_magic): + pl.scan_parquet("gs://.../...", credential_provider=raises).collect()