Skip to content

Commit 05a5d8f

Browse files
authored
{core} Fixed generic update issue. (#30703)
* {core} --set: Minor fix * add test
1 parent d60b5a8 commit 05a5d8f

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

src/azure-cli-core/azure/cli/core/commands/arm.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from azure.cli.core.commands.client_factory import get_mgmt_service_client
1616
from azure.cli.core.commands.events import EVENT_INVOKER_PRE_LOAD_ARGUMENTS
1717
from azure.cli.core.commands.validators import IterateValue
18-
from azure.cli.core.util import shell_safe_json_parse, get_command_type_kwarg
18+
from azure.cli.core.util import shell_safe_json_parse, get_command_type_kwarg, getprop
1919
from azure.cli.core.profiles import ResourceType, get_sdk
2020

2121
from knack.arguments import CLICommandArgument, ignore_type
@@ -600,7 +600,7 @@ def remove_properties(instance, argument_values):
600600
def throw_and_show_options(instance, part, path):
601601
from msrest.serialization import Model
602602
options = instance.__dict__ if hasattr(instance, '__dict__') else instance
603-
if isinstance(instance, Model) and isinstance(getattr(instance, 'additional_properties', None), dict):
603+
if isinstance(instance, Model) and isinstance(getprop(instance, 'additional_properties', None), dict):
604604
options.update(options.pop('additional_properties'))
605605
parent = '.'.join(path[:-1]).replace('.[', '[')
606606
error_message = "Couldn't find '{}' in '{}'.".format(part, parent)
@@ -673,15 +673,15 @@ def _update_instance(instance, part, path): # pylint: disable=too-many-return-s
673673
matches.append(x)
674674
elif not isinstance(x, dict):
675675
snake_key = make_snake_case(key)
676-
if hasattr(x, snake_key) and getattr(x, snake_key, None) == value:
676+
if hasattr(x, snake_key) and getprop(x, snake_key, None) == value:
677677
matches.append(x)
678678

679679
if len(matches) == 1:
680680
return matches[0]
681681
if len(matches) > 1:
682682
raise CLIError("non-unique key '{}' found multiple matches on {}. Key must be unique."
683683
.format(key, path[-2]))
684-
if key in getattr(instance, 'additional_properties', {}):
684+
if key in getprop(instance, 'additional_properties', {}):
685685
instance.enable_additional_properties_sending()
686686
return instance.additional_properties[key]
687687
raise CLIError("item with value '{}' doesn\'t exist for key '{}' on {}".format(value, key, path[-2]))
@@ -697,8 +697,8 @@ def _update_instance(instance, part, path): # pylint: disable=too-many-return-s
697697
return instance[part]
698698

699699
if hasattr(instance, make_snake_case(part)):
700-
return getattr(instance, make_snake_case(part), None)
701-
if part in getattr(instance, 'additional_properties', {}):
700+
return getprop(instance, make_snake_case(part), None)
701+
if part in getprop(instance, 'additional_properties', {}):
702702
instance.enable_additional_properties_sending()
703703
return instance.additional_properties[part]
704704
raise AttributeError()

src/azure-cli-core/azure/cli/core/tests/test_util.py

+18
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,24 @@ def test_b64_to_hex_type(self):
463463
self.assertIsInstance(b64_to_hex(self.base64), str)
464464

465465

466+
class TestGetProperty(unittest.TestCase):
467+
468+
def test_getprop(self):
469+
from azure.cli.core.util import getprop
470+
with self.assertRaises(AttributeError):
471+
getprop(self, '__class__')
472+
with self.assertRaises(AttributeError):
473+
getprop(self, '__init__')
474+
with self.assertRaises(AttributeError):
475+
getprop(self, 'assertRaises')
476+
with self.assertRaises(AttributeError):
477+
getprop(self, '_diffThreshold')
478+
with self.assertRaises(AttributeError):
479+
getprop(self, 'new_props')
480+
self.assertEqual(getprop(self, 'maxDiff'), self.maxDiff)
481+
self.assertEqual(getprop(self, 'new_props', "new_props"), "new_props")
482+
483+
466484
class TestHandleException(unittest.TestCase):
467485

468486
@mock.patch('azure.cli.core.azclierror.logger.error', autospec=True)

src/azure-cli-core/azure/cli/core/util.py

+14
Original file line numberDiff line numberDiff line change
@@ -1428,3 +1428,17 @@ def run_az_cmd(args, out_file=None):
14281428
cli = get_default_cli()
14291429
cli.invoke(args, out_file=out_file)
14301430
return cli.result
1431+
1432+
1433+
def getprop(o, name, *default):
1434+
""" This function is used to get the property of the object.
1435+
It will raise an error if the property is a private property or a method.
1436+
"""
1437+
if name.startswith('_'):
1438+
# avoid to access the private properties or methods
1439+
raise AttributeError(name)
1440+
v = getattr(o, name, *default)
1441+
if callable(v):
1442+
# avoid to access the methods
1443+
raise AttributeError(name)
1444+
return v

0 commit comments

Comments
 (0)