Skip to content
Merged
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ generated library will use that auth policy unless they pass in a separate one t

- Fix typing for discriminator values in models, so Python 3.5 can import py3 file for models #691

**Bug Fixes**

- Make enum names all upper case. This fixes issues that arise if the name of an enum is also a method that can be applied to, say, a string.
For example, if an enum's name is count. Made sure this fix will not break users currently accessing with lower case enum names #692

### 2020-06-08 - 5.1.0-preview.2
Modelerfour version: 4.13.351

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ modelerfour:
operation: snakecase
operationGroup: pascalcase
choice: pascalcase
choiceValue: snakecase
choiceValue: uppercase
constant: snakecase
constantParameter: snakecase
type: pascalcase
Expand Down
2 changes: 1 addition & 1 deletion autorest/codegen/templates/enum.py.jinja2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

class {{ enum.name }}({{ enum.enum_type.type_annotation }}, Enum):
class {{ enum.name }}(with_metaclass(_CaseInsensitiveEnumMeta, {{ enum.enum_type.type_annotation }}, Enum)):
{% if enum.description %}
"""{{ enum.description | wordwrap(width=95, break_long_words=False, wrapstring='\n ') }}
"""
Expand Down
20 changes: 19 additions & 1 deletion autorest/codegen/templates/enum_container.py.jinja2
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
# coding=utf-8
{{ code_model.options['license_header'] }}

from enum import Enum
from enum import Enum, EnumMeta
from six import with_metaclass

class _CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, name):
return super().__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)

{% for enum in code_model.enums.values() | sort %}
{% include "enum.py.jinja2" %}
{% endfor %}
15 changes: 12 additions & 3 deletions autorest/namer/name_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def _convert_schemas(schemas: Dict[str, Any]) -> None:
def _convert_enum_schema(schema: Dict[str, Any]) -> None:
NameConverter._convert_language_default_pascal_case(schema)
for choice in schema["choices"]:
NameConverter._convert_language_default_python_case(choice, pad_string=PadType.Enum)
NameConverter._convert_language_default_python_case(choice, pad_string=PadType.Enum, all_upper=True)

@staticmethod
def _convert_object_schema(schema: Dict[str, Any]) -> None:
Expand All @@ -99,7 +99,11 @@ def _convert_object_schema(schema: Dict[str, Any]) -> None:

@staticmethod
def _convert_language_default_python_case(
schema: Dict[str, Any], *, pad_string: Optional[PadType] = None, convert_name: bool = False
schema: Dict[str, Any],
*,
pad_string: Optional[PadType] = None,
convert_name: bool = False,
all_upper: bool = False
) -> None:
if not schema.get("language") or schema["language"].get("python"):
return
Expand All @@ -117,7 +121,12 @@ def _convert_language_default_python_case(
schema_python_name = NameConverter._to_valid_python_name(
name=schema_name, pad_string=pad_string, convert_name=convert_name
)
schema['language']['python']['name'] = schema_python_name.lower()
# need to add the lower in case certain words, like LRO, are overriden to
# always return LRO. Without .lower(), for example, begin_lro would be
# begin_LRO
schema['language']['python']['name'] = (
schema_python_name.upper() if all_upper else schema_python_name.lower()
)

schema_description = schema["language"]["default"]["description"].strip()
if pad_string == PadType.Method and not schema_description and not schema["language"]["default"].get("summary"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,66 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from enum import Enum
from enum import Enum, EnumMeta
from six import with_metaclass

class OperationResultStatus(str, Enum):
class _CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, name):
return super().__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)


class OperationResultStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""The status of the request
"""

succeeded = "Succeeded"
failed = "Failed"
canceled = "canceled"
accepted = "Accepted"
creating = "Creating"
created = "Created"
updating = "Updating"
updated = "Updated"
deleting = "Deleting"
deleted = "Deleted"
ok = "OK"

class ProductPropertiesProvisioningStateValues(str, Enum):

succeeded = "Succeeded"
failed = "Failed"
canceled = "canceled"
accepted = "Accepted"
creating = "Creating"
created = "Created"
updating = "Updating"
updated = "Updated"
deleting = "Deleting"
deleted = "Deleted"
ok = "OK"

class SubProductPropertiesProvisioningStateValues(str, Enum):

succeeded = "Succeeded"
failed = "Failed"
canceled = "canceled"
accepted = "Accepted"
creating = "Creating"
created = "Created"
updating = "Updating"
updated = "Updated"
deleting = "Deleting"
deleted = "Deleted"
ok = "OK"
SUCCEEDED = "Succeeded"
FAILED = "Failed"
CANCELED = "canceled"
ACCEPTED = "Accepted"
CREATING = "Creating"
CREATED = "Created"
UPDATING = "Updating"
UPDATED = "Updated"
DELETING = "Deleting"
DELETED = "Deleted"
OK = "OK"

class ProductPropertiesProvisioningStateValues(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):

SUCCEEDED = "Succeeded"
FAILED = "Failed"
CANCELED = "canceled"
ACCEPTED = "Accepted"
CREATING = "Creating"
CREATED = "Created"
UPDATING = "Updating"
UPDATED = "Updated"
DELETING = "Deleting"
DELETED = "Deleted"
OK = "OK"

class SubProductPropertiesProvisioningStateValues(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):

SUCCEEDED = "Succeeded"
FAILED = "Failed"
CANCELED = "canceled"
ACCEPTED = "Accepted"
CREATING = "Creating"
CREATED = "Created"
UPDATING = "Updating"
UPDATED = "Updated"
DELETING = "Deleting"
DELETED = "Deleted"
OK = "OK"
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,38 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from enum import Enum
from enum import Enum, EnumMeta
from six import with_metaclass

class OperationResultStatus(str, Enum):
class _CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, name):
return super().__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)


class OperationResultStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""The status of the request
"""

succeeded = "Succeeded"
failed = "Failed"
canceled = "canceled"
accepted = "Accepted"
creating = "Creating"
created = "Created"
updating = "Updating"
updated = "Updated"
deleting = "Deleting"
deleted = "Deleted"
ok = "OK"
SUCCEEDED = "Succeeded"
FAILED = "Failed"
CANCELED = "canceled"
ACCEPTED = "Accepted"
CREATING = "Creating"
CREATED = "Created"
UPDATING = "Updating"
UPDATED = "Updated"
DELETING = "Deleting"
DELETED = "Deleted"
OK = "OK"
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,72 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from enum import Enum
from enum import Enum, EnumMeta
from six import with_metaclass

class AccountStatus(str, Enum):
class _CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, name):
return super().__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)


class AccountStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Gets the status indicating whether the primary location of the storage account is available or
unavailable.
"""

available = "Available"
unavailable = "Unavailable"
AVAILABLE = "Available"
UNAVAILABLE = "Unavailable"

class AccountType(str, Enum):
class AccountType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Gets or sets the account type.
"""

standard_lrs = "Standard_LRS"
standard_zrs = "Standard_ZRS"
standard_grs = "Standard_GRS"
standard_ragrs = "Standard_RAGRS"
premium_lrs = "Premium_LRS"
STANDARD_LRS = "Standard_LRS"
STANDARD_ZRS = "Standard_ZRS"
STANDARD_GRS = "Standard_GRS"
STANDARD_RAGRS = "Standard_RAGRS"
PREMIUM_LRS = "Premium_LRS"

class KeyName(str, Enum):
class KeyName(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):

key1 = "key1"
key2 = "key2"
KEY1 = "key1"
KEY2 = "key2"

class ProvisioningState(str, Enum):
class ProvisioningState(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Gets the status of the storage account at the time the operation was called.
"""

creating = "Creating"
resolving_dns = "ResolvingDNS"
succeeded = "Succeeded"
CREATING = "Creating"
RESOLVING_DNS = "ResolvingDNS"
SUCCEEDED = "Succeeded"

class Reason(str, Enum):
class Reason(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Gets the reason that a storage account name could not be used. The Reason element is only
returned if NameAvailable is false.
"""

account_name_invalid = "AccountNameInvalid"
already_exists = "AlreadyExists"
ACCOUNT_NAME_INVALID = "AccountNameInvalid"
ALREADY_EXISTS = "AlreadyExists"

class UsageUnit(str, Enum):
class UsageUnit(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Gets the unit of measurement.
"""

count = "Count"
bytes = "Bytes"
seconds = "Seconds"
percent = "Percent"
counts_per_second = "CountsPerSecond"
bytes_per_second = "BytesPerSecond"
COUNT = "Count"
BYTES = "Bytes"
SECONDS = "Seconds"
PERCENT = "Percent"
COUNTS_PER_SECOND = "CountsPerSecond"
BYTES_PER_SECOND = "BytesPerSecond"
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,31 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from enum import Enum
from enum import Enum, EnumMeta
from six import with_metaclass

class ContentType(str, Enum):
class _CaseInsensitiveEnumMeta(EnumMeta):
def __getitem__(self, name):
return super().__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)


class ContentType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
"""Content type for upload
"""

application_pdf = "application/pdf" #: Content Type 'application/pdf'.
image_jpeg = "image/jpeg" #: Content Type 'image/jpeg'.
image_png = "image/png" #: Content Type 'image/png'.
image_tiff = "image/tiff" #: Content Type 'image/tiff'.
APPLICATION_PDF = "application/pdf" #: Content Type 'application/pdf'.
IMAGE_JPEG = "image/jpeg" #: Content Type 'image/jpeg'.
IMAGE_PNG = "image/png" #: Content Type 'image/png'.
IMAGE_TIFF = "image/tiff" #: Content Type 'image/tiff'.
Loading