Skip to content

Commit c9ef719

Browse files
Python: fix mypy pre-commit setup, mypy fixes (microsoft#9498)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> Fixes the mypy pre-commit job, and subsequent fixes from there. Moved all python tests to use the uv setup task instead of manual cache, python install and uv install. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄
1 parent 801436c commit c9ef719

File tree

75 files changed

+593
-494
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+593
-494
lines changed

.github/workflows/merge-gatekeeper.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ jobs:
2929
token: ${{ secrets.GITHUB_TOKEN }}
3030
timeout: 3600
3131
interval: 30
32-
ignored: "python-tests-coverage"
32+
ignored: python-tests-coverage

.github/workflows/python-build.yml

+7-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ jobs:
1111
runs-on: ubuntu-latest
1212
permissions:
1313
contents: write
14+
env:
15+
UV_PYTHON: "3.10"
1416
steps:
1517
- uses: actions/checkout@v4
16-
- uses: actions/setup-python@v5
17-
with:
18-
python-version: "3.10"
1918
- name: Set up uv
20-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
19+
uses: astral-sh/setup-uv@v3
20+
with:
21+
version: "0.4.30"
22+
enable-cache: true
23+
cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
2124
- name: Check version
2225
run: |
2326
echo "Building and uploading Python package version: ${{ github.event.release.tag_name }}"

.github/workflows/python-integration-tests.yml

+9-31
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,11 @@ jobs:
102102
steps:
103103
- uses: actions/checkout@v4
104104
- name: Set up uv
105-
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' }}
106-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
107-
- name: Set up uv
108-
if: ${{ matrix.os == 'windows-latest' }}
109-
run: irm https://astral.sh/uv/install.ps1 | iex
110-
shell: powershell
111-
- name: Set up Python ${{ matrix.python-version }}
112-
uses: actions/setup-python@v5
113-
with:
114-
python-version: ${{ matrix.python-version }}
115-
- name: Restore uv cache
116-
id: cache
117-
uses: actions/cache@v4
105+
uses: astral-sh/setup-uv@v3
118106
with:
119-
path: ${{ env.UV_CACHE_DIR }}
120-
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/uv.lock') }}
107+
version: "0.4.30"
108+
enable-cache: true
109+
cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
121110
- name: Install dependencies with hnswlib native disabled
122111
if: matrix.os == 'macos-latest' && matrix.python-version == '3.11'
123112
run: |
@@ -267,22 +256,11 @@ jobs:
267256
steps:
268257
- uses: actions/checkout@v4
269258
- name: Set up uv
270-
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' }}
271-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
272-
- name: Set up uv
273-
if: ${{ matrix.os == 'windows-latest' }}
274-
run: irm https://astral.sh/uv/install.ps1 | iex
275-
shell: powershell
276-
- name: Set up Python ${{ matrix.python-version }}
277-
uses: actions/setup-python@v5
259+
uses: astral-sh/setup-uv@v3
278260
with:
279-
python-version: ${{ matrix.python-version }}
280-
- name: Restore uv cache
281-
id: cache
282-
uses: actions/cache@v4
283-
with:
284-
path: ${{ env.UV_CACHE_DIR }}
285-
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/uv.lock') }}
261+
version: "0.4.30"
262+
enable-cache: true
263+
cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
286264
- name: Install dependencies with hnswlib native disabled
287265
if: matrix.os == 'macos-latest' && matrix.python-version == '3.11'
288266
run: |
@@ -438,4 +416,4 @@ jobs:
438416
dry_run: ${{ env.run_type != 'Daily' && env.run_type != 'Manual'}}
439417
job: ${{ toJson(job) }}
440418
steps: ${{ toJson(steps) }}
441-
overwrite: "{title: ` ${{ env.run_type }}: ${{ env.date }} `, text: ` ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`}"
419+
overwrite: "{title: ` ${{ env.run_type }}: ${{ env.date }} `, text: ` ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`}"

.github/workflows/python-lint.yml

+6-10
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,19 @@ jobs:
2121
env:
2222
# Configure a constant location for the uv cache
2323
UV_CACHE_DIR: /tmp/.uv-cache
24+
UV_PYTHON: ${{ matrix.python-version }}
2425
steps:
2526
- uses: actions/checkout@v4
2627
- name: Set up uv
27-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
28-
- name: Set up Python ${{ matrix.python-version }}
29-
uses: actions/setup-python@v5
28+
uses: astral-sh/setup-uv@v3
3029
with:
31-
python-version: ${{ matrix.python-version }}
32-
- name: Restore uv cache
33-
uses: actions/cache@v4
34-
with:
35-
path: ${{ env.UV_CACHE_DIR }}
36-
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/uv.lock') }}
30+
version: "0.4.30"
31+
enable-cache: true
32+
cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
3733
- name: Install the project
3834
run: uv sync --all-extras --dev
3935
- uses: pre-commit/[email protected]
4036
with:
41-
extra_args: --config python/.pre-commit-config.yaml
37+
extra_args: --config python/.pre-commit-config.yaml --all-files
4238
- name: Minimize uv cache
4339
run: uv cache prune --ci

.github/workflows/python-unit-tests.yml

+28-32
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,20 @@ jobs:
2020
python-version: ["3.10", "3.11", "3.12"]
2121
os: [ubuntu-latest, windows-latest, macos-latest]
2222
experimental: [false]
23-
include:
24-
- python-version: "3.13.0-beta.4"
25-
os: "ubuntu-latest"
26-
experimental: true
23+
# include:
24+
# - python-version: "3.13"
25+
# os: "ubuntu-latest"
26+
# experimental: true
27+
# - python-version: "3.13t"
28+
# os: "ubuntu-latest"
29+
# experimental: true
30+
# gil: 0
31+
# - python-version: "3.13t"
32+
# os: "ubuntu-latest"
33+
# experimental: true
34+
# gil: 1
35+
env:
36+
UV_PYTHON: ${{ matrix.python-version }}
2737
permissions:
2838
contents: write
2939
defaults:
@@ -32,28 +42,19 @@ jobs:
3242
steps:
3343
- uses: actions/checkout@v4
3444
- name: Set up uv
35-
if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' }}
36-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
37-
- name: Set up uv
38-
if: ${{ matrix.os == 'windows-latest' }}
39-
run: irm https://astral.sh/uv/install.ps1 | iex
40-
shell: powershell
41-
- name: Set up Python ${{ matrix.python-version }}
42-
uses: actions/setup-python@v5
43-
with:
44-
python-version: ${{ matrix.python-version }}
45-
- name: Restore uv cache
46-
id: cache
47-
uses: actions/cache@v4
45+
uses: astral-sh/setup-uv@v3
4846
with:
49-
path: ${{ env.UV_CACHE_DIR }}
50-
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/uv.lock') }}
47+
version: "0.4.30"
48+
enable-cache: true
49+
cache-suffix: ${{ runner.os }}-${{ matrix.python-version }}
5150
- name: Install the project
5251
run: uv sync --all-extras --dev
5352
- name: Test with pytest
54-
run: uv run pytest --junitxml=pytest.xml ./tests/unit
53+
env:
54+
PYTHON_GIL: ${{ matrix.gil }}
55+
run: uv run --frozen pytest --junitxml=pytest.xml ./tests/unit
5556
- name: Surface failing tests
56-
if: always()
57+
if: ${{ !matrix.experimental }}
5758
uses: pmeier/pytest-results-action@main
5859
with:
5960
path: python/pytest.xml
@@ -73,26 +74,21 @@ jobs:
7374
run:
7475
working-directory: python
7576
env:
76-
PYTHON_VERSION: "3.10"
77+
UV_PYTHON: "3.10"
7778
steps:
7879
- uses: actions/checkout@v4
7980
- name: Setup filename variables
8081
run: echo "FILE_ID=${{ github.event.number }}" >> $GITHUB_ENV
8182
- name: Set up uv
82-
run: curl -LsSf https://astral.sh/uv/install.sh | sh
83-
- name: Set up Python ${{ env.PYTHON_VERSION }}
84-
uses: actions/setup-python@v5
85-
with:
86-
python-version: ${{ env.PYTHON_VERSION }}
87-
- name: Restore uv cache
88-
uses: actions/cache@v4
83+
uses: astral-sh/setup-uv@v3
8984
with:
90-
path: ${{ env.UV_CACHE_DIR }}
91-
key: uv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/uv.lock') }}
85+
version: "0.4.30"
86+
enable-cache: true
87+
cache-suffix: ${{ runner.os }}-${{ env.UV_PYTHON }}
9288
- name: Install the project
9389
run: uv sync --all-extras --dev
9490
- name: Test with pytest
95-
run: uv run pytest -q --junitxml=pytest.xml --cov=semantic_kernel --cov-report=term-missing:skip-covered ./tests/unit | tee python-coverage.txt
91+
run: uv run --frozen pytest -q --junitxml=pytest.xml --cov=semantic_kernel --cov-report=term-missing:skip-covered ./tests/unit | tee python-coverage.txt
9692
- name: Upload coverage
9793
if: always()
9894
uses: actions/upload-artifact@v4

python/.pre-commit-config.yaml

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,30 @@ repos:
3232
- id: pyupgrade
3333
args: [--py310-plus]
3434
- repo: https://github.com/astral-sh/ruff-pre-commit
35-
rev: v0.6.1
35+
rev: v0.7.1
3636
hooks:
3737
- id: ruff
3838
args: [ --fix, --exit-non-zero-on-fix ]
3939
- id: ruff-format
4040
- repo: https://github.com/astral-sh/uv-pre-commit
4141
# uv version.
42-
rev: 0.3.3
42+
rev: 0.4.29
4343
hooks:
4444
# Update the uv lockfile
4545
- id: uv-lock
46-
files: ^\./python/(uv\.lock|pyproject\.toml)$
4746
- repo: local
4847
hooks:
4948
- id: mypy
5049
files: ^python/semantic_kernel/
5150
name: mypy
52-
entry: cd python && uv run mypy -p semantic_kernel --config-file mypy.ini
51+
entry: bash -c 'cd python && uv run mypy -p semantic_kernel --config-file mypy.ini'
5352
language: system
5453
types: [python]
55-
pass_filenames: false
54+
pass_filenames: true
5655
- repo: https://github.com/PyCQA/bandit
5756
rev: 1.7.8
5857
hooks:
5958
- id: bandit
6059
args: ["-c", "python/pyproject.toml"]
61-
additional_dependencies: [ "bandit[toml]" ]
60+
additional_dependencies: [ "bandit[toml]" ]
61+

python/mypy.ini

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ warn_untyped_fields = true
1212
[mypy-semantic_kernel]
1313
no_implicit_reexport = true
1414

15+
[mypy-semantic_kernel.data.*]
16+
disable_error_code = method-assign
17+
1518
[mypy-semantic_kernel.memory.*]
1619
ignore_errors = true
1720
# TODO (eavanvalkenburg): remove this

python/pyproject.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors = [{ name = "Microsoft", email = "[email protected]"}]
55
readme = "pip/README.md"
66
# Version read from __version__ field in __init__.py by Flit
77
dynamic = ["version"]
8-
requires-python = ">=3.10,<3.13"
8+
requires-python = ">=3.10"
99
license = {file = "LICENSE"}
1010
urls.homepage = "https://learn.microsoft.com/en-us/semantic-kernel/overview/"
1111
urls.source = "https://github.com/microsoft/semantic-kernel/tree/main/python"
@@ -50,7 +50,7 @@ dependencies = [
5050
### Optional dependencies
5151
[project.optional-dependencies]
5252
azure = [
53-
"azure-ai-inference >= 1.0.0b3",
53+
"azure-ai-inference >= 1.0.0b4",
5454
"azure-search-documents >= 11.6.0b4",
5555
"azure-identity ~= 1.13",
5656
"azure-cosmos ~= 4.7"
@@ -141,6 +141,9 @@ environments = [
141141
[tool.pytest.ini_options]
142142
addopts = "-ra -q -r fEX"
143143
asyncio_default_fixture_loop_scope = "function"
144+
filterwarnings = [
145+
'ignore:.*FunctionChoiceBehavior.*:DeprecationWarning'
146+
]
144147

145148
[tool.ruff]
146149
line-length = 120

python/samples/concepts/auto_function_calling/nexus_raven.py

+16-20
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,17 @@ async def get_chat_message_contents(
108108
try:
109109
function_call, function_result = await self._execute_function_calls(part, chat_history, **kwargs)
110110
if function_call:
111-
messages.extend(
112-
[
113-
ChatMessageContent(
114-
role="assistant", items=[function_call], metadata={"ai_model_id": self.ai_model_id}
115-
),
116-
ChatMessageContent(
117-
role="tool",
118-
items=[function_result],
119-
name="nexus",
120-
metadata={"ai_model_id": self.ai_model_id},
121-
),
122-
]
123-
)
111+
messages.extend([
112+
ChatMessageContent(
113+
role="assistant", items=[function_call], metadata={"ai_model_id": self.ai_model_id}
114+
),
115+
ChatMessageContent(
116+
role="tool",
117+
items=[function_result],
118+
name="nexus",
119+
metadata={"ai_model_id": self.ai_model_id},
120+
),
121+
])
124122
else:
125123
messages.append(ChatMessageContent(role="assistant", content=part, ai_model_id=self.ai_model_id))
126124
except Exception as e:
@@ -175,13 +173,11 @@ async def _execute_function_calls(
175173
}
176174
call_stack[current_idx] = call
177175
while any(call["result"] is None for call in call_stack.values()):
178-
await asyncio.gather(
179-
*[
180-
self._execute_function_call(call, chat_history, kwargs.get("kernel"))
181-
for call in call_stack.values()
182-
if not any(isinstance(arg, tuple) for arg in call["args"].values()) and call["result"] is None
183-
]
184-
)
176+
await asyncio.gather(*[
177+
self._execute_function_call(call, chat_history, kwargs.get("kernel"))
178+
for call in call_stack.values()
179+
if not any(isinstance(arg, tuple) for arg in call["args"].values()) and call["result"] is None
180+
])
185181
for call in call_stack.values():
186182
if call["result"] is None:
187183
for name, arg in call["args"].items():

python/samples/concepts/filtering/function_invocation_filters.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ async def input_output_filter(
4040
await next(context)
4141

4242
if context.result:
43-
logger.info(f'Usage: {context.result.metadata.get("usage")}')
43+
logger.info(f"Usage: {context.result.metadata.get('usage')}")
4444
context.arguments["chat_history"].add_message(context.result.value[0])
4545
print(f"Mosscap:> {context.result!s}")
4646

0 commit comments

Comments
 (0)