Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package azure-cli-core for openSUSE:Factory checked in at 2025-08-07 16:48:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old) and /work/SRC/openSUSE:Factory/.azure-cli-core.new.1085 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-core" Thu Aug 7 16:48:36 2025 rev:84 rq:1297725 version:2.76.0 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes 2025-07-10 22:12:28.376524862 +0200 +++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.1085/azure-cli-core.changes 2025-08-07 16:49:09.185147705 +0200 @@ -1,0 +2,8 @@ +Tue Aug 5 08:54:42 UTC 2025 - John Paul Adrian Glaubitz <[email protected]> + +- New upstream release + + Version 2.76.0 + + For detailed information about changes see the + HISTORY.rst file provided with this package + +------------------------------------------------------------------- Old: ---- azure_cli_core-2.75.0.tar.gz New: ---- azure_cli_core-2.76.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-core.spec ++++++ --- /var/tmp/diff_new_pack.hrAt9r/_old 2025-08-07 16:49:09.869176478 +0200 +++ /var/tmp/diff_new_pack.hrAt9r/_new 2025-08-07 16:49:09.869176478 +0200 @@ -24,7 +24,7 @@ %global _sitelibdir %{%{pythons}_sitelib} Name: azure-cli-core -Version: 2.75.0 +Version: 2.76.0 Release: 0 Summary: Microsoft Azure CLI Core Module License: MIT ++++++ azure_cli_core-2.75.0.tar.gz -> azure_cli_core-2.76.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/HISTORY.rst new/azure_cli_core-2.76.0/HISTORY.rst --- old/azure_cli_core-2.75.0/HISTORY.rst 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/HISTORY.rst 2025-07-29 11:27:20.000000000 +0200 @@ -3,6 +3,10 @@ Release History =============== +2.76.0 +++++++ +* Resolve CVE-2024-47081 (#31708) + 2.75.0 ++++++ * Resolve CVE-2025-50181 (#31669) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/PKG-INFO new/azure_cli_core-2.76.0/PKG-INFO --- old/azure_cli_core-2.75.0/PKG-INFO 2025-06-24 12:17:13.254765300 +0200 +++ new/azure_cli_core-2.76.0/PKG-INFO 2025-07-29 11:27:46.090991000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: azure-cli-core -Version: 2.75.0 +Version: 2.76.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/__init__.py new/azure_cli_core-2.76.0/azure/cli/core/__init__.py --- old/azure_cli_core-2.75.0/azure/cli/core/__init__.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/__init__.py 2025-07-29 11:27:20.000000000 +0200 @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.75.0" +__version__ = "2.76.0" import os import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/_profile.py new/azure_cli_core-2.76.0/azure/cli/core/_profile.py --- old/azure_cli_core-2.75.0/azure/cli/core/_profile.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/_profile.py 2025-07-29 11:27:20.000000000 +0200 @@ -152,7 +152,7 @@ allow_no_subscriptions=False, use_cert_sn_issuer=None, show_progress=False, - **kwargs): + claims_challenge=None): """ For service principal, `password` is a dict returned by ServicePrincipalAuth.build_credential """ @@ -172,12 +172,12 @@ use_device_code = True if use_device_code: - user_identity = identity.login_with_device_code(scopes=scopes, **kwargs) + user_identity = identity.login_with_device_code(scopes=scopes) else: - user_identity = identity.login_with_auth_code(scopes=scopes, **kwargs) + user_identity = identity.login_with_auth_code(scopes=scopes, claims_challenge=claims_challenge) else: if not is_service_principal: - user_identity = identity.login_with_username_password(username, password, scopes=scopes, **kwargs) + user_identity = identity.login_with_username_password(username, password, scopes=scopes) else: identity.login_with_service_principal(username, password, scopes=scopes) @@ -299,7 +299,8 @@ identity.logout_all_users() identity.logout_all_service_principal() - def get_login_credentials(self, subscription_id=None, aux_subscriptions=None, aux_tenants=None): + def get_login_credentials(self, subscription_id=None, aux_subscriptions=None, aux_tenants=None, + sdk_credential=True): """Get a credential compatible with Track 2 SDK.""" if aux_tenants and aux_subscriptions: raise CLIError("Please specify only one of aux_subscriptions and aux_tenants, not both") @@ -307,18 +308,15 @@ account = self.get_subscription(subscription_id) managed_identity_type, managed_identity_id = Profile._parse_managed_identity_account(account) - + external_credentials = None if in_cloud_console() and account[_USER_ENTITY].get(_CLOUD_SHELL_ID): # Cloud Shell from .auth.msal_credentials import CloudShellCredential - # The credential must be wrapped by CredentialAdaptor so that it can work with SDK. - sdk_cred = CredentialAdaptor(CloudShellCredential()) + cred = CloudShellCredential() elif managed_identity_type: # managed identity - # The credential must be wrapped by CredentialAdaptor so that it can work with SDK. cred = ManagedIdentityAuth.credential_factory(managed_identity_type, managed_identity_id) - sdk_cred = CredentialAdaptor(cred) else: # user and service principal @@ -332,13 +330,15 @@ if sub[_TENANT_ID] != account[_TENANT_ID]: external_tenants.append(sub[_TENANT_ID]) - credential = self._create_credential(account) + cred = self._create_credential(account) external_credentials = [] for external_tenant in external_tenants: external_credentials.append(self._create_credential(account, tenant_id=external_tenant)) - sdk_cred = CredentialAdaptor(credential, auxiliary_credentials=external_credentials) - return (sdk_cred, + # Wrapping the credential with CredentialAdaptor makes it compatible with SDK. + cred_result = CredentialAdaptor(cred, auxiliary_credentials=external_credentials) if sdk_credential else cred + + return (cred_result, str(account[_SUBSCRIPTION_ID]), str(account[_TENANT_ID])) @@ -401,6 +401,15 @@ None if tenant else str(account[_SUBSCRIPTION_ID]), str(tenant if tenant else account[_TENANT_ID])) + def get_msal_token(self, scopes, data): + """Get VM SSH certificate. DO NOT use it for other purposes. To get an access token, use get_raw_token instead. + """ + credential, _, _ = self.get_login_credentials(sdk_credential=False) + from .auth.constants import ACCESS_TOKEN + certificate_string = credential.acquire_token(scopes, data=data)[ACCESS_TOKEN] + # The first value used to be username, but it is no longer used. + return None, certificate_string + def _normalize_properties(self, user, subscriptions, is_service_principal, cert_sn_issuer_auth=None, assigned_identity_info=None): consolidated = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/auth/identity.py new/azure_cli_core-2.76.0/azure/cli/core/auth/identity.py --- old/azure_cli_core-2.75.0/azure/cli/core/auth/identity.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/auth/identity.py 2025-07-29 11:27:20.000000000 +0200 @@ -145,7 +145,7 @@ Identity._service_principal_store_instance = ServicePrincipalStore(store) return Identity._service_principal_store_instance - def login_with_auth_code(self, scopes, **kwargs): + def login_with_auth_code(self, scopes, claims_challenge=None): # Emit a warning to inform that a browser is opened. # Only show the path part of the URL and hide the query string. @@ -168,21 +168,21 @@ success_template=success_template, error_template=error_template, parent_window_handle=self._msal_app.CONSOLE_WINDOW_HANDLE, on_before_launching_ui=_prompt_launching_ui, enable_msa_passthrough=True, - **kwargs) + claims_challenge=claims_challenge) return check_result(result) - def login_with_device_code(self, scopes, **kwargs): - flow = self._msal_app.initiate_device_flow(scopes, **kwargs) + def login_with_device_code(self, scopes): + flow = self._msal_app.initiate_device_flow(scopes) if "user_code" not in flow: raise ValueError( "Fail to create device flow. Err: %s" % json.dumps(flow, indent=4)) from azure.cli.core.style import print_styled_text, Style print_styled_text((Style.WARNING, flow["message"]), file=sys.stderr) - result = self._msal_app.acquire_token_by_device_flow(flow, **kwargs) # By default it will block + result = self._msal_app.acquire_token_by_device_flow(flow) # By default it will block return check_result(result) - def login_with_username_password(self, username, password, scopes, **kwargs): - result = self._msal_app.acquire_token_by_username_password(username, password, scopes, **kwargs) + def login_with_username_password(self, username, password, scopes): + result = self._msal_app.acquire_token_by_username_password(username, password, scopes) return check_result(result) def login_with_service_principal(self, client_id, credential, scopes): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/auth/msal_credentials.py new/azure_cli_core-2.76.0/azure/cli/core/auth/msal_credentials.py --- old/azure_cli_core-2.75.0/azure/cli/core/auth/msal_credentials.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/auth/msal_credentials.py 2025-07-29 11:27:20.000000000 +0200 @@ -51,15 +51,15 @@ scopes, claims_challenge, kwargs) if claims_challenge: - logger.warning('Acquiring new access token silently for tenant %s with claims challenge: %s', - self._msal_app.authority.tenant, claims_challenge) + logger.info('Acquiring new access token silently with claims challenge: %s', claims_challenge) result = self._msal_app.acquire_token_silent_with_error( scopes, self._account, claims_challenge=claims_challenge, **kwargs) from azure.cli.core.azclierror import AuthenticationError try: # Check if an access token is returned. - check_result(result, scopes=scopes, claims_challenge=claims_challenge) + check_result(result, tenant=self._msal_app.authority.tenant, scopes=scopes, + claims_challenge=claims_challenge) except AuthenticationError as ex: # For VM SSH ('data' is passed), if getting access token fails because # Conditional Access MFA step-up or compliance check is required, re-launch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/auth/util.py new/azure_cli_core-2.76.0/azure/cli/core/auth/util.py --- old/azure_cli_core-2.75.0/azure/cli/core/auth/util.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/auth/util.py 2025-07-29 11:27:20.000000000 +0200 @@ -20,7 +20,7 @@ "To pass a service principal certificate, use --certificate instead.") -def aad_error_handler(error, **kwargs): +def aad_error_handler(error, tenant=None, scopes=None, claims_challenge=None): """ Handle the error from AAD server returned by ADAL or MSAL. """ # https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes @@ -29,6 +29,8 @@ # To trigger this function for testing, simply provide an invalid scope: # az account get-access-token --scope https://my-invalid-scope + logger.debug('MSAL error: %r', error) + from azure.cli.core.util import in_cloud_console if in_cloud_console(): import socket @@ -39,33 +41,52 @@ error_codes = error.get('error_codes') # Build recommendation message + recommendation = None if error_codes and 7000215 in error_codes: recommendation = PASSWORD_CERTIFICATE_WARNING else: - login_command = _generate_login_command(**kwargs) - recommendation = ( - # Cloud Shell uses IMDS-like interface for implicit login. If getting token/cert failed, - # we let the user explicitly log in to AAD with MSAL. - "Please explicitly log in with:\n{}" if error.get('error') == 'broker_error' - else "Interactive authentication is needed. Please run:\n{}").format(login_command) + login_command = _generate_login_command(tenant=tenant, scopes=scopes, claims_challenge=claims_challenge) + login_message = ('Run the command below to authenticate interactively; ' + 'additional arguments may be added as needed:\n' + f'{login_command}') + + # During a challenge, the exception will caught by azure-mgmt-core, so we show a warning now + if claims_challenge: + logger.info('Failed to acquire token silently. Error detail: %s', error_description) + logger.warning(login_message) + else: + recommendation = login_message from azure.cli.core.azclierror import AuthenticationError raise AuthenticationError(error_description, msal_error=error, recommendation=recommendation) -def _generate_login_command(scopes=None, claims_challenge=None): +def _generate_login_command(tenant=None, scopes=None, claims_challenge=None): login_command = ['az login'] - # Rejected by Conditional Access policy, like MFA + # Rejected by Conditional Access policy, like MFA. + # MFA status is not shared between tenants. Specifying tenant triggers the MFA process for that tenant. + # Double quotes are not necessary, but we add them following the best practice to avoid shell interpretation. + if tenant: + login_command.extend(['--tenant', f'"{tenant}"']) + + # Some scopes (such as Graph) may require MFA while ARM may not. + # Specifying scope triggers the MFA process for that scope. if scopes: - login_command.append('--scope {}'.format(' '.join(scopes))) + login_command.append('--scope') + for s in scopes: + login_command.append(f'"{s}"') # Rejected by CAE if claims_challenge: - # Explicit logout is needed: https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/335 - return 'az logout\n' + ' '.join(login_command) - - return ' '.join(login_command) + from azure.cli.core.util import b64encode + # Base64 encode the claims_challenge to avoid shell interpretation + claims_challenge_encoded = b64encode(claims_challenge) + login_command.extend(['--claims-challenge', f'"{claims_challenge_encoded}"']) + + # Explicit logout is preferred, making sure MSAL cache is purged: + # https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/335 + return 'az logout\n' + ' '.join(login_command) def resource_to_scopes(resource): @@ -106,7 +127,7 @@ return scope -def check_result(result, **kwargs): +def check_result(result, tenant=None, scopes=None, claims_challenge=None): """Parse the result returned by MSAL: 1. Check if the MSAL result contains a valid access token. @@ -125,7 +146,7 @@ set_msal_telemetry(result['msal_telemetry']) if 'error' in result: - aad_error_handler(result, **kwargs) + aad_error_handler(result, tenant=tenant, scopes=scopes, claims_challenge=claims_challenge) # For user authentication if 'id_token_claims' in result: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/cloud.py new/azure_cli_core-2.76.0/azure/cli/core/cloud.py --- old/azure_cli_core-2.75.0/azure/cli/core/cloud.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/cloud.py 2025-07-29 11:27:20.000000000 +0200 @@ -434,7 +434,7 @@ gallery='https://gallery.usgovcloudapi.net/', active_directory='https://login.microsoftonline.us', active_directory_resource_id='https://management.core.usgovcloudapi.net/', - active_directory_graph_resource_id='https://graph.windows.net/', + active_directory_graph_resource_id='https://graph.microsoftazure.us/', microsoft_graph_resource_id='https://graph.microsoft.us/', vm_image_alias_doc='https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/arm-compute/quickstart-templates/aliases.json', media_resource_id='https://rest.media.usgovcloudapi.net', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/profiles/_shared.py new/azure_cli_core-2.76.0/azure/cli/core/profiles/_shared.py --- old/azure_cli_core-2.75.0/azure/cli/core/profiles/_shared.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/profiles/_shared.py 2025-07-29 11:27:20.000000000 +0200 @@ -48,7 +48,6 @@ MGMT_STORAGE = ('azure.mgmt.storage', 'StorageManagementClient') MGMT_COMPUTE = ('azure.mgmt.compute', 'ComputeManagementClient') MGMT_NETWORK = ('azure.mgmt.network', 'NetworkManagementClient') - MGMT_NETWORK_DNS = ('azure.mgmt.dns', 'DnsManagementClient') MGMT_NETWORK_PRIVATEDNS = ('azure.mgmt.privatedns', 'PrivateDnsManagementClient') MGMT_AUTHORIZATION = ('azure.mgmt.authorization', 'AuthorizationManagementClient') MGMT_CONTAINERREGISTRY = ('azure.mgmt.containerregistry', 'ContainerRegistryManagementClient') @@ -58,6 +57,7 @@ MGMT_RESOURCE_POLICY = ('azure.mgmt.resource.policy', 'PolicyClient') MGMT_RESOURCE_RESOURCES = ('azure.mgmt.resource.resources', 'ResourceManagementClient') MGMT_RESOURCE_SUBSCRIPTIONS = ('azure.mgmt.resource.subscriptions', 'SubscriptionClient') + MGMT_RESOURCE_DEPLOYMENTS = ('azure.mgmt.resource.deployments', 'DeploymentsMgmtClient') MGMT_RESOURCE_DEPLOYMENTSCRIPTS = ('azure.mgmt.resource.deploymentscripts', 'DeploymentScriptsClient') MGMT_RESOURCE_TEMPLATESPECS = ('azure.mgmt.resource.templatespecs', 'TemplateSpecsClient') MGMT_RESOURCE_DEPLOYMENTSTACKS = ('azure.mgmt.resource.deploymentstacks', 'DeploymentStacksClient') @@ -179,17 +179,14 @@ }), ResourceType.MGMT_RESOURCE_RESOURCES: '2024-11-01', ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS: '2022-12-01', - ResourceType.MGMT_RESOURCE_DEPLOYMENTSCRIPTS: '2020-10-01', - ResourceType.MGMT_RESOURCE_TEMPLATESPECS: '2021-05-01', - ResourceType.MGMT_RESOURCE_DEPLOYMENTSTACKS: '2024-03-01', + ResourceType.MGMT_RESOURCE_DEPLOYMENTS: None, + ResourceType.MGMT_RESOURCE_DEPLOYMENTSCRIPTS: None, + ResourceType.MGMT_RESOURCE_TEMPLATESPECS: None, + ResourceType.MGMT_RESOURCE_DEPLOYMENTSTACKS: None, ResourceType.MGMT_RESOURCE_PRIVATELINKS: '2020-05-01', ResourceType.MGMT_RESOURCE_MANAGEDAPPLICATIONS: '2019-07-01', - ResourceType.MGMT_NETWORK_DNS: '2018-05-01', ResourceType.MGMT_NETWORK_PRIVATEDNS: None, - ResourceType.MGMT_KEYVAULT: SDKProfile('2024-11-01', { - 'vaults': '2023-02-01', - 'managed_hsms': '2024-11-01' - }), + ResourceType.MGMT_KEYVAULT: None, ResourceType.MGMT_AUTHORIZATION: SDKProfile('2022-04-01', { 'role_definitions': '2022-05-01-preview', 'provider_operations_metadata': '2018-01-01-preview' @@ -219,18 +216,18 @@ ResourceType.DATA_STORAGE_QUEUE: '2018-03-28', ResourceType.DATA_COSMOS_TABLE: '2017-04-17', ResourceType.DATA_STORAGE_TABLE: None, - ResourceType.MGMT_SERVICEBUS: '2022-10-01-preview', - ResourceType.MGMT_EVENTHUB: '2022-01-01-preview', + ResourceType.MGMT_SERVICEBUS: None, + ResourceType.MGMT_EVENTHUB: None, ResourceType.MGMT_MONITOR: None, ResourceType.MGMT_MSI: '2023-01-31', - ResourceType.MGMT_APPSERVICE: '2023-01-01', + ResourceType.MGMT_APPSERVICE: '2024-11-01', ResourceType.MGMT_IOTHUB: '2023-06-30-preview', ResourceType.MGMT_IOTDPS: '2021-10-15', ResourceType.MGMT_IOTCENTRAL: '2021-11-01-preview', ResourceType.MGMT_ARO: '2023-11-22', ResourceType.MGMT_DATABOXEDGE: '2021-02-01-preview', ResourceType.MGMT_CUSTOMLOCATION: '2021-03-15-preview', - ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2025-04-01'), + ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2025-05-01'), ResourceType.MGMT_APPCONTAINERS: '2022-10-01', } } @@ -259,10 +256,6 @@ 'VERSION_2025_03_01_PREVIEW': "2025-03-01-preview", 'VERSION_2025_04_01': "2025-04-01" }, - ResourceType.MGMT_CONTAINERSERVICE: { - # src/azure-cli/azure/cli/command_modules/acs/tests/latest/test_custom.py:50 - 'ManagedClusterAddonProfile': '2020-03-01', - }, ResourceType.MGMT_MSI: { 'user_assigned_identities': '2022-01-31-preview', } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure/cli/core/util.py new/azure_cli_core-2.76.0/azure/cli/core/util.py --- old/azure_cli_core-2.75.0/azure/cli/core/util.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure/cli/core/util.py 2025-07-29 11:27:20.000000000 +0200 @@ -603,13 +603,24 @@ def b64encode(s): """ - Encodes a string to base64 on 2.x and 3.x + Encodes a string to a base64 string. :param str s: latin_1 encoded string :return: base64 encoded string :rtype: str """ encoded = base64.b64encode(s.encode("latin-1")) - return encoded if encoded is str else encoded.decode('latin-1') + return encoded.decode('latin-1') + + +def b64decode(s): + """ + Decodes a base64 string to a string. + :param str s: latin_1 encoded base64 string + :return: decoded string + :rtype: str + """ + encoded = base64.b64decode(s.encode("latin-1")) + return encoded.decode('latin-1') def b64_to_hex(s): @@ -633,6 +644,7 @@ """ from datetime import date, time, datetime, timedelta from enum import Enum + from azure.core.serialization import attribute_list if isinstance(obj, dict): result = {k: todict(v, post_processor) for (k, v) in obj.items()} return post_processor(obj, result) if post_processor else result @@ -646,9 +658,12 @@ return str(obj) # This is the only difference with knack.util.todict because for typespec generated SDKs # The base model stores data in obj.__dict__['_data'] instead of in obj.__dict__ - # We need to call obj.as_dict() to extract data for this kind of model - if hasattr(obj, 'as_dict') and not hasattr(obj, '_attribute_map'): - result = {to_camel_case(k): todict(v, post_processor) for k, v in obj.as_dict().items()} + # The way to detect if it's a typespec generated model is to check the private `_is_model` attribute + # azure-core provided new function `attribute_list` to list all attribute names + # so that we don't need to use raw __dict__ directly + if getattr(obj, "_is_model", False): + result = {to_camel_case(attr): todict(getattr(obj, attr), post_processor) + for attr in attribute_list(obj) if hasattr(obj, attr)} return post_processor(obj, result) if post_processor else result if hasattr(obj, '_asdict'): return todict(obj._asdict(), post_processor) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/azure_cli_core.egg-info/PKG-INFO new/azure_cli_core-2.76.0/azure_cli_core.egg-info/PKG-INFO --- old/azure_cli_core-2.75.0/azure_cli_core.egg-info/PKG-INFO 2025-06-24 12:17:13.000000000 +0200 +++ new/azure_cli_core-2.76.0/azure_cli_core.egg-info/PKG-INFO 2025-07-29 11:27:46.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: azure-cli-core -Version: 2.75.0 +Version: 2.76.0 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure_cli_core-2.75.0/setup.py new/azure_cli_core-2.76.0/setup.py --- old/azure_cli_core-2.75.0/setup.py 2025-06-24 12:16:29.000000000 +0200 +++ new/azure_cli_core-2.76.0/setup.py 2025-07-29 11:27:20.000000000 +0200 @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.75.0" +VERSION = "2.76.0" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions.
