From 1c19c30e07576c3a86a9bc5fb66c20efd8bd19d8 Mon Sep 17 00:00:00 2001 From: "positron-bot[bot]" <173392469+positron-bot[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:03:42 -0500 Subject: [PATCH 1/6] vscode-python changes from v2025.12.0 to v2025.14.0 --- .../.github/workflows/build.yml | 20 ++++----- .../.github/workflows/codeql-analysis.yml | 2 +- .../.github/workflows/gen-issue-velocity.yml | 2 +- .../.github/workflows/info-needed-closer.yml | 2 +- .../.github/workflows/issue-labels.yml | 2 +- .../.github/workflows/pr-check.yml | 30 ++++++------- .../workflows/test-plan-item-validator.yml | 2 +- .../.github/workflows/triage-info-needed.yml | 4 +- .../build/azure-pipeline.pre-release.yml | 2 +- .../build/azure-pipeline.stable.yml | 4 +- .../build/azure-pipelines/pipeline.yml | 6 +-- extensions/positron-python/package-lock.json | 32 +++----------- extensions/positron-python/package.json | 13 +++--- .../pythonExtensionApi/package-lock.json | 2 +- .../pythonExtensionApi/package.json | 4 +- .../tests/unittestadapter/test_utils.py | 5 +-- .../unittestadapter/pvsc_utils.py | 10 +++-- .../src/client/common/platform/fs-temp.ts | 24 ++++------- .../src/client/common/process/logger.ts | 7 +++ .../condaActivationProvider.ts | 26 +++++++++-- .../src/client/envExt/api.legacy.ts | 4 +- .../environmentManagers/condaService.ts | 5 +++ .../codeExecution/codeExecutionManager.ts | 24 +++++------ .../test/common/platform/fs-temp.unit.test.ts | 17 +++++--- .../test/common/process/logger.unit.test.ts | 43 ++++++++++++++----- 25 files changed, 161 insertions(+), 131 deletions(-) diff --git a/extensions/positron-python/.github/workflows/build.yml b/extensions/positron-python/.github/workflows/build.yml index ca75f6ef7727..6d122b77288b 100644 --- a/extensions/positron-python/.github/workflows/build.yml +++ b/extensions/positron-python/.github/workflows/build.yml @@ -11,7 +11,7 @@ on: permissions: {} env: - NODE_VERSION: 20.18.1 + NODE_VERSION: 22.17.0 PYTHON_VERSION: '3.10' # YML treats 3.10 the number as 3.1, so quotes around 3.10 # Force a path with spaces and to test extension works in these scenarios # Unicode characters are causing 2.7 failures so skip that for now. @@ -84,12 +84,12 @@ jobs: # vsix-target: alpine-arm64 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: 'python-env-tools' @@ -115,7 +115,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -135,7 +135,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -178,7 +178,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: ${{ env.special-working-directory-relative }} persist-credentials: false @@ -218,13 +218,13 @@ jobs: test-suite: [ts-unit, venv, single-workspace, multi-workspace, debugger, functional] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: ${{ env.special-working-directory-relative }} persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: ${{ env.special-working-directory-relative }}/python-env-tools @@ -426,12 +426,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: ${{ env.special-working-directory-relative }}/python-env-tools diff --git a/extensions/positron-python/.github/workflows/codeql-analysis.yml b/extensions/positron-python/.github/workflows/codeql-analysis.yml index cfd7c393e3ed..84de97c4dc9a 100644 --- a/extensions/positron-python/.github/workflows/codeql-analysis.yml +++ b/extensions/positron-python/.github/workflows/codeql-analysis.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false diff --git a/extensions/positron-python/.github/workflows/gen-issue-velocity.yml b/extensions/positron-python/.github/workflows/gen-issue-velocity.yml index 344fa161f02e..c28c6c368562 100644 --- a/extensions/positron-python/.github/workflows/gen-issue-velocity.yml +++ b/extensions/positron-python/.github/workflows/gen-issue-velocity.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false diff --git a/extensions/positron-python/.github/workflows/info-needed-closer.yml b/extensions/positron-python/.github/workflows/info-needed-closer.yml index d7efbd199451..33f53fc20dca 100644 --- a/extensions/positron-python/.github/workflows/info-needed-closer.yml +++ b/extensions/positron-python/.github/workflows/info-needed-closer.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/vscode-github-triage-actions' path: ./actions diff --git a/extensions/positron-python/.github/workflows/issue-labels.yml b/extensions/positron-python/.github/workflows/issue-labels.yml index ec7d14d96cda..a78ca03d5ee9 100644 --- a/extensions/positron-python/.github/workflows/issue-labels.yml +++ b/extensions/positron-python/.github/workflows/issue-labels.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/vscode-github-triage-actions' ref: stable diff --git a/extensions/positron-python/.github/workflows/pr-check.yml b/extensions/positron-python/.github/workflows/pr-check.yml index aee69794fa41..b410c37215b9 100644 --- a/extensions/positron-python/.github/workflows/pr-check.yml +++ b/extensions/positron-python/.github/workflows/pr-check.yml @@ -10,7 +10,7 @@ on: permissions: {} env: - NODE_VERSION: 20.18.1 + NODE_VERSION: 22.17.0 PYTHON_VERSION: '3.10' # YML treats 3.10 the number as 3.1, so quotes around 3.10 MOCHA_REPORTER_JUNIT: true # Use the mocha-multi-reporters and send output to both console (spec) and JUnit (mocha-junit-reporter). Also enables a reporter which exits the process running the tests if it haven't already. ARTIFACT_NAME_VSIX: ms-python-insiders-vsix @@ -57,12 +57,12 @@ jobs: # vsix-target: alpine-arm64 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: 'python-env-tools' @@ -87,7 +87,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false @@ -106,12 +106,12 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: 'python-env-tools' @@ -162,7 +162,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: ${{ env.special-working-directory-relative }} persist-credentials: false @@ -215,13 +215,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: ${{ env.special-working-directory-relative }} persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: ${{ env.special-working-directory-relative }}/python-env-tools @@ -412,13 +412,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: ${{ env.special-working-directory-relative }} persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: ${{ env.special-working-directory-relative }}/python-env-tools @@ -452,12 +452,12 @@ jobs: steps: # Need the source to have the tests available. - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: python-env-tools @@ -488,12 +488,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false - name: Checkout Python Environment Tools - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/python-environment-tools' path: python-env-tools diff --git a/extensions/positron-python/.github/workflows/test-plan-item-validator.yml b/extensions/positron-python/.github/workflows/test-plan-item-validator.yml index 91e8948cc784..6e62058b04c6 100644 --- a/extensions/positron-python/.github/workflows/test-plan-item-validator.yml +++ b/extensions/positron-python/.github/workflows/test-plan-item-validator.yml @@ -12,7 +12,7 @@ jobs: if: contains(github.event.issue.labels.*.name, 'testplan-item') || contains(github.event.issue.labels.*.name, 'invalid-testplan-item') steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/vscode-github-triage-actions' path: ./actions diff --git a/extensions/positron-python/.github/workflows/triage-info-needed.yml b/extensions/positron-python/.github/workflows/triage-info-needed.yml index f468fb293acd..f61d17c033d7 100644 --- a/extensions/positron-python/.github/workflows/triage-info-needed.yml +++ b/extensions/positron-python/.github/workflows/triage-info-needed.yml @@ -15,7 +15,7 @@ jobs: issues: write steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/vscode-github-triage-actions' ref: stable @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: 'microsoft/vscode-github-triage-actions' ref: stable diff --git a/extensions/positron-python/build/azure-pipeline.pre-release.yml b/extensions/positron-python/build/azure-pipeline.pre-release.yml index ab087673f1e7..e7159618d3ae 100644 --- a/extensions/positron-python/build/azure-pipeline.pre-release.yml +++ b/extensions/positron-python/build/azure-pipeline.pre-release.yml @@ -66,7 +66,7 @@ extends: buildSteps: - task: NodeTool@0 inputs: - versionSpec: '20.18.1' + versionSpec: '22.17.0' displayName: Select Node version - task: UsePythonVersion@0 diff --git a/extensions/positron-python/build/azure-pipeline.stable.yml b/extensions/positron-python/build/azure-pipeline.stable.yml index c68dacc7db80..71399281efd9 100644 --- a/extensions/positron-python/build/azure-pipeline.stable.yml +++ b/extensions/positron-python/build/azure-pipeline.stable.yml @@ -60,7 +60,7 @@ extends: buildSteps: - task: NodeTool@0 inputs: - versionSpec: '20.18.1' + versionSpec: '22.17.0' displayName: Select Node version - task: UsePythonVersion@0 @@ -128,7 +128,7 @@ extends: project: 'Monaco' definition: 593 buildVersionToDownload: 'latestFromBranch' - branchName: 'refs/heads/release/2025.12' + branchName: 'refs/heads/release/2025.14' targetPath: '$(Build.SourcesDirectory)/python-env-tools/bin' artifactName: 'bin-$(buildTarget)' itemPattern: | diff --git a/extensions/positron-python/build/azure-pipelines/pipeline.yml b/extensions/positron-python/build/azure-pipelines/pipeline.yml index ebb8a141d9d3..46302aa6ff90 100644 --- a/extensions/positron-python/build/azure-pipelines/pipeline.yml +++ b/extensions/positron-python/build/azure-pipelines/pipeline.yml @@ -37,13 +37,13 @@ extends: testPlatforms: - name: Linux nodeVersions: - - 20.18.1 + - 22.17.0 - name: MacOS nodeVersions: - - 20.18.1 + - 22.17.0 - name: Windows nodeVersions: - - 20.18.1 + - 22.17.0 testSteps: - template: /build/azure-pipelines/templates/test-steps.yml@self parameters: diff --git a/extensions/positron-python/package-lock.json b/extensions/positron-python/package-lock.json index 64fde7c529da..b041a4ea5a21 100644 --- a/extensions/positron-python/package-lock.json +++ b/extensions/positron-python/package-lock.json @@ -30,7 +30,7 @@ "semver": "^7.5.2", "stack-trace": "0.0.10", "sudo-prompt": "^9.2.1", - "tmp": "^0.0.33", + "tmp": "^0.2.5", "uint64be": "^3.0.0", "unicode": "^14.0.0", "vscode-debugprotocol": "^1.28.0", @@ -2254,16 +2254,6 @@ "node": "*" } }, - "node_modules/@vscode/vsce/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -11703,15 +11693,6 @@ "dev": true, "license": "MIT" }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -14598,15 +14579,12 @@ } }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/to-absolute-glob": { diff --git a/extensions/positron-python/package.json b/extensions/positron-python/package.json index ae3c23ab9cae..e2fa433ca13c 100644 --- a/extensions/positron-python/package.json +++ b/extensions/positron-python/package.json @@ -95,7 +95,8 @@ "onLanguageModelTool:get_python_executable_details", "onLanguageModelTool:install_python_packages", "onLanguageModelTool:configure_python_environment", - "onLanguageModelTool:create_virtual_environment" + "onLanguageModelTool:create_virtual_environment", + "onTerminalShellIntegration:python" ], "main": "./out/client/extension", "browser": "./dist/extension.browser.js", @@ -874,7 +875,7 @@ "type": "array" }, "python.terminal.shellIntegration.enabled": { - "default": false, + "default": true, "markdownDescription": "%python.terminal.shellIntegration.enabled.description%", "scope": "resource", "type": "boolean", @@ -1958,7 +1959,7 @@ "displayName": "Get Python Environment Info", "when": "false", "userDescription": "%python.languageModelTools.get_python_environment_details.userDescription%", - "modelDescription": "This tool will retrieve the details of the Python Environment for the specified file or workspace. The details returned include the 1. Type of Environment (conda, venv, etec), 2. Version of Python, 3. List of all installed packages with their versions. ALWAYS call configure_python_environment before using this tool.", + "modelDescription": "This tool will retrieve the details of the Python Environment for the specified file or workspace. The details returned include the 1. Type of Python Environment (conda, venv, etec), 2. Version of Python, 3. List of all installed Python packages with their versions. ALWAYS call configure_python_environment before using this tool.", "toolReferenceName": "getPythonEnvironmentInfo", "tags": [ "python", @@ -2010,7 +2011,7 @@ "displayName": "Install Python Package", "when": "false", "userDescription": "%python.languageModelTools.install_python_packages.userDescription%", - "modelDescription": "Installs Python packages in the given workspace. Use this tool to install packages in the user's chosen environment. ALWAYS call configure_python_environment before using this tool.", + "modelDescription": "Installs Python packages in the given workspace. Use this tool to install Python packages in the user's chosen Python environment. ALWAYS call configure_python_environment before using this tool.", "toolReferenceName": "installPythonPackage", "tags": [ "python", @@ -2029,7 +2030,7 @@ "items": { "type": "string" }, - "description": "The list of packages to install." + "description": "The list of Python packages to install." }, "resourcePath": { "type": "string", @@ -2177,7 +2178,7 @@ "semver": "^7.5.2", "stack-trace": "0.0.10", "sudo-prompt": "^9.2.1", - "tmp": "^0.0.33", + "tmp": "^0.2.5", "uint64be": "^3.0.0", "unicode": "^14.0.0", "vscode-debugprotocol": "^1.28.0", diff --git a/extensions/positron-python/pythonExtensionApi/package-lock.json b/extensions/positron-python/pythonExtensionApi/package-lock.json index ec175f1aaa5d..e462fc1c888a 100644 --- a/extensions/positron-python/pythonExtensionApi/package-lock.json +++ b/extensions/positron-python/pythonExtensionApi/package-lock.json @@ -14,7 +14,7 @@ "typescript": "~5.2" }, "engines": { - "node": ">=20.18.1", + "node": ">=22.17.0", "vscode": "^1.93.0" } }, diff --git a/extensions/positron-python/pythonExtensionApi/package.json b/extensions/positron-python/pythonExtensionApi/package.json index 9a27e5a09b0a..e4e956ff6065 100644 --- a/extensions/positron-python/pythonExtensionApi/package.json +++ b/extensions/positron-python/pythonExtensionApi/package.json @@ -13,7 +13,7 @@ "main": "./out/main.js", "types": "./out/main.d.ts", "engines": { - "node": ">=20.18.1", + "node": ">=22.17.0", "vscode": "^1.93.0" }, "license": "MIT", @@ -27,7 +27,7 @@ }, "devDependencies": { "typescript": "~5.2", - "@types/vscode": "^1.93.0", + "@types/vscode": "^1.102.0", "source-map": "^0.8.0-beta.0" }, "scripts": { diff --git a/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py b/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py index b0341ce37b63..390b0779a44d 100644 --- a/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py +++ b/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py @@ -284,11 +284,10 @@ def test_build_empty_tree() -> None: start_dir = os.fsdecode(TEST_DATA_PATH) pattern = "does_not_exist*" - expected = None - loader = unittest.TestLoader() suite = loader.discover(start_dir, pattern) tests, errors = build_test_tree(suite, start_dir) - assert expected == tests + assert tests is not None + assert tests.get("children") == [] assert not errors diff --git a/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py b/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py index 017bad38966a..09a5ec9f3be5 100644 --- a/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py +++ b/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py @@ -3,6 +3,7 @@ import argparse import atexit +import doctest import enum import inspect import json @@ -202,6 +203,12 @@ def build_test_tree( root = build_test_node(top_level_directory, directory_path.name, TestNodeTypeEnum.folder) for test_case in get_test_case(suite): + if isinstance(test_case, doctest.DocTestCase): + print( + "Skipping doctest as it is not supported for the extension. Test case: ", test_case + ) + error = ["Skipping doctest as it is not supported for the extension."] + continue test_id = test_case.id() if test_id.startswith("unittest.loader._FailedTest"): error.append(str(test_case._exception)) # type: ignore # noqa: SLF001 @@ -255,9 +262,6 @@ def build_test_tree( } # concatenate class name and function test name current_node["children"].append(test_node) - if not root["children"]: - root = None - return root, error diff --git a/extensions/positron-python/src/client/common/platform/fs-temp.ts b/extensions/positron-python/src/client/common/platform/fs-temp.ts index 32b57df15387..60dde040f454 100644 --- a/extensions/positron-python/src/client/common/platform/fs-temp.ts +++ b/extensions/positron-python/src/client/common/platform/fs-temp.ts @@ -5,14 +5,7 @@ import * as tmp from 'tmp'; import { ITempFileSystem, TemporaryFile } from './types'; interface IRawTempFS { - // TODO (https://github.com/microsoft/vscode/issues/84517) - // This functionality has been requested for the - // VS Code FS API (vscode.workspace.fs.*). - file( - config: tmp.Options, - - callback?: (err: any, path: string, fd: number, cleanupCallback: () => void) => void, - ): void; + fileSync(config?: tmp.Options): tmp.SynchrounousResult; } // Operations related to temporary files and directories. @@ -35,14 +28,13 @@ export class TemporaryFileSystem implements ITempFileSystem { mode, }; return new Promise((resolve, reject) => { - this.raw.file(opts, (err, filename, _fd, cleanUp) => { - if (err) { - return reject(err); - } - resolve({ - filePath: filename, - dispose: cleanUp, - }); + const { name, removeCallback } = this.raw.fileSync(opts); + if (!name) { + return reject(new Error('Failed to create temp file')); + } + resolve({ + filePath: name, + dispose: removeCallback, }); }); } diff --git a/extensions/positron-python/src/client/common/process/logger.ts b/extensions/positron-python/src/client/common/process/logger.ts index cbc5d729aa81..4fd3602ad57f 100644 --- a/extensions/positron-python/src/client/common/process/logger.ts +++ b/extensions/positron-python/src/client/common/process/logger.ts @@ -43,6 +43,13 @@ export class ProcessLogger implements IProcessLogger { }); } + /** + * Formats command strings for display by replacing common paths with symbols. + * - Replaces the workspace folder path with '.' if there's exactly one workspace folder + * - Replaces the user's home directory path with '~' + * @param command The command string to format + * @returns The formatted command string with paths replaced by symbols + */ private getDisplayCommands(command: string): string { if (this.workspaceService.workspaceFolders && this.workspaceService.workspaceFolders.length === 1) { command = replaceMatchesWithCharacter(command, this.workspaceService.workspaceFolders[0].uri.fsPath, '.'); diff --git a/extensions/positron-python/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts b/extensions/positron-python/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts index d209550e04a4..42bb8f38fc9e 100644 --- a/extensions/positron-python/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts +++ b/extensions/positron-python/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts @@ -8,6 +8,7 @@ import '../../extensions'; import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; +import { traceInfo, traceVerbose, traceWarn } from '../../../logging'; import { IComponentAdapter, ICondaService } from '../../../interpreter/contracts'; import { IPlatformService } from '../../platform/types'; @@ -53,16 +54,21 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman pythonPath: string, targetShell: TerminalShellType, ): Promise { + traceVerbose(`Getting conda activation commands for interpreter ${pythonPath} with shell ${targetShell}`); const envInfo = await this.pyenvs.getCondaEnvironment(pythonPath); if (!envInfo) { + traceWarn(`No conda environment found for interpreter ${pythonPath}`); return undefined; } + traceVerbose(`Found conda environment: ${JSON.stringify(envInfo)}`); const condaEnv = envInfo.name.length > 0 ? envInfo.name : envInfo.path; // New version. const interpreterPath = await this.condaService.getInterpreterPathForEnvironment(envInfo); + traceInfo(`Using interpreter path: ${interpreterPath}`); const activatePath = await this.condaService.getActivationScriptFromInterpreter(interpreterPath, envInfo.name); + traceVerbose(`Got activation script: ${activatePath?.path}} with type: ${activatePath?.type}`); // eslint-disable-next-line camelcase if (activatePath?.path) { if ( @@ -70,11 +76,14 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman targetShell !== TerminalShellType.bash && targetShell !== TerminalShellType.gitbash ) { - return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`]; + const commands = [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`]; + traceInfo(`Using Windows-specific commands: ${commands.join(', ')}`); + return commands; } const condaInfo = await this.condaService.getCondaInfo(); + traceVerbose(`Conda shell level: ${condaInfo?.conda_shlvl}`); if ( activatePath.type !== 'global' || // eslint-disable-next-line camelcase @@ -84,27 +93,36 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman // activatePath is not the global activate path, or we don't have a shlvl, or it's -1(conda never sourced). // and we need to source the activate path. if (activatePath.path === 'activate') { - return [ + const commands = [ `source ${activatePath.path}`, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`, ]; + traceInfo(`Using source activate commands: ${commands.join(', ')}`); + return commands; } - return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`]; + const command = [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`]; + traceInfo(`Using single source command: ${command}`); + return command; } - return [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`]; + const command = [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`]; + traceInfo(`Using direct conda activate command: ${command}`); + return command; } switch (targetShell) { case TerminalShellType.powershell: case TerminalShellType.powershellCore: + traceVerbose('Using PowerShell-specific activation'); return _getPowershellCommands(condaEnv); // TODO: Do we really special-case fish on Windows? case TerminalShellType.fish: + traceVerbose('Using Fish shell-specific activation'); return getFishCommands(condaEnv, await this.condaService.getCondaFile()); default: if (this.platform.isWindows) { + traceVerbose('Using Windows shell-specific activation fallback option.'); return this.getWindowsCommands(condaEnv); } return getUnixCommands(condaEnv, await this.condaService.getCondaFile()); diff --git a/extensions/positron-python/src/client/envExt/api.legacy.ts b/extensions/positron-python/src/client/envExt/api.legacy.ts index 4e3631497caa..af95ed40fa22 100644 --- a/extensions/positron-python/src/client/envExt/api.legacy.ts +++ b/extensions/positron-python/src/client/envExt/api.legacy.ts @@ -86,13 +86,13 @@ function toLegacyType(env: PythonEnvironment): PythonEnvironmentLegacy { const ver = parseVersion(env.version); const envType = toEnvironmentType(env); return { - id: env.environmentPath.fsPath, + id: env.execInfo.run.executable, displayName: env.displayName, detailedDisplayName: env.name, envType, envPath: env.sysPrefix, type: getEnvType(envType), - path: env.environmentPath.fsPath, + path: env.execInfo.run.executable, version: { raw: env.version, major: ver.major, diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/condaService.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/condaService.ts index 0739993dad37..0aa91bdbfb45 100644 --- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/condaService.ts +++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/condaService.ts @@ -2,6 +2,7 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { SemVer } from 'semver'; import { IFileSystem, IPlatformService } from '../../../common/platform/types'; +import { traceVerbose } from '../../../logging'; import { cache } from '../../../common/utils/decorators'; import { ICondaService } from '../../../interpreter/contracts'; import { traceDecoratorVerbose } from '../../../logging'; @@ -23,12 +24,15 @@ export class CondaService implements ICondaService { interpreterPath?: string, envName?: string, ): Promise<{ path: string | undefined; type: 'local' | 'global' } | undefined> { + traceVerbose(`Getting activation script for interpreter ${interpreterPath}, env ${envName}`); const condaPath = await this.getCondaFileFromInterpreter(interpreterPath, envName); + traceVerbose(`Found conda path: ${condaPath}`); const activatePath = (condaPath ? path.join(path.dirname(condaPath), 'activate') : 'activate' ).fileToCommandArgumentForPythonExt(); // maybe global activate? + traceVerbose(`Using activate path: ${activatePath}`); // try to find the activate script in the global conda root prefix. if (this.platform.isLinux || this.platform.isMac) { @@ -41,6 +45,7 @@ export class CondaService implements ICondaService { .fileToCommandArgumentForPythonExt(); if (activatePath === globalActivatePath || !(await this.fileSystem.fileExists(activatePath))) { + traceVerbose(`Using global activate path: ${globalActivatePath}`); return { path: globalActivatePath, type: 'global', diff --git a/extensions/positron-python/src/client/terminals/codeExecution/codeExecutionManager.ts b/extensions/positron-python/src/client/terminals/codeExecution/codeExecutionManager.ts index 80f78a31f65b..134ea972b628 100644 --- a/extensions/positron-python/src/client/terminals/codeExecution/codeExecutionManager.ts +++ b/extensions/positron-python/src/client/terminals/codeExecution/codeExecutionManager.ts @@ -10,6 +10,7 @@ import * as vscode from 'vscode'; import * as positron from 'positron'; // --- End Positron --- +import * as path from 'path'; import { ICommandManager, IDocumentManager } from '../../common/application/types'; import { Commands } from '../../common/constants'; import '../../common/extensions'; @@ -195,6 +196,15 @@ export class CodeExecutionManager implements ICodeExecutionManager { if (!fileToExecute) { return; } + + // Check on setting terminal.executeInFileDir + const pythonSettings = this.configSettings.getSettings(file); + let cwd = pythonSettings.terminal.executeInFileDir ? path.dirname(fileToExecute.fsPath) : undefined; + + // Check on setting terminal.launchArgs + const launchArgs = pythonSettings.terminal.launchArgs; + const totalArgs = [...launchArgs, fileToExecute.fsPath.fileToCommandArgumentForPythonExt()]; + const fileAfterSave = await codeExecutionHelper.saveFileIfDirty(fileToExecute); if (fileAfterSave) { fileToExecute = fileAfterSave; @@ -203,19 +213,9 @@ export class CodeExecutionManager implements ICodeExecutionManager { const show = this.shouldTerminalFocusOnStart(fileToExecute); let terminal: Terminal | undefined; if (dedicated) { - terminal = await runInDedicatedTerminal( - fileToExecute, - [fileToExecute.fsPath.fileToCommandArgumentForPythonExt()], - undefined, - show, - ); + terminal = await runInDedicatedTerminal(fileToExecute, totalArgs, cwd, show); } else { - terminal = await runInTerminal( - fileToExecute, - [fileToExecute.fsPath.fileToCommandArgumentForPythonExt()], - undefined, - show, - ); + terminal = await runInTerminal(fileToExecute, totalArgs, cwd, show); } if (terminal) { diff --git a/extensions/positron-python/src/test/common/platform/fs-temp.unit.test.ts b/extensions/positron-python/src/test/common/platform/fs-temp.unit.test.ts index bfc8284b33d6..29b4e5f42b12 100644 --- a/extensions/positron-python/src/test/common/platform/fs-temp.unit.test.ts +++ b/extensions/positron-python/src/test/common/platform/fs-temp.unit.test.ts @@ -7,11 +7,14 @@ import { TemporaryFileSystem } from '../../../client/common/platform/fs-temp'; interface IDeps { // tmp module - file( - config: { postfix?: string; mode?: number }, - - callback?: (err: any, path: string, fd: number, cleanupCallback: () => void) => void, - ): void; + fileSync(config: { + postfix?: string; + mode?: number; + }): { + name: string; + fd: number; + removeCallback(): void; + }; } suite('FileSystem - temp files', () => { @@ -28,7 +31,7 @@ suite('FileSystem - temp files', () => { suite('createFile', () => { test(`fails if the raw call fails`, async () => { const failure = new Error('oops'); - deps.setup((d) => d.file({ postfix: '.tmp', mode: undefined }, TypeMoq.It.isAny())) + deps.setup((d) => d.fileSync({ postfix: '.tmp', mode: undefined })) // fail with an arbitrary error .throws(failure); @@ -40,7 +43,7 @@ suite('FileSystem - temp files', () => { test(`fails if the raw call "returns" an error`, async () => { const failure = new Error('oops'); - deps.setup((d) => d.file({ postfix: '.tmp', mode: undefined }, TypeMoq.It.isAny())).callback((_cfg, cb) => + deps.setup((d) => d.fileSync({ postfix: '.tmp', mode: undefined })).callback((_cfg, cb) => cb(failure, '...', -1, () => {}), ); diff --git a/extensions/positron-python/src/test/common/process/logger.unit.test.ts b/extensions/positron-python/src/test/common/process/logger.unit.test.ts index f1421ea58b85..366a7056e89e 100644 --- a/extensions/positron-python/src/test/common/process/logger.unit.test.ts +++ b/extensions/positron-python/src/test/common/process/logger.unit.test.ts @@ -109,32 +109,55 @@ suite('ProcessLogger suite', () => { test('Logger replaces the path/to/home with ~ in the command path where the home path IS NOT at the beginning of the path', async () => { const options = { cwd: path.join('debug', 'path') }; - logger.logProcess(path.join('net', untildify('~'), 'test'), ['--foo', '--bar'], options); + const untildifyStr = untildify('~'); + + let p1 = path.join('net', untildifyStr, 'test'); + if (p1.startsWith('.')) { + if (getOSType() === OSType.Windows) { + p1 = p1.replace(/^\.\\+/, ''); + } else { + p1 = p1.replace(/^\.\\/, ''); + } + } + logger.logProcess(p1, ['--foo', '--bar'], options); - sinon.assert.calledWithExactly(traceLogStub, `> ${path.join('net', '~', 'test')} --foo --bar`); + const path1 = path.join('.', 'net', '~', 'test'); + sinon.assert.calledWithExactly(traceLogStub, `> ${path1} --foo --bar`); sinon.assert.calledWithExactly(traceLogStub, `cwd: ${options.cwd}`); }); test('Logger replaces the path/to/home with ~ in the command path where the home path IS NOT at the beginning of the path but another arg contains other ref to home folder', async () => { const options = { cwd: path.join('debug', 'path') }; - logger.logProcess( - path.join('net', untildify('~'), 'test'), - ['--foo', path.join(untildify('~'), 'boo')], - options, - ); + let p1 = path.join('net', untildify('~'), 'test'); + if (p1.startsWith('.')) { + if (getOSType() === OSType.Windows) { + p1 = p1.replace(/^\.\\+/, ''); + } else { + p1 = p1.replace(/^\.\\/, ''); + } + } + logger.logProcess(p1, ['--foo', path.join(untildify('~'), 'boo')], options); sinon.assert.calledWithExactly( traceLogStub, - `> ${path.join('net', '~', 'test')} --foo ${path.join('~', 'boo')}`, + `> ${path.join('.', 'net', '~', 'test')} --foo ${path.join('~', 'boo')}`, ); sinon.assert.calledWithExactly(traceLogStub, `cwd: ${options.cwd}`); }); test('Logger replaces the path/to/home with ~ in the command path where the home path IS NOT at the beginning of the path between doble quotes', async () => { const options = { cwd: path.join('debug', 'path') }; - logger.logProcess(`"${path.join('net', untildify('~'), 'test')}" "--foo" "--bar"`, undefined, options); + let p1 = path.join('net', untildify('~'), 'test'); + if (p1.startsWith('.')) { + if (getOSType() === OSType.Windows) { + p1 = p1.replace(/^\.\\+/, ''); + } else { + p1 = p1.replace(/^\.\\/, ''); + } + } + logger.logProcess(`"${p1}" "--foo" "--bar"`, undefined, options); - sinon.assert.calledWithExactly(traceLogStub, `> "${path.join('net', '~', 'test')}" "--foo" "--bar"`); + sinon.assert.calledWithExactly(traceLogStub, `> "${path.join('.', 'net', '~', 'test')}" "--foo" "--bar"`); sinon.assert.calledWithExactly(traceLogStub, `cwd: ${options.cwd}`); }); From 2d4c73f4a170246962fda3c85a5689ea2d80c409 Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Sat, 27 Sep 2025 21:26:56 -0500 Subject: [PATCH 2/6] everything else --- .github/workflows/positron-python-ci.yml | 7 +- .github/workflows/positron-python-nightly.yml | 6 +- extensions/positron-python/gulpfile.js | 2 +- extensions/positron-python/package.json | 2 +- .../cp3-requirements.txt | 19 ++- .../py3-requirements.txt | 60 ++++---- .../jedilsp_requirements/requirements.txt | 52 +++++-- .../posit/pinned-test-requirements.txt | 35 ++--- .../posit/positron/tests/test_access_keys.py | 4 +- .../python_files/posit/test-requirements.txt | 12 +- .../positron_requirements/requirements.txt | 138 +++++++++--------- .../scripts/pip-compile-ipykernel.py | 8 +- .../creation/provider/uvUtils.ts | 2 +- 13 files changed, 185 insertions(+), 162 deletions(-) diff --git a/.github/workflows/positron-python-ci.yml b/.github/workflows/positron-python-ci.yml index 0d45e74c0713..ab1a14d22e67 100644 --- a/.github/workflows/positron-python-ci.yml +++ b/.github/workflows/positron-python-ci.yml @@ -23,7 +23,7 @@ defaults: working-directory: 'extensions/positron-python' env: - NODE_VERSION: '20.12.1' + NODE_VERSION: '22.17.0' PYTHON_VERSION: '3.10' PROJECT_DIR: 'extensions/positron-python' PYTHON_SRC_DIR: 'extensions/positron-python/python_files' @@ -131,7 +131,7 @@ jobs: matrix: os: [ubuntu-latest] # Run the tests on the oldest and most recent versions of Python. - python: ['3.9', '3.13'] + python: ['3.9', '3.14'] steps: - name: Checkout @@ -178,6 +178,8 @@ jobs: python: '3.12' - os: 'ubuntu-latest' python: '3.13' + - os: 'ubuntu-latest' + python: '3.14' env: SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }} SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }} @@ -428,4 +430,3 @@ jobs: - name: Run TypeScript functional tests run: npm run test:functional if: matrix.test-suite == 'functional' - diff --git a/.github/workflows/positron-python-nightly.yml b/.github/workflows/positron-python-nightly.yml index e0297b87b302..b80e7a8f949e 100644 --- a/.github/workflows/positron-python-nightly.yml +++ b/.github/workflows/positron-python-nightly.yml @@ -11,7 +11,7 @@ defaults: working-directory: 'extensions/positron-python' env: - NODE_VERSION: '18.17.1' + NODE_VERSION: '22.17.0' PYTHON_VERSION: '3.10' PROJECT_DIR: 'extensions/positron-python' PYTHON_SRC_DIR: 'extensions/positron-python/python_files' @@ -43,6 +43,8 @@ jobs: python: '3.12' - os: 'ubuntu-latest' python: '3.13' + - os: 'ubuntu-latest' + python: '3.14' steps: @@ -97,6 +99,8 @@ jobs: python: '3.12' - os: 'ubuntu-latest' python: '3.13' + - os: 'ubuntu-latest' + python: '3.14' steps: diff --git a/extensions/positron-python/gulpfile.js b/extensions/positron-python/gulpfile.js index 350fe30bb6e1..867bf2d2c6c8 100644 --- a/extensions/positron-python/gulpfile.js +++ b/extensions/positron-python/gulpfile.js @@ -286,7 +286,7 @@ async function vendorPythonKernelRequirements() { } async function bundleIPykernel() { - const pythonVersions = ['3.9', '3.10', '3.11', '3.12', '3.13']; + const pythonVersions = ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']; const minimumPythonVersion = '3.9'; // Pure Python 3 requirements. diff --git a/extensions/positron-python/package.json b/extensions/positron-python/package.json index e2fa433ca13c..3784972be92e 100644 --- a/extensions/positron-python/package.json +++ b/extensions/positron-python/package.json @@ -2270,7 +2270,7 @@ }, "positron": { "externalDependencies": { - "pet": "2025.12" + "pet": "2025.14" } } } diff --git a/extensions/positron-python/python_files/ipykernel_requirements/cp3-requirements.txt b/extensions/positron-python/python_files/ipykernel_requirements/cp3-requirements.txt index 8eb5efdcdb9d..b85af4128ce2 100644 --- a/extensions/positron-python/python_files/ipykernel_requirements/cp3-requirements.txt +++ b/extensions/positron-python/python_files/ipykernel_requirements/cp3-requirements.txt @@ -6,16 +6,15 @@ # --only-binary :all: -psutil==7.0.0 \ - --hash=sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25 \ - --hash=sha256:1e744154a6580bc968a0195fd25e80432d3afec619daf145b9e5ba16cc1d688e \ - --hash=sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91 \ - --hash=sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da \ - --hash=sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34 \ - --hash=sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553 \ - --hash=sha256:84df4eb63e16849689f76b1ffcb36db7b8de703d1bc1fe41773db487621b6c17 \ - --hash=sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993 \ - --hash=sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99 +psutil==7.1.0 \ + --hash=sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca \ + --hash=sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3 \ + --hash=sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d \ + --hash=sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5 \ + --hash=sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07 \ + --hash=sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13 \ + --hash=sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d \ + --hash=sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3 # via ipykernel tornado==6.5.2 \ --hash=sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c \ diff --git a/extensions/positron-python/python_files/ipykernel_requirements/py3-requirements.txt b/extensions/positron-python/python_files/ipykernel_requirements/py3-requirements.txt index 45a2a3ed36c2..aba26d5a1920 100644 --- a/extensions/positron-python/python_files/ipykernel_requirements/py3-requirements.txt +++ b/extensions/positron-python/python_files/ipykernel_requirements/py3-requirements.txt @@ -15,32 +15,36 @@ asttokens==3.0.0 \ comm==0.2.3 \ --hash=sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417 # via ipykernel -debugpy==1.8.16 \ - --hash=sha256:135ccd2b1161bade72a7a099c9208811c137a150839e970aeaf121c2467debe8 \ - --hash=sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e \ - --hash=sha256:211238306331a9089e253fd997213bc4a4c65f949271057d6695953254095376 \ - --hash=sha256:2801329c38f77c47976d341d18040a9ac09d0c71bf2c8b484ad27c74f83dc36f \ - --hash=sha256:2a3958fb9c2f40ed8ea48a0d34895b461de57a1f9862e7478716c35d76f56c65 \ - --hash=sha256:64473c4a306ba11a99fe0bb14622ba4fbd943eb004847d9b69b107bde45aa9ea \ - --hash=sha256:67371b28b79a6a12bcc027d94a06158f2fde223e35b5c4e0783b6f9d3b39274a \ - --hash=sha256:687c7ab47948697c03b8f81424aa6dc3f923e6ebab1294732df1ca9773cc67bc \ - --hash=sha256:70f5fcd6d4d0c150a878d2aa37391c52de788c3dc680b97bdb5e529cb80df87a \ - --hash=sha256:75f204684581e9ef3dc2f67687c3c8c183fde2d6675ab131d94084baf8084121 \ - --hash=sha256:833a61ed446426e38b0dd8be3e9d45ae285d424f5bf6cd5b2b559c8f12305508 \ - --hash=sha256:85df3adb1de5258dca910ae0bb185e48c98801ec15018a263a92bb06be1c8787 \ - --hash=sha256:8624a6111dc312ed8c363347a0b59c5acc6210d897e41a7c069de3c53235c9a6 \ - --hash=sha256:88eb9ffdfb59bf63835d146c183d6dba1f722b3ae2a5f4b9fc03e925b3358922 \ - --hash=sha256:a2ba6fc5d7c4bc84bcae6c5f8edf5988146e55ae654b1bb36fecee9e5e77e9e2 \ - --hash=sha256:b202e2843e32e80b3b584bcebfe0e65e0392920dc70df11b2bfe1afcb7a085e4 \ - --hash=sha256:b2abae6dd02523bec2dee16bd6b0781cccb53fd4995e5c71cc659b5f45581898 \ - --hash=sha256:b5aea1083f6f50023e8509399d7dc6535a351cc9f2e8827d1e093175e4d9fa4c \ - --hash=sha256:bee89e948bc236a5c43c4214ac62d28b29388453f5fd328d739035e205365f0b \ - --hash=sha256:c2c47c2e52b40449552843b913786499efcc3dbc21d6c49287d939cd0dbc49fd \ - --hash=sha256:cf358066650439847ec5ff3dae1da98b5461ea5da0173d93d5e10f477c94609a \ - --hash=sha256:d58c48d8dbbbf48a3a3a638714a2d16de537b0dace1e3432b8e92c57d43707f8 \ - --hash=sha256:e5ca7314042e8a614cc2574cd71f6ccd7e13a9708ce3c6d8436959eae56f2378 \ - --hash=sha256:f8340a3ac2ed4f5da59e064aa92e39edd52729a88fbde7bbaa54e08249a04493 \ - --hash=sha256:fee6db83ea5c978baf042440cfe29695e1a5d48a30147abf4c3be87513609817 +debugpy==1.8.17 \ + --hash=sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1 \ + --hash=sha256:1440fd514e1b815edd5861ca394786f90eb24960eb26d6f7200994333b1d79e3 \ + --hash=sha256:17e456da14848d618662354e1dccfd5e5fb75deec3d1d48dc0aa0baacda55860 \ + --hash=sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc \ + --hash=sha256:3a32c0af575749083d7492dc79f6ab69f21b2d2ad4cd977a958a07d5865316e4 \ + --hash=sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088 \ + --hash=sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670 \ + --hash=sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef \ + --hash=sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf \ + --hash=sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420 \ + --hash=sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464 \ + --hash=sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c \ + --hash=sha256:8deb4e31cd575c9f9370042876e078ca118117c1b5e1f22c32befcfbb6955f0c \ + --hash=sha256:a3aad0537cf4d9c1996434be68c6c9a6d233ac6f76c2a482c7803295b4e4f99a \ + --hash=sha256:b13eea5587e44f27f6c48588b5ad56dcb74a4f3a5f89250443c94587f3eb2ea1 \ + --hash=sha256:b532282ad4eca958b1b2d7dbcb2b7218e02cb934165859b918e3b6ba7772d3f4 \ + --hash=sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f \ + --hash=sha256:b75868b675949a96ab51abc114c7163f40ff0d8f7d6d5fd63f8932fd38e9c6d7 \ + --hash=sha256:bb1bbf92317e1f35afcf3ef0450219efb3afe00be79d8664b250ac0933b9015f \ + --hash=sha256:c41d2ce8bbaddcc0009cc73f65318eedfa3dbc88a8298081deb05389f1ab5542 \ + --hash=sha256:c6bdf134457ae0cac6fb68205776be635d31174eeac9541e1d0c062165c6461f \ + --hash=sha256:d3fce3f0e3de262a3b67e69916d001f3e767661c6e1ee42553009d445d1cd840 \ + --hash=sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83 \ + --hash=sha256:e79a195f9e059edfe5d8bf6f3749b2599452d3e9380484cd261f6b7cd2c7c4da \ + --hash=sha256:e851beb536a427b5df8aa7d0c7835b29a13812f41e46292ff80b2ef77327355a \ + --hash=sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464 \ + --hash=sha256:eaa85bce251feca8e4c87ce3b954aba84b8c645b90f0e6a515c00394a9f5c0e7 \ + --hash=sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d \ + --hash=sha256:f2ac8055a0c4a09b30b931100996ba49ef334c6947e7ae365cdd870416d7513e # via ipykernel decorator==5.2.1 \ --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a @@ -125,8 +129,8 @@ typing-extensions==4.15.0 \ # via # exceptiongroup # ipython -wcwidth==0.2.13 \ - --hash=sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859 +wcwidth==0.2.14 \ + --hash=sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1 # via prompt-toolkit zipp==3.23.0 \ --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e diff --git a/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt b/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt index 3c3e0510bd64..e2599e7bbce4 100644 --- a/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt +++ b/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt @@ -1,29 +1,37 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --generate-hashes python_files/jedilsp_requirements/requirements.in -o ./python_files/jedilsp_requirements/requirements.txt -attrs==24.2.0 \ - --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ - --hash=sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2 +# uv pip compile --generate-hashes python_files\jedilsp_requirements\requirements.in -o .\python_files\jedilsp_requirements\requirements.txt +attrs==25.3.0 \ + --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \ + --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b # via # cattrs # lsprotocol -cattrs==24.1.2 \ - --hash=sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0 \ - --hash=sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85 +cattrs==25.2.0 \ + --hash=sha256:539d7eedee7d2f0706e4e109182ad096d608ba84633c32c75ef3458f1d11e8f1 \ + --hash=sha256:f46c918e955db0177be6aa559068390f71988e877c603ae2e56c71827165cc06 # via # jedi-language-server # lsprotocol # pygls -docstring-to-markdown==0.15 \ - --hash=sha256:27afb3faedba81e34c33521c32bbd258d7fbb79eedf7d29bc4e81080e854aec0 \ - --hash=sha256:e146114d9c50c181b1d25505054a8d0f7a476837f0da2c19f07e06eaed52b73d +docstring-to-markdown==0.17 \ + --hash=sha256:df72a112294c7492487c9da2451cae0faeee06e86008245c188c5761c9590ca3 \ + --hash=sha256:fd7d5094aa83943bf5f9e1a13701866b7c452eac19765380dead666e36d3711c # via jedi-language-server +exceptiongroup==1.3.0 \ + --hash=sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10 \ + --hash=sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88 + # via cattrs +importlib-metadata==8.7.0 \ + --hash=sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000 \ + --hash=sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd + # via docstring-to-markdown jedi==0.19.2 \ --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 # via jedi-language-server -jedi-language-server==0.42.0 \ - --hash=sha256:ac5a3f711694432f4677ccba5eacdde1bebc2b3b2fa361c553e28efbe526dc98 \ - --hash=sha256:db818d956c16f79a32bbde4c6f7189282725977246199b09ac8155429432632c +jedi-language-server==0.45.1 \ + --hash=sha256:8c0c6b4eaeffdbb87be79e9897c9929ffeddf875dff7c1c36dd67768e294942b \ + --hash=sha256:a1fcfba8008f2640e921937fcf1933c3961d74249341eba8b3ef9a0c3f817102 # via -r python_files/jedilsp_requirements/requirements.in lsprotocol==2023.0.1 \ --hash=sha256:c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2 \ @@ -31,9 +39,9 @@ lsprotocol==2023.0.1 \ # via # jedi-language-server # pygls -parso==0.8.4 \ - --hash=sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18 \ - --hash=sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d +parso==0.8.5 \ + --hash=sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a \ + --hash=sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 # via jedi pygls==1.3.1 \ --hash=sha256:140edceefa0da0e9b3c533547c892a42a7d2fd9217ae848c330c53d266a55018 \ @@ -41,3 +49,15 @@ pygls==1.3.1 \ # via # -r python_files/jedilsp_requirements/requirements.in # jedi-language-server +typing-extensions==4.15.0 \ + --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ + --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 + # via + # cattrs + # docstring-to-markdown + # exceptiongroup + # jedi-language-server +zipp==3.23.0 \ + --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ + --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 + # via importlib-metadata diff --git a/extensions/positron-python/python_files/posit/pinned-test-requirements.txt b/extensions/positron-python/python_files/posit/pinned-test-requirements.txt index 9a74d253ecca..e068bb9d175f 100644 --- a/extensions/positron-python/python_files/posit/pinned-test-requirements.txt +++ b/extensions/positron-python/python_files/posit/pinned-test-requirements.txt @@ -10,45 +10,46 @@ # Then iterate through supported PYTHON_VERSIONS to make sure we covered the latest versions. -duckdb<1.4.0 -fastcore==1.8.8 +duckdb==1.3.2 +fastcore==1.8.9; python_version == '3.9' +fastcore==1.8.11; python_version >= '3.10' geopandas==1.0.1; python_version == '3.9' -geopandas==1.1.1; python_version >= '3.10' -haystack-ai==2.17.1 +geopandas==1.1.1; python_version >= '3.10' and python_version < '3.14' +haystack-ai==2.18.0; python_version < '3.14' holoviews==1.20.2; python_version == '3.9' holoviews==1.21.0; python_version >= '3.10' hvplot==0.11.3; python_version == '3.9' hvplot==0.12.1; python_version >= '3.10' -ibis-framework[duckdb]==10.8.0 +ibis-framework[duckdb]==10.8.0; python_version < '3.14' ipykernel==6.30.1 ipython==8.18.1; python_version == '3.9' ipython==8.37.0; python_version == '3.10' ipython==9.5.0; python_version >= '3.11' ipywidgets==8.1.7 -lightning==2.5.4 +lightning==2.5.5; python_version < '3.14' matplotlib==3.9.4; python_version == '3.9' matplotlib==3.10.6; python_version >= '3.10' numpy==2.0.2; python_version == '3.9' numpy==2.2.6; python_version == '3.10' -numpy==2.3.2; python_version >= '3.11' +numpy==2.3.3; python_version >= '3.11' pandas==2.3.2 plotly==6.3.0 plotnine==0.13.6; python_version == '3.9' plotnine==0.15.0; python_version >= '3.10' -polars==1.33.0 -polars[timezone]==1.33.0; sys_platform == 'win32' -pyarrow==21.0.0 -pytest==8.4.1 -pytest-asyncio==1.1.0 -pytest-mock==3.14.1 +polars==1.33.1 +polars[timezone]==1.33.1; sys_platform == 'win32' +pyarrow==21.0.0; python_version < '3.14' +pytest==8.4.2 +pytest-asyncio==1.2.0 +pytest-mock==3.15.1 syrupy==4.9.1 -torch==2.8.0 +torch==2.8.0; python_version < '3.14' scipy==1.13.1; python_version == '3.9' scipy==1.15.3; python_version == '3.10' -scipy==1.16.1; python_version >= '3.11' -snowflake-connector-python==3.17.2 +scipy==1.16.2; python_version >= '3.11' +snowflake-connector-python==3.17.4 SQLAlchemy==2.0.43 # putting this last like test-requirements.txt bokeh==3.4.3; python_version == '3.9' -bokeh==3.7.3; python_version >= '3.10' +bokeh==3.8.0; python_version >= '3.10' diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py b/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py index 3156a0bb1d66..f5a7d90f9bb4 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py @@ -28,7 +28,7 @@ ) try: - import torch # type: ignore [reportMissingImports] for 3.12 + import torch # type: ignore [reportMissingImports] for 3.14 except ImportError: torch = None @@ -98,7 +98,7 @@ def test_encode_access_key_not_implemented_error(case: Any) -> None: @pytest.mark.parametrize( "type_name", [ - # for Python 3.12 + # for Python 3.14 "torch.Tensor" if torch else "None", "function", ], diff --git a/extensions/positron-python/python_files/posit/test-requirements.txt b/extensions/positron-python/python_files/posit/test-requirements.txt index d54bd5519c65..b9bae3ffb0c4 100644 --- a/extensions/positron-python/python_files/posit/test-requirements.txt +++ b/extensions/positron-python/python_files/posit/test-requirements.txt @@ -1,15 +1,15 @@ duckdb<1.4.0 fastcore -geopandas -haystack-ai +geopandas; python_version < '3.14' +haystack-ai; python_version < '3.14' holoviews hvplot ibis-framework[polars]; python_version == '3.9' -ibis-framework[duckdb]; python_version >= '3.10' +ibis-framework[duckdb]; python_version >= '3.10' and python_version < '3.14' ipykernel ipython ipywidgets -lightning +lightning; python_version < '3.14' matplotlib numpy pandas @@ -17,12 +17,12 @@ plotly plotnine polars polars[timezone]; sys_platform == 'win32' -pyarrow +pyarrow; python_version < '3.14' pytest pytest-asyncio pytest-mock syrupy -torch +torch; python_version < '3.14' scipy snowflake-connector-python sqlalchemy diff --git a/extensions/positron-python/python_files/positron_requirements/requirements.txt b/extensions/positron-python/python_files/positron_requirements/requirements.txt index 979953345b79..592aa8206442 100644 --- a/extensions/positron-python/python_files/positron_requirements/requirements.txt +++ b/extensions/positron-python/python_files/positron_requirements/requirements.txt @@ -6,9 +6,9 @@ attrs==25.3.0 \ # via # cattrs # lsprotocol -cattrs==24.1.2 \ - --hash=sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0 \ - --hash=sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85 +cattrs==24.1.3 \ + --hash=sha256:981a6ef05875b5bb0c7fb68885546186d306f10f0f6718fe9b96c226e68821ff \ + --hash=sha256:adf957dddd26840f27ffbd060a6c4dd3b2192c5b7c2c0525ef1bd8131d8a83f5 # via # jedi-language-server # lsprotocol @@ -19,17 +19,13 @@ docstring-to-markdown==0.13 \ # via # -r python_files/positron_requirements/requirements.in # jedi-language-server -exceptiongroup==1.2.2 \ - --hash=sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b \ - --hash=sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc - # via cattrs jedi==0.19.2 \ --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 # via jedi-language-server -jedi-language-server==0.44.0 \ - --hash=sha256:17619fac5faf7111036c0b01d460c4eb848ce8df1af8208d85c255db34ec2eff \ - --hash=sha256:276536bd00e64e65753d54cd35237d62730daffd65292dc8510d3063ebaefe4d +jedi-language-server==0.45.1 \ + --hash=sha256:8c0c6b4eaeffdbb87be79e9897c9929ffeddf875dff7c1c36dd67768e294942b \ + --hash=sha256:a1fcfba8008f2640e921937fcf1933c3961d74249341eba8b3ef9a0c3f817102 # via -r python_files/positron_requirements/requirements.in lsprotocol==2023.0.1 \ --hash=sha256:c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2 \ @@ -37,69 +33,69 @@ lsprotocol==2023.0.1 \ # via # jedi-language-server # pygls -markdown-it-py==3.0.0 \ - --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ - --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb +markdown-it-py==4.0.0 \ + --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ + --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 # via -r python_files/positron_requirements/requirements.in mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -parso==0.8.4 \ - --hash=sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18 \ - --hash=sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d +parso==0.8.5 \ + --hash=sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a \ + --hash=sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 # via jedi -pydantic==1.10.21 \ - --hash=sha256:0067935d35044950be781933ab91b9a708eaff124bf860fa2f70aeb1c4be7212 \ - --hash=sha256:08caa8c0468172d27c669abfe9e7d96a8b1655ec0833753e117061febaaadef5 \ - --hash=sha256:0bb58bbe65a43483d49f66b6c8474424d551a3fbe8a7796c42da314bac712738 \ - --hash=sha256:185d5f1dff1fead51766da9b2de4f3dc3b8fca39e59383c273f34a6ae254e3e2 \ - --hash=sha256:1d7c332685eafacb64a1a7645b409a166eb7537f23142d26895746f628a3149b \ - --hash=sha256:245e486e0fec53ec2366df9cf1cba36e0bbf066af7cd9c974bbbd9ba10e1e586 \ - --hash=sha256:266ecfc384861d7b0b9c214788ddff75a2ea123aa756bcca6b2a1175edeca0fe \ - --hash=sha256:298d6f765e3c9825dfa78f24c1efd29af91c3ab1b763e1fd26ae4d9e1749e5c8 \ - --hash=sha256:2b6a04efdcd25486b27f24c1648d5adc1633ad8b4506d0e96e5367f075ed2e0b \ - --hash=sha256:2c9b782db6f993a36092480eeaab8ba0609f786041b01f39c7c52252bda6d85f \ - --hash=sha256:2ed4a5f13cf160d64aa331ab9017af81f3481cd9fd0e49f1d707b57fe1b9f3ae \ - --hash=sha256:35b263b60c519354afb3a60107d20470dd5250b3ce54c08753f6975c406d949b \ - --hash=sha256:36ceadef055af06e7756eb4b871cdc9e5a27bdc06a45c820cd94b443de019bbf \ - --hash=sha256:38e6d35cf7cd1727822c79e324fa0677e1a08c88a34f56695101f5ad4d5e20e5 \ - --hash=sha256:3b7693bb6ed3fbe250e222f9415abb73111bb09b73ab90d2d4d53f6390e0ccc1 \ - --hash=sha256:3c96fed246ccc1acb2df032ff642459e4ae18b315ecbab4d95c95cfa292e8517 \ - --hash=sha256:46cffa24891b06269e12f7e1ec50b73f0c9ab4ce71c2caa4ccf1fb36845e1ff7 \ - --hash=sha256:57f0101e6c97b411f287a0b7cf5ebc4e5d3b18254bf926f45a11615d29475793 \ - --hash=sha256:5d387940f0f1a0adb3c44481aa379122d06df8486cc8f652a7b3b0caf08435f7 \ - --hash=sha256:5e8148c2ce4894ce7e5a4925d9d3fdce429fb0e821b5a8783573f3611933a251 \ - --hash=sha256:61da798c05a06a362a2f8c5e3ff0341743e2818d0f530eaac0d6898f1b187f1f \ - --hash=sha256:64b48e2b609a6c22178a56c408ee1215a7206077ecb8a193e2fda31858b2362a \ - --hash=sha256:662bf5ce3c9b1cef32a32a2f4debe00d2f4839fefbebe1d6956e681122a9c839 \ - --hash=sha256:6a497bc66b3374b7d105763d1d3de76d949287bf28969bff4656206ab8a53aa9 \ - --hash=sha256:6b64708009cfabd9c2211295144ff455ec7ceb4c4fb45a07a804309598f36187 \ - --hash=sha256:6c54f8d4c151c1de784c5b93dfbb872067e3414619e10e21e695f7bb84d1d1fd \ - --hash=sha256:79577cc045d3442c4e845df53df9f9202546e2ba54954c057d253fc17cd16cb1 \ - --hash=sha256:7ce64d23d4e71d9698492479505674c5c5b92cda02b07c91dfc13633b2eef805 \ - --hash=sha256:8a148410fa0e971ba333358d11a6dea7b48e063de127c2b09ece9d1c1137dde4 \ - --hash=sha256:8b6350b68566bb6b164fb06a3772e878887f3c857c46c0c534788081cb48adf4 \ - --hash=sha256:90e85834f0370d737c77a386ce505c21b06bfe7086c1c568b70e15a568d9670d \ - --hash=sha256:935b19fdcde236f4fbf691959fa5c3e2b6951fff132964e869e57c70f2ad1ba3 \ - --hash=sha256:98737c3ab5a2f8a85f2326eebcd214510f898881a290a7939a45ec294743c875 \ - --hash=sha256:9e3e4000cd54ef455694b8be9111ea20f66a686fc155feda1ecacf2322b115da \ - --hash=sha256:a4973232c98b9b44c78b1233693e5e1938add5af18042f031737e1214455f9b8 \ - --hash=sha256:a621742da75ce272d64ea57bd7651ee2a115fa67c0f11d66d9dcfc18c2f1b106 \ - --hash=sha256:b6b73ab347284719f818acb14f7cd80696c6fdf1bd34feee1955d7a72d2e64ce \ - --hash=sha256:b8460bc256bf0de821839aea6794bb38a4c0fbd48f949ea51093f6edce0be459 \ - --hash=sha256:b92893ebefc0151474f682e7debb6ab38552ce56a90e39a8834734c81f37c8a9 \ - --hash=sha256:c0501e1d12df6ab1211b8cad52d2f7b2cd81f8e8e776d39aa5e71e2998d0379f \ - --hash=sha256:c1ba253eb5af8d89864073e6ce8e6c8dec5f49920cff61f38f5c3383e38b1c9f \ - --hash=sha256:c261127c275d7bce50b26b26c7d8427dcb5c4803e840e913f8d9df3f99dca55f \ - --hash=sha256:c677aa39ec737fec932feb68e4a2abe142682f2885558402602cd9746a1c92e8 \ - --hash=sha256:d356aa5b18ef5a24d8081f5c5beb67c0a2a6ff2a953ee38d65a2aa96526b274f \ - --hash=sha256:db70c920cba9d05c69ad4a9e7f8e9e83011abb2c6490e561de9ae24aee44925c \ - --hash=sha256:e23a97a6c2f2db88995496db9387cd1727acdacc85835ba8619dce826c0b11a6 \ - --hash=sha256:e622314542fb48542c09c7bd1ac51d71c5632dd3c92dc82ede6da233f55f4848 \ - --hash=sha256:e7f0cda108b36a30c8fc882e4fc5b7eec8ef584aa43aa43694c6a7b274fb2b56 \ - --hash=sha256:f198c8206640f4c0ef5a76b779241efb1380a300d88b1bce9bfe95a6362e674d \ - --hash=sha256:f2f4a2305f15eff68f874766d982114ac89468f1c2c0b97640e719cf1a078374 +pydantic==1.10.24 \ + --hash=sha256:02f7a25e8949d8ca568e4bcef2ffed7881d7843286e7c3488bdd3b67f092059c \ + --hash=sha256:076fff9da02ca716e4c8299c68512fdfbeac32fdefc9c160e6f80bdadca0993d \ + --hash=sha256:093768eba26db55a88b12f3073017e3fdee319ef60d3aef5c6c04a4e484db193 \ + --hash=sha256:0cbbf306124ae41cc153fdc2559b37faa1bec9a23ef7b082c1756d1315ceffe6 \ + --hash=sha256:17e7610119483f03954569c18d4de16f4e92f1585f20975414033ac2d4a96624 \ + --hash=sha256:1a1ae996daa3d43c530b8d0bacc7e2d9cb55e3991f0e6b7cc2cb61a0fb9f6667 \ + --hash=sha256:25fb9a69a21d711deb5acefdab9ff8fb49e6cc77fdd46d38217d433bff2e3de2 \ + --hash=sha256:265788a1120285c4955f8b3d52b3ea6a52c7a74db097c4c13a4d3567f0c6df3c \ + --hash=sha256:2d1a5ef77efeb54def2695f2b8f4301aae8c7aa2b334bd15f61c18ef54317621 \ + --hash=sha256:34109b0afa63b36eec2f2b115694e48ae5ee52f7d3c1baa0be36f80e586bda52 \ + --hash=sha256:415c638ca5fd57b915a62dd38c18c8e0afe5adf5527be6f8ce16b4636b616816 \ + --hash=sha256:49a6f0178063f15eaea6cbcb2dba04db0b73db9834bc7b1e1c4dbea28c7cd22f \ + --hash=sha256:4a9e92b9c78d7f3cfa085c21c110e7000894446e24a836d006aabfc6ae3f1813 \ + --hash=sha256:4d7336bfcdb8cb58411e6b498772ba2cff84a2ce92f389bae3a8f1bb2c840c49 \ + --hash=sha256:50d9f8a207c07f347d4b34806dc576872000d9a60fd481ed9eb78ea8512e0666 \ + --hash=sha256:52219b4e70c1db185cfd103a804e416384e1c8950168a2d4f385664c7c35d21a \ + --hash=sha256:58d42a7c344882c00e3bb7c6c8c6f62db2e3aafa671f307271c45ad96e8ccf7a \ + --hash=sha256:5a42033fac69b9f1f867ecc3a2159f0e94dceb1abfc509ad57e9e88d49774683 \ + --hash=sha256:5ce0986799248082e9a5a026c9b5d2f9fa2e24d2afb9b0eace9104334a58fdc1 \ + --hash=sha256:5da2775712dda8b89e701ed2a72d5d81d23dbc6af84089da8a0f61a0be439c8c \ + --hash=sha256:5fc35569dfd15d3b3fc06a22abee0a45fdde0784be644e650a8769cd0b2abd94 \ + --hash=sha256:6af36a8fb3072526b5b38d3f341b12d8f423188e7d185f130c0079fe02cdec7f \ + --hash=sha256:6f25d2f792afcd874cc8339c1da1cc52739f4f3d52993ed1f6c263ef2afadc47 \ + --hash=sha256:70152291488f8d2bbcf2027b5c28c27724c78a7949c91b466d28ad75d6d12702 \ + --hash=sha256:75259be0558ca3af09192ad7b18557f2e9033ad4cbd48c252131f5292f6374fd \ + --hash=sha256:7c8bbad6037a87effe9f3739bdf39851add6e0f7e101d103a601c504892ffa70 \ + --hash=sha256:7e6d1af1bd3d2312079f28c9baf2aafb4a452a06b50717526e5ac562e37baa53 \ + --hash=sha256:8057172868b0d98f95e6fcddcc5f75d01570e85c6308702dd2c50ea673bc197b \ + --hash=sha256:82f951210ebcdb778b1d93075af43adcd04e9ebfd4f44b1baa8eeb21fbd71e36 \ + --hash=sha256:874a78e4ed821258295a472e325eee7de3d91ba7a61d0639ce1b0367a3c63d4c \ + --hash=sha256:8f2447ca88a7e14fd4d268857521fb37535c53a367b594fa2d7c2551af905993 \ + --hash=sha256:956b30638272c51c85caaff76851b60db4b339022c0ee6eca677c41e3646255b \ + --hash=sha256:9c377fc30d9ca40dbff5fd79c5a5e1f0d6fff040fa47a18851bb6b0bd040a5d8 \ + --hash=sha256:a5bf94042efbc6ab56b18a5921f426ebbeefc04f554a911d76029e7be9057d01 \ + --hash=sha256:af31565b12a7db5bfa5fe8c3a4f8fda4d32f5c2929998b1b241f1c22e9ab6e69 \ + --hash=sha256:af8e2b3648128b8cadb1a71e2f8092a6f42d4ca123fad7a8d7ce6db8938b1db3 \ + --hash=sha256:b644d6f14b2ce617d6def21622f9ba73961a16b7dffdba7f6692e2f66fa05d00 \ + --hash=sha256:b66e4892d8ae005f436a5c5f1519ecf837574d8414b1c93860fb3c13943d9b37 \ + --hash=sha256:bb3df10be3c7d264947180615819aeec0916f19650f2ba7309ed1fe546ead0d2 \ + --hash=sha256:bed9d6eea5fabbc6978c42e947190c7bd628ddaff3b56fc963fe696c3710ccd6 \ + --hash=sha256:c626596c1b95dc6d45f7129f10b6743fbb50f29d942d25a22b2ceead670c067d \ + --hash=sha256:d255bebd927e5f1e026b32605684f7b6fc36a13e62b07cb97b29027b91657def \ + --hash=sha256:d6e45dbc79a44e34c2c83ef1fcb56ff663040474dcf4dfc452db24a1de0f7574 \ + --hash=sha256:e24435a9970dcb2b35648f2cf57505d4bd414fcca1a404c82e28d948183fe0a6 \ + --hash=sha256:eef07ea2fba12f9188cfa2c50cb3eaa6516b56c33e2a8cc3cd288b4190ee6c0c \ + --hash=sha256:ef14dfa7c98b314a3e449e92df6f1479cafe74c626952f353ff0176b075070de \ + --hash=sha256:f154a8a46a0d950c055254f8f010ba07e742ac4404a3b6e281a31913ac45ccd0 \ + --hash=sha256:fa0ebefc169439267e4b4147c7d458908788367640509ed32c90a91a63ebb579 \ + --hash=sha256:fac7fbcb65171959973f3136d0792c3d1668bc01fd414738f0898b01f692f1b4 \ + --hash=sha256:fc3f4a6544517380658b63b144c7d43d5276a343012913b7e5d18d9fba2f12bb # via -r python_files/positron_requirements/requirements.in pygls==1.3.1 \ --hash=sha256:140edceefa0da0e9b3c533547c892a42a7d2fd9217ae848c330c53d266a55018 \ @@ -107,15 +103,13 @@ pygls==1.3.1 \ # via # -r python_files/positron_requirements/requirements.in # jedi-language-server -pygments==2.19.1 \ - --hash=sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f \ - --hash=sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c +pygments==2.19.2 \ + --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ + --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # via -r python_files/positron_requirements/requirements.in typing-extensions==4.10.0 \ --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb # via # -r python_files/positron_requirements/requirements.in - # cattrs - # jedi-language-server # pydantic diff --git a/extensions/positron-python/scripts/pip-compile-ipykernel.py b/extensions/positron-python/scripts/pip-compile-ipykernel.py index 4f3ad22de2b6..2ebdd0ce08ba 100644 --- a/extensions/positron-python/scripts/pip-compile-ipykernel.py +++ b/extensions/positron-python/scripts/pip-compile-ipykernel.py @@ -14,9 +14,9 @@ Our solution is to split the requirements into three groups: -1. `py3-requirements.txt` for pure Python >=3.8. -2. `cp3-requirements.txt` for CPython >=3.8. -3. `cpx-requirements.txt` for specific versions of CPython >=3.8,<=3.13. +1. `py3-requirements.txt` for pure Python >=3.9. +2. `cp3-requirements.txt` for CPython >=3.9. +3. `cpx-requirements.txt` for specific versions of CPython >=3.9,<=3.14. Each of these requirements files are `pip install`ed into separate directories, which are selectively added to the user's Python search path based on the current interpreter. @@ -317,7 +317,7 @@ def write_output( if __name__ == "__main__": main( requirement="ipykernel", - python_versions=["3.9", "3.10", "3.11", "3.12", "3.13"], + python_versions=["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"], output_dir=Path("./python_files/ipykernel_requirements/"), max_rounds=10, cache_dir=CACHE_DIR, diff --git a/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts b/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts index dccd358c7cb3..d6c5d33b18cc 100644 --- a/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts +++ b/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts @@ -7,7 +7,7 @@ import { CancellationToken, QuickPickItem } from 'vscode'; import { showQuickPickWithBack } from '../../../common/vscodeApis/windowApis'; import { CreateEnv } from '../../../common/utils/localize'; -const SUPPORTED_UV_PYTHON_VERSIONS = ['3.13', '3.12', '3.11', '3.10', '3.9']; +const SUPPORTED_UV_PYTHON_VERSIONS = ['3.14', '3.13', '3.12', '3.11', '3.10', '3.9']; export function getUvPythonVersions(): { versions: string[] } { return { From 08ea9e36216d22009776efcf5944c4859c558f82 Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Sat, 27 Sep 2025 21:39:29 -0500 Subject: [PATCH 3/6] 3.14 is weird --- .github/workflows/positron-python-ci.yml | 2 +- .../positron-python/build/test-requirements.txt | 2 +- .../positron_requirements/requirements.txt | 13 ++++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/positron-python-ci.yml b/.github/workflows/positron-python-ci.yml index ab1a14d22e67..0c8a4960a91f 100644 --- a/.github/workflows/positron-python-ci.yml +++ b/.github/workflows/positron-python-ci.yml @@ -131,7 +131,7 @@ jobs: matrix: os: [ubuntu-latest] # Run the tests on the oldest and most recent versions of Python. - python: ['3.9', '3.14'] + python: ['3.9', '3.13', '3.14'] steps: - name: Checkout diff --git a/extensions/positron-python/build/test-requirements.txt b/extensions/positron-python/build/test-requirements.txt index 6d64ff72ac7f..776517ab1d30 100644 --- a/extensions/positron-python/build/test-requirements.txt +++ b/extensions/positron-python/build/test-requirements.txt @@ -9,7 +9,7 @@ pydocstyle prospector pytest flask -fastapi +fastapi; python_version < '3.14' uvicorn django testresources diff --git a/extensions/positron-python/python_files/positron_requirements/requirements.txt b/extensions/positron-python/python_files/positron_requirements/requirements.txt index 592aa8206442..464624b1ad8a 100644 --- a/extensions/positron-python/python_files/positron_requirements/requirements.txt +++ b/extensions/positron-python/python_files/positron_requirements/requirements.txt @@ -19,6 +19,10 @@ docstring-to-markdown==0.13 \ # via # -r python_files/positron_requirements/requirements.in # jedi-language-server +exceptiongroup==1.3.0 \ + --hash=sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10 \ + --hash=sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88 + # via cattrs jedi==0.19.2 \ --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 @@ -33,9 +37,9 @@ lsprotocol==2023.0.1 \ # via # jedi-language-server # pygls -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==3.0.0 \ + --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ + --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb # via -r python_files/positron_requirements/requirements.in mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ @@ -112,4 +116,7 @@ typing-extensions==4.10.0 \ --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb # via # -r python_files/positron_requirements/requirements.in + # cattrs + # exceptiongroup + # jedi-language-server # pydantic From af28ebed854101075be626b9bc029d5e7860fb0c Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Mon, 29 Sep 2025 13:40:16 -0500 Subject: [PATCH 4/6] fix tests --- .../posit/positron/tests/test_convert.py | 11 +- .../positron/tests/test_data_explorer.py | 26 ++-- .../posit/positron/tests/test_inspectors.py | 127 +++++++++++------- .../tests/test_patch/test_haystack.py | 6 + .../positron/tests/test_positron_ipkernel.py | 6 + .../posit/positron/tests/test_ui.py | 5 +- .../src/client/common/constants.ts | 2 +- .../src/client/positron/ipykernel.ts | 2 +- .../creation/provider/uvUtils.ts | 4 +- .../platform/filesystem.functional.test.ts | 13 ++ .../utilities/uvUtils.ts | 2 +- 11 files changed, 135 insertions(+), 69 deletions(-) diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_convert.py b/extensions/positron-python/python_files/posit/positron/tests/test_convert.py index 427b679adc5c..b9379d8e5f09 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_convert.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_convert.py @@ -20,6 +20,7 @@ from .conftest import DummyComm, PositronShell from .test_data_explorer import ( COMPARE_OPS, + SIMPLE_DATA, SIMPLE_PANDAS_DF, DataExplorerFixture, _between_filter, @@ -42,8 +43,13 @@ except ImportError: has_sqlalchemy = False +try: + import pyarrow -SIMPLE_POLARS_DF = pl.DataFrame(SIMPLE_PANDAS_DF.drop(columns=["f"])) + SIMPLE_POLARS_DF = pl.DataFrame(SIMPLE_PANDAS_DF.drop(columns=["f"])) +except ImportError: + pyarrow = None + SIMPLE_POLARS_DF = pl.DataFrame({k: v for k, v in SIMPLE_DATA.items() if k != "f"}) # ruff: noqa: E712 @@ -655,7 +661,7 @@ def test_convert_polars_filter_compare(dxf: DataExplorerConvertFixture): def test_convert_polars_filter_datetimetz(dxf: DataExplorerConvertFixture): test_df = pl.DataFrame( { - "date": pd.date_range("2000-01-01", periods=5, tz="US/Eastern"), + "date": pd.date_range("2000-01-01", periods=5, tz="US/Eastern").to_list(), } ) tz = pytz.timezone("US/Eastern") @@ -692,6 +698,7 @@ def test_convert_polars_sort_and_filter(dxf: DataExplorerConvertFixture): ) +@pytest.mark.skipif(pyarrow is None, reason="pyarrow is not installed") def test_convert_polars_sort_to_pandas(dxf: DataExplorerConvertFixture): # Test that we can convert a sort operation to pandas test_df = SIMPLE_POLARS_DF diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_data_explorer.py b/extensions/positron-python/python_files/posit/positron/tests/test_data_explorer.py index c040319b1f28..ce5a8a1e956f 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_data_explorer.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_data_explorer.py @@ -14,7 +14,6 @@ from io import StringIO from typing import Any, Dict, List, Optional, Type, cast -import ibis import numpy as np import pandas as pd import polars as pl @@ -59,6 +58,11 @@ from .test_variables import BIG_ARRAY_LENGTH, _assign_variables from .utils import dummy_rpc_request, json_rpc_notification, json_rpc_request +try: + import ibis +except ImportError: + ibis = None + TARGET_NAME = "positron.dataExplorer" @@ -122,7 +126,7 @@ def __repr__(self): "a": [1, 2, 3, 4, 5], "b": [True, False, True, None, True], "c": ["foo", "bar", None, "bar", "None"], - "d": [0, 1.2, -4.5, 6, np.nan], + "d": [0.0, 1.2, -4.5, 6, np.nan], "e": pd.to_datetime( [ "2024-01-01 00:00:00", @@ -139,13 +143,16 @@ def __repr__(self): SIMPLE_PANDAS_DF = pd.DataFrame(SIMPLE_DATA) -SIMPLE_IBIS_DF = ibis.memtable( - { - "a": [1, 2, 3, 4, 5], - "b": [True, False, True, None, True], - "c": ["foo", "bar", None, "bar", "None"], - } -) +if ibis: + SIMPLE_IBIS_DF = ibis.memtable( + { + "a": [1, 2, 3, 4, 5], + "b": [True, False, True, None, True], + "c": ["foo", "bar", None, "bar", "None"], + } + ) +else: + SIMPLE_IBIS_DF = None def test_service_properties(de_service: DataExplorerService): @@ -4211,6 +4218,7 @@ def test_polars_profile_summary_stats(dxf: DataExplorerFixture): assert_summary_stats_equal(stats["type_display"], stats, ex_result) +@pytest.mark.skipif(ibis is None, reason="ibis is not available") def test_ibis_supported_features(dxf: DataExplorerFixture): dxf.register_table("example", SIMPLE_IBIS_DF) features = dxf.get_state("example")["supported_features"] diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py index 15ad0aed6bcd..ca5dd900baaf 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py @@ -9,14 +9,11 @@ import types from typing import Any, Callable, Iterable, Optional, Tuple -import geopandas import numpy as np import pandas as pd import polars as pl import pytest -import torch from fastcore.foundation import L -from shapely.geometry import Polygon from positron import inspectors from positron.inspectors import _get_simplified_qualname, get_inspector @@ -37,6 +34,23 @@ ) from .utils import get_type_as_str +try: + import geopandas + from shapely.geometry import Polygon +except ImportError: + geopandas = None + Polygon = None + +try: + import torch +except ImportError: + torch = None + +try: + import ibis +except ImportError: + ibis = None + def verify_inspector( *, @@ -627,6 +641,7 @@ def mutate(x): ) +@pytest.mark.skipif(geopandas is None, reason="geopandas is not available") def test_inspect_geopandas_dataframe() -> None: p1 = Polygon([(0, 0), (1, 0), (1, 1)]) p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) @@ -708,19 +723,15 @@ def mutate(x): ) -@pytest.mark.parametrize( - "value", - [ - geopandas.GeoSeries( - [ - Polygon([(0, 0), (1, 0), (1, 1)]), - Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), - Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), - ] - ), - ], -) -def test_inspect_geopandas_series(value: geopandas.GeoSeries) -> None: +@pytest.mark.skipif(geopandas is None, reason="geopandas is not available") +def test_inspect_geopandas_series() -> None: + value = geopandas.GeoSeries( + [ + Polygon([(0, 0), (1, 0), (1, 1)]), + Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), + Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), + ] + ) (rows,) = value.shape def mutate(x): @@ -875,9 +886,8 @@ def test_get_child(value: Any, key: Any, expected: Any) -> None: @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10 or higher") +@pytest.mark.skipif(ibis is None, reason="ibis not available") def test_inspect_ibis_exprs() -> None: - import ibis - # Make sure we don't return an executed repr ibis.options.interactive = True @@ -921,16 +931,21 @@ def test_inspect_ibis_exprs() -> None: @pytest.mark.parametrize( ("value", "expected"), [ - (np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), 48), - (torch.Tensor([[1, 2, 3], [4, 5, 6]]), 24), - (pd.Series([1, 2, 3, 4]), 32), - (pl.Series([1, 2, 3, 4]), 32), - (pd.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), - (pl.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), - (pd.Index([0, 1]), 16), + (lambda: np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), 48), + pytest.param( + lambda: torch.Tensor([[1, 2, 3], [4, 5, 6]]), + 24, + marks=pytest.mark.skipif(torch is None, reason="torch not available"), + ), + (lambda: pd.Series([1, 2, 3, 4]), 32), + (lambda: pl.Series([1, 2, 3, 4]), 32), + (lambda: pd.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), + (lambda: pl.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), + (lambda: pd.Index([0, 1]), 16), ], ) -def test_arrays_maps_get_size(value: Any, expected: int) -> None: +def test_arrays_maps_get_size(value: Callable, expected: int) -> None: + value = value() if value is None: return inspector = get_inspector(value) @@ -944,43 +959,53 @@ class VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong: @pytest.mark.parametrize( "value", [ - pytest.param("The quick brown fox jumps over the lazy dog", id="string"), - pytest.param(sys.maxsize * 100, id="int"), - pytest.param(sys.float_info.max, id="float"), - pytest.param(complex(sys.float_info.min, sys.float_info.max), id="complex"), + pytest.param(lambda: "The quick brown fox jumps over the lazy dog", id="string"), + pytest.param(lambda: sys.maxsize * 100, id="int"), + pytest.param(lambda: sys.float_info.max, id="float"), + pytest.param(lambda: complex(sys.float_info.min, sys.float_info.max), id="complex"), pytest.param( - VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong, id="class" + lambda: VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong, + id="class", ), - pytest.param(b"The quick brown fox jumps over the lazy dog", id="bytes"), - pytest.param(bytearray(b"The quick brown fox jumps over the lazy dog"), id="bytearray"), - pytest.param(set(range(20)), id="set"), - pytest.param(frozenset(range(20)), id="frozenset"), - pytest.param(list(range(20)), id="list"), - pytest.param(LIST_WITH_CYCLE, id="list_cycle"), - pytest.param(range(12345678901), id="range"), - pytest.param(L(range(20)), id="fastcore_list"), - pytest.param(FASTCORE_LIST_WITH_CYCLE, id="fastcore_list_cycle"), - pytest.param({str(i): i for i in range(20)}, id="map"), - pytest.param(MAP_WITH_CYCLE, id="map_cycle"), + pytest.param(lambda: b"The quick brown fox jumps over the lazy dog", id="bytes"), pytest.param( - datetime.datetime(2021, 1, 1, 1, 23, 45, tzinfo=datetime.timezone.utc), + lambda: bytearray(b"The quick brown fox jumps over the lazy dog"), id="bytearray" + ), + pytest.param(lambda: set(range(20)), id="set"), + pytest.param(lambda: frozenset(range(20)), id="frozenset"), + pytest.param(lambda: list(range(20)), id="list"), + pytest.param(lambda: LIST_WITH_CYCLE, id="list_cycle"), + pytest.param(lambda: range(12345678901), id="range"), + pytest.param(lambda: L(range(20)), id="fastcore_list"), + pytest.param(lambda: FASTCORE_LIST_WITH_CYCLE, id="fastcore_list_cycle"), + pytest.param(lambda: {str(i): i for i in range(20)}, id="map"), + pytest.param(lambda: MAP_WITH_CYCLE, id="map_cycle"), + pytest.param( + lambda: datetime.datetime(2021, 1, 1, 1, 23, 45, tzinfo=datetime.timezone.utc), id="timestamp_datetime", ), - pytest.param(pd.Timestamp("2021-01-01 01:23:45"), id="timestamp_pandas"), - pytest.param(pd.Index(list(range(20))), id="pandas_index"), - pytest.param(pd.Series(list(range(20))), id="pandas_series"), + pytest.param(lambda: pd.Timestamp("2021-01-01 01:23:45"), id="timestamp_pandas"), + pytest.param(lambda: pd.Index(list(range(20))), id="pandas_index"), + pytest.param(lambda: pd.Series(list(range(20))), id="pandas_series"), + pytest.param( + lambda: pd.DataFrame({"a": list(range(20)), "b": list(range(20))}), + id="pandas_dataframe", + ), + pytest.param(lambda: pl.Series(list(range(20))), id="polars_series"), pytest.param( - pd.DataFrame({"a": list(range(20)), "b": list(range(20))}), id="pandas_dataframe" + lambda: pl.DataFrame({"a": list(range(20)), "b": list(range(20))}), + id="polars_dataframe", ), - pytest.param(pl.Series(list(range(20))), id="polars_series"), + pytest.param(lambda: np.ones((20, 20)), id="numpy_array"), pytest.param( - pl.DataFrame({"a": list(range(20)), "b": list(range(20))}), id="polars_dataframe" + lambda: torch.ones((20, 20)), + id="torch_tensor", + marks=pytest.mark.skipif(torch is None, reason="torch not available"), ), - pytest.param(np.ones((20, 20)), id="numpy_array"), - pytest.param(torch.ones((20, 20)), id="torch_tensor"), ], ) def test_truncated_display_value(value, snapshot, monkeypatch) -> None: + value = value() # Patch the maximum string length for faster and more readable tests. monkeypatch.setattr(inspectors, "MAX_ITEMS_BY_LEVEL", (20, 10)) monkeypatch.setattr(inspectors, "MAX_CHARACTERS", 20) diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py b/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py index 42ce40ca61f7..9331f3f761dd 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py @@ -3,12 +3,18 @@ # Licensed under the Elastic License 2.0. See LICENSE.txt for license information. # +import sys from typing import Any, Dict from unittest.mock import patch +import pytest + from positron.positron_ipkernel import PositronShell +@pytest.mark.skipif( + sys.version_info >= (3, 14), reason="haystack is not installed at all on 3.14 yet" +) def test_haystack_patch_automatically_applied(shell: PositronShell): """ Test that the haystack is_in_jupyter function is automatically patched to return True. diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_positron_ipkernel.py b/extensions/positron-python/python_files/posit/positron/tests/test_positron_ipkernel.py index 66ecd33ef841..e1e2d0e763b1 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_positron_ipkernel.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_positron_ipkernel.py @@ -24,6 +24,11 @@ from .conftest import PositronShell from .utils import assert_register_table_called +try: + import lightning +except ImportError: + lightning = None + # The idea for these tests is to mock out communications with Positron # via our various comms, and only test IPython interactions. For # example, in testing the %view magic, we assert that running a cell @@ -420,6 +425,7 @@ def test_console_warning_logger(shell: PositronShell, caplog, warning_kwargs): assert "this is a warning" in caplog.text +@pytest.mark.skipif(lightning is None, reason="lightning is not installed") def test_import_lightning_and_torch_dynamo(shell: PositronShell) -> None: # See: https://github.com/posit-dev/positron/issues/5879 shell.run_cell("import lightning").raise_error() diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py index 06982225d0c6..63d433a7c300 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py @@ -29,7 +29,7 @@ ) try: - import torch # type: ignore [reportMissingImports] for 3.12 + import torch except ImportError: torch = None @@ -104,7 +104,8 @@ def test_set_console_width(ui_comm: DummyComm) -> None: assert np.get_printoptions()["linewidth"] == width assert pd.get_option("display.width") is None assert pl.Config.state()["POLARS_TABLE_WIDTH"] == str(width) - assert torch._tensor_str.PRINT_OPTS.linewidth == width # type: ignore[reportGeneralTypeIssues] # noqa: SLF001 + if torch is not None: + assert torch._tensor_str.PRINT_OPTS.linewidth == width # noqa: SLF001 def test_open_editor(ui_service: UiService, ui_comm: DummyComm) -> None: diff --git a/extensions/positron-python/src/client/common/constants.ts b/extensions/positron-python/src/client/common/constants.ts index 5ab383d420f0..750c2246edde 100644 --- a/extensions/positron-python/src/client/common/constants.ts +++ b/extensions/positron-python/src/client/common/constants.ts @@ -157,7 +157,7 @@ export const UseProposedApi = Symbol('USE_VSC_PROPOSED_API'); export const IPYKERNEL_VERSION = '>=6.19.1'; // We support versions where MINIMUM_PYTHON_VERSION <= version < MAXIMUM_PYTHON_VERSION_EXCLUSIVE. export const MINIMUM_PYTHON_VERSION = { major: 3, minor: 9, patch: 0, raw: '3.9.0' } as PythonVersion; -export const MAXIMUM_PYTHON_VERSION_EXCLUSIVE = { major: 3, minor: 14, patch: 0, raw: '3.14.0' } as PythonVersion; +export const MAXIMUM_PYTHON_VERSION_EXCLUSIVE = { major: 3, minor: 15, patch: 0, raw: '3.15.0' } as PythonVersion; export const INTERPRETERS_INCLUDE_SETTING_KEY = 'interpreters.include'; export const INTERPRETERS_EXCLUDE_SETTING_KEY = 'interpreters.exclude'; export const INTERPRETERS_OVERRIDE_SETTING_KEY = 'interpreters.override'; diff --git a/extensions/positron-python/src/client/positron/ipykernel.ts b/extensions/positron-python/src/client/positron/ipykernel.ts index cecfa83588f2..4d361f4c545c 100644 --- a/extensions/positron-python/src/client/positron/ipykernel.ts +++ b/extensions/positron-python/src/client/positron/ipykernel.ts @@ -49,7 +49,7 @@ export async function getIpykernelBundle( // Check if ipykernel is bundled for the interpreter version. // (defined in scripts/pip-compile-ipykernel.py). - if (interpreter.version?.major !== 3 || ![9, 10, 11, 12, 13].includes(interpreter.version?.minor)) { + if (interpreter.version?.major !== 3 || ![9, 10, 11, 12, 13, 14].includes(interpreter.version?.minor)) { return { disabledReason: `unsupported interpreter version: ${interpreter.version?.raw}` }; } diff --git a/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts b/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts index d6c5d33b18cc..8a3b6207d91f 100644 --- a/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts +++ b/extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvUtils.ts @@ -7,7 +7,7 @@ import { CancellationToken, QuickPickItem } from 'vscode'; import { showQuickPickWithBack } from '../../../common/vscodeApis/windowApis'; import { CreateEnv } from '../../../common/utils/localize'; -const SUPPORTED_UV_PYTHON_VERSIONS = ['3.14', '3.13', '3.12', '3.11', '3.10', '3.9']; +const SUPPORTED_UV_PYTHON_VERSIONS = ['3.13', '3.12', '3.11', '3.10', '3.9', '3.14']; export function getUvPythonVersions(): { versions: string[] } { return { @@ -18,7 +18,7 @@ export function getUvPythonVersions(): { versions: string[] } { export async function pickPythonVersion(token?: CancellationToken): Promise { const items: QuickPickItem[] = SUPPORTED_UV_PYTHON_VERSIONS.map((v) => ({ label: 'Python', - description: v, + description: v === '3.14' ? `${v} (preview)` : v, })); const selection = await showQuickPickWithBack( items, diff --git a/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts b/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts index be9a369935f3..37ff6ff4ea53 100644 --- a/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts +++ b/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts @@ -13,6 +13,7 @@ import { DOES_NOT_EXIST, fixPath, FSFixture, + OSX, SUPPORTS_SOCKETS, SUPPORTS_SYMLINKS, WINDOWS, @@ -468,6 +469,12 @@ suite('FileSystem - utils', () => { if (!SUPPORTS_SOCKETS) { this.skip(); } + // --- Start Positron --- + // for some reason this fails only on macOS, which upstream does not test on but we do + if (OSX) { + this.skip(); + } + // --- End Positron --- const sockFile = await fix.createSocket('x/y/z/ipc.sock'); const exists = utils.fileExistsSync(sockFile); @@ -764,6 +771,12 @@ suite('FileSystem', () => { if (!SUPPORTS_SOCKETS) { this.skip(); } + // --- Start Positron --- + // for some reason this fails only on macOS, which upstream does not test on but we do + if (OSX) { + this.skip(); + } + // --- End Positron --- const sockFile = await fix.createSocket('x/y/z/ipc.sock'); const exists = fileSystem.fileExistsSync(sockFile); diff --git a/src/vs/workbench/browser/positronNewFolderFlow/utilities/uvUtils.ts b/src/vs/workbench/browser/positronNewFolderFlow/utilities/uvUtils.ts index a7a5d5eccf45..fe61c2e030f9 100644 --- a/src/vs/workbench/browser/positronNewFolderFlow/utilities/uvUtils.ts +++ b/src/vs/workbench/browser/positronNewFolderFlow/utilities/uvUtils.ts @@ -42,7 +42,7 @@ export const uvInterpretersToDropdownItems = ( preferred: false, runtimeId: version, languageName: 'Python', - languageVersion: version, + languageVersion: version === '3.14' ? `${version} (preview)` : version, runtimePath: '', runtimeSource: PythonEnvironmentProvider.Uv, }, From 3c198ce067c34329aa141afa3a02635b04c98567 Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Mon, 29 Sep 2025 14:27:19 -0500 Subject: [PATCH 5/6] fix more tests --- .../posit/pinned-test-requirements.txt | 2 +- .../posit/positron/tests/test_inspectors.py | 24 +++++++++---------- .../posit/positron/tests/test_ui.py | 2 +- .../python_files/posit/test-requirements.txt | 2 +- .../platform/filesystem.functional.test.ts | 13 ---------- .../src/test/common/platform/utils.ts | 6 ++++- 6 files changed, 20 insertions(+), 29 deletions(-) diff --git a/extensions/positron-python/python_files/posit/pinned-test-requirements.txt b/extensions/positron-python/python_files/posit/pinned-test-requirements.txt index e068bb9d175f..a314516791be 100644 --- a/extensions/positron-python/python_files/posit/pinned-test-requirements.txt +++ b/extensions/positron-python/python_files/posit/pinned-test-requirements.txt @@ -47,7 +47,7 @@ torch==2.8.0; python_version < '3.14' scipy==1.13.1; python_version == '3.9' scipy==1.15.3; python_version == '3.10' scipy==1.16.2; python_version >= '3.11' -snowflake-connector-python==3.17.4 +snowflake-connector-python==3.17.4; python_version < '3.14' SQLAlchemy==2.0.43 # putting this last like test-requirements.txt diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py index ca5dd900baaf..8d02bf99c49a 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py @@ -643,11 +643,11 @@ def mutate(x): @pytest.mark.skipif(geopandas is None, reason="geopandas is not available") def test_inspect_geopandas_dataframe() -> None: - p1 = Polygon([(0, 0), (1, 0), (1, 1)]) - p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) - p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]) + p1 = Polygon([(0, 0), (1, 0), (1, 1)]) # type: ignore + p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) # type: ignore + p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]) # type: ignore - value = geopandas.GeoDataFrame({"g": geopandas.GeoSeries([p1, p2, p3]), "data": [0, 1, 2]}) + value = geopandas.GeoDataFrame({"g": geopandas.GeoSeries([p1, p2, p3]), "data": [0, 1, 2]}) # type: ignore rows, cols = value.shape @@ -725,11 +725,11 @@ def mutate(x): @pytest.mark.skipif(geopandas is None, reason="geopandas is not available") def test_inspect_geopandas_series() -> None: - value = geopandas.GeoSeries( + value = geopandas.GeoSeries( # type: ignore [ - Polygon([(0, 0), (1, 0), (1, 1)]), - Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), - Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), + Polygon([(0, 0), (1, 0), (1, 1)]), # type: ignore + Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), # type: ignore + Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), # type: ignore ] ) (rows,) = value.shape @@ -889,11 +889,11 @@ def test_get_child(value: Any, key: Any, expected: Any) -> None: @pytest.mark.skipif(ibis is None, reason="ibis not available") def test_inspect_ibis_exprs() -> None: # Make sure we don't return an executed repr - ibis.options.interactive = True + ibis.options.interactive = True # type: ignore test_df = pd.DataFrame({"a": [1, 2, 1, 1, 2], "b": ["foo", "bar", "baz", "qux", None]}) _, columns = test_df.shape - t = ibis.memtable(test_df, name="df") + t = ibis.memtable(test_df, name="df") # type: ignore table_type = "ibis.Table" verify_inspector( @@ -933,7 +933,7 @@ def test_inspect_ibis_exprs() -> None: [ (lambda: np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), 48), pytest.param( - lambda: torch.Tensor([[1, 2, 3], [4, 5, 6]]), + lambda: torch.Tensor([[1, 2, 3], [4, 5, 6]]), # type: ignore 24, marks=pytest.mark.skipif(torch is None, reason="torch not available"), ), @@ -998,7 +998,7 @@ class VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong: ), pytest.param(lambda: np.ones((20, 20)), id="numpy_array"), pytest.param( - lambda: torch.ones((20, 20)), + lambda: torch.ones((20, 20)), # type: ignore id="torch_tensor", marks=pytest.mark.skipif(torch is None, reason="torch not available"), ), diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py index 63d433a7c300..e5feaf49d2ea 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py @@ -105,7 +105,7 @@ def test_set_console_width(ui_comm: DummyComm) -> None: assert pd.get_option("display.width") is None assert pl.Config.state()["POLARS_TABLE_WIDTH"] == str(width) if torch is not None: - assert torch._tensor_str.PRINT_OPTS.linewidth == width # noqa: SLF001 + assert torch._tensor_str.PRINT_OPTS.linewidth == width # noqa: SLF001 # type: ignore def test_open_editor(ui_service: UiService, ui_comm: DummyComm) -> None: diff --git a/extensions/positron-python/python_files/posit/test-requirements.txt b/extensions/positron-python/python_files/posit/test-requirements.txt index b9bae3ffb0c4..e7f47462c3a9 100644 --- a/extensions/positron-python/python_files/posit/test-requirements.txt +++ b/extensions/positron-python/python_files/posit/test-requirements.txt @@ -24,7 +24,7 @@ pytest-mock syrupy torch; python_version < '3.14' scipy -snowflake-connector-python +snowflake-connector-python; python_version < '3.14' sqlalchemy # putting this last because holoviews is picky about dependency versions (including bokeh), diff --git a/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts b/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts index 37ff6ff4ea53..be9a369935f3 100644 --- a/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts +++ b/extensions/positron-python/src/test/common/platform/filesystem.functional.test.ts @@ -13,7 +13,6 @@ import { DOES_NOT_EXIST, fixPath, FSFixture, - OSX, SUPPORTS_SOCKETS, SUPPORTS_SYMLINKS, WINDOWS, @@ -469,12 +468,6 @@ suite('FileSystem - utils', () => { if (!SUPPORTS_SOCKETS) { this.skip(); } - // --- Start Positron --- - // for some reason this fails only on macOS, which upstream does not test on but we do - if (OSX) { - this.skip(); - } - // --- End Positron --- const sockFile = await fix.createSocket('x/y/z/ipc.sock'); const exists = utils.fileExistsSync(sockFile); @@ -771,12 +764,6 @@ suite('FileSystem', () => { if (!SUPPORTS_SOCKETS) { this.skip(); } - // --- Start Positron --- - // for some reason this fails only on macOS, which upstream does not test on but we do - if (OSX) { - this.skip(); - } - // --- End Positron --- const sockFile = await fix.createSocket('x/y/z/ipc.sock'); const exists = fileSystem.fileExistsSync(sockFile); diff --git a/extensions/positron-python/src/test/common/platform/utils.ts b/extensions/positron-python/src/test/common/platform/utils.ts index 881e3cd019b9..76da140dd41b 100644 --- a/extensions/positron-python/src/test/common/platform/utils.ts +++ b/extensions/positron-python/src/test/common/platform/utils.ts @@ -28,7 +28,11 @@ export const SUPPORTS_SYMLINKS = (() => { return true; })(); export const SUPPORTS_SOCKETS = (() => { - if (WINDOWS) { + // --- Start Positron --- + // Upstream doesn't run on OSX but that seems to fail too. + // if (WINDOWS) { + if (WINDOWS || OSX) { + // --- End Positron --- // Windows requires named pipes to have a specific path under // the local domain ("\\.\pipe\*"). This makes them relatively // useless in our functional tests, where we want to use them From 7a84a7a37f2b1cbe53d71ca457a8bfeb67bb12bf Mon Sep 17 00:00:00 2001 From: Austin Dickey Date: Tue, 30 Sep 2025 12:41:54 -0500 Subject: [PATCH 6/6] asserts --- .../posit/positron/tests/test_access_keys.py | 3 +- .../posit/positron/tests/test_inspectors.py | 101 +++++++++--------- .../tests/test_patch/test_haystack.py | 8 +- .../posit/positron/tests/test_ui.py | 2 +- 4 files changed, 56 insertions(+), 58 deletions(-) diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py b/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py index f5a7d90f9bb4..d1a1652444df 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_access_keys.py @@ -28,7 +28,7 @@ ) try: - import torch # type: ignore [reportMissingImports] for 3.14 + import torch except ImportError: torch = None @@ -98,7 +98,6 @@ def test_encode_access_key_not_implemented_error(case: Any) -> None: @pytest.mark.parametrize( "type_name", [ - # for Python 3.14 "torch.Tensor" if torch else "None", "function", ], diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py index 8d02bf99c49a..6a88ac630121 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_inspectors.py @@ -643,11 +643,13 @@ def mutate(x): @pytest.mark.skipif(geopandas is None, reason="geopandas is not available") def test_inspect_geopandas_dataframe() -> None: - p1 = Polygon([(0, 0), (1, 0), (1, 1)]) # type: ignore - p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) # type: ignore - p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]) # type: ignore + assert Polygon + assert geopandas + p1 = Polygon([(0, 0), (1, 0), (1, 1)]) + p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) + p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]) - value = geopandas.GeoDataFrame({"g": geopandas.GeoSeries([p1, p2, p3]), "data": [0, 1, 2]}) # type: ignore + value = geopandas.GeoDataFrame({"g": geopandas.GeoSeries([p1, p2, p3]), "data": [0, 1, 2]}) rows, cols = value.shape @@ -725,11 +727,13 @@ def mutate(x): @pytest.mark.skipif(geopandas is None, reason="geopandas is not available") def test_inspect_geopandas_series() -> None: - value = geopandas.GeoSeries( # type: ignore + assert Polygon + assert geopandas + value = geopandas.GeoSeries( [ - Polygon([(0, 0), (1, 0), (1, 1)]), # type: ignore - Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), # type: ignore - Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), # type: ignore + Polygon([(0, 0), (1, 0), (1, 1)]), + Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), + Polygon([(2, 0), (3, 0), (3, 1), (2, 1)]), ] ) (rows,) = value.shape @@ -888,12 +892,13 @@ def test_get_child(value: Any, key: Any, expected: Any) -> None: @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires Python 3.10 or higher") @pytest.mark.skipif(ibis is None, reason="ibis not available") def test_inspect_ibis_exprs() -> None: + assert ibis # Make sure we don't return an executed repr - ibis.options.interactive = True # type: ignore + ibis.options.interactive = True test_df = pd.DataFrame({"a": [1, 2, 1, 1, 2], "b": ["foo", "bar", "baz", "qux", None]}) _, columns = test_df.shape - t = ibis.memtable(test_df, name="df") # type: ignore + t = ibis.memtable(test_df, name="df") table_type = "ibis.Table" verify_inspector( @@ -931,21 +936,16 @@ def test_inspect_ibis_exprs() -> None: @pytest.mark.parametrize( ("value", "expected"), [ - (lambda: np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), 48), - pytest.param( - lambda: torch.Tensor([[1, 2, 3], [4, 5, 6]]), # type: ignore - 24, - marks=pytest.mark.skipif(torch is None, reason="torch not available"), - ), - (lambda: pd.Series([1, 2, 3, 4]), 32), - (lambda: pl.Series([1, 2, 3, 4]), 32), - (lambda: pd.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), - (lambda: pl.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), - (lambda: pd.Index([0, 1]), 16), + (np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), 48), + (torch.Tensor([[1, 2, 3], [4, 5, 6]]) if torch else None, 24), + (pd.Series([1, 2, 3, 4]), 32), + (pl.Series([1, 2, 3, 4]), 32), + (pd.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), + (pl.DataFrame({"a": [1, 2], "b": ["3", "4"]}), 4), + (pd.Index([0, 1]), 16), ], ) -def test_arrays_maps_get_size(value: Callable, expected: int) -> None: - value = value() +def test_arrays_maps_get_size(value: Any, expected: int) -> None: if value is None: return inspector = get_inspector(value) @@ -959,53 +959,52 @@ class VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong: @pytest.mark.parametrize( "value", [ - pytest.param(lambda: "The quick brown fox jumps over the lazy dog", id="string"), - pytest.param(lambda: sys.maxsize * 100, id="int"), - pytest.param(lambda: sys.float_info.max, id="float"), - pytest.param(lambda: complex(sys.float_info.min, sys.float_info.max), id="complex"), + pytest.param("The quick brown fox jumps over the lazy dog", id="string"), + pytest.param(sys.maxsize * 100, id="int"), + pytest.param(sys.float_info.max, id="float"), + pytest.param(complex(sys.float_info.min, sys.float_info.max), id="complex"), pytest.param( - lambda: VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong, + VeryLongClassNameThatShouldDefinitelyBeTruncatedBecauseItIsWayTooLong, id="class", ), - pytest.param(lambda: b"The quick brown fox jumps over the lazy dog", id="bytes"), + pytest.param(b"The quick brown fox jumps over the lazy dog", id="bytes"), + pytest.param(bytearray(b"The quick brown fox jumps over the lazy dog"), id="bytearray"), + pytest.param(set(range(20)), id="set"), + pytest.param(frozenset(range(20)), id="frozenset"), + pytest.param(list(range(20)), id="list"), + pytest.param(LIST_WITH_CYCLE, id="list_cycle"), + pytest.param(range(12345678901), id="range"), + pytest.param(L(range(20)), id="fastcore_list"), + pytest.param(FASTCORE_LIST_WITH_CYCLE, id="fastcore_list_cycle"), + pytest.param({str(i): i for i in range(20)}, id="map"), + pytest.param(MAP_WITH_CYCLE, id="map_cycle"), pytest.param( - lambda: bytearray(b"The quick brown fox jumps over the lazy dog"), id="bytearray" - ), - pytest.param(lambda: set(range(20)), id="set"), - pytest.param(lambda: frozenset(range(20)), id="frozenset"), - pytest.param(lambda: list(range(20)), id="list"), - pytest.param(lambda: LIST_WITH_CYCLE, id="list_cycle"), - pytest.param(lambda: range(12345678901), id="range"), - pytest.param(lambda: L(range(20)), id="fastcore_list"), - pytest.param(lambda: FASTCORE_LIST_WITH_CYCLE, id="fastcore_list_cycle"), - pytest.param(lambda: {str(i): i for i in range(20)}, id="map"), - pytest.param(lambda: MAP_WITH_CYCLE, id="map_cycle"), - pytest.param( - lambda: datetime.datetime(2021, 1, 1, 1, 23, 45, tzinfo=datetime.timezone.utc), + datetime.datetime(2021, 1, 1, 1, 23, 45, tzinfo=datetime.timezone.utc), id="timestamp_datetime", ), - pytest.param(lambda: pd.Timestamp("2021-01-01 01:23:45"), id="timestamp_pandas"), - pytest.param(lambda: pd.Index(list(range(20))), id="pandas_index"), - pytest.param(lambda: pd.Series(list(range(20))), id="pandas_series"), + pytest.param(pd.Timestamp("2021-01-01 01:23:45"), id="timestamp_pandas"), + pytest.param(pd.Index(list(range(20))), id="pandas_index"), + pytest.param(pd.Series(list(range(20))), id="pandas_series"), pytest.param( - lambda: pd.DataFrame({"a": list(range(20)), "b": list(range(20))}), + pd.DataFrame({"a": list(range(20)), "b": list(range(20))}), id="pandas_dataframe", ), - pytest.param(lambda: pl.Series(list(range(20))), id="polars_series"), + pytest.param(pl.Series(list(range(20))), id="polars_series"), pytest.param( - lambda: pl.DataFrame({"a": list(range(20)), "b": list(range(20))}), + pl.DataFrame({"a": list(range(20)), "b": list(range(20))}), id="polars_dataframe", ), - pytest.param(lambda: np.ones((20, 20)), id="numpy_array"), + pytest.param(np.ones((20, 20)), id="numpy_array"), pytest.param( - lambda: torch.ones((20, 20)), # type: ignore + torch.ones((20, 20)) if torch else None, id="torch_tensor", marks=pytest.mark.skipif(torch is None, reason="torch not available"), ), ], ) def test_truncated_display_value(value, snapshot, monkeypatch) -> None: - value = value() + if value is None: + return # Patch the maximum string length for faster and more readable tests. monkeypatch.setattr(inspectors, "MAX_ITEMS_BY_LEVEL", (20, 10)) monkeypatch.setattr(inspectors, "MAX_CHARACTERS", 20) diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py b/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py index 9331f3f761dd..b79cbed0b861 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_patch/test_haystack.py @@ -3,7 +3,7 @@ # Licensed under the Elastic License 2.0. See LICENSE.txt for license information. # -import sys +from importlib.util import find_spec from typing import Any, Dict from unittest.mock import patch @@ -11,10 +11,10 @@ from positron.positron_ipkernel import PositronShell +missing_haystack = find_spec("haystack") is None and find_spec("haystack_ai") is None -@pytest.mark.skipif( - sys.version_info >= (3, 14), reason="haystack is not installed at all on 3.14 yet" -) + +@pytest.mark.skipif(missing_haystack, reason="haystack is not installed") def test_haystack_patch_automatically_applied(shell: PositronShell): """ Test that the haystack is_in_jupyter function is automatically patched to return True. diff --git a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py index e5feaf49d2ea..0725998a7cfa 100644 --- a/extensions/positron-python/python_files/posit/positron/tests/test_ui.py +++ b/extensions/positron-python/python_files/posit/positron/tests/test_ui.py @@ -105,7 +105,7 @@ def test_set_console_width(ui_comm: DummyComm) -> None: assert pd.get_option("display.width") is None assert pl.Config.state()["POLARS_TABLE_WIDTH"] == str(width) if torch is not None: - assert torch._tensor_str.PRINT_OPTS.linewidth == width # noqa: SLF001 # type: ignore + assert torch._tensor_str.PRINT_OPTS.linewidth == width # type: ignore[reportGeneralTypeIssues] # noqa: SLF001 def test_open_editor(ui_service: UiService, ui_comm: DummyComm) -> None: