Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .azure-pipelines/templates/automation_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
parameters:
- name: pythonVersion
type: string
default: 3.10
default: '3.11'

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type says string, so lets make that explicit. Otherwise we're implicitly converting a float to a string, which might cause weird behaviour.

- name: profile
type: string
default: latest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ $VENV = "$SPEC_ROOT\.venv-aaz"

## 2. Environment

**Python 3.10-3.14 required.** Verify with the explicit path, not `PATH`; do not install it yourself.
**Python 3.11-3.15 required.** Verify with the explicit path, not `PATH`; do not install it yourself.
* Windows: `& "$env:LOCALAPPDATA\Programs\Python\Python312\python.exe" --version`
(installer from <https://www.python.org/downloads/>; path form
`C:\Users\{xxxx}\AppData\Local\Programs\Python\Python3{xxxx}`)
Expand Down Expand Up @@ -734,7 +734,7 @@ Further reading: azure-cli `doc/` (extensions, command guidelines, authoring tes
- [ ] Plan echoed back and confirmed (service, `<OLD>` -> `<NEW>`, swagger path, branch, scope).
- [ ] **Section 4.1 pre-flight**: `az provider show` confirms whether ARM serves `<NEW>` yet.
- [ ] **Section 4.2**: pre-existing aaz<->azure-cli drift isolated and listed before generating.
- [ ] Python 3.10-3.14 venv active; `aaz-dev` + `azdev` installed.
- [ ] Python 3.11-3.15 venv active; `aaz-dev` + `azdev` installed.
- [ ] Repos synced from upstream; `aaz` and `azure-cli` on identically named `feature-*` branches.
- [ ] `azdev setup --cli $CLI --repo $EXT` clean.
- [ ] `aaz-dev run` generation complete for the agreed scope.
Expand Down
12 changes: 6 additions & 6 deletions azure-pipelines-full-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ variables:
- template: ${{ variables.Pipeline.Workspace }}/.azure-pipelines/templates/variables.yml

jobs:
- job: AutomationFullTestPython312ProfileLatest
displayName: Automation Full Test Python312 Profile Latest
- job: AutomationFullTestPython311ProfileLatest

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add oldest supported version (3.11), instead of one newer.

displayName: Automation Full Test Python311 Profile Latest
timeoutInMinutes: 9999
strategy:
maxParallel: 8
Expand All @@ -43,15 +43,15 @@ jobs:
steps:
- template: .azure-pipelines/templates/automation_test.yml
parameters:
pythonVersion: '3.12'
pythonVersion: '3.11'
profile: 'latest'
instance_cnt: '8'
instance_idx: '$(Instance_idx)'
fullTest: true
jobName: 'FullTest'

- job: AutomationFullTestPython314ProfileLatest
displayName: Automation Full Test Python314 Profile Latest
- job: AutomationFullTestPython315ProfileLatest

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add newest (3.15) here.

displayName: Automation Full Test Python315 Profile Latest
timeoutInMinutes: 9999
strategy:
maxParallel: 8
Expand All @@ -77,7 +77,7 @@ jobs:
steps:
- template: .azure-pipelines/templates/automation_test.yml
parameters:
pythonVersion: '3.14'
pythonVersion: '3.15'
profile: 'latest'
instance_cnt: '8'
instance_idx: '$(Instance_idx)'
Expand Down
52 changes: 26 additions & 26 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -491,10 +491,10 @@ jobs:
displayName: Test Python Wheels
strategy:
matrix:
Python312:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I presume we're not running all versions here as a cost-saving measure. Under that presumption it would make sense to run the oldest and newest versions of Python that are supported, no?

python.version: '3.12'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
dependsOn: BuildPythonWheel
condition: succeeded()
pool:
Expand Down Expand Up @@ -531,10 +531,10 @@ jobs:
name: ${{ variables.ubuntu_pool }}
strategy:
matrix:
Python312:
python.version: '3.12'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
steps:
- template: .azure-pipelines/templates/automation_test.yml
parameters:
Expand All @@ -548,10 +548,10 @@ jobs:
name: ${{ variables.ubuntu_pool }}
strategy:
matrix:
Python310:
python.version: '3.10'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
steps:
- task: UsePythonVersion@0
inputs:
Expand All @@ -570,10 +570,10 @@ jobs:
name: ${{ variables.ubuntu_pool }}
strategy:
matrix:
Python312:
python.version: '3.12'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
steps:
- template: .azure-pipelines/templates/automation_test.yml
parameters:
Expand All @@ -590,10 +590,10 @@ jobs:
name: ${{ variables.ubuntu_pool }}
strategy:
matrix:
Python312:
python.version: '3.12'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python $(python.version)'
Expand All @@ -613,8 +613,8 @@ jobs:
name: ${{ variables.ubuntu_pool }}
strategy:
matrix:
Python314:
python.version: '3.14'
Python315:
python.version: '3.15'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python $(python.version)'
Expand Down Expand Up @@ -1058,10 +1058,10 @@ jobs:
displayName: "PerformanceCheck"
strategy:
matrix:
Python312:
python.version: '3.12'
Python314:
python.version: '3.14'
Python311:
python.version: '3.11'
Python315:
python.version: '3.15'
pool:
name: ${{ variables.ubuntu_pool }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion doc/command_guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ Follow the [Error Handling Guidelines](https://github.com/Azure/azure-cli/blob/d

## Coding Practices

- All code must support Python 3.10 ~ 3.14
- All code must support Python 3.11 ~ 3.15
- PRs to Azure/azure-cli and Azure/azure-cli-extensions must pass CI
- Code must pass style checks with pylint and pep8
- (*) All commands should have tests
2 changes: 1 addition & 1 deletion doc/debug/debug_in_vs_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

* Visual Studio Code [Link](http://code.visualstudio.com/)
* Visual Studio Code Python Extension [Link](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
* Python 3.10+
* Python 3.11+
* Set up development environment [Link](https://github.com/Azure/azure-cli/blob/master/doc/configuring_your_machine.md)

## Quick start
Expand Down
2 changes: 1 addition & 1 deletion doc/extensions/authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ See [Extension Metadata](metadata.md) for more information.

### Test your extension on Python 3

- The Azure CLI supports Python 3.10 ~ 3.14 so verify that your extension does the same.
- The Azure CLI supports Python 3.11 ~ 3.15 so verify that your extension does the same.
- You can create virtual environments for different versions and run your extension in them.
- e.g. `python3.14 -m venv env314`.

Expand Down
2 changes: 1 addition & 1 deletion doc/install_linux_prerequisites.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Some native Linux packages are required when installing the CLI with:
- Interactive installation script
- `pip`

Current supported Python versions are Python 3.10 ~ 3.14.
Current supported Python versions are Python 3.11 ~ 3.15.

The commands to run to install the dependencies for some common distributions are listed below.

Expand Down
5 changes: 4 additions & 1 deletion scripts/ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ CLASSIFIERS = [
'Intended Audience :: Developers',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3.15',
'License :: OSI Approved :: MIT License',
]

Expand All @@ -125,6 +127,7 @@ setup(
name='azure-cli-fulltest',
version=VERSION,
description='Microsoft Azure Command-Line Tools Full Tests',
python_requires='>=3.11.0',
license='MIT',
author='Microsoft Corporation',
author_email='azpycli@microsoft.com',
Expand Down
4 changes: 2 additions & 2 deletions scripts/ci/codegen_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import datetime
import datetime as dt
import json
import logging
import os
Expand Down Expand Up @@ -111,7 +111,7 @@ def generate_csv():
total = ref['total']
manual = total - codegenv1 - codegenv2
is_release = True if BUILD_BRANCH == 'release' else False
date = (datetime.datetime.utcnow() + datetime.timedelta(hours=8)).strftime("%Y-%m-%d")
date = (dt.datetime.now(dt.UTC) + dt.timedelta(hours=8)).strftime("%Y-%m-%d")
data.append([BUILD_ID, manual, codegenv1, codegenv2, total, is_release, date])
logger.info('Finish generate data for codegen report:')
logger.info("BUILD_ID, manual, codegenv1, codegenv2, total, is_release, date")
Expand Down
2 changes: 1 addition & 1 deletion scripts/release/debian/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ RUN apt-get update
RUN apt-get install -y libssl-dev libffi-dev python3-dev debhelper zlib1g-dev wget

# Download Python source code
ARG python_version="3.10.10"
ARG python_version="3.11.17"
ENV PYTHON_SRC_DIR=/usr/src/python
RUN mkdir -p ${PYTHON_SRC_DIR} && \
wget -qO- https://www.python.org/ftp/python/${python_version}/Python-${python_version}.tgz \
Expand Down
20 changes: 10 additions & 10 deletions src/azure-cli-core/azure/cli/core/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# pylint: disable=too-many-lines

import argparse
import datetime
import datetime as dt
import json
import logging as logs
import os
Expand Down Expand Up @@ -218,7 +218,7 @@ def save(self, args, kwargs):
"Caching %s '%s' as: %s", self._model_name, self._resource_name,
os.path.join(directory, filename)
)
self.last_saved = str(datetime.datetime.now())
self.last_saved = str(dt.datetime.now())
self._dump_to_file(f)

def result(self):
Expand Down Expand Up @@ -396,9 +396,9 @@ def _is_stale(cli_ctx, cache_obj):
cache_ttl = DEFAULT_CACHE_TTL
else:
raise ex
time_now = datetime.datetime.now()
time_cache = datetime.datetime.strptime(cache_obj.last_saved, '%Y-%m-%d %H:%M:%S.%f')
return time_now - time_cache > datetime.timedelta(minutes=int(cache_ttl))
time_now = dt.datetime.now()
time_cache = dt.datetime.strptime(cache_obj.last_saved, '%Y-%m-%d %H:%M:%S.%f')
return time_now - time_cache > dt.timedelta(minutes=int(cache_ttl))


def cached_get(cmd_obj, operation, *args, **kwargs):
Expand Down Expand Up @@ -1032,7 +1032,7 @@ def __init__(self, cli_ctx, start_msg='', finish_msg='', poller_done_interval_ms
self.finish_msg = finish_msg
self.poller_done_interval_ms = poller_done_interval_ms
self.deploy_dict = {}
self.last_progress_report = datetime.datetime.now()
self.last_progress_report = dt.datetime.now()

self._progress_bar = None
disable_progress_bar = self.cli_ctx.config.getboolean('core', 'disable_progress_bar', False)
Expand Down Expand Up @@ -1060,8 +1060,8 @@ def _generate_template_progress(self, correlation_id): # pylint: disable=no-sel
if correlation_id is not None: # pylint: disable=too-many-nested-blocks
formatter = "eventTimestamp ge {}"

end_time = datetime.datetime.utcnow()
start_time = end_time - datetime.timedelta(seconds=DEFAULT_QUERY_TIME_RANGE)
end_time = dt.datetime.now(dt.UTC)
start_time = end_time - dt.timedelta(seconds=DEFAULT_QUERY_TIME_RANGE)
odata_filters = formatter.format(start_time.strftime('%Y-%m-%dT%H:%M:%SZ'))

odata_filters = "{} and {} eq '{}'".format(odata_filters, 'correlationId', correlation_id)
Expand Down Expand Up @@ -1141,8 +1141,8 @@ def __call__(self, poller): # pylint: disable=too-many-statements
except: # pylint: disable=bare-except
pass

current_time = datetime.datetime.now()
if is_verbose and current_time - self.last_progress_report >= datetime.timedelta(seconds=10):
current_time = dt.datetime.now()
if is_verbose and current_time - self.last_progress_report >= dt.timedelta(seconds=10):
self.last_progress_report = current_time
try:
self._generate_template_progress(correlation_id)
Expand Down
13 changes: 7 additions & 6 deletions src/azure-cli-core/azure/cli/core/intercept_survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import os
import sys
import json
from datetime import datetime, timedelta
import datetime as dt
from azure.cli.core._config import GLOBAL_CONFIG_DIR
from azure.cli.core._profile import Profile
from azure.cli.core.style import print_styled_text
Expand Down Expand Up @@ -56,7 +56,7 @@ def should_prompt(cli):
# using their installationId
installation_id = Profile(cli_ctx=cli).get_installation_id()
prompt_period = EXPERIENCE_PERIOD_IN_DAYS + (uuid.UUID(installation_id).int & 127)
next_prompt_time = datetime.utcnow() + timedelta(days=prompt_period)
next_prompt_time = dt.datetime.now(dt.UTC) + dt.timedelta(days=prompt_period)
survey_note = {
'last_prompt_time': '',
'next_prompt_time': next_prompt_time.strftime('%Y-%m-%dT%H:%M:%S')
Expand All @@ -67,8 +67,9 @@ def should_prompt(cli):

with open(GLOBAL_SURVEY_NOTE_PATH, 'r', encoding='utf-8-sig') as f:
survey_note = json.load(f)
next_prompt_time = datetime.strptime(survey_note['next_prompt_time'], '%Y-%m-%dT%H:%M:%S')
if datetime.utcnow() < next_prompt_time:
next_prompt_time = dt.datetime.strptime(
survey_note['next_prompt_time'], '%Y-%m-%dT%H:%M:%S').replace(tzinfo=dt.UTC)
if dt.datetime.now(dt.UTC) < next_prompt_time:
return False

return True
Expand All @@ -92,9 +93,9 @@ def prompt_survey_message(cli):
telemetry.set_survey_info(show_survey_message=True)

# log prompt time
next_prompt_time = datetime.utcnow() + timedelta(days=PROMPT_INTERVAL_IN_DAYS)
next_prompt_time = dt.datetime.now(dt.UTC) + dt.timedelta(days=PROMPT_INTERVAL_IN_DAYS)
survey_note = {
'last_prompt_time': datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S'),
'last_prompt_time': dt.datetime.now(dt.UTC).strftime('%Y-%m-%dT%H:%M:%S'),
'next_prompt_time': next_prompt_time.strftime('%Y-%m-%dT%H:%M:%S')
}
with open(GLOBAL_SURVEY_NOTE_PATH, 'w') as f:
Expand Down
Loading
Loading