Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion sdk/core/azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Release History

## 1.10.1 (Unreleased)
## 1.11.0 (Unreleased)

### Features

- Added `CaseInsensitiveEnumMeta` class for case-insensitive enums.


## 1.10.0 (2021-01-11)
Expand Down
14 changes: 14 additions & 0 deletions sdk/core/azure-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,20 @@ class MatchConditions(Enum):
IfMissing = 5
```

#### CaseInsensitiveEnumMeta

A metaclass to support case-insensitive enums.
```python
from enum import Enum
from six import with_metaclass

from azure.core import CaseInsensitiveEnumMeta

class MyCustomEnum(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
FOO = 'foo'
BAR = 'bar'
```

## Contributing
This project welcomes contributions and suggestions. Most contributions require
you to agree to a Contributor License Agreement (CLA) declaring that you have
Expand Down
4 changes: 3 additions & 1 deletion sdk/core/azure-core/azure/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@

from ._pipeline_client import PipelineClient
from ._match_conditions import MatchConditions
from ._enum_meta import CaseInsensitiveEnumMeta


__all__ = [
"PipelineClient",
"MatchConditions"
"MatchConditions",
"CaseInsensitiveEnumMeta"
]

try:
Expand Down
60 changes: 60 additions & 0 deletions sdk/core/azure-core/azure/core/_enum_meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# --------------------------------------------------------------------------

from enum import EnumMeta


class CaseInsensitiveEnumMeta(EnumMeta):
"""Enum metaclass to allow for interoperability with case-insensitive strings.

Consuming this metaclass in an SDK should be done in the following manner:

.. code-block:: python

from enum import Enum
from six import with_metaclass
from azure.core import CaseInsensitiveEnumMeta

class MyCustomEnum(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
FOO = 'foo'
BAR = 'bar'

"""

def __getitem__(cls, name):
return super(CaseInsensitiveEnumMeta, cls).__getitem__(name.upper())

def __getattr__(cls, name):
"""Return the enum member matching `name`
We use __getattr__ instead of descriptors or inserting into the enum
class' __dict__ in order to support `name` and `value` being both
properties for enum members (which live in the class' __dict__) and
enum members themselves.
"""
try:
return cls._member_map_[name.upper()]
except KeyError:
raise AttributeError(name)
2 changes: 1 addition & 1 deletion sdk/core/azure-core/azure/core/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# regenerated.
# --------------------------------------------------------------------------

VERSION = "1.10.1"
VERSION = "1.11.0"
44 changes: 44 additions & 0 deletions sdk/core/azure-core/tests/test_enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# --------------------------------------------------------------------------
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# The MIT License (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the ""Software""), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# --------------------------------------------------------------------------
from enum import Enum
from six import with_metaclass

from azure.core import CaseInsensitiveEnumMeta

class MyCustomEnum(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
FOO = 'foo'
BAR = 'bar'


def test_case_insensitive_enums():
assert MyCustomEnum.foo.value == 'foo'
assert MyCustomEnum.FOO.value == 'foo'
assert MyCustomEnum('bar').value == 'bar'
assert 'bar' == MyCustomEnum.BAR
assert 'bar' == MyCustomEnum.bar
assert MyCustomEnum['foo'] == 'foo'
assert MyCustomEnum['FOO'] == 'foo'
assert isinstance(MyCustomEnum.BAR, str)