Skip to content

Commit afe666e

Browse files
[Storage] Add missing include-leased option for delete_snapshots= (#34042)
1 parent 55b1d2e commit afe666e

File tree

6 files changed

+93
-66
lines changed

6 files changed

+93
-66
lines changed

sdk/storage/azure-storage-file-share/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pointing to the root of the file share would raise an `InvalidResourceName` on a
1414
Python 3.12.
1515
- Fixed an issue where authentication errors could raise `AttributeError` instead of `ClientAuthenticationError` when
1616
using async OAuth credentials.
17+
- Fixed an issue where parameter `delete_snapshots` to `delete_share` API did not support all possible enums. This change
18+
makes `delete_snapshots` now accept string literals 'include' and 'include-leased'.
1719
- Fixed an issue where specifying datetime objects with less than 7 digits of precision as input could incorrectly raise
1820
`InvalidHeaderValue` due to improper precision parsing.
1921

sdk/storage/azure-storage-file-share/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/storage/azure-storage-file-share",
5-
"Tag": "python/storage/azure-storage-file-share_48979bc3d9"
5+
"Tag": "python/storage/azure-storage-file-share_4de10ed98c"
66
}

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_share_client.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
# --------------------------------------------------------------------------
66
# pylint: disable=too-many-lines
77

8-
import sys
98
from typing import (
10-
Optional, Union, Dict, Any, Iterable, TYPE_CHECKING
9+
Optional, Union, Dict, Any, Iterable, Literal, TYPE_CHECKING
1110
)
1211
from urllib.parse import urlparse, quote, unquote
1312

@@ -34,10 +33,6 @@
3433
from ._lease import ShareLeaseClient
3534
from ._models import ShareProtocols
3635

37-
if sys.version_info >= (3, 8):
38-
from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
39-
else:
40-
from typing_extensions import Literal # pylint: disable=ungrouped-imports
4136

4237
if TYPE_CHECKING:
4338
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential, TokenCredential
@@ -454,15 +449,16 @@ def create_snapshot( # type: ignore
454449

455450
@distributed_trace
456451
def delete_share(
457-
self, delete_snapshots=False, # type: Optional[bool]
458-
**kwargs
459-
):
460-
# type: (...) -> None
452+
self, delete_snapshots: Optional[Union[bool, Literal['include', 'include-leased']]] = False,
453+
**kwargs: Any
454+
) -> None:
461455
"""Marks the specified share for deletion. The share is
462456
later deleted during garbage collection.
463457
464-
:param bool delete_snapshots:
458+
:param delete_snapshots:
465459
Indicates if snapshots are to be deleted.
460+
:type delete_snapshots:
461+
Optional[Union[bool, Literal['include', 'include-leased']]]
466462
:keyword lease:
467463
Required if the share has an active lease. Value can be a ShareLeaseClient object
468464
or the lease ID as a string.
@@ -489,8 +485,13 @@ def delete_share(
489485
access_conditions = get_access_conditions(kwargs.pop('lease', None))
490486
timeout = kwargs.pop('timeout', None)
491487
delete_include = None
492-
if delete_snapshots:
493-
delete_include = DeleteSnapshotsOptionType.include
488+
if isinstance(delete_snapshots, bool) and delete_snapshots:
489+
delete_include = DeleteSnapshotsOptionType.INCLUDE
490+
else:
491+
if delete_snapshots == 'include':
492+
delete_include = DeleteSnapshotsOptionType.INCLUDE
493+
elif delete_snapshots == 'include-leased':
494+
delete_include = DeleteSnapshotsOptionType.INCLUDE_LEASED
494495
try:
495496
self._client.share.delete(
496497
timeout=timeout,

sdk/storage/azure-storage-file-share/azure/storage/fileshare/aio/_share_client_async.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import warnings
88
import sys
99
from typing import ( # pylint: disable=unused-import
10-
Optional, Union, Dict, Any, Iterable, TYPE_CHECKING
10+
Optional, Union, Dict, Any, Iterable, Literal, TYPE_CHECKING
1111
)
1212

1313
from azure.core.exceptions import HttpResponseError
@@ -33,11 +33,6 @@
3333
from ..aio._lease_async import ShareLeaseClient
3434
from .._models import ShareProtocols
3535

36-
if sys.version_info >= (3, 8):
37-
from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
38-
else:
39-
from typing_extensions import Literal # pylint: disable=ungrouped-imports
40-
4136
if TYPE_CHECKING:
4237
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
4338
from azure.core.credentials_async import AsyncTokenCredential
@@ -320,15 +315,16 @@ async def create_snapshot( # type: ignore
320315

321316
@distributed_trace_async
322317
async def delete_share(
323-
self, delete_snapshots=False, # type: Optional[bool]
324-
**kwargs
325-
):
326-
# type: (...) -> None
318+
self, delete_snapshots: Optional[Union[bool, Literal['include', 'include-leased']]] = False,
319+
**kwargs: Any
320+
) -> None:
327321
"""Marks the specified share for deletion. The share is
328322
later deleted during garbage collection.
329323
330-
:param bool delete_snapshots:
324+
:param delete_snapshots:
331325
Indicates if snapshots are to be deleted.
326+
:type delete_snapshots:
327+
Optional[Union[bool, Literal['include', 'include-leased']]]
332328
:keyword int timeout:
333329
Sets the server-side timeout for the operation in seconds. For more details see
334330
https://learn.microsoft.com/rest/api/storageservices/setting-timeouts-for-file-service-operations.
@@ -354,8 +350,13 @@ async def delete_share(
354350
access_conditions = get_access_conditions(kwargs.pop('lease', None))
355351
timeout = kwargs.pop('timeout', None)
356352
delete_include = None
357-
if delete_snapshots:
358-
delete_include = DeleteSnapshotsOptionType.include
353+
if isinstance(delete_snapshots, bool) and delete_snapshots:
354+
delete_include = DeleteSnapshotsOptionType.INCLUDE
355+
else:
356+
if delete_snapshots == 'include':
357+
delete_include = DeleteSnapshotsOptionType.INCLUDE
358+
elif delete_snapshots == 'include-leased':
359+
delete_include = DeleteSnapshotsOptionType.INCLUDE_LEASED
359360
try:
360361
await self._client.share.delete(
361362
timeout=timeout,

sdk/storage/azure-storage-file-share/tests/test_share.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -172,25 +172,6 @@ def test_create_snapshot_with_metadata(self, **kwargs):
172172
assert snapshot_props.metadata == metadata2
173173
self._delete_shares(share.share_name)
174174

175-
@FileSharePreparer()
176-
@recorded_by_proxy
177-
def test_delete_share_with_snapshots(self, **kwargs):
178-
storage_account_name = kwargs.pop("storage_account_name")
179-
storage_account_key = kwargs.pop("storage_account_key")
180-
181-
self._setup(storage_account_name, storage_account_key)
182-
share = self._get_share_reference()
183-
share.create_share()
184-
snapshot = share.create_snapshot()
185-
186-
# Act
187-
with pytest.raises(HttpResponseError):
188-
share.delete_share()
189-
190-
deleted = share.delete_share(delete_snapshots=True)
191-
assert deleted is None
192-
self._delete_shares()
193-
194175
@pytest.mark.playback_test_only
195176
@FileSharePreparer()
196177
@recorded_by_proxy
@@ -834,6 +815,37 @@ def test_list_shares_with_snapshot(self, **kwargs):
834815
share.delete_share(delete_snapshots=True)
835816
self._delete_shares()
836817

818+
@FileSharePreparer()
819+
@recorded_by_proxy
820+
def test_delete_snapshots_options(self, **kwargs):
821+
storage_account_name = kwargs.pop("storage_account_name")
822+
storage_account_key = kwargs.pop("storage_account_key")
823+
824+
self._setup(storage_account_name, storage_account_key)
825+
share = self._create_share('prefix')
826+
share.create_snapshot()
827+
share.create_snapshot()
828+
829+
# Act / Assert
830+
831+
# Test backwards compatibility (False)
832+
with pytest.raises(ResourceExistsError):
833+
share.delete_share(delete_snapshots=False)
834+
835+
# Test backwards compatibility (True)
836+
share.delete_share(delete_snapshots=True)
837+
838+
# Test "include"
839+
share = self._create_share('prefix2')
840+
share.create_snapshot()
841+
share.delete_share(delete_snapshots='include')
842+
843+
# Test "include-leased"
844+
share = self._create_share('prefix3')
845+
lease = share.acquire_lease(lease_id='00000000-1111-2222-3333-444444444444')
846+
share.create_snapshot()
847+
share.delete_share(delete_snapshots='include-leased', lease='00000000-1111-2222-3333-444444444444')
848+
837849
@FileSharePreparer()
838850
@recorded_by_proxy
839851
def test_list_shares_with_prefix(self, **kwargs):

sdk/storage/azure-storage-file-share/tests/test_share_async.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,26 +158,6 @@ async def test_create_snapshot_with_metadata(self, **kwargs):
158158
assert snapshot_props.metadata == metadata2
159159
await self._delete_shares(share.share_name)
160160

161-
162-
@FileSharePreparer()
163-
@recorded_by_proxy_async
164-
async def test_delete_share_with_snapshots(self, **kwargs):
165-
storage_account_name = kwargs.pop("storage_account_name")
166-
storage_account_key = kwargs.pop("storage_account_key")
167-
168-
self._setup(storage_account_name, storage_account_key)
169-
share = self._get_share_reference()
170-
await share.create_share()
171-
snapshot = await share.create_snapshot()
172-
173-
# Act
174-
with pytest.raises(HttpResponseError):
175-
await share.delete_share()
176-
177-
deleted = await share.delete_share(delete_snapshots=True)
178-
assert deleted is None
179-
await self._delete_shares(share.share_name)
180-
181161
@pytest.mark.playback_test_only
182162
@FileSharePreparer()
183163
@recorded_by_proxy_async
@@ -837,6 +817,37 @@ async def test_list_shares_with_snapshot(self, **kwargs):
837817
self.assertNamedItemInContainer(all_shares, snapshot2['snapshot'])
838818
await self._delete_shares(share.share_name)
839819

820+
@FileSharePreparer()
821+
@recorded_by_proxy_async
822+
async def test_delete_snapshots_options(self, **kwargs):
823+
storage_account_name = kwargs.pop("storage_account_name")
824+
storage_account_key = kwargs.pop("storage_account_key")
825+
826+
self._setup(storage_account_name, storage_account_key)
827+
share = await self._create_share('prefix')
828+
await share.create_snapshot()
829+
await share.create_snapshot()
830+
831+
# Act / Assert
832+
833+
# Test backwards compatibility (False)
834+
with pytest.raises(ResourceExistsError):
835+
await share.delete_share(delete_snapshots=False)
836+
837+
# Test backwards compatibility (True)
838+
await share.delete_share(delete_snapshots=True)
839+
840+
# Test "include"
841+
share = await self._create_share('prefix2')
842+
await share.create_snapshot()
843+
await share.delete_share(delete_snapshots='include')
844+
845+
# Test "include-leased"
846+
share = await self._create_share('prefix3')
847+
lease = await share.acquire_lease(lease_id='00000000-1111-2222-3333-444444444444')
848+
await share.create_snapshot()
849+
await share.delete_share(delete_snapshots='include-leased', lease='00000000-1111-2222-3333-444444444444')
850+
840851
@FileSharePreparer()
841852
@recorded_by_proxy_async
842853
async def test_list_shares_with_prefix(self, **kwargs):

0 commit comments

Comments
 (0)