From f7d343ba76b8b71ab8a23fe19a348e6f7256db10 Mon Sep 17 00:00:00 2001 From: Ahmed Taeha Date: Sun, 5 Apr 2026 23:10:41 -0400 Subject: [PATCH 1/3] Fix async TableClient.list_entities(query_filter=...) leaking kwarg to transport Fixes #46014. list_entities() was forwarding all **kwargs (including query_filter and parameters) into the generated operation's partial, causing them to leak to the aiohttp transport layer as unexpected kwargs. Now consumes query_filter/parameters before building the partial and passes the substituted filter value to the pager, matching query_entities() behavior. Fix applied to both sync and async clients. --- .../azure/data/tables/_table_client.py | 6 ++ .../data/tables/aio/_table_client_async.py | 6 ++ .../tests/test_table_client.py | 62 +++++++++++++++++- .../tests/test_table_client_async.py | 64 ++++++++++++++++++- 4 files changed, 136 insertions(+), 2 deletions(-) diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py index 63f8c891038f..042b4dc514a7 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py @@ -528,6 +528,11 @@ def list_entities( :rtype: An iterator of custom entity type. :raises: :class:`~azure.core.exceptions.HttpResponseError` """ + query_filter = kwargs.pop("query_filter", None) + parameters = kwargs.pop("parameters", None) + if query_filter is not None: + query_filter = _parameter_filter_substitution(parameters, query_filter) + if select and not isinstance(select, str): select = ",".join(select) @@ -536,6 +541,7 @@ def list_entities( command, table=self.table_name, results_per_page=results_per_page, + filter=query_filter, select=select, decoder=self.decoder, page_iterator_class=TableEntityPropertiesPaged, diff --git a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py index d8d69f8f1a01..289cba04ef9e 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py @@ -550,6 +550,11 @@ def list_entities( :dedent: 16 :caption: Listing all entities held within a table """ + query_filter = kwargs.pop("query_filter", None) + parameters = kwargs.pop("parameters", None) + if query_filter is not None: + query_filter = _parameter_filter_substitution(parameters, query_filter) + if select and not isinstance(select, str): select = ",".join(select) @@ -558,6 +563,7 @@ def list_entities( command, table=self.table_name, results_per_page=results_per_page, + filter=query_filter, select=select, decoder=self.decoder, page_iterator_class=TableEntityPropertiesPaged, diff --git a/sdk/tables/azure-data-tables/tests/test_table_client.py b/sdk/tables/azure-data-tables/tests/test_table_client.py index f4e11d11ab22..31e5c5819336 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client.py @@ -10,7 +10,7 @@ from datetime import datetime, timedelta from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from unittest.mock import patch +from unittest.mock import patch, MagicMock from azure.data.tables import ( TableServiceClient, @@ -1049,3 +1049,63 @@ def test_use_development_storage(self): assert tsc._primary_endpoint == "http://127.0.0.1:10002/devstoreaccount1" assert tsc._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary" assert not tsc._cosmos_endpoint + + def test_list_entities_query_filter_not_leaked(self): + """Regression test: query_filter must not leak through kwargs to transport.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + captured = {} + + def mock_query_entities(*args, **kwargs): + if "query_filter" in kwargs: + raise TypeError("query_filter leaked to transport layer") + captured.update(kwargs) + resp = MagicMock() + resp.value = [] + return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} + + client._client.table.query_entities = mock_query_entities + + pager = client.list_entities(query_filter="PartitionKey eq 'mypartition'") + pages = pager.by_page() + for _ in pages: + break + + assert "query_filter" not in captured + assert captured.get("filter") == "PartitionKey eq 'mypartition'" + client.close() + + def test_list_entities_query_filter_with_parameters(self): + """Regression test: query_filter with parameter substitution in list_entities.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + captured = {} + + def mock_query_entities(*args, **kwargs): + if "query_filter" in kwargs or "parameters" in kwargs: + raise TypeError("SDK kwargs leaked to transport layer") + captured.update(kwargs) + resp = MagicMock() + resp.value = [] + return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} + + client._client.table.query_entities = mock_query_entities + + pager = client.list_entities( + query_filter="PartitionKey eq @pk", + parameters={"pk": "mypartition"}, + ) + pages = pager.by_page() + for _ in pages: + break + + assert "query_filter" not in captured + assert "parameters" not in captured + assert captured.get("filter") == "PartitionKey eq 'mypartition'" + client.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_async.py b/sdk/tables/azure-data-tables/tests/test_table_client_async.py index 52cf51514c97..14ad13aff63a 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_async.py @@ -11,7 +11,7 @@ from datetime import datetime, timedelta from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from unittest.mock import patch +from unittest.mock import patch, MagicMock from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ClientAuthenticationError @@ -1075,3 +1075,65 @@ def test_use_development_storage(self): assert tsc._primary_endpoint == "http://127.0.0.1:10002/devstoreaccount1" assert tsc._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary" assert not tsc._cosmos_endpoint + + @pytest.mark.asyncio + async def test_list_entities_query_filter_not_leaked(self): + """Regression test: query_filter must not leak through kwargs to transport.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + captured = {} + + async def mock_query_entities(*args, **kwargs): + if "query_filter" in kwargs: + raise TypeError("query_filter leaked to transport layer") + captured.update(kwargs) + resp = MagicMock() + resp.value = [] + return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} + + client._client.table.query_entities = mock_query_entities + + pager = client.list_entities(query_filter="PartitionKey eq 'mypartition'") + pages = pager.by_page() + async for _ in pages: + break + + assert "query_filter" not in captured + assert captured.get("filter") == "PartitionKey eq 'mypartition'" + await client.close() + + @pytest.mark.asyncio + async def test_list_entities_query_filter_with_parameters(self): + """Regression test: query_filter with parameter substitution in list_entities.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + captured = {} + + async def mock_query_entities(*args, **kwargs): + if "query_filter" in kwargs or "parameters" in kwargs: + raise TypeError("SDK kwargs leaked to transport layer") + captured.update(kwargs) + resp = MagicMock() + resp.value = [] + return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} + + client._client.table.query_entities = mock_query_entities + + pager = client.list_entities( + query_filter="PartitionKey eq @pk", + parameters={"pk": "mypartition"}, + ) + pages = pager.by_page() + async for _ in pages: + break + + assert "query_filter" not in captured + assert "parameters" not in captured + assert captured.get("filter") == "PartitionKey eq 'mypartition'" + await client.close() From 84adc2dca60d8109d884ca86537dab4c3a712f3a Mon Sep 17 00:00:00 2001 From: Ahmed Taeha Date: Mon, 6 Apr 2026 17:30:19 -0400 Subject: [PATCH 2/3] Revise fix: reject query_filter with ValueError instead of forwarding it Per maintainer feedback, list_entities should not support query_filter. Instead of forwarding it as filter= to the pager, now raises a clear ValueError pointing users to query_entities for server-side filtering. Also replaces mypartition with pk001 in tests to pass cspell CI check. --- .../azure/data/tables/_table_client.py | 10 ++-- .../data/tables/aio/_table_client_async.py | 10 ++-- .../tests/test_table_client.py | 56 +++---------------- .../tests/test_table_client_async.py | 56 +++---------------- 4 files changed, 28 insertions(+), 104 deletions(-) diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py index 042b4dc514a7..defa249e8233 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py @@ -528,10 +528,11 @@ def list_entities( :rtype: An iterator of custom entity type. :raises: :class:`~azure.core.exceptions.HttpResponseError` """ - query_filter = kwargs.pop("query_filter", None) - parameters = kwargs.pop("parameters", None) - if query_filter is not None: - query_filter = _parameter_filter_substitution(parameters, query_filter) + if kwargs.pop("query_filter", None) is not None: + raise ValueError( + "'query_filter' is not supported for 'list_entities'. Use 'query_entities' for server-side filtering." + ) + kwargs.pop("parameters", None) if select and not isinstance(select, str): select = ",".join(select) @@ -541,7 +542,6 @@ def list_entities( command, table=self.table_name, results_per_page=results_per_page, - filter=query_filter, select=select, decoder=self.decoder, page_iterator_class=TableEntityPropertiesPaged, diff --git a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py index 289cba04ef9e..7e1ee25e7d7f 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py @@ -550,10 +550,11 @@ def list_entities( :dedent: 16 :caption: Listing all entities held within a table """ - query_filter = kwargs.pop("query_filter", None) - parameters = kwargs.pop("parameters", None) - if query_filter is not None: - query_filter = _parameter_filter_substitution(parameters, query_filter) + if kwargs.pop("query_filter", None) is not None: + raise ValueError( + "'query_filter' is not supported for 'list_entities'. Use 'query_entities' for server-side filtering." + ) + kwargs.pop("parameters", None) if select and not isinstance(select, str): select = ",".join(select) @@ -563,7 +564,6 @@ def list_entities( command, table=self.table_name, results_per_page=results_per_page, - filter=query_filter, select=select, decoder=self.decoder, page_iterator_class=TableEntityPropertiesPaged, diff --git a/sdk/tables/azure-data-tables/tests/test_table_client.py b/sdk/tables/azure-data-tables/tests/test_table_client.py index 31e5c5819336..8157d26cba34 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client.py @@ -10,7 +10,7 @@ from datetime import datetime, timedelta from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy -from unittest.mock import patch, MagicMock +from unittest.mock import patch from azure.data.tables import ( TableServiceClient, @@ -1050,62 +1050,24 @@ def test_use_development_storage(self): assert tsc._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary" assert not tsc._cosmos_endpoint - def test_list_entities_query_filter_not_leaked(self): - """Regression test: query_filter must not leak through kwargs to transport.""" + def test_list_entities_rejects_query_filter(self): + """Regression test: list_entities raises ValueError for query_filter instead of leaking to transport.""" credential = AzureNamedKeyCredential( "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" ) client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) - captured = {} - - def mock_query_entities(*args, **kwargs): - if "query_filter" in kwargs: - raise TypeError("query_filter leaked to transport layer") - captured.update(kwargs) - resp = MagicMock() - resp.value = [] - return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} - - client._client.table.query_entities = mock_query_entities - - pager = client.list_entities(query_filter="PartitionKey eq 'mypartition'") - pages = pager.by_page() - for _ in pages: - break - - assert "query_filter" not in captured - assert captured.get("filter") == "PartitionKey eq 'mypartition'" + with pytest.raises(ValueError, match="query_filter"): + client.list_entities(query_filter="PartitionKey eq 'pk001'") client.close() - def test_list_entities_query_filter_with_parameters(self): - """Regression test: query_filter with parameter substitution in list_entities.""" + def test_list_entities_rejects_query_filter_with_parameters(self): + """Regression test: list_entities raises ValueError when query_filter is passed with parameters.""" credential = AzureNamedKeyCredential( "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" ) client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) - captured = {} - - def mock_query_entities(*args, **kwargs): - if "query_filter" in kwargs or "parameters" in kwargs: - raise TypeError("SDK kwargs leaked to transport layer") - captured.update(kwargs) - resp = MagicMock() - resp.value = [] - return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} - - client._client.table.query_entities = mock_query_entities - - pager = client.list_entities( - query_filter="PartitionKey eq @pk", - parameters={"pk": "mypartition"}, - ) - pages = pager.by_page() - for _ in pages: - break - - assert "query_filter" not in captured - assert "parameters" not in captured - assert captured.get("filter") == "PartitionKey eq 'mypartition'" + with pytest.raises(ValueError, match="query_entities"): + client.list_entities(query_filter="PartitionKey eq @pk", parameters={"pk": "pk001"}) client.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_async.py b/sdk/tables/azure-data-tables/tests/test_table_client_async.py index 14ad13aff63a..6592f03d26fc 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_async.py @@ -11,7 +11,7 @@ from datetime import datetime, timedelta from devtools_testutils import AzureRecordedTestCase from devtools_testutils.aio import recorded_by_proxy_async -from unittest.mock import patch, MagicMock +from unittest.mock import patch from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ClientAuthenticationError @@ -1077,63 +1077,25 @@ def test_use_development_storage(self): assert not tsc._cosmos_endpoint @pytest.mark.asyncio - async def test_list_entities_query_filter_not_leaked(self): - """Regression test: query_filter must not leak through kwargs to transport.""" + async def test_list_entities_rejects_query_filter(self): + """Regression test: list_entities raises ValueError for query_filter instead of leaking to transport.""" credential = AzureNamedKeyCredential( "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" ) client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) - captured = {} - - async def mock_query_entities(*args, **kwargs): - if "query_filter" in kwargs: - raise TypeError("query_filter leaked to transport layer") - captured.update(kwargs) - resp = MagicMock() - resp.value = [] - return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} - - client._client.table.query_entities = mock_query_entities - - pager = client.list_entities(query_filter="PartitionKey eq 'mypartition'") - pages = pager.by_page() - async for _ in pages: - break - - assert "query_filter" not in captured - assert captured.get("filter") == "PartitionKey eq 'mypartition'" + with pytest.raises(ValueError, match="query_filter"): + client.list_entities(query_filter="PartitionKey eq 'pk001'") await client.close() @pytest.mark.asyncio - async def test_list_entities_query_filter_with_parameters(self): - """Regression test: query_filter with parameter substitution in list_entities.""" + async def test_list_entities_rejects_query_filter_with_parameters(self): + """Regression test: list_entities raises ValueError when query_filter is passed with parameters.""" credential = AzureNamedKeyCredential( "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" ) client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) - captured = {} - - async def mock_query_entities(*args, **kwargs): - if "query_filter" in kwargs or "parameters" in kwargs: - raise TypeError("SDK kwargs leaked to transport layer") - captured.update(kwargs) - resp = MagicMock() - resp.value = [] - return None, resp, {"x-ms-continuation-NextPartitionKey": None, "x-ms-continuation-NextRowKey": None} - - client._client.table.query_entities = mock_query_entities - - pager = client.list_entities( - query_filter="PartitionKey eq @pk", - parameters={"pk": "mypartition"}, - ) - pages = pager.by_page() - async for _ in pages: - break - - assert "query_filter" not in captured - assert "parameters" not in captured - assert captured.get("filter") == "PartitionKey eq 'mypartition'" + with pytest.raises(ValueError, match="query_entities"): + client.list_entities(query_filter="PartitionKey eq @pk", parameters={"pk": "pk001"}) await client.close() From 46b185bca8d02d214751a16e2b236e7f274e02e1 Mon Sep 17 00:00:00 2001 From: Ahmed Taeha Date: Mon, 20 Apr 2026 20:39:20 -0400 Subject: [PATCH 3/3] Reject parameters-only kwargs in list_entities --- .../azure/data/tables/_table_client.py | 6 +++--- .../azure/data/tables/aio/_table_client_async.py | 6 +++--- .../azure-data-tables/tests/test_table_client.py | 11 +++++++++++ .../tests/test_table_client_async.py | 12 ++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py index defa249e8233..ae7d45680d7a 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_table_client.py @@ -528,11 +528,11 @@ def list_entities( :rtype: An iterator of custom entity type. :raises: :class:`~azure.core.exceptions.HttpResponseError` """ - if kwargs.pop("query_filter", None) is not None: + if "query_filter" in kwargs or "parameters" in kwargs: raise ValueError( - "'query_filter' is not supported for 'list_entities'. Use 'query_entities' for server-side filtering." + "'query_filter' and 'parameters' are not supported for 'list_entities'. " + "Use 'query_entities' for server-side filtering." ) - kwargs.pop("parameters", None) if select and not isinstance(select, str): select = ",".join(select) diff --git a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py index 7e1ee25e7d7f..df60342c6acd 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/aio/_table_client_async.py @@ -550,11 +550,11 @@ def list_entities( :dedent: 16 :caption: Listing all entities held within a table """ - if kwargs.pop("query_filter", None) is not None: + if "query_filter" in kwargs or "parameters" in kwargs: raise ValueError( - "'query_filter' is not supported for 'list_entities'. Use 'query_entities' for server-side filtering." + "'query_filter' and 'parameters' are not supported for 'list_entities'. " + "Use 'query_entities' for server-side filtering." ) - kwargs.pop("parameters", None) if select and not isinstance(select, str): select = ",".join(select) diff --git a/sdk/tables/azure-data-tables/tests/test_table_client.py b/sdk/tables/azure-data-tables/tests/test_table_client.py index 8157d26cba34..59e4f3c728d8 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client.py @@ -1071,3 +1071,14 @@ def test_list_entities_rejects_query_filter_with_parameters(self): with pytest.raises(ValueError, match="query_entities"): client.list_entities(query_filter="PartitionKey eq @pk", parameters={"pk": "pk001"}) client.close() + + def test_list_entities_rejects_parameters_without_query_filter(self): + """Regression test: list_entities raises ValueError when parameters are passed without query_filter.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + with pytest.raises(ValueError, match="parameters"): + client.list_entities(parameters={"pk": "pk001"}) + client.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_async.py b/sdk/tables/azure-data-tables/tests/test_table_client_async.py index 6592f03d26fc..3086a3989dfa 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_async.py @@ -1099,3 +1099,15 @@ async def test_list_entities_rejects_query_filter_with_parameters(self): with pytest.raises(ValueError, match="query_entities"): client.list_entities(query_filter="PartitionKey eq @pk", parameters={"pk": "pk001"}) await client.close() + + @pytest.mark.asyncio + async def test_list_entities_rejects_parameters_without_query_filter(self): + """Regression test: list_entities raises ValueError when parameters are passed without query_filter.""" + credential = AzureNamedKeyCredential( + "fake_account", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + ) + client = TableClient("https://fake_account.table.core.windows.net", "testtable", credential=credential) + + with pytest.raises(ValueError, match="parameters"): + client.list_entities(parameters={"pk": "pk001"}) + await client.close()