diff --git a/.github/workflows/positron-python-ci.yml b/.github/workflows/positron-python-ci.yml
index cb86336b1c8..f077fbc4e23 100644
--- a/.github/workflows/positron-python-ci.yml
+++ b/.github/workflows/positron-python-ci.yml
@@ -23,7 +23,7 @@ env:
NODE_VERSION: '18.17.1'
PYTHON_VERSION: '3.10'
PROJECT_DIR: 'extensions/positron-python'
- PYTHON_SRC_DIR: 'extensions/positron-python/pythonFiles'
+ PYTHON_SRC_DIR: 'extensions/positron-python/python_files'
# 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.
special-working-directory: './path with spaces'
@@ -67,16 +67,11 @@ jobs:
- name: Check TypeScript format
run: yarn format-check
- - name: Check Python format
- run: |
- python -m pip install -U black
- python -m black . --check
- working-directory: ${{ env.PYTHON_SRC_DIR }}
-
- - name: Run Ruff
+ - name: Lint and Check Formatting with Ruff
run: |
python -m pip install -U ruff
python -m ruff check .
+ python -m ruff format --check
working-directory: ${{ env.PYTHON_SRC_DIR }}
check-types:
@@ -93,16 +88,16 @@ jobs:
cache: 'pip'
- name: Install base Python requirements
- run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --no-cache-dir --implementation py -r requirements.txt'
+ run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/python --no-cache-dir --implementation py -r requirements.txt'
- name: Install Positron IPyKernel requirements
run: python scripts/vendor.py
- name: Install other Python requirements
run: |
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- python -m pip install --upgrade -r ./pythonFiles/positron/pinned-test-requirements.txt
+ python -m pip install --upgrade -r ./python_files/positron/pinned-test-requirements.txt
- name: Run Pyright
uses: jakebailey/pyright-action@v2
@@ -169,13 +164,13 @@ jobs:
run: python -m pytest --version
- name: Install base Python requirements
- run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --no-cache-dir --implementation py -r requirements.txt'
+ run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/python --no-cache-dir --implementation py -r requirements.txt'
- name: Install test requirements
run: python -m pip install -r build/test-requirements.txt
- name: Run Python unit tests
- run: python pythonFiles/tests/run_all.py
+ run: python python_files/tests/run_all.py
positron-ipykernel-tests:
name: Test Positron IPyKernel
@@ -225,7 +220,7 @@ jobs:
run: python scripts/vendor.py
- name: Install Positron IPyKernel test requirements
- run: python -m pip install --prefer-binary --upgrade -r pythonFiles/positron/pinned-test-requirements.txt
+ run: python -m pip install --prefer-binary --upgrade -r python_files/positron/pinned-test-requirements.txt
- name: Get date for older dependencies
if: ${{ matrix.time-elapsed != '' }}
@@ -237,10 +232,10 @@ jobs:
run: |
python -m pip config set global.index-url https://packagemanager.posit.co/pypi/${{ env.SNAPSHOT_DATE }}/simple
python -m pip config set global.trusted-host packagemanager.posit.co
- python -m pip install --prefer-binary --force-reinstall -r pythonFiles/positron/data-science-requirements.txt
+ python -m pip install --prefer-binary --force-reinstall -r python_files/positron/data-science-requirements.txt
- name: Run Positron IPyKernel unit tests
- run: pytest pythonFiles/positron
+ run: pytest python_files/positron
typescript-tests:
name: Test TypeScript
diff --git a/extensions/positron-python/.devcontainer/devcontainer.json b/extensions/positron-python/.devcontainer/devcontainer.json
index fe15f35764e..67a8833d30c 100644
--- a/extensions/positron-python/.devcontainer/devcontainer.json
+++ b/extensions/positron-python/.devcontainer/devcontainer.json
@@ -9,13 +9,13 @@
"customizations": {
"vscode": {
"extensions": [
+ "charliermarsh.ruff",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-python.python",
- "ms-python.black-formatter",
"ms-python.vscode-pylance",
- "charliermarsh.ruff"
+ "ms-python.debugpy"
]
}
},
diff --git a/extensions/positron-python/.eslintignore b/extensions/positron-python/.eslintignore
index 7f6bb48d6c8..9399ff461dc 100644
--- a/extensions/positron-python/.eslintignore
+++ b/extensions/positron-python/.eslintignore
@@ -105,7 +105,7 @@ src/test/common/process/proc.unit.test.ts
src/test/common/interpreterPathService.unit.test.ts
-src/test/pythonFiles/formatting/dummy.ts
+src/test/python_files/formatting/dummy.ts
src/test/debugger/extension/adapter/adapter.test.ts
src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts
diff --git a/extensions/positron-python/.git-blame-ignore-revs b/extensions/positron-python/.git-blame-ignore-revs
new file mode 100644
index 00000000000..e2c2a50781b
--- /dev/null
+++ b/extensions/positron-python/.git-blame-ignore-revs
@@ -0,0 +1,15 @@
+# Prettier
+2b6a8f2d439fe9d5e66665ea46d8b690ac9b2c39
+649156a09ccdc51c0d20f7cd44540f1918f9347b
+4f774d94bf4fbf87bb417b2b2b8e79e334eb3536
+61b179b2092050709e3c373a6738abad8ce581c4
+c33617b0b98daeb4d72040b48c5850b476d6256c
+db8e1e2460e9754ec0672d958789382b6d15c5aa
+08bc9ad3bee5b19f02fa756fbc53ab32f1b39920
+# Black
+a58eeffd1b64498e2afe5f11597888dfd1c8699c
+5cd8f539f4d2086b718c8f11f823c0ac12fc2c49
+9ec9e9eaebb25adc6d942ac19d4d6c128abb987f
+c4af91e090057d20d7a633b3afa45eaa13ece76f
+# Ruff
+e931bed3efbede7b05113316506958ecd7506777
diff --git a/extensions/positron-python/.github/actions/build-vsix/action.yml b/extensions/positron-python/.github/actions/build-vsix/action.yml
index 52d6d1cdbdd..5b8a569889a 100644
--- a/extensions/positron-python/.github/actions/build-vsix/action.yml
+++ b/extensions/positron-python/.github/actions/build-vsix/action.yml
@@ -30,7 +30,7 @@ runs:
cache-dependency-path: |
requirements.txt
build/build-install-requirements.txt
- pythonFiles/jedilsp_requirements/requirements.txt
+ python_files/jedilsp_requirements/requirements.txt
- name: Upgrade Pip
run: python -m pip install -U pip
@@ -44,20 +44,20 @@ runs:
- name: Install Python dependencies
uses: brettcannon/pip-secure-install@v1
with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ options: '-t ./python_files/lib/python --implementation py'
- name: Install debugpy and get-pip
run: |
python -m pip --disable-pip-version-check install packaging
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
+ python ./python_files/install_debugpy.py
+ python ./python_files/download_get_pip.py
shell: bash
- name: Install Jedi LSP
uses: brettcannon/pip-secure-install@v1
with:
- requirements-file: './pythonFiles/jedilsp_requirements/requirements.txt'
- options: '-t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none'
+ requirements-file: './python_files/jedilsp_requirements/requirements.txt'
+ options: '-t ./python_files/lib/jedilsp --implementation py --platform any --abi none'
- name: Run npm ci
run: npm ci --prefer-offline
diff --git a/extensions/positron-python/.github/actions/lint/action.yml b/extensions/positron-python/.github/actions/lint/action.yml
index 47924c10815..444f331a3a9 100644
--- a/extensions/positron-python/.github/actions/lint/action.yml
+++ b/extensions/positron-python/.github/actions/lint/action.yml
@@ -41,16 +41,10 @@ runs:
python-version: '3.x'
cache: 'pip'
- - name: Check Python format
- run: |
- python -m pip install -U black
- python -m black . --check
- working-directory: pythonFiles
- shell: bash
-
- name: Run Ruff
run: |
python -m pip install -U ruff
python -m ruff check .
- working-directory: pythonFiles
+ python -m ruff format --check
+ working-directory: python_files
shell: bash
diff --git a/extensions/positron-python/.github/actions/smoke-tests/action.yml b/extensions/positron-python/.github/actions/smoke-tests/action.yml
index b2d00205043..7eaa2483942 100644
--- a/extensions/positron-python/.github/actions/smoke-tests/action.yml
+++ b/extensions/positron-python/.github/actions/smoke-tests/action.yml
@@ -34,12 +34,12 @@ runs:
- name: Install Python requirements
uses: brettcannon/pip-secure-install@v1
with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ options: '-t ./python_files/lib/python --implementation py'
- name: pip install system test requirements
run: |
python -m pip install --upgrade -r build/test-requirements.txt
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --implementation py --no-deps --upgrade --pre debugpy
shell: bash
# Bits from the VSIX are reused by smokeTest.ts to speed things up.
diff --git a/extensions/positron-python/.github/release_plan.md b/extensions/positron-python/.github/release_plan.md
index 71f8d8aa095..4d57726b4d0 100644
--- a/extensions/positron-python/.github/release_plan.md
+++ b/extensions/positron-python/.github/release_plan.md
@@ -1,14 +1,34 @@
+### General Notes
All dates should align with VS Code's [iteration](https://github.com/microsoft/vscode/labels/iteration-plan) and [endgame](https://github.com/microsoft/vscode/labels/endgame-plan) plans.
Feature freeze is Monday @ 17:00 America/Vancouver, XXX XX. At that point, commits to `main` should only be in response to bugs found during endgame testing until the release candidate is ready.
+
+ Release Primary and Secondary Assignments for the 2024 Calendar Year
-NOTE: the number of this release is in the issue title and can be substituted in wherever you see [YYYY.minor].
+| Month | Primary | Secondary |
+|:----------|:----------|:------------|
+✅ | ~~January~~ | ~~Eleanor~~ | ~~Karthik~~ |
+✅ | February | Kartik | Anthony |
+| March | Karthik | Eleanor |
+| April | Paula | Kartik |
+| May | Anthony | Karthik |
+| June | Eleanor | Paula |
+| July | Anthony | Karthik |
+| August | Paula | Kartik |
+| September | Anthony | Eleanor |
+| October | Paula | Kartik |
+| November | Kartik | Eleanor |
+| December | Karthik | Anthony |
+
+
# Release candidate (Monday, XXX XX)
NOTE: Third Party Notices are automatically added by our build pipelines using https://tools.opensource.microsoft.com/notice.
+NOTE: the number of this release is in the issue title and can be substituted in wherever you see [YYYY.minor].
+
### Step 1:
##### Bump the version of `main` to be a release candidate (also updating debugpy dependences, third party notices, and package-lock.json).❄️ (steps with ❄️ will dictate this step happens while main is frozen 🥶)
@@ -17,7 +37,7 @@ NOTE: Third Party Notices are automatically added by our build pipelines using
- [ ] Create a new branch called **`bump-release-[YYYY.minor]`**.
- [ ] Change the version in `package.json` to the next **even** number and switch the `-dev` to `-rc`. (🤖)
- [ ] Run `npm install` to make sure `package-lock.json` is up-to-date _(you should now see changes to the `package.json` and `package-lock.json` at this point which update the version number **only**)_. (🤖)
-- [ ] Check [debugpy on PyPI](https://pypi.org/project/debugpy/) for a new release and update the version of debugpy in [`install_debugpy.py`](https://github.com/microsoft/vscode-python/blob/main/pythonFiles/install_debugpy.py) if necessary.
+- [ ] Check [debugpy on PyPI](https://pypi.org/project/debugpy/) for a new release and update the version of debugpy in [`install_debugpy.py`](https://github.com/microsoft/vscode-python/blob/main/python_files/install_debugpy.py) if necessary.
- [ ] Update `ThirdPartyNotices-Repository.txt` as appropriate. You can check by looking at the [commit history](https://github.com/microsoft/vscode-python/commits/main) and scrolling through to see if there's anything listed there which might have pulled in some code directly into the repository from somewhere else. If you are still unsure you can check with the team.
- [ ] Create a PR from your branch **`bump-release-[YYYY.minor]`** to `main`. Add the `"no change-log"` tag to the PR so it does not show up on the release notes before merging it.
diff --git a/extensions/positron-python/.github/workflows/build.yml b/extensions/positron-python/.github/workflows/build.yml
index 586fe619d5d..544d07a6574 100644
--- a/extensions/positron-python/.github/workflows/build.yml
+++ b/extensions/positron-python/.github/workflows/build.yml
@@ -87,21 +87,21 @@ jobs:
- name: Install core Python requirements
uses: brettcannon/pip-secure-install@v1
with:
- options: '-t ./pythonFiles/lib/python --no-cache-dir --implementation py'
+ options: '-t ./python_files/lib/python --no-cache-dir --implementation py'
- name: Install Jedi requirements
run: python scripts/vendor.py
- name: Install other Python requirements
run: |
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
uses: jakebailey/pyright-action@v2
with:
version: 1.1.308
- working-directory: 'pythonFiles'
+ working-directory: 'python_files'
python-tests:
name: Python Tests
@@ -134,13 +134,13 @@ jobs:
uses: brettcannon/pip-secure-install@v1
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Python unit tests
- run: python pythonFiles/tests/run_all.py
+ run: python python_files/tests/run_all.py
tests:
name: Tests
@@ -189,19 +189,19 @@ jobs:
run: |
python -m pip install wheel
python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/download_get_pip.py
+ python ./python_files/download_get_pip.py
shell: bash
- name: Install debugpy
run: |
# We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
- name: Install core Python requirements
uses: brettcannon/pip-secure-install@v1
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
if: startsWith(matrix.python, 3.)
- name: Install Jedi requirements
@@ -215,7 +215,7 @@ jobs:
run: |
python -m pip install wheel
python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
+ python ./python_files/install_debugpy.py
shell: bash
if: matrix.test-suite == 'debugger'
diff --git a/extensions/positron-python/.github/workflows/pr-check.yml b/extensions/positron-python/.github/workflows/pr-check.yml
index 9b2aaa09974..427649ecd62 100644
--- a/extensions/positron-python/.github/workflows/pr-check.yml
+++ b/extensions/positron-python/.github/workflows/pr-check.yml
@@ -61,21 +61,21 @@ jobs:
- name: Install base Python requirements
uses: brettcannon/pip-secure-install@v1
with:
- options: '-t ./pythonFiles/lib/python --no-cache-dir --implementation py'
+ options: '-t ./python_files/lib/python --no-cache-dir --implementation py'
- name: Install Jedi requirements
run: python scripts/vendor.py
- name: Install other Python requirements
run: |
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
uses: jakebailey/pyright-action@v2
with:
version: 1.1.308
- working-directory: 'pythonFiles'
+ working-directory: 'python_files'
python-tests:
name: Python Tests
@@ -121,13 +121,13 @@ jobs:
uses: brettcannon/pip-secure-install@v1
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Python unit tests
- run: python pythonFiles/tests/run_all.py
+ run: python python_files/tests/run_all.py
tests:
name: Tests
@@ -176,20 +176,20 @@ jobs:
- name: Install debugpy
run: |
# We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
- name: Download get-pip.py
run: |
python -m pip install wheel
python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/download_get_pip.py
+ python ./python_files/download_get_pip.py
shell: bash
- name: Install base Python requirements
uses: brettcannon/pip-secure-install@v1
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
- name: Install Jedi requirements
run: python scripts/vendor.py
@@ -201,7 +201,7 @@ jobs:
run: |
python -m pip install wheel
python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
+ python ./python_files/install_debugpy.py
shell: bash
if: matrix.test-suite == 'debugger'
@@ -387,14 +387,14 @@ jobs:
cache: 'pip'
cache-dependency-path: |
requirements.txt
- pythonFiles/jedilsp_requirements/requirements.txt
+ python_files/jedilsp_requirements/requirements.txt
build/test-requirements.txt
build/functional-test-requirements.txt
- name: Install base Python requirements
uses: brettcannon/pip-secure-install@v1
with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ options: '-t ./python_files/lib/python --implementation py'
- name: Install Jedi requirements
run: python scripts/vendor.py
@@ -402,7 +402,7 @@ jobs:
- name: Install debugpy
run: |
# We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --implementation py --no-deps --upgrade --pre debugpy
+ python -m pip --disable-pip-version-check install -t ./python_files/lib/python --implementation py --no-deps --upgrade --pre debugpy
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
@@ -478,7 +478,7 @@ jobs:
- name: Run Python unit tests
run: |
- python pythonFiles/tests/run_all.py
+ python python_files/tests/run_all.py
# The virtual environment based tests use the `testSingleWorkspace` set of tests
# with the environment variable `TEST_FILES_SUFFIX` set to `testvirtualenvs`,
diff --git a/extensions/positron-python/.gitignore b/extensions/positron-python/.gitignore
index dceec679bc2..b38aca49bd6 100644
--- a/extensions/positron-python/.gitignore
+++ b/extensions/positron-python/.gitignore
@@ -23,9 +23,8 @@ cucumber-report.json
**/.venv*/
port.txt
precommit.hook
-pythonFiles/lib/**
-pythonFiles/get-pip.py
-pythonFiles/get_pip.py
+python_files/lib/**
+python_files/get-pip.py
debug_coverage*/**
languageServer/**
languageServer.*/**
@@ -52,6 +51,6 @@ dist/**
l10n/
tags
# --- Start Positron ---
-pythonFiles/positron/positron_ipykernel/tests/images
-pythonFiles/positron/positron_ipykernel/_vendor/**
+python_files/positron/positron_ipykernel/tests/images
+python_files/positron/positron_ipykernel/_vendor/**
# --- End Positron ---
diff --git a/extensions/positron-python/.pre-commit-config.yaml b/extensions/positron-python/.pre-commit-config.yaml
index 25e2507b3ad..21de8f8f8da 100644
--- a/extensions/positron-python/.pre-commit-config.yaml
+++ b/extensions/positron-python/.pre-commit-config.yaml
@@ -1,4 +1,4 @@
-exclude: "(.*\\.csv)|(^build/)|(^src/)|(^resources/)|(^pythonFiles/tests/unittestadapter)|(^pythonFiles/tests/testing_tools)"
+exclude: "(.*\\.csv)|(^build/)|(^src/)|(^resources/)|(^python_files/tests/unittestadapter)|(^python_files/tests/testing_tools)"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
diff --git a/extensions/positron-python/.vscode/extensions.json b/extensions/positron-python/.vscode/extensions.json
index 93a73827e7a..15e6aada1d5 100644
--- a/extensions/positron-python/.vscode/extensions.json
+++ b/extensions/positron-python/.vscode/extensions.json
@@ -2,13 +2,11 @@
// See https://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
+ "charliermarsh.ruff",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-python.python",
- "ms-python.black-formatter",
- "ms-python.vscode-pylance",
- "ms-python.isort",
- "ms-python.flake8"
+ "ms-python.vscode-pylance"
]
}
diff --git a/extensions/positron-python/.vscode/launch.json b/extensions/positron-python/.vscode/launch.json
index bfb336d767b..ce67e4f77d6 100644
--- a/extensions/positron-python/.vscode/launch.json
+++ b/extensions/positron-python/.vscode/launch.json
@@ -268,7 +268,7 @@
},
{
"name": "Listen",
- "type": "python",
+ "type": "debugpy",
"request": "attach",
"listen": { "host": "localhost", "port": 5678 },
"justMyCode": true
@@ -276,10 +276,10 @@
{
"name": "Debug pytest plugin tests",
- "type": "python",
+ "type": "debugpy",
"request": "launch",
"module": "pytest",
- "args": ["${workspaceFolder}/pythonFiles/tests/pytestadapter"],
+ "args": ["${workspaceFolder}/python_files/tests/pytestadapter"],
"justMyCode": true
}
],
diff --git a/extensions/positron-python/.vscode/settings.json b/extensions/positron-python/.vscode/settings.json
index 72f4133a4a9..0a2f64ec534 100644
--- a/extensions/positron-python/.vscode/settings.json
+++ b/extensions/positron-python/.vscode/settings.json
@@ -27,7 +27,7 @@
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
- "editor.defaultFormatter": "ms-python.black-formatter"
+ "editor.defaultFormatter": "charliermarsh.ruff",
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
@@ -68,7 +68,7 @@
// Open merge editor for resolving conflicts.
"git.mergeEditor": true,
"python.testing.pytestArgs": [
- "pythonFiles/tests"
+ "python_files/tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
diff --git a/extensions/positron-python/.vscodeignore b/extensions/positron-python/.vscodeignore
index 6788f9b6d8e..9d1934545bf 100644
--- a/extensions/positron-python/.vscodeignore
+++ b/extensions/positron-python/.vscodeignore
@@ -51,16 +51,16 @@ obj/**
out/**/*.stats.json
out/client/**/*.analyzer.html
out/coverconfig.json
-out/pythonFiles/**
+out/python_files/**
out/src/**
out/test/**
out/testMultiRootWkspc/**
precommit.hook
-pythonFiles/**/*.pyc
-pythonFiles/lib/**/*.egg-info/**
-pythonFiles/lib/python/bin/**
-pythonFiles/jedilsp_requirements/**
-pythonFiles/tests/**
+python_files/**/*.pyc
+python_files/lib/**/*.egg-info/**
+python_files/lib/python/bin/**
+python_files/jedilsp_requirements/**
+python_files/tests/**
scripts/**
src/**
test/**
diff --git a/extensions/positron-python/README.md b/extensions/positron-python/README.md
index 718f4b48857..3fc04e10197 100644
--- a/extensions/positron-python/README.md
+++ b/extensions/positron-python/README.md
@@ -6,23 +6,23 @@ You can read more about Positron IDE development on the [Positron Wiki](https://
## About
-The extension is a fork of [Microsoft's Python VSCode extension](https://github.com/microsoft/vscode-python). The main TypeScript functionality (mostly UI) is implemented in [`src`](src) and calls out to Python scripts in [`pythonFiles`](pythonFiles).
+The extension is a fork of [Microsoft's Python VSCode extension](https://github.com/microsoft/vscode-python). The main TypeScript functionality (mostly UI) is implemented in [`src`](src) and calls out to Python scripts in [`python_files`](python_files).
We provide a custom Positron Python Kernel based on the following open-source Python projects:
- [**IPyKernel**](https://github.com/ipython/ipykernel), a Jupyter kernel for the Python programming language written in Python
- [**Jedi Language Server**](https://github.com/pappasam/jedi-language-server), a language server built on the [pygls](https://github.com/openlawlibrary/pygls) (Python Generic Language Server Framework) using the [Jedi](https://github.com/davidhalter/jedi) library for autocompletion, static analysis, and refactoring
-The entrypoint to our kernel is the [`positron_language_server.py`](pythonFiles/positron/positron_language_server.py) script. The core functionality of the kernel can be found in the [`positron_ipykernel`](pythonFiles/positron/positron/positron_ipykernel/) package, which consists of these services:
+The entrypoint to our kernel is the [`positron_language_server.py`](python_files/positron/positron_language_server.py) script. The core functionality of the kernel can be found in the [`positron_ipykernel`](python_files/positron/positron/positron_ipykernel/) package, which consists of these services:
-- [`positron_ipkernel`](pythonFiles/positron/positron_ipykernel/positron_ipkernel.py), the Positron Python Kernel
-- [`positron_jedilsp`](pythonFiles/positron/positron_ipykernel/positron_jedilsp.py), the Positron Python Language Server
-- [`variables`](pythonFiles/positron/positron_ipykernel/variables.py), manages Positron's Variables pane
-- [`ui`](pythonFiles/positron/positron_ipykernel/ui.py), manages Positron's Frontend comm channel (a global channel for communication unscoped to any particular view)
-- [`help`](pythonFiles/positron/positron_ipykernel/help.py), manages Positron's Help pane
-- [`lsp`](pythonFiles/positron/positron_ipykernel/lsp.py), manages the language server
-- [`plots`](pythonFiles/positron/positron_ipykernel/plots.py), a custom [IPython display publisher](https://github.com/ipython/ipython/blob/main/IPython/core/displaypub.py) that displays to Positron's Plots pane
-- [`data_explorer`](pythonFiles/positron/positron_ipykernel/data_explorer.py), manages Positron's Data Viewer
+- [`positron_ipkernel`](python_files/positron/positron_ipykernel/positron_ipkernel.py), the Positron Python Kernel
+- [`positron_jedilsp`](python_files/positron/positron_ipykernel/positron_jedilsp.py), the Positron Python Language Server
+- [`variables`](python_files/positron/positron_ipykernel/variables.py), manages Positron's Variables pane
+- [`ui`](python_files/positron/positron_ipykernel/ui.py), manages Positron's Frontend comm channel (a global channel for communication unscoped to any particular view)
+- [`help`](python_files/positron/positron_ipykernel/help.py), manages Positron's Help pane
+- [`lsp`](python_files/positron/positron_ipykernel/lsp.py), manages the language server
+- [`plots`](python_files/positron/positron_ipykernel/plots.py), a custom [IPython display publisher](https://github.com/ipython/ipython/blob/main/IPython/core/displaypub.py) that displays to Positron's Plots pane
+- [`data_explorer`](python_files/positron/positron_ipykernel/data_explorer.py), manages Positron's Data Viewer
The various Positron services communicate with the front end via Jupyter's [comms](https://connect.rstudioservices.com/content/59a1f153-dcd8-44ac-849b-3371829b7002/positron-architecture.html#comms-and-ui-bindings) messaging protocol.
@@ -30,7 +30,7 @@ The various Positron services communicate with the front end via Jupyter's [comm
When editing the Python source, **open a new workspace at the root `positron-python` folder** to use the settings for the various tools (linters, testers, etc) to match the CI workflows.
-From the `positron-python/pythonFiles` folder, you can run the following commands.
+From the `positron-python/python_files` folder, you can run the following commands.
Format source files with [Black](https://github.com/psf/black):
@@ -53,5 +53,5 @@ pip install -r ../build/pinned-test-requirements.txt
Run Positron's unit tests with [pytest](https://docs.pytest.org/en/8.0.x/):
```sh
-pytest pythonFiles/positron/
+pytest python_files/positron/
```
diff --git a/extensions/positron-python/build/azure-pipeline.pre-release.yml b/extensions/positron-python/build/azure-pipeline.pre-release.yml
index bb52f983d02..bee373845e2 100644
--- a/extensions/positron-python/build/azure-pipeline.pre-release.yml
+++ b/extensions/positron-python/build/azure-pipeline.pre-release.yml
@@ -54,16 +54,16 @@ extends:
- script: |
python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
+ python ./python_files/install_debugpy.py
+ python ./python_files/download_get_pip.py
displayName: Install debugpy and get-pip.py
- script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --implementation py -r ./requirements.txt
+ python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/python --implementation py -r ./requirements.txt
displayName: Install Python dependencies
- script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none -r ./pythonFiles/jedilsp_requirements/requirements.txt
+ python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/jedilsp --implementation py --platform any --abi none -r ./python_files/jedilsp_requirements/requirements.txt
displayName: Install Jedi Language Server
- script: |
@@ -79,3 +79,8 @@ extends:
- script: gulp prePublishBundle
displayName: Build
+ tsa:
+ config:
+ areaPath: 'Visual Studio Code Python Extensions'
+ serviceTreeID: '6e6194bc-7baa-4486-86d0-9f5419626d46'
+ enabled: true
diff --git a/extensions/positron-python/build/azure-pipeline.stable.yml b/extensions/positron-python/build/azure-pipeline.stable.yml
index 02f8bd38cf8..754a820e36e 100644
--- a/extensions/positron-python/build/azure-pipeline.stable.yml
+++ b/extensions/positron-python/build/azure-pipeline.stable.yml
@@ -49,16 +49,16 @@ extends:
- script: |
python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
+ python ./python_files/install_debugpy.py
+ python ./python_files/download_get_pip.py
displayName: Install debugpy and get-pip.py
- script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --implementation py -r ./requirements.txt
+ python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/python --implementation py -r ./requirements.txt
displayName: Install Python dependencies
- script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none -r ./pythonFiles/jedilsp_requirements/requirements.txt
+ python -m pip install --no-deps --require-hashes --only-binary :all: -t ./python_files/lib/jedilsp --implementation py --platform any --abi none -r ./python_files/jedilsp_requirements/requirements.txt
displayName: Install Jedi Language Server
- script: |
@@ -75,15 +75,8 @@ extends:
- script: gulp prePublishBundle
displayName: Build
tsa:
- enabled: true
- options:
- codebaseName: 'devdiv_$(Build.Repository.Name)'
+ config:
+ areaPath: 'Visual Studio Code Python Extensions'
serviceTreeID: '6e6194bc-7baa-4486-86d0-9f5419626d46'
- instanceUrl: 'https://devdiv.visualstudio.com/defaultcollection'
- projectName: 'DevDiv'
- areaPath: "DevDiv\\VS Code (compliance tracking only)\\Visual Studio Code Python Extensions"
- notificationAliases:
- - 'stbatt@microsoft.com'
- - 'lszomoru@microsoft.com'
- - 'brcan@microsoft.com'
- - 'kanadig@microsoft.com'
+ enabled: true
+ apiScanSoftwareVersion: '2024'
diff --git a/extensions/positron-python/build/existingFiles.json b/extensions/positron-python/build/existingFiles.json
index 1f5acc727d8..48ab84ff565 100644
--- a/extensions/positron-python/build/existingFiles.json
+++ b/extensions/positron-python/build/existingFiles.json
@@ -500,7 +500,7 @@
"src/test/providers/shebangCodeLenseProvider.test.ts",
"src/test/providers/symbolProvider.unit.test.ts",
"src/test/providers/terminal.unit.test.ts",
- "src/test/pythonFiles/formatting/dummy.ts",
+ "src/test/python_files/formatting/dummy.ts",
"src/test/refactor/extension.refactor.extract.method.test.ts",
"src/test/refactor/extension.refactor.extract.var.test.ts",
"src/test/refactor/rename.test.ts",
diff --git a/extensions/positron-python/gulpfile.js b/extensions/positron-python/gulpfile.js
index 4950eeb0af9..50772926088 100644
--- a/extensions/positron-python/gulpfile.js
+++ b/extensions/positron-python/gulpfile.js
@@ -262,7 +262,7 @@ gulp.task('installPythonRequirements', async (done) => {
'install',
'--no-user',
'-t',
- './pythonFiles/lib/python',
+ './python_files/lib/python',
'--no-cache-dir',
'--implementation',
'py',
@@ -298,7 +298,7 @@ gulp.task('installDebugpy', async (done) => {
'--no-user',
'--upgrade',
'-t',
- './pythonFiles/lib/temp',
+ './python_files/lib/temp',
'-r',
'./build/build-install-requirements.txt',
];
@@ -311,8 +311,8 @@ gulp.task('installDebugpy', async (done) => {
});
// Install new DEBUGPY with wheels for python
- const wheelsArgs = ['./pythonFiles/install_debugpy.py'];
- const wheelsEnv = { PYTHONPATH: './pythonFiles/lib/temp' };
+ const wheelsArgs = ['./python_files/install_debugpy.py'];
+ const wheelsEnv = { PYTHONPATH: './python_files/lib/temp' };
await spawnAsync(pythonCommand, wheelsArgs, wheelsEnv)
.then(() => true)
.catch((ex) => {
@@ -322,8 +322,8 @@ gulp.task('installDebugpy', async (done) => {
});
// Download get-pip.py
- const getPipArgs = ['./pythonFiles/download_get_pip.py'];
- const getPipEnv = { PYTHONPATH: './pythonFiles/lib/temp' };
+ const getPipArgs = ['./python_files/download_get_pip.py'];
+ const getPipEnv = { PYTHONPATH: './python_files/lib/temp' };
await spawnAsync(pythonCommand, getPipArgs, getPipEnv)
.then(() => true)
.catch((ex) => {
@@ -332,7 +332,7 @@ gulp.task('installDebugpy', async (done) => {
done(new Error(msg));
});
- rmrf.sync('./pythonFiles/lib/temp');
+ rmrf.sync('./python_files/lib/temp');
});
gulp.task('installPythonLibs', gulp.series('installPythonRequirements', 'installDebugpy'));
diff --git a/extensions/positron-python/noxfile.py b/extensions/positron-python/noxfile.py
index b9ebba64544..aa6d0253c66 100644
--- a/extensions/positron-python/noxfile.py
+++ b/extensions/positron-python/noxfile.py
@@ -9,10 +9,10 @@
@nox.session()
def install_python_libs(session: nox.Session):
requirements = [
- ("./pythonFiles/lib/python", "./requirements.txt"),
+ ("./python_files/lib/python", "./requirements.txt"),
(
- "./pythonFiles/lib/jedilsp",
- "./pythonFiles/jedilsp_requirements/requirements.txt",
+ "./python_files/lib/jedilsp",
+ "./python_files/jedilsp_requirements/requirements.txt",
),
]
for target, file in requirements:
@@ -35,16 +35,16 @@ def install_python_libs(session: nox.Session):
# Install debugger
session.run(
"python",
- "./pythonFiles/install_debugpy.py",
- env={"PYTHONPATH": "./pythonFiles/lib/temp"},
+ "./python_files/install_debugpy.py",
+ env={"PYTHONPATH": "./python_files/lib/temp"},
)
# Download get-pip script
session.run(
"python",
- "./pythonFiles/download_get_pip.py",
- env={"PYTHONPATH": "./pythonFiles/lib/temp"},
+ "./python_files/download_get_pip.py",
+ env={"PYTHONPATH": "./python_files/lib/temp"},
)
- if pathlib.Path("./pythonFiles/lib/temp").exists():
- shutil.rmtree("./pythonFiles/lib/temp")
+ if pathlib.Path("./python_files/lib/temp").exists():
+ shutil.rmtree("./python_files/lib/temp")
diff --git a/extensions/positron-python/package.json b/extensions/positron-python/package.json
index 83845e7920e..04c7e999d3f 100644
--- a/extensions/positron-python/package.json
+++ b/extensions/positron-python/package.json
@@ -23,7 +23,8 @@
"testObserver",
"quickPickItemTooltip",
"terminalDataWriteEvent",
- "terminalExecuteCommandEvent"
+ "terminalExecuteCommandEvent",
+ "contribIssueReporter"
],
"author": {
"name": "Posit Software, PBC",
@@ -50,7 +51,7 @@
"theme": "dark"
},
"engines": {
- "vscode": "^1.82.0"
+ "vscode": "^1.86.0"
},
"enableTelemetry": false,
"keywords": [
@@ -62,8 +63,6 @@
"categories": [
"Programming Languages",
"Debuggers",
- "Linters",
- "Formatters",
"Other",
"Data Science",
"Machine Learning"
@@ -169,16 +168,6 @@
"description": "%walkthrough.pythonWelcome.description%",
"when": "false",
"steps": [
- {
- "id": "python.createPythonFolder",
- "title": "%walkthrough.step.python.createPythonFolder.title%",
- "description": "%walkthrough.step.python.createPythonFolder.description%",
- "media": {
- "svg": "resources/walkthrough/open-folder.svg",
- "altText": "%walkthrough.step.python.createPythonFile.altText%"
- },
- "when": "workspaceFolderCount = 0"
- },
{
"id": "python.createPythonFile",
"title": "%walkthrough.step.python.createPythonFile.title%",
@@ -223,14 +212,15 @@
"title": "%walkthrough.step.python.createEnvironment.title2%",
"description": "%walkthrough.step.python.createEnvironment.description2%",
"media": {
- "markdown": "resources/walkthrough/environments-info.md"
+ "svg": "resources/walkthrough/create-environment.svg",
+ "altText": "%walkthrough.step.python.createEnvironment.altText%"
},
"when": ""
},
{
- "id": "python.runAndDebug",
- "title": "%walkthrough.step.python.runAndDebug.title%",
- "description": "%walkthrough.step.python.runAndDebug.description%",
+ "id": "python.runAndDebug2",
+ "title": "%walkthrough.step.python.runAndDebug2.title%",
+ "description": "%walkthrough.step.python.runAndDebug2.description%",
"media": {
"svg": "resources/walkthrough/rundebug2.svg",
"altText": "%walkthrough.step.python.runAndDebug.altText%"
@@ -239,7 +229,7 @@
},
{
"id": "python.learnMoreWithDS2",
- "title": "%walkthrough.step.python.learnMoreWithDS.title%",
+ "title": "%walkthrough.step.python.learnMoreWithDS2.title%",
"description": "%walkthrough.step.python.learnMoreWithDS.description2%",
"media": {
"altText": "%walkthrough.step.python.learnMoreWithDS.altText%",
@@ -475,7 +465,7 @@
"uniqueItems": true
},
"python.createEnvironment.contentButton": {
- "default": "show",
+ "default": "hide",
"markdownDescription": "%python.createEnvironment.contentButton.description%",
"scope": "machine-overridable",
"type": "string",
@@ -485,7 +475,7 @@
]
},
"python.createEnvironment.trigger": {
- "default": "off",
+ "default": "prompt",
"markdownDescription": "%python.createEnvironment.trigger.description%",
"scope": "machine-overridable",
"type": "string",
@@ -1274,6 +1264,11 @@
}
],
"menus": {
+ "issue/reporter": [
+ {
+ "command": "python.reportIssue"
+ }
+ ],
"commandPalette": [
{
"category": "Python",
@@ -1651,9 +1646,9 @@
"unicode": "^14.0.0",
"untildify": "^4.0.0",
"vscode-debugprotocol": "^1.28.0",
- "vscode-jsonrpc": "^8.2.0",
- "vscode-languageclient": "^9.0.1",
- "vscode-languageserver-protocol": "^3.17.5",
+ "vscode-jsonrpc": "^9.0.0-next.2",
+ "vscode-languageclient": "^10.0.0-next.2",
+ "vscode-languageserver-protocol": "^3.17.6-next.3",
"vscode-tas-client": "^0.1.84",
"which": "^2.0.2",
"winreg": "^1.2.4",
@@ -1737,4 +1732,4 @@
"extensionDependencies": [
"vscode.jupyter-adapter"
]
-}
\ No newline at end of file
+}
diff --git a/extensions/positron-python/package.nls.json b/extensions/positron-python/package.nls.json
index 127c2b08ac4..891d56bced3 100644
--- a/extensions/positron-python/package.nls.json
+++ b/extensions/positron-python/package.nls.json
@@ -94,6 +94,7 @@
"walkthrough.step.python.createPythonFile.description": {
"message": "[Open](command:toSide:workbench.action.files.openFile) or [create](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22python%22%7D) a Python file - make sure to save it as \".py\".\n[Create Python File](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22python%22%7D)",
"comment": [
+ "{Locked='](command:toSide:workbench.action.files.openFile'}",
"{Locked='](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22python%22%7D'}",
"Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
@@ -131,14 +132,14 @@
"walkthrough.step.python.selectInterpreter.description": {
"message": "Choose which Python interpreter/environment you want to use for your Python project.\n[Select Python Interpreter](command:python.setInterpreter)\n**Tip**: Run the ``Python: Select Interpreter`` command in the [Command Palette](command:workbench.action.showCommands).",
"comment": [
- "{Locked='](command:python.setInterpreter'}",
- "{Locked='](command:workbench.action.showCommands'}",
- "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
- "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
+ "{Locked='](command:python.setInterpreter'}",
+ "{Locked='](command:workbench.action.showCommands'}",
+ "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
+ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
]
},
- "walkthrough.step.python.createEnvironment.title": "Create a Python Environment ",
- "walkthrough.step.python.createEnvironment.title2": "Create or select a Python Environment ",
+ "walkthrough.step.python.createEnvironment.title": "Create a Python Environment",
+ "walkthrough.step.python.createEnvironment.title2": "Select a Python environment",
"walkthrough.step.python.createEnvironment.description": {
"message": "Create an environment for your Python project.\n[Create Environment](command:python.createEnvironment)\n**Tip**: Run the ``Python: Create Environment`` command in the [Command Palette](command:workbench.action.showCommands).\n 🔍 Check out our [docs](https://aka.ms/pythonenvs) to learn more.",
"comment": [
@@ -148,12 +149,32 @@
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
]
},
- "walkthrough.step.python.createEnvironment.description2": "Create an environment for your Python project or use [Select Python Interpreter](command:python.setInterpreter) to select an existing one.\n[Create Environment](command:python.createEnvironment)\n**Tip**: Run the ``Python: Create Environment`` command in the [Command Palette](command:workbench.action.showCommands).",
+ "walkthrough.step.python.createEnvironment.description2": {
+ "message": "[Select a Python interpreter](command:python.setInterpreter) or [create an environment](command:python.createEnvironment) for your Python project.\n[Select Interpreter](command:python.setInterpreter)",
+ "comment": [
+ "{Locked='](command:python.createEnvironment'}",
+ "{Locked='](command:python.setInterpreter'}",
+ "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
+ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
+ ]
+ },
"walkthrough.step.python.runAndDebug.title": "Run and debug your Python file",
- "walkthrough.step.python.runAndDebug.description": "Open your Python file and click on the play button on the top right of the editor, or press F5 when on the file and select \"Python File\" to run with the debugger. \n \n[Learn more](https://code.visualstudio.com/docs/python/python-tutorial#_run-hello-world)",
+ "walkthrough.step.python.runAndDebug2.title": "Run and debug",
+ "walkthrough.step.python.runAndDebug2.description": "Click the play button on the top right of the editor, or press F5 when on the file and select \"Python File\" to run with the debugger.",
+ "walkthrough.step.python.runAndDebug.description": "Open your Python file and click on the play button on the top right of the editor, or press F5 when on the file and select \"Python File\" to run with the debugger. \n \n[Learn more](https://code.visualstudio.com/docs/python/python-tutorial#_run-hello-world)",
"walkthrough.step.python.learnMoreWithDS.title": "Explore more resources",
+ "walkthrough.step.python.learnMoreWithDS2.title": "Keep exploring!",
"walkthrough.step.python.learnMoreWithDS.description": {
- "message": "🎨 Explore all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n 📈 Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n ✨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Learn More](https://aka.ms/AA8dqti)",
+ "message": "🎨 Find all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n 📈 Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n ✨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Learn More](https://aka.ms/AA8dqti)",
+ "comment": [
+ "{Locked='](command:workbench.action.showCommands'}",
+ "{Locked='](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D'}",
+ "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
+ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
+ ]
+ },
+ "walkthrough.step.python.learnMoreWithDS.description2": {
+ "message": "🎨 Explore all the features the Python extension has to offer by searching for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n 📈 Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n ✨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Follow along with the Python Quick Start](https://code.visualstudio.com/docs/python/python-quick-start)",
"comment": [
"{Locked='](command:workbench.action.showCommands'}",
"{Locked='](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D'}",
@@ -161,7 +182,6 @@
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
]
},
- "walkthrough.step.python.learnMoreWithDS.description2": "🎨 Explore all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n 📈 Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n ✨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Follow along with the Python Tutorial](https://aka.ms/AA8dqti)",
"walkthrough.pythonDataScienceWelcome.title": "Get Started with Python for Data Science",
"walkthrough.pythonDataScienceWelcome.description": "Your first steps to getting started with a Data Science project with Python!",
"walkthrough.step.python.installJupyterExt.title": "Install Jupyter extension",
diff --git a/extensions/positron-python/pythonExtensionApi/src/main.ts b/extensions/positron-python/pythonExtensionApi/src/main.ts
index 4de554bf5a2..dccbd78f6f0 100644
--- a/extensions/positron-python/pythonExtensionApi/src/main.ts
+++ b/extensions/positron-python/pythonExtensionApi/src/main.ts
@@ -16,7 +16,7 @@ export interface PythonExtension {
/**
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
* Users can append another array of strings of what they want to execute along with relevant arguments to Python.
- * E.g `['/Users/..../pythonVSCode/pythonFiles/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
+ * E.g `['/Users/..../pythonVSCode/python_files/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
* @param host
* @param port
* @param waitUntilDebuggerAttaches Defaults to `true`.
diff --git a/extensions/positron-python/pythonFiles/.vscode/launch.json b/extensions/positron-python/pythonFiles/.vscode/launch.json
deleted file mode 100644
index c525016b309..00000000000
--- a/extensions/positron-python/pythonFiles/.vscode/launch.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Debug unit tests",
- "type": "python",
- "request": "test",
- "console": "integratedTerminal",
- "justMyCode": false
- }
- ]
-}
diff --git a/extensions/positron-python/pythonFiles/.env b/extensions/positron-python/python_files/.env
similarity index 100%
rename from extensions/positron-python/pythonFiles/.env
rename to extensions/positron-python/python_files/.env
diff --git a/extensions/positron-python/pythonFiles/.vscode/settings.json b/extensions/positron-python/python_files/.vscode/settings.json
similarity index 100%
rename from extensions/positron-python/pythonFiles/.vscode/settings.json
rename to extensions/positron-python/python_files/.vscode/settings.json
diff --git a/extensions/positron-python/pythonFiles/Notebooks intro.ipynb b/extensions/positron-python/python_files/Notebooks intro.ipynb
similarity index 100%
rename from extensions/positron-python/pythonFiles/Notebooks intro.ipynb
rename to extensions/positron-python/python_files/Notebooks intro.ipynb
diff --git a/extensions/positron-python/pythonFiles/create_conda.py b/extensions/positron-python/python_files/create_conda.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/create_conda.py
rename to extensions/positron-python/python_files/create_conda.py
diff --git a/extensions/positron-python/pythonFiles/create_microvenv.py b/extensions/positron-python/python_files/create_microvenv.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/create_microvenv.py
rename to extensions/positron-python/python_files/create_microvenv.py
diff --git a/extensions/positron-python/pythonFiles/create_venv.py b/extensions/positron-python/python_files/create_venv.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/create_venv.py
rename to extensions/positron-python/python_files/create_venv.py
diff --git a/extensions/positron-python/pythonFiles/deactivate/bash/deactivate b/extensions/positron-python/python_files/deactivate/bash/deactivate
old mode 100755
new mode 100644
similarity index 100%
rename from extensions/positron-python/pythonFiles/deactivate/bash/deactivate
rename to extensions/positron-python/python_files/deactivate/bash/deactivate
diff --git a/extensions/positron-python/pythonFiles/deactivate/fish/deactivate b/extensions/positron-python/python_files/deactivate/fish/deactivate
old mode 100755
new mode 100644
similarity index 100%
rename from extensions/positron-python/pythonFiles/deactivate/fish/deactivate
rename to extensions/positron-python/python_files/deactivate/fish/deactivate
diff --git a/extensions/positron-python/pythonFiles/deactivate/powershell/deactivate.ps1 b/extensions/positron-python/python_files/deactivate/powershell/deactivate.ps1
similarity index 100%
rename from extensions/positron-python/pythonFiles/deactivate/powershell/deactivate.ps1
rename to extensions/positron-python/python_files/deactivate/powershell/deactivate.ps1
diff --git a/extensions/positron-python/pythonFiles/deactivate/zsh/deactivate b/extensions/positron-python/python_files/deactivate/zsh/deactivate
old mode 100755
new mode 100644
similarity index 100%
rename from extensions/positron-python/pythonFiles/deactivate/zsh/deactivate
rename to extensions/positron-python/python_files/deactivate/zsh/deactivate
diff --git a/extensions/positron-python/pythonFiles/download_get_pip.py b/extensions/positron-python/python_files/download_get_pip.py
similarity index 96%
rename from extensions/positron-python/pythonFiles/download_get_pip.py
rename to extensions/positron-python/python_files/download_get_pip.py
index b8238d60f26..d87d1cf032f 100644
--- a/extensions/positron-python/pythonFiles/download_get_pip.py
+++ b/extensions/positron-python/python_files/download_get_pip.py
@@ -8,7 +8,7 @@
from packaging.version import parse as version_parser
EXTENSION_ROOT = pathlib.Path(__file__).parent.parent
-GET_PIP_DEST = EXTENSION_ROOT / "pythonFiles"
+GET_PIP_DEST = EXTENSION_ROOT / "python_files"
PIP_PACKAGE = "pip"
PIP_VERSION = "latest" # Can be "latest", or specific version "23.1.2"
diff --git a/extensions/positron-python/pythonFiles/get_output_via_markers.py b/extensions/positron-python/python_files/get_output_via_markers.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/get_output_via_markers.py
rename to extensions/positron-python/python_files/get_output_via_markers.py
diff --git a/extensions/positron-python/pythonFiles/install_debugpy.py b/extensions/positron-python/python_files/install_debugpy.py
similarity index 96%
rename from extensions/positron-python/pythonFiles/install_debugpy.py
rename to extensions/positron-python/python_files/install_debugpy.py
index c217e81fd21..e38ca82230c 100644
--- a/extensions/positron-python/pythonFiles/install_debugpy.py
+++ b/extensions/positron-python/python_files/install_debugpy.py
@@ -10,7 +10,7 @@
from packaging.version import parse as version_parser
EXTENSION_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-DEBUGGER_DEST = os.path.join(EXTENSION_ROOT, "pythonFiles", "lib", "python")
+DEBUGGER_DEST = os.path.join(EXTENSION_ROOT, "python_files", "lib", "python")
DEBUGGER_PACKAGE = "debugpy"
DEBUGGER_PYTHON_ABI_VERSIONS = ("cp310",)
DEBUGGER_VERSION = "1.8.1" # can also be "latest"
diff --git a/extensions/positron-python/pythonFiles/installed_check.py b/extensions/positron-python/python_files/installed_check.py
similarity index 96%
rename from extensions/positron-python/pythonFiles/installed_check.py
rename to extensions/positron-python/python_files/installed_check.py
index 4a43a8bc8b3..6dafe23b512 100644
--- a/extensions/positron-python/pythonFiles/installed_check.py
+++ b/extensions/positron-python/python_files/installed_check.py
@@ -11,9 +11,9 @@
LIB_ROOT = pathlib.Path(__file__).parent / "lib" / "python"
sys.path.insert(0, os.fspath(LIB_ROOT))
-import tomli
-from importlib_metadata import metadata
-from packaging.requirements import Requirement
+import tomli # noqa: E402
+from importlib_metadata import metadata # noqa: E402
+from packaging.requirements import Requirement # noqa: E402
DEFAULT_SEVERITY = "3" # 'Hint'
try:
diff --git a/extensions/positron-python/pythonFiles/interpreterInfo.py b/extensions/positron-python/python_files/interpreterInfo.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/interpreterInfo.py
rename to extensions/positron-python/python_files/interpreterInfo.py
diff --git a/extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.in b/extensions/positron-python/python_files/jedilsp_requirements/requirements.in
similarity index 87%
rename from extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.in
rename to extensions/positron-python/python_files/jedilsp_requirements/requirements.in
index 826bcf1e158..b0471a1e765 100644
--- a/extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.in
+++ b/extensions/positron-python/python_files/jedilsp_requirements/requirements.in
@@ -2,7 +2,7 @@
# To update requirements.txt, run the following commands.
# Use Python 3.8 when creating the environment or using pip-tools
# 1) pip install pip-tools
-# 2) pip-compile --generate-hashes --upgrade pythonFiles\jedilsp_requirements\requirements.in
+# 2) pip-compile --generate-hashes --upgrade python_files\jedilsp_requirements\requirements.in
jedi-language-server>=0.34.3
pygls>=0.10.3
diff --git a/extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.txt b/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt
similarity index 92%
rename from extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.txt
rename to extensions/positron-python/python_files/jedilsp_requirements/requirements.txt
index fdaa547f714..cd8945d8a52 100644
--- a/extensions/positron-python/pythonFiles/jedilsp_requirements/requirements.txt
+++ b/extensions/positron-python/python_files/jedilsp_requirements/requirements.txt
@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
-# pip-compile --generate-hashes pythonFiles/jedilsp_requirements/requirements.in
+# pip-compile --generate-hashes 'python_files/jedilsp_requirements/requirements.in'
#
attrs==23.2.0 \
--hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \
@@ -20,7 +20,7 @@ docstring-to-markdown==0.13 \
--hash=sha256:3025c428638ececae920d6d26054546a20335af3504a145327e657e7ad7ce1ce \
--hash=sha256:aa487059d0883e70e54da25c7b230e918d9e4d40f23d6dfaa2b73e4225b2d7dd
# via
- # -r pythonFiles/jedilsp_requirements/requirements.in
+ # -r python_files/jedilsp_requirements/requirements.in
# jedi-language-server
exceptiongroup==1.2.0 \
--hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \
@@ -33,7 +33,7 @@ jedi==0.19.1 \
jedi-language-server==0.41.2 \
--hash=sha256:865a93546b3711713eaca1a76b3a5d4aaacd4594c87f777aa8d54da37ae5aeca \
--hash=sha256:bfa112d88c0bd21872522b96c64e8054854f767449bbb3d858be04fb2cda0606
- # via -r pythonFiles/jedilsp_requirements/requirements.in
+ # via -r python_files/jedilsp_requirements/requirements.in
lsprotocol==2023.0.0 \
--hash=sha256:c9d92e12a3f4ed9317d3068226592860aab5357d93cf5b2451dc244eee8f35f2 \
--hash=sha256:e85fc87ee26c816adca9eb497bb3db1a7c79c477a11563626e712eaccf926a05
@@ -43,7 +43,7 @@ lsprotocol==2023.0.0 \
markdown-it-py==3.0.0 \
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
- # via -r pythonFiles/jedilsp_requirements/requirements.in
+ # via -r python_files/jedilsp_requirements/requirements.in
mdurl==0.1.2 \
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
@@ -89,17 +89,17 @@ pydantic==1.10.14 \
--hash=sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f \
--hash=sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a \
--hash=sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b
- # via -r pythonFiles/jedilsp_requirements/requirements.in
+ # via -r python_files/jedilsp_requirements/requirements.in
pygls==1.2.1 \
--hash=sha256:04f9b9c115b622dcc346fb390289066565343d60245a424eca77cb429b911ed8 \
--hash=sha256:7dcfcf12b6f15beb606afa46de2ed348b65a279c340ef2242a9a35c22eeafe94
# via
- # -r pythonFiles/jedilsp_requirements/requirements.in
+ # -r python_files\jedilsp_requirements\requirements.in
# jedi-language-server
pygments==2.17.2 \
--hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \
--hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367
- # via -r pythonFiles/jedilsp_requirements/requirements.in
+ # via -r python_files/jedilsp_requirements/requirements.in
typing-extensions==4.9.0 \
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
--hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
diff --git a/extensions/positron-python/pythonFiles/linter.py b/extensions/positron-python/python_files/linter.py
similarity index 89%
rename from extensions/positron-python/pythonFiles/linter.py
rename to extensions/positron-python/python_files/linter.py
index 58ad9397f58..af9634f83f4 100644
--- a/extensions/positron-python/pythonFiles/linter.py
+++ b/extensions/positron-python/python_files/linter.py
@@ -37,11 +37,7 @@ def main():
invoke = sys.argv[1]
if invoke == "-m":
linter = sys.argv[2]
- args = (
- [sys.executable, "-m", linter]
- + linter_settings[linter]["args"]
- + sys.argv[3:]
- )
+ args = [sys.executable, "-m", linter] + linter_settings[linter]["args"] + sys.argv[3:]
else:
linter = sys.argv[2]
args = [sys.argv[3]] + linter_settings[linter]["args"] + sys.argv[4:]
diff --git a/extensions/positron-python/pythonFiles/normalizeSelection.py b/extensions/positron-python/python_files/normalizeSelection.py
similarity index 98%
rename from extensions/positron-python/pythonFiles/normalizeSelection.py
rename to extensions/positron-python/python_files/normalizeSelection.py
index f0397b7db3a..523db0727e5 100644
--- a/extensions/positron-python/pythonFiles/normalizeSelection.py
+++ b/extensions/positron-python/python_files/normalizeSelection.py
@@ -297,11 +297,7 @@ def get_next_block_lineno(which_line_next):
data = None
which_line_next = 0
- if (
- empty_Highlight
- and contents.get("smartSendExperimentEnabled")
- and contents.get("smartSendSettingsEnabled")
- ):
+ if empty_Highlight and contents.get("smartSendSettingsEnabled"):
result = traverse_file(
contents["wholeFileContent"],
vscode_start_line,
diff --git a/extensions/positron-python/pythonFiles/positron/data-science-requirements.txt b/extensions/positron-python/python_files/positron/data-science-requirements.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/data-science-requirements.txt
rename to extensions/positron-python/python_files/positron/data-science-requirements.txt
diff --git a/extensions/positron-python/pythonFiles/positron/pinned-test-requirements.txt b/extensions/positron-python/python_files/positron/pinned-test-requirements.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/pinned-test-requirements.txt
rename to extensions/positron-python/python_files/positron/pinned-test-requirements.txt
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/__init__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/__init__.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/__init__.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_pydoc.css b/extensions/positron-python/python_files/positron/positron_ipykernel/_pydoc.css
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/_pydoc.css
rename to extensions/positron-python/python_files/positron/positron_ipykernel/_pydoc.css
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/access_keys.py b/extensions/positron-python/python_files/positron/positron_ipykernel/access_keys.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/access_keys.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/access_keys.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/connections.py b/extensions/positron-python/python_files/positron/positron_ipykernel/connections.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/connections.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/connections.py
index 8bf793dfd34..c2bae01cd42 100644
--- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/connections.py
+++ b/extensions/positron-python/python_files/positron/positron_ipykernel/connections.py
@@ -184,7 +184,6 @@ def _wrap_connection(self, obj: Any) -> Connection:
raise ValueError(f"Unsupported connection type {type_name}")
def _close_connection(self, comm_id: str):
-
try:
# calling disconnect can fail if the connection has already been closed or
# if it's called from a different thread.
@@ -396,7 +395,6 @@ def disconnect(self):
self.conn.close()
def preview_object(self, path: List[ObjectSchema]):
-
if pd_ is None:
raise ModuleNotFoundError("Pandas is required for previewing SQLite tables.")
@@ -429,14 +427,12 @@ class SQLAlchemyConnection(Connection):
"""
def __init__(self, conn):
-
self.conn: sqlalchemy.Engine = conn
self.display_name = f"SQLAlchemy ({conn.name})"
self.host = conn.url
self.type = "SQLAlchemy"
def list_objects(self, path: List[ObjectSchema]):
-
if sqlalchemy_ is None:
raise ModuleNotFoundError(
"SQLAlchemy is required for listing objects in SQLAlchemy connections."
@@ -466,7 +462,6 @@ def list_objects(self, path: List[ObjectSchema]):
raise ValueError(f"Path length must be at most 1, but got {len(path)}. Path: {path}")
def list_fields(self, path: List[ObjectSchema]):
-
if sqlalchemy_ is None:
raise ModuleNotFoundError(
"SQLAlchemy is required for listing fields in SQLAlchemy connections."
@@ -492,7 +487,6 @@ def list_object_types(self):
}
def preview_object(self, path: List[ObjectSchema]):
-
if sqlalchemy_ is None:
raise ModuleNotFoundError(
"SQLAlchemy is required for previewing objects in SQLAlchemy connections."
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/connections_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/connections_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/connections_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/connections_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/data_explorer.py b/extensions/positron-python/python_files/positron/positron_ipykernel/data_explorer.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/data_explorer.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/data_explorer.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/data_explorer_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/data_explorer_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/data_explorer_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/data_explorer_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/docstrings/__init__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/docstrings/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/docstrings/__init__.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/docstrings/__init__.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/docstrings/epytext.py b/extensions/positron-python/python_files/positron/positron_ipykernel/docstrings/epytext.py
similarity index 98%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/docstrings/epytext.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/docstrings/epytext.py
index 044d0510966..9cae9a7884e 100644
--- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/docstrings/epytext.py
+++ b/extensions/positron-python/python_files/positron/positron_ipykernel/docstrings/epytext.py
@@ -202,9 +202,9 @@ def combine_sections(self):
if name == "Type:":
type_sections[section.arg_name] = content.split(f"`{section.arg_name}`: ", 1)[1]
elif name == "Rtype:":
- unique_sections["Return:"].content = (
- f"({content.rstrip()}) {unique_sections['Return:'].content}"
- )
+ unique_sections[
+ "Return:"
+ ].content = f"({content.rstrip()}) {unique_sections['Return:'].content}"
else:
matching_type = type_sections.get(str(section.arg_name))
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/help.py b/extensions/positron-python/python_files/positron/positron_ipykernel/help.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/help.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/help.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/help_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/help_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/help_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/help_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/inspectors.py b/extensions/positron-python/python_files/positron/positron_ipykernel/inspectors.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/inspectors.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/inspectors.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/jedi.py b/extensions/positron-python/python_files/positron/positron_ipykernel/jedi.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/jedi.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/jedi.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/lsp.py b/extensions/positron-python/python_files/positron/positron_ipykernel/lsp.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/lsp.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/lsp.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/plot_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/plot_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/plot_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/plot_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/plots.py b/extensions/positron-python/python_files/positron/positron_ipykernel/plots.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/plots.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/plots.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/positron_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_ipkernel.py b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_ipkernel.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py
index 8bc9fd8c293..d3356795800 100644
--- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_ipkernel.py
+++ b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py
@@ -2,7 +2,8 @@
# Copyright (C) 2023-2024 Posit Software, PBC. All rights reserved.
#
-""" Positron extensions to the iPython Kernel."""
+"""Positron extensions to the iPython Kernel."""
+
from __future__ import annotations
import enum
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_jedilsp.py b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_jedilsp.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/positron_jedilsp.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/positron_jedilsp.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/pydoc.py b/extensions/positron-python/python_files/positron/positron_ipykernel/pydoc.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/pydoc.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/pydoc.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/__init__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/__init__.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/conftest.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/conftest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/conftest.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/conftest.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/data.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/data.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/data.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/data.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_access_keys.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_access_keys.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_access_keys.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_access_keys.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_connections.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_connections.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_connections.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_connections.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_data_explorer.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_data_explorer.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_data_explorer.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_data_explorer.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_docstrings_epytext.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_docstrings_epytext.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_docstrings_epytext.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_docstrings_epytext.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_help.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_help.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_help.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_help.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_inspectors.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_inspectors.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_inspectors.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_inspectors.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_plots.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_plots.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_plots.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_plots.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_positron_ipkernel.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_positron_ipkernel.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_positron_jedilsp.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_jedilsp.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_positron_jedilsp.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_jedilsp.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_pydoc.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_pydoc.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_pydoc.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_pydoc.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_ui.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_ui.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_ui.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_ui.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_variables.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_variables.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_variables.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_variables.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_widget.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_widget.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/test_widget.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_widget.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/utils.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/utils.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/tests/utils.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/tests/utils.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/third_party.py b/extensions/positron-python/python_files/positron/positron_ipykernel/third_party.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/third_party.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/third_party.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/ui.py b/extensions/positron-python/python_files/positron/positron_ipykernel/ui.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/ui.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/ui.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/ui_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/ui_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/ui_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/ui_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/utils.py b/extensions/positron-python/python_files/positron/positron_ipykernel/utils.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/utils.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/utils.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/variables.py b/extensions/positron-python/python_files/positron/positron_ipykernel/variables.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/variables.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/variables.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/variables_comm.py b/extensions/positron-python/python_files/positron/positron_ipykernel/variables_comm.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/variables_comm.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/variables_comm.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/widget.py b/extensions/positron-python/python_files/positron/positron_ipykernel/widget.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_ipykernel/widget.py
rename to extensions/positron-python/python_files/positron/positron_ipykernel/widget.py
diff --git a/extensions/positron-python/pythonFiles/positron/positron_language_server.py b/extensions/positron-python/python_files/positron/positron_language_server.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/positron_language_server.py
rename to extensions/positron-python/python_files/positron/positron_language_server.py
diff --git a/extensions/positron-python/pythonFiles/positron/test-requirements.txt b/extensions/positron-python/python_files/positron/test-requirements.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/positron/test-requirements.txt
rename to extensions/positron-python/python_files/positron/test-requirements.txt
diff --git a/extensions/positron-python/pythonFiles/printEnvVariables.py b/extensions/positron-python/python_files/printEnvVariables.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/printEnvVariables.py
rename to extensions/positron-python/python_files/printEnvVariables.py
diff --git a/extensions/positron-python/pythonFiles/printEnvVariablesToFile.py b/extensions/positron-python/python_files/printEnvVariablesToFile.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/printEnvVariablesToFile.py
rename to extensions/positron-python/python_files/printEnvVariablesToFile.py
diff --git a/extensions/positron-python/pythonFiles/pyproject.toml b/extensions/positron-python/python_files/pyproject.toml
similarity index 61%
rename from extensions/positron-python/pythonFiles/pyproject.toml
rename to extensions/positron-python/python_files/pyproject.toml
index 878c4a8b6b6..fe9368dab5e 100644
--- a/extensions/positron-python/pythonFiles/pyproject.toml
+++ b/extensions/positron-python/python_files/pyproject.toml
@@ -54,35 +54,18 @@ ignore = [
[tool.ruff]
line-length = 100
-lint.ignore = ["E402"]
exclude = [
- # Ignore testing_tools files same as Pyright way
- 'get-pip.py',
- 'install_debugpy.py',
- 'tensorboard_launcher.py',
- 'testlauncher.py',
- 'visualstudio_py_testlauncher.py',
- 'testing_tools/unittest_discovery.py',
- 'testing_tools/adapter/util.py',
- 'testing_tools/adapter/pytest/_discovery.py',
- 'testing_tools/adapter/pytest/_pytest_item.py',
- 'tests/debug_adapter/test_install_debugpy.py',
- 'tests/testing_tools/adapter/.data',
- 'tests/testing_tools/adapter/test___main__.py',
- 'tests/testing_tools/adapter/test_discovery.py',
- 'tests/testing_tools/adapter/test_functional.py',
- 'tests/testing_tools/adapter/test_report.py',
- 'tests/testing_tools/adapter/test_util.py',
- 'tests/testing_tools/adapter/pytest/test_cli.py',
- 'tests/testing_tools/adapter/pytest/test_discovery.py',
- 'pythonFiles/testing_tools/*',
- 'pythonFiles/testing_tools/adapter/pytest/__init__.py',
- 'pythonFiles/tests/pytestadapter/expected_execution_test_output.py',
- 'pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py',
- 'pythonFiles/tests/unittestadapter/test_utils.py',
+ "tests/testing_tools/adapter/.data",
+ "tests/unittestadapter/.data",
# --- Start Positron ---
# Ignore vendored dependencies
'lib/',
'positron/positron_ipykernel/_vendor/',
# --- End Positron ---
]
+
+[tool.ruff.format]
+docstring-code-format = true
+
+[tool.ruff.lint.pydocstyle]
+convention = "pep257"
diff --git a/extensions/positron-python/pythonFiles/pythonrc.py b/extensions/positron-python/python_files/pythonrc.py
similarity index 95%
rename from extensions/positron-python/pythonFiles/pythonrc.py
rename to extensions/positron-python/python_files/pythonrc.py
index 374888ddada..2edd8887467 100644
--- a/extensions/positron-python/pythonFiles/pythonrc.py
+++ b/extensions/positron-python/python_files/pythonrc.py
@@ -54,13 +54,13 @@ def __str__(self):
result = ""
# For non-windows allow recent_command history.
if sys.platform != "win32":
- result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}{command_line}".format(
+ result = "{command_line}{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
+ command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
command_start="\x1b]633;B\x07",
command_executed="\x1b]633;C\x07",
- command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
)
else:
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
diff --git a/extensions/positron-python/pythonFiles/run-jedi-language-server.py b/extensions/positron-python/python_files/run-jedi-language-server.py
similarity index 59%
rename from extensions/positron-python/pythonFiles/run-jedi-language-server.py
rename to extensions/positron-python/python_files/run-jedi-language-server.py
index 31095121409..5a972799bc3 100644
--- a/extensions/positron-python/pythonFiles/run-jedi-language-server.py
+++ b/extensions/positron-python/python_files/run-jedi-language-server.py
@@ -1,11 +1,11 @@
-import sys
import os
+import sys
# Add the lib path to our sys path so jedi_language_server can find its references
EXTENSION_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.insert(0, os.path.join(EXTENSION_ROOT, "pythonFiles", "lib", "jedilsp"))
+sys.path.insert(0, os.path.join(EXTENSION_ROOT, "python_files", "lib", "jedilsp"))
-from jedi_language_server.cli import cli
+from jedi_language_server.cli import cli # noqa: E402
sys.exit(cli())
diff --git a/extensions/positron-python/pythonFiles/shell_exec.py b/extensions/positron-python/python_files/shell_exec.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/shell_exec.py
rename to extensions/positron-python/python_files/shell_exec.py
diff --git a/extensions/positron-python/pythonFiles/tensorboard_launcher.py b/extensions/positron-python/python_files/tensorboard_launcher.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tensorboard_launcher.py
rename to extensions/positron-python/python_files/tensorboard_launcher.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/__init__.py b/extensions/positron-python/python_files/testing_tools/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/__init__.py
rename to extensions/positron-python/python_files/testing_tools/__init__.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/__init__.py b/extensions/positron-python/python_files/testing_tools/adapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/__init__.py
rename to extensions/positron-python/python_files/testing_tools/adapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/__main__.py b/extensions/positron-python/python_files/testing_tools/adapter/__main__.py
similarity index 95%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/__main__.py
rename to extensions/positron-python/python_files/testing_tools/adapter/__main__.py
index 218456897df..cc7084eb943 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/__main__.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/__main__.py
@@ -50,9 +50,7 @@ def parse_args(
subsub = add_subparser(cmdname, toolname, subsubs)
if cmdname == "discover":
subsub.add_argument("--simple", action="store_true")
- subsub.add_argument(
- "--no-hide-stdio", dest="hidestdio", action="store_false"
- )
+ subsub.add_argument("--no-hide-stdio", dest="hidestdio", action="store_false")
subsub.add_argument("--pretty", action="store_true")
# Parse the args!
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/discovery.py b/extensions/positron-python/python_files/testing_tools/adapter/discovery.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/discovery.py
rename to extensions/positron-python/python_files/testing_tools/adapter/discovery.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/errors.py b/extensions/positron-python/python_files/testing_tools/adapter/errors.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/errors.py
rename to extensions/positron-python/python_files/testing_tools/adapter/errors.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/info.py b/extensions/positron-python/python_files/testing_tools/adapter/info.py
similarity index 97%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/info.py
rename to extensions/positron-python/python_files/testing_tools/adapter/info.py
index d518a29dd97..8e5d0442ce1 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/info.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/info.py
@@ -61,9 +61,7 @@ def __init__(self, *args, **kwargs):
raise TypeError("missing relpath")
-class SingleTestInfo(
- namedtuple("TestInfo", "id name path source markers parentid kind")
-):
+class SingleTestInfo(namedtuple("TestInfo", "id name path source markers parentid kind")):
"""Info for a single test."""
MARKERS = ("skip", "skip-if", "expected-failure")
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/__init__.py b/extensions/positron-python/python_files/testing_tools/adapter/pytest/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/__init__.py
rename to extensions/positron-python/python_files/testing_tools/adapter/pytest/__init__.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_cli.py b/extensions/positron-python/python_files/testing_tools/adapter/pytest/_cli.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_cli.py
rename to extensions/positron-python/python_files/testing_tools/adapter/pytest/_cli.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_discovery.py b/extensions/positron-python/python_files/testing_tools/adapter/pytest/_discovery.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_discovery.py
rename to extensions/positron-python/python_files/testing_tools/adapter/pytest/_discovery.py
index 4b852ecf81c..bbe5ae9856c 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_discovery.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/pytest/_discovery.py
@@ -17,7 +17,7 @@ def discover(
# *,
_pytest_main=pytest.main,
_plugin=None,
- **_ignored
+ **_ignored,
):
"""Return the results of test discovery."""
if _plugin is None:
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py b/extensions/positron-python/python_files/testing_tools/adapter/pytest/_pytest_item.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py
rename to extensions/positron-python/python_files/testing_tools/adapter/pytest/_pytest_item.py
index ccfe1412231..724b71a1ac4 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/pytest/_pytest_item.py
@@ -170,9 +170,7 @@ def parse_item(
parents = [(parentid, item.originalname, kind)] + parents
name = parameterized[1:-1] or ""
else:
- (nodeid, parents, fileid, testfunc, parameterized) = _parse_node_id(
- item.nodeid, kind
- )
+ (nodeid, parents, fileid, testfunc, parameterized) = _parse_node_id(item.nodeid, kind)
name = item.name
# Note: testfunc does not necessarily match item.function.__name__.
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/report.py b/extensions/positron-python/python_files/testing_tools/adapter/report.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/report.py
rename to extensions/positron-python/python_files/testing_tools/adapter/report.py
index bacdef7b9a0..1ad02fe7bcd 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/report.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/report.py
@@ -13,7 +13,7 @@ def report_discovered(
pretty=False,
simple=False,
_send=print,
- **_ignored
+ **_ignored,
):
"""Serialize the discovered tests and write to stdout."""
if simple:
diff --git a/extensions/positron-python/pythonFiles/testing_tools/adapter/util.py b/extensions/positron-python/python_files/testing_tools/adapter/util.py
similarity index 94%
rename from extensions/positron-python/pythonFiles/testing_tools/adapter/util.py
rename to extensions/positron-python/python_files/testing_tools/adapter/util.py
index c7a178311b8..9f3089fb29d 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/adapter/util.py
+++ b/extensions/positron-python/python_files/testing_tools/adapter/util.py
@@ -46,12 +46,6 @@ def group_attr_names(attrnames):
return grouped
-if sys.version_info < (3,):
- _str_to_lower = lambda val: val.decode().lower()
-else:
- _str_to_lower = str.lower
-
-
#############################
# file paths
@@ -134,7 +128,7 @@ def fix_fileid(
normalize=False,
strictpathsep=None,
_pathsep=PATH_SEP,
- **kwargs
+ **kwargs,
):
"""Return a pathsep-separated file ID ("./"-prefixed) for the given value.
@@ -156,7 +150,7 @@ def fix_fileid(
rootdir,
_pathsep=_pathsep,
# ...
- **kwargs
+ **kwargs,
)
if relpath: # Note that we treat "" here as an absolute path.
_fileid = "./" + relpath
@@ -164,7 +158,7 @@ def fix_fileid(
if normalize:
if strictpathsep:
raise ValueError("cannot normalize *and* keep strict path separator")
- _fileid = _str_to_lower(_fileid)
+ _fileid = _fileid.lower()
elif strictpathsep:
# We do not use _normcase since we want to preserve capitalization.
_fileid = _fileid.replace("/", _pathsep)
@@ -224,12 +218,6 @@ def _replace_stderr(target):
sys.stderr = orig
-if sys.version_info < (3,):
- _coerce_unicode = lambda s: unicode(s)
-else:
- _coerce_unicode = lambda s: s
-
-
@contextlib.contextmanager
def _temp_io():
sio = StringIO()
@@ -239,7 +227,7 @@ def _temp_io():
finally:
tmp.seek(0)
buff = tmp.read()
- sio.write(_coerce_unicode(buff))
+ sio.write(buff)
@contextlib.contextmanager
diff --git a/extensions/positron-python/pythonFiles/testing_tools/process_json_util.py b/extensions/positron-python/python_files/testing_tools/process_json_util.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testing_tools/process_json_util.py
rename to extensions/positron-python/python_files/testing_tools/process_json_util.py
diff --git a/extensions/positron-python/pythonFiles/testing_tools/run_adapter.py b/extensions/positron-python/python_files/testing_tools/run_adapter.py
similarity index 81%
rename from extensions/positron-python/pythonFiles/testing_tools/run_adapter.py
rename to extensions/positron-python/python_files/testing_tools/run_adapter.py
index 1eeef194f8f..8af4e49dd31 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/run_adapter.py
+++ b/extensions/positron-python/python_files/testing_tools/run_adapter.py
@@ -7,8 +7,8 @@
sys.path.insert(
1,
- os.path.dirname( # pythonFiles
- os.path.dirname( # pythonFiles/testing_tools
+ os.path.dirname( # python_files
+ os.path.dirname( # python_files/testing_tools
os.path.abspath(__file__) # this file
)
),
diff --git a/extensions/positron-python/pythonFiles/testing_tools/socket_manager.py b/extensions/positron-python/python_files/testing_tools/socket_manager.py
similarity index 90%
rename from extensions/positron-python/pythonFiles/testing_tools/socket_manager.py
rename to extensions/positron-python/python_files/testing_tools/socket_manager.py
index b2afbf0e5a1..3392a4d54e0 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/socket_manager.py
+++ b/extensions/positron-python/python_files/testing_tools/socket_manager.py
@@ -29,9 +29,7 @@ def __exit__(self, *_):
self.close()
def connect(self):
- self.socket = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP
- )
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
if sys.platform == "win32":
addr_use = socket.SO_EXCLUSIVEADDRUSE
else:
diff --git a/extensions/positron-python/pythonFiles/testing_tools/unittest_discovery.py b/extensions/positron-python/python_files/testing_tools/unittest_discovery.py
similarity index 90%
rename from extensions/positron-python/pythonFiles/testing_tools/unittest_discovery.py
rename to extensions/positron-python/python_files/testing_tools/unittest_discovery.py
index 2988092c387..5d5e9bcc660 100644
--- a/extensions/positron-python/pythonFiles/testing_tools/unittest_discovery.py
+++ b/extensions/positron-python/python_files/testing_tools/unittest_discovery.py
@@ -1,3 +1,4 @@
+import contextlib
import inspect
import os
import sys
@@ -13,13 +14,13 @@
def get_sourceline(obj):
try:
s, n = inspect.getsourcelines(obj)
- except:
+ except Exception:
try:
# this handles `tornado` case we need a better
# way to get to the wrapped function.
- # This is a temporary solution
+ # XXX This is a temporary solution
s, n = inspect.getsourcelines(obj.orig_method)
- except:
+ except Exception:
return "*"
for i, v in enumerate(s):
@@ -50,16 +51,14 @@ def generate_test_cases(suite):
loader_errors.append(s._exception)
else:
print(testId.replace(".", ":") + ":" + get_sourceline(tm))
-except:
+except Exception:
print("=== exception start ===")
traceback.print_exc()
print("=== exception end ===")
for error in loader_errors:
- try:
+ with contextlib.suppress(Exception):
print("=== exception start ===")
print(error.msg)
print("=== exception end ===")
- except:
- pass
diff --git a/extensions/positron-python/pythonFiles/testlauncher.py b/extensions/positron-python/python_files/testlauncher.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/testlauncher.py
rename to extensions/positron-python/python_files/testlauncher.py
diff --git a/extensions/positron-python/pythonFiles/tests/__init__.py b/extensions/positron-python/python_files/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/__init__.py
rename to extensions/positron-python/python_files/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/__main__.py b/extensions/positron-python/python_files/tests/__main__.py
similarity index 92%
rename from extensions/positron-python/pythonFiles/tests/__main__.py
rename to extensions/positron-python/python_files/tests/__main__.py
index 901385d41d8..347222bd85d 100644
--- a/extensions/positron-python/pythonFiles/tests/__main__.py
+++ b/extensions/positron-python/python_files/tests/__main__.py
@@ -12,9 +12,7 @@
def parse_args():
parser = argparse.ArgumentParser()
# To mark a test as functional: (decorator) @pytest.mark.functional
- parser.add_argument(
- "--functional", dest="markers", action="append_const", const="functional"
- )
+ parser.add_argument("--functional", dest="markers", action="append_const", const="functional")
parser.add_argument(
"--no-functional", dest="markers", action="append_const", const="not functional"
)
diff --git a/extensions/positron-python/pythonFiles/tests/debug_adapter/__init__.py b/extensions/positron-python/python_files/tests/debug_adapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/debug_adapter/__init__.py
rename to extensions/positron-python/python_files/tests/debug_adapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/debug_adapter/test_install_debugpy.py b/extensions/positron-python/python_files/tests/debug_adapter/test_install_debugpy.py
similarity index 64%
rename from extensions/positron-python/pythonFiles/tests/debug_adapter/test_install_debugpy.py
rename to extensions/positron-python/python_files/tests/debug_adapter/test_install_debugpy.py
index 8e2ed33a1da..f72e1089aaa 100644
--- a/extensions/positron-python/pythonFiles/tests/debug_adapter/test_install_debugpy.py
+++ b/extensions/positron-python/python_files/tests/debug_adapter/test_install_debugpy.py
@@ -1,7 +1,4 @@
import os
-import pytest
-import subprocess
-import sys
def _check_binaries(dir_path):
@@ -21,12 +18,8 @@ def test_install_debugpy(tmpdir):
import install_debugpy
install_debugpy.main(str(tmpdir))
- dir_path = os.path.join(
- str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_bundle"
- )
+ dir_path = os.path.join(str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_bundle")
_check_binaries(dir_path)
- dir_path = os.path.join(
- str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_frame_eval"
- )
+ dir_path = os.path.join(str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_frame_eval")
_check_binaries(dir_path)
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/empty_discovery.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/empty_discovery.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/empty_discovery.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/empty_discovery.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_parametrize_discovery.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/error_parametrize_discovery.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_parametrize_discovery.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/error_parametrize_discovery.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_pytest_import.txt b/extensions/positron-python/python_files/tests/pytestadapter/.data/error_pytest_import.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_pytest_import.txt
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/error_pytest_import.txt
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_raise_exception.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/error_raise_exception.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_raise_exception.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/error_raise_exception.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_syntax_discovery.txt b/extensions/positron-python/python_files/tests/pytestadapter/.data/error_syntax_discovery.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/error_syntax_discovery.txt
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/error_syntax_discovery.txt
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param1.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/param_same_name/test_param1.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param1.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/param_same_name/test_param1.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param2.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/param_same_name/test_param2.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param2.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/param_same_name/test_param2.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/parametrize_tests.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/parametrize_tests.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/parametrize_tests.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/parametrize_tests.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini b/extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/pytest.ini
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/pytest.ini
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/test_a.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/test_a.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/test_b.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/root/tests/test_b.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/simple_pytest.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/simple_pytest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/simple_pytest.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/simple_pytest.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/skip_tests.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/skip_tests.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/skip_tests.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/skip_tests.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_env_vars.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/test_env_vars.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_env_vars.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/test_env_vars.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_logging.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/test_logging.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_logging.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/test_logging.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_multi_class_nest.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/test_multi_class_nest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/test_multi_class_nest.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/test_multi_class_nest.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/text_docstring.txt b/extensions/positron-python/python_files/tests/pytestadapter/.data/text_docstring.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/text_docstring.txt
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/text_docstring.txt
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_add.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_folder/test_add.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_add.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_folder/test_add.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_subtract.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_folder/test_subtract.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_subtract.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_folder/test_subtract.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_pytest_same_file.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_pytest_same_file.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_pytest_same_file.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_pytest_same_file.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_skiptest_file_level.py b/extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_skiptest_file_level.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/.data/unittest_skiptest_file_level.py
rename to extensions/positron-python/python_files/tests/pytestadapter/.data/unittest_skiptest_file_level.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/__init__.py b/extensions/positron-python/python_files/tests/pytestadapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/__init__.py
rename to extensions/positron-python/python_files/tests/pytestadapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py b/extensions/positron-python/python_files/tests/pytestadapter/expected_discovery_test_output.py
similarity index 97%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py
rename to extensions/positron-python/python_files/tests/pytestadapter/expected_discovery_test_output.py
index 7fbb0c5c43e..ba42fcc68fe 100644
--- a/extensions/positron-python/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py
+++ b/extensions/positron-python/python_files/tests/pytestadapter/expected_discovery_test_output.py
@@ -322,19 +322,12 @@
# └── test_bottom_function_t
# └── test_bottom_function_f
dual_level_nested_folder_path = TEST_DATA_PATH / "dual_level_nested_folder"
-test_top_folder_path = (
- TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
-)
+test_top_folder_path = TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
-test_nested_folder_one_path = (
- TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one"
-)
+test_nested_folder_one_path = TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one"
test_bottom_folder_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "nested_folder_one"
- / "test_bottom_folder.py"
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
)
@@ -851,12 +844,8 @@
os.path.join(tests_path, "test_a.py"),
),
"type_": "test",
- "id_": get_absolute_test_id(
- "tests/test_a.py::test_a_function", tests_a_path
- ),
- "runID": get_absolute_test_id(
- "tests/test_a.py::test_a_function", tests_a_path
- ),
+ "id_": get_absolute_test_id("tests/test_a.py::test_a_function", tests_a_path),
+ "runID": get_absolute_test_id("tests/test_a.py::test_a_function", tests_a_path),
}
],
},
@@ -874,12 +863,8 @@
os.path.join(tests_path, "test_b.py"),
),
"type_": "test",
- "id_": get_absolute_test_id(
- "tests/test_b.py::test_b_function", tests_b_path
- ),
- "runID": get_absolute_test_id(
- "tests/test_b.py::test_b_function", tests_b_path
- ),
+ "id_": get_absolute_test_id("tests/test_b.py::test_b_function", tests_b_path),
+ "runID": get_absolute_test_id("tests/test_b.py::test_b_function", tests_b_path),
}
],
},
@@ -996,12 +981,8 @@
}
SYMLINK_FOLDER_PATH = TEST_DATA_PATH / "symlink_folder"
SYMLINK_FOLDER_PATH_TESTS = TEST_DATA_PATH / "symlink_folder" / "tests"
-SYMLINK_FOLDER_PATH_TESTS_TEST_A = (
- TEST_DATA_PATH / "symlink_folder" / "tests" / "test_a.py"
-)
-SYMLINK_FOLDER_PATH_TESTS_TEST_B = (
- TEST_DATA_PATH / "symlink_folder" / "tests" / "test_b.py"
-)
+SYMLINK_FOLDER_PATH_TESTS_TEST_A = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_a.py"
+SYMLINK_FOLDER_PATH_TESTS_TEST_B = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_b.py"
symlink_expected_discovery_output = {
"name": "symlink_folder",
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/expected_execution_test_output.py b/extensions/positron-python/python_files/tests/pytestadapter/expected_execution_test_output.py
similarity index 86%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/expected_execution_test_output.py
rename to extensions/positron-python/python_files/tests/pytestadapter/expected_execution_test_output.py
index db4e493c3da..34693d36b12 100644
--- a/extensions/positron-python/pythonFiles/tests/pytestadapter/expected_execution_test_output.py
+++ b/extensions/positron-python/python_files/tests/pytestadapter/expected_execution_test_output.py
@@ -20,9 +20,7 @@
test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
uf_execution_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
),
@@ -31,9 +29,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -80,9 +76,7 @@
test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
uf_single_file_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
),
@@ -91,9 +85,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -111,9 +103,7 @@
# │ └── TestAddFunction
# │ └── test_add_positive_numbers: success
uf_single_method_execution_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -149,9 +139,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -252,35 +240,27 @@
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_another_thing", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_another_thing", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_another_thing", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_decorator_thing", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_decorator_thing", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_decorator_thing", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_decorator_thing_2", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_decorator_thing_2", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_decorator_thing_2", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "skip_tests.py::TestClass::test_class_function_a", skip_tests_path
- ): {
+ get_absolute_test_id("skip_tests.py::TestClass::test_class_function_a", skip_tests_path): {
"test": get_absolute_test_id(
"skip_tests.py::TestClass::test_class_function_a", skip_tests_path
),
@@ -289,9 +269,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "skip_tests.py::TestClass::test_class_function_b", skip_tests_path
- ): {
+ get_absolute_test_id("skip_tests.py::TestClass::test_class_function_b", skip_tests_path): {
"test": get_absolute_test_id(
"skip_tests.py::TestClass::test_class_function_b", skip_tests_path
),
@@ -316,10 +294,7 @@
TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
)
dual_level_nested_folder_bottom_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "nested_folder_one"
- / "test_bottom_folder.py"
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
)
dual_level_nested_folder_execution_expected_output = {
get_absolute_test_id(
@@ -379,9 +354,7 @@
# └── test_nest.py
# └── test_function: success
-nested_folder_path = (
- TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
-)
+nested_folder_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
double_nested_folder_expected_execution_output = {
get_absolute_test_id(
"folder_a/folder_b/folder_a/test_nest.py::test_function", nested_folder_path
@@ -403,9 +376,7 @@
parametrize_tests_path = TEST_DATA_PATH / "parametrize_tests.py"
parametrize_tests_expected_execution_output = {
- get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
- ): {
+ get_absolute_test_id("parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path): {
"test": get_absolute_test_id(
"parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
),
@@ -414,9 +385,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path
- ): {
+ get_absolute_test_id("parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path): {
"test": get_absolute_test_id(
"parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path
),
@@ -425,9 +394,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path
- ): {
+ get_absolute_test_id("parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path): {
"test": get_absolute_test_id(
"parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path
),
@@ -442,9 +409,7 @@
# └── parametrize_tests.py
# └── test_adding[3+5-8]: success
single_parametrize_tests_expected_execution_output = {
- get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
- ): {
+ get_absolute_test_id("parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path): {
"test": get_absolute_test_id(
"parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
),
@@ -461,9 +426,7 @@
doc_test_path = TEST_DATA_PATH / "text_docstring.txt"
doctest_pytest_expected_execution_output = {
get_absolute_test_id("text_docstring.txt::text_docstring.txt", doc_test_path): {
- "test": get_absolute_test_id(
- "text_docstring.txt::text_docstring.txt", doc_test_path
- ),
+ "test": get_absolute_test_id("text_docstring.txt::text_docstring.txt", doc_test_path),
"outcome": "success",
"message": None,
"traceback": None,
@@ -477,10 +440,7 @@
TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
)
dual_level_nested_folder_bottom_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "nested_folder_one"
- / "test_bottom_folder.py"
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
)
unittest_folder_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
unittest_folder_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
@@ -494,26 +454,20 @@
"subtest": None,
},
get_absolute_test_id("test_top_function_t", dual_level_nested_folder_top_path): {
- "test": get_absolute_test_id(
- "test_top_function_t", dual_level_nested_folder_top_path
- ),
+ "test": get_absolute_test_id("test_top_function_t", dual_level_nested_folder_top_path),
"outcome": "success",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("test_top_function_f", dual_level_nested_folder_top_path): {
- "test": get_absolute_test_id(
- "test_top_function_f", dual_level_nested_folder_top_path
- ),
+ "test": get_absolute_test_id("test_top_function_f", dual_level_nested_folder_top_path),
"outcome": "failure",
"message": "ERROR MESSAGE",
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_bottom_function_t", dual_level_nested_folder_bottom_path
- ): {
+ get_absolute_test_id("test_bottom_function_t", dual_level_nested_folder_bottom_path): {
"test": get_absolute_test_id(
"test_bottom_function_t", dual_level_nested_folder_bottom_path
),
@@ -522,9 +476,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_bottom_function_f", dual_level_nested_folder_bottom_path
- ): {
+ get_absolute_test_id("test_bottom_function_f", dual_level_nested_folder_bottom_path): {
"test": get_absolute_test_id(
"test_bottom_function_f", dual_level_nested_folder_bottom_path
),
@@ -533,9 +485,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "TestAddFunction::test_add_negative_numbers", unittest_folder_add_path
- ): {
+ get_absolute_test_id("TestAddFunction::test_add_negative_numbers", unittest_folder_add_path): {
"test": get_absolute_test_id(
"TestAddFunction::test_add_negative_numbers", unittest_folder_add_path
),
@@ -544,9 +494,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "TestAddFunction::test_add_positive_numbers", unittest_folder_add_path
- ): {
+ get_absolute_test_id("TestAddFunction::test_add_positive_numbers", unittest_folder_add_path): {
"test": get_absolute_test_id(
"TestAddFunction::test_add_positive_numbers", unittest_folder_add_path
),
@@ -606,18 +554,14 @@
logging_test_expected_execution_output = {
get_absolute_test_id("test_logging.py::test_logging2", test_logging_path): {
- "test": get_absolute_test_id(
- "test_logging.py::test_logging2", test_logging_path
- ),
+ "test": get_absolute_test_id("test_logging.py::test_logging2", test_logging_path),
"outcome": "failure",
"message": "ERROR MESSAGE",
"traceback": None,
"subtest": None,
},
get_absolute_test_id("test_logging.py::test_logging", test_logging_path): {
- "test": get_absolute_test_id(
- "test_logging.py::test_logging", test_logging_path
- ),
+ "test": get_absolute_test_id("test_logging.py::test_logging", test_logging_path),
"outcome": "success",
"message": None,
"traceback": None,
@@ -632,9 +576,7 @@
test_safe_clear_env_vars_path = TEST_DATA_PATH / "test_env_vars.py"
safe_clear_env_vars_expected_execution_output = {
- get_absolute_test_id(
- "test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path
- ): {
+ get_absolute_test_id("test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path): {
"test": get_absolute_test_id(
"test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path
),
@@ -643,9 +585,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_env_vars.py::test_check_env", test_safe_clear_env_vars_path
- ): {
+ get_absolute_test_id("test_env_vars.py::test_check_env", test_safe_clear_env_vars_path): {
"test": get_absolute_test_id(
"test_env_vars.py::test_check_env", test_safe_clear_env_vars_path
),
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/helpers.py b/extensions/positron-python/python_files/tests/pytestadapter/helpers.py
similarity index 89%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/helpers.py
rename to extensions/positron-python/python_files/tests/pytestadapter/helpers.py
index a3ed21cc553..dd69379a45b 100644
--- a/extensions/positron-python/pythonFiles/tests/pytestadapter/helpers.py
+++ b/extensions/positron-python/python_files/tests/pytestadapter/helpers.py
@@ -11,14 +11,10 @@
import sys
import threading
import uuid
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any, Dict, List, Optional, Tuple, TypedDict
-script_dir = pathlib.Path(__file__).parent.parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.append(os.fspath(script_dir / "lib" / "python"))
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
-from typing_extensions import TypedDict
def get_absolute_test_id(test_id: str, testPath: pathlib.Path) -> str:
@@ -72,9 +68,7 @@ def create_server(
def _new_sock() -> socket.socket:
- sock: socket.socket = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP
- )
+ sock: socket.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
options = [
("SOL_SOCKET", "SO_KEEPALIVE", 1),
("IPPROTO_TCP", "TCP_KEEPIDLE", 1),
@@ -92,9 +86,7 @@ def _new_sock() -> socket.socket:
CONTENT_LENGTH: str = "Content-Length:"
-Env_Dict = TypedDict(
- "Env_Dict", {"TEST_UUID": str, "TEST_PORT": str, "PYTHONPATH": str}
-)
+Env_Dict = TypedDict("Env_Dict", {"TEST_UUID": str, "TEST_PORT": str, "PYTHONPATH": str})
def process_rpc_message(data: str) -> Tuple[Dict[str, Any], str]:
@@ -137,9 +129,7 @@ def runner(args: List[str]) -> Optional[List[Dict[str, Any]]]:
return runner_with_cwd(args, TEST_DATA_PATH)
-def runner_with_cwd(
- args: List[str], path: pathlib.Path
-) -> Optional[List[Dict[str, Any]]]:
+def runner_with_cwd(args: List[str], path: pathlib.Path) -> Optional[List[Dict[str, Any]]]:
"""Run the pytest discovery and return the JSON data from the server."""
process_args: List[str] = [
sys.executable,
@@ -181,9 +171,7 @@ def runner_with_cwd(
return process_rpc_json(result[0]) if result else None
-def _listen_on_socket(
- listener: socket.socket, result: List[str], completed: threading.Event
-):
+def _listen_on_socket(listener: socket.socket, result: List[str], completed: threading.Event):
"""Listen on the socket for the JSON data from the server.
Created as a separate function for clarity in threading.
"""
@@ -205,9 +193,7 @@ def _listen_on_socket(
result.append("".join(all_data))
-def _run_test_code(
- proc_args: List[str], proc_env, proc_cwd: str, completed: threading.Event
-):
+def _run_test_code(proc_args: List[str], proc_env, proc_cwd: str, completed: threading.Event):
result = subprocess.run(proc_args, env=proc_env, cwd=proc_cwd)
completed.set()
return result
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/test_discovery.py b/extensions/positron-python/python_files/tests/pytestadapter/test_discovery.py
similarity index 79%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/test_discovery.py
rename to extensions/positron-python/python_files/tests/pytestadapter/test_discovery.py
index a1f4e4f266a..fb8a97a2df1 100644
--- a/extensions/positron-python/pythonFiles/tests/pytestadapter/test_discovery.py
+++ b/extensions/positron-python/python_files/tests/pytestadapter/test_discovery.py
@@ -2,20 +2,15 @@
# Licensed under the MIT License.
import json
import os
-import pathlib
import shutil
import sys
from typing import Any, Dict, List, Optional
import pytest
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.append(os.fspath(script_dir))
+from tests.tree_comparison_helper import is_same_tree # noqa: E402
-from tests.tree_comparison_helper import is_same_tree
-
-from . import expected_discovery_test_output
-from .helpers import TEST_DATA_PATH, runner, runner_with_cwd, create_symlink
+from . import expected_discovery_test_output, helpers # noqa: E402
@pytest.mark.skipif(
@@ -36,22 +31,20 @@ def test_import_error(tmp_path):
# Saving some files as .txt to avoid that file displaying a syntax error for
# the extension as a whole. Instead, rename it before running this test
# in order to test the error handling.
- file_path = TEST_DATA_PATH / "error_pytest_import.txt"
+ file_path = helpers.TEST_DATA_PATH / "error_pytest_import.txt"
temp_dir = tmp_path / "temp_data"
temp_dir.mkdir()
p = temp_dir / "error_pytest_import.py"
shutil.copyfile(file_path, p)
- actual: Optional[List[Dict[str, Any]]] = runner(["--collect-only", os.fspath(p)])
+ actual: Optional[List[Dict[str, Any]]] = helpers.runner(["--collect-only", os.fspath(p)])
assert actual
actual_list: List[Dict[str, Any]] = actual
if actual_list is not None:
assert actual_list.pop(-1).get("eot")
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
# Ensure that 'error' is a list and then check its length
error_content = actual_item.get("error")
@@ -81,22 +74,20 @@ def test_syntax_error(tmp_path):
# Saving some files as .txt to avoid that file displaying a syntax error for
# the extension as a whole. Instead, rename it before running this test
# in order to test the error handling.
- file_path = TEST_DATA_PATH / "error_syntax_discovery.txt"
+ file_path = helpers.TEST_DATA_PATH / "error_syntax_discovery.txt"
temp_dir = tmp_path / "temp_data"
temp_dir.mkdir()
p = temp_dir / "error_syntax_discovery.py"
shutil.copyfile(file_path, p)
- actual = runner(["--collect-only", os.fspath(p)])
+ actual = helpers.runner(["--collect-only", os.fspath(p)])
assert actual
actual_list: List[Dict[str, Any]] = actual
if actual_list is not None:
assert actual_list.pop(-1).get("eot")
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
# Ensure that 'error' is a list and then check its length
error_content = actual_item.get("error")
@@ -114,17 +105,15 @@ def test_parameterized_error_collect():
The json should still be returned but the errors list should be present.
"""
file_path_str = "error_parametrize_discovery.py"
- actual = runner(["--collect-only", file_path_str])
+ actual = helpers.runner(["--collect-only", file_path_str])
assert actual
actual_list: List[Dict[str, Any]] = actual
if actual_list is not None:
assert actual_list.pop(-1).get("eot")
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
# Ensure that 'error' is a list and then check its length
error_content = actual_item.get("error")
@@ -196,10 +185,10 @@ def test_pytest_collect(file, expected_const):
file -- a string with the file or folder to run pytest discovery on.
expected_const -- the expected output from running pytest discovery on the file.
"""
- actual = runner(
+ actual = helpers.runner(
[
"--collect-only",
- os.fspath(TEST_DATA_PATH / file),
+ os.fspath(helpers.TEST_DATA_PATH / file),
]
)
@@ -210,8 +199,10 @@ def test_pytest_collect(file, expected_const):
actual_item = actual_list.pop(0)
assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
- assert is_same_tree(actual_item.get("tests"), expected_const)
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+ assert is_same_tree(
+ actual_item.get("tests"), expected_const
+ ), f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_const, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
def test_symlink_root_dir():
@@ -219,14 +210,14 @@ def test_symlink_root_dir():
Test to test pytest discovery with the command line arg --rootdir specified as a symlink path.
Discovery should succeed and testids should be relative to the symlinked root directory.
"""
- with create_symlink(TEST_DATA_PATH, "root", "symlink_folder") as (
+ with helpers.create_symlink(helpers.TEST_DATA_PATH, "root", "symlink_folder") as (
source,
destination,
):
assert destination.is_symlink()
# Run pytest with the cwd being the resolved symlink path (as it will be when we run the subprocess from node).
- actual = runner_with_cwd(
+ actual = helpers.runner_with_cwd(
["--collect-only", f"--rootdir={os.fspath(destination)}"], source
)
expected = expected_discovery_test_output.symlink_expected_discovery_output
@@ -244,9 +235,7 @@ def test_symlink_root_dir():
assert actual_item.get("cwd") == os.fspath(
destination
), f"CWD does not match: {os.fspath(destination)}"
- assert (
- actual_item.get("tests") == expected
- ), "Tests do not match expected value"
+ assert actual_item.get("tests") == expected, "Tests do not match expected value"
except AssertionError as e:
# Print the actual_item in JSON format if an assertion fails
print(json.dumps(actual_item, indent=4))
@@ -258,13 +247,13 @@ def test_pytest_root_dir():
Test to test pytest discovery with the command line arg --rootdir specified to be a subfolder
of the workspace root. Discovery should succeed and testids should be relative to workspace root.
"""
- rd = f"--rootdir={TEST_DATA_PATH / 'root' / 'tests'}"
- actual = runner_with_cwd(
+ rd = f"--rootdir={helpers.TEST_DATA_PATH / 'root' / 'tests'}"
+ actual = helpers.runner_with_cwd(
[
"--collect-only",
rd,
],
- TEST_DATA_PATH / "root",
+ helpers.TEST_DATA_PATH / "root",
)
assert actual
actual_list: List[Dict[str, Any]] = actual
@@ -273,11 +262,11 @@ def test_pytest_root_dir():
actual_item = actual_list.pop(0)
assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH / "root")
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH / "root")
assert is_same_tree(
actual_item.get("tests"),
expected_discovery_test_output.root_with_config_expected_output,
- )
+ ), f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_discovery_test_output.root_with_config_expected_output, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
def test_pytest_config_file():
@@ -285,12 +274,12 @@ def test_pytest_config_file():
Test to test pytest discovery with the command line arg -c with a specified config file which
changes the workspace root. Discovery should succeed and testids should be relative to workspace root.
"""
- actual = runner_with_cwd(
+ actual = helpers.runner_with_cwd(
[
"--collect-only",
"tests/",
],
- TEST_DATA_PATH / "root",
+ helpers.TEST_DATA_PATH / "root",
)
assert actual
actual_list: List[Dict[str, Any]] = actual
@@ -299,8 +288,8 @@ def test_pytest_config_file():
actual_item = actual_list.pop(0)
assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH / "root")
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH / "root")
assert is_same_tree(
actual_item.get("tests"),
expected_discovery_test_output.root_with_config_expected_output,
- )
+ ), f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_discovery_test_output.root_with_config_expected_output, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
diff --git a/extensions/positron-python/pythonFiles/tests/pytestadapter/test_execution.py b/extensions/positron-python/python_files/tests/pytestadapter/test_execution.py
similarity index 92%
rename from extensions/positron-python/pythonFiles/tests/pytestadapter/test_execution.py
rename to extensions/positron-python/python_files/tests/pytestadapter/test_execution.py
index a8336089d0a..b4fffd6a640 100644
--- a/extensions/positron-python/pythonFiles/tests/pytestadapter/test_execution.py
+++ b/extensions/positron-python/python_files/tests/pytestadapter/test_execution.py
@@ -28,9 +28,7 @@ def test_config_file():
]
new_cwd = TEST_DATA_PATH / "root"
actual = runner_with_cwd(args, new_cwd)
- expected_const = (
- expected_execution_test_output.config_file_pytest_expected_execution_output
- )
+ expected_const = expected_execution_test_output.config_file_pytest_expected_execution_output
assert actual
actual_list: List[Dict[str, Any]] = actual
assert actual_list.pop(-1).get("eot")
@@ -38,9 +36,7 @@ def test_config_file():
actual_result_dict = dict()
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(new_cwd)
actual_result_dict.update(actual_item["result"])
@@ -53,9 +49,7 @@ def test_rootdir_specified():
args = [rd, "tests/test_a.py::test_a_function"]
new_cwd = TEST_DATA_PATH / "root"
actual = runner_with_cwd(args, new_cwd)
- expected_const = (
- expected_execution_test_output.config_file_pytest_expected_execution_output
- )
+ expected_const = expected_execution_test_output.config_file_pytest_expected_execution_output
assert actual
actual_list: List[Dict[str, Any]] = actual
assert actual_list.pop(-1).get("eot")
@@ -63,9 +57,7 @@ def test_rootdir_specified():
actual_result_dict = dict()
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(new_cwd)
actual_result_dict.update(actual_item["result"])
@@ -101,9 +93,7 @@ def test_syntax_error_execution(tmp_path):
assert actual_list.pop(-1).get("eot")
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "error"
assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
error_content = actual_item.get("error")
@@ -126,9 +116,7 @@ def test_bad_id_error_execution():
assert actual_list.pop(-1).get("eot")
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
assert actual_item.get("status") == "error"
assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
error_content = actual_item.get("error")
@@ -273,9 +261,7 @@ def test_pytest_execution(test_ids, expected_const):
actual_result_dict = dict()
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item.keys() for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
actual_result_dict.update(actual_item["result"])
@@ -307,13 +293,9 @@ def test_symlink_run():
)
# Run pytest with the cwd being the resolved symlink path (as it will be when we run the subprocess from node).
- actual = runner_with_cwd(
- [f"--rootdir={os.fspath(destination)}", test_a_id], source
- )
+ actual = runner_with_cwd([f"--rootdir={os.fspath(destination)}", test_a_id], source)
- expected_const = (
- expected_execution_test_output.symlink_run_expected_execution_output
- )
+ expected_const = expected_execution_test_output.symlink_run_expected_execution_output
assert actual
actual_list: List[Dict[str, Any]] = actual
if actual_list is not None:
diff --git a/extensions/positron-python/pythonFiles/tests/run_all.py b/extensions/positron-python/python_files/tests/run_all.py
similarity index 85%
rename from extensions/positron-python/pythonFiles/tests/run_all.py
rename to extensions/positron-python/python_files/tests/run_all.py
index ce5a6264996..7c864ba7c5c 100644
--- a/extensions/positron-python/pythonFiles/tests/run_all.py
+++ b/extensions/positron-python/python_files/tests/run_all.py
@@ -7,8 +7,7 @@
sys.path[0] = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-from tests.__main__ import main, parse_args
-
+from tests.__main__ import main, parse_args # noqa: E402
if __name__ == "__main__":
mainkwargs, pytestargs = parse_args()
diff --git a/extensions/positron-python/pythonFiles/tests/test_create_conda.py b/extensions/positron-python/python_files/tests/test_create_conda.py
similarity index 94%
rename from extensions/positron-python/pythonFiles/tests/test_create_conda.py
rename to extensions/positron-python/python_files/tests/test_create_conda.py
index 29dc323402e..8681184ba82 100644
--- a/extensions/positron-python/pythonFiles/tests/test_create_conda.py
+++ b/extensions/positron-python/python_files/tests/test_create_conda.py
@@ -29,9 +29,7 @@ def install_packages(_name):
def run_process(args, error_message):
nonlocal run_process_called
run_process_called = True
- version = (
- "12345" if python else f"{sys.version_info.major}.{sys.version_info.minor}"
- )
+ version = "12345" if python else f"{sys.version_info.major}.{sys.version_info.minor}"
if not env_exists:
assert args == [
sys.executable,
diff --git a/extensions/positron-python/pythonFiles/tests/test_create_microvenv.py b/extensions/positron-python/python_files/tests/test_create_microvenv.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_create_microvenv.py
rename to extensions/positron-python/python_files/tests/test_create_microvenv.py
diff --git a/extensions/positron-python/pythonFiles/tests/test_create_venv.py b/extensions/positron-python/python_files/tests/test_create_venv.py
similarity index 95%
rename from extensions/positron-python/pythonFiles/tests/test_create_venv.py
rename to extensions/positron-python/python_files/tests/test_create_venv.py
index 57df0a7fb3c..27bd45f9c37 100644
--- a/extensions/positron-python/pythonFiles/tests/test_create_venv.py
+++ b/extensions/positron-python/python_files/tests/test_create_venv.py
@@ -14,9 +14,7 @@
import create_venv
-@pytest.mark.skipif(
- sys.platform == "win32", reason="Windows does not have micro venv fallback."
-)
+@pytest.mark.skipif(sys.platform == "win32", reason="Windows does not have micro venv fallback.")
def test_venv_not_installed_unix():
importlib.reload(create_venv)
create_venv.is_installed = lambda module: module != "venv"
@@ -43,9 +41,7 @@ def run_process(args, error_message):
assert run_process_called is True
-@pytest.mark.skipif(
- sys.platform != "win32", reason="Windows does not have microvenv fallback."
-)
+@pytest.mark.skipif(sys.platform != "win32", reason="Windows does not have microvenv fallback.")
def test_venv_not_installed_windows():
importlib.reload(create_venv)
create_venv.is_installed = lambda module: module != "venv"
@@ -106,9 +102,7 @@ def add_gitignore(_name):
assert run_process_called == (env_exists == "noEnv")
# add_gitignore is called when new venv is created and git_ignore is True
- assert add_gitignore_called == (
- (env_exists == "noEnv") and (git_ignore == "useGitIgnore")
- )
+ assert add_gitignore_called == ((env_exists == "noEnv") and (git_ignore == "useGitIgnore"))
@pytest.mark.parametrize("install_type", ["requirements", "pyproject", "both"])
@@ -238,9 +232,7 @@ def run_process(args, error_message):
if "install" in args and "pip" in args:
nonlocal run_process_called
run_process_called = True
- pip_pyz_path = os.fspath(
- create_venv.CWD / create_venv.VENV_NAME / "pip.pyz"
- )
+ pip_pyz_path = os.fspath(create_venv.CWD / create_venv.VENV_NAME / "pip.pyz")
assert args[1:] == [pip_pyz_path, "install", "pip"]
assert error_message == "CREATE_VENV.INSTALL_PIP_FAILED"
diff --git a/extensions/positron-python/pythonFiles/tests/test_data/missing-deps.data b/extensions/positron-python/python_files/tests/test_data/missing-deps.data
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_data/missing-deps.data
rename to extensions/positron-python/python_files/tests/test_data/missing-deps.data
diff --git a/extensions/positron-python/pythonFiles/tests/test_data/no-missing-deps.data b/extensions/positron-python/python_files/tests/test_data/no-missing-deps.data
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_data/no-missing-deps.data
rename to extensions/positron-python/python_files/tests/test_data/no-missing-deps.data
diff --git a/extensions/positron-python/pythonFiles/tests/test_data/pyproject-missing-deps.data b/extensions/positron-python/python_files/tests/test_data/pyproject-missing-deps.data
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_data/pyproject-missing-deps.data
rename to extensions/positron-python/python_files/tests/test_data/pyproject-missing-deps.data
diff --git a/extensions/positron-python/pythonFiles/tests/test_data/pyproject-no-missing-deps.data b/extensions/positron-python/python_files/tests/test_data/pyproject-no-missing-deps.data
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_data/pyproject-no-missing-deps.data
rename to extensions/positron-python/python_files/tests/test_data/pyproject-no-missing-deps.data
diff --git a/extensions/positron-python/pythonFiles/tests/test_dynamic_cursor.py b/extensions/positron-python/python_files/tests/test_dynamic_cursor.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_dynamic_cursor.py
rename to extensions/positron-python/python_files/tests/test_dynamic_cursor.py
diff --git a/extensions/positron-python/pythonFiles/tests/test_installed_check.py b/extensions/positron-python/python_files/tests/test_installed_check.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_installed_check.py
rename to extensions/positron-python/python_files/tests/test_installed_check.py
diff --git a/extensions/positron-python/pythonFiles/tests/test_normalize_selection.py b/extensions/positron-python/python_files/tests/test_normalize_selection.py
similarity index 98%
rename from extensions/positron-python/pythonFiles/tests/test_normalize_selection.py
rename to extensions/positron-python/python_files/tests/test_normalize_selection.py
index 5f4d6d7d4a1..60dfddb11e2 100644
--- a/extensions/positron-python/pythonFiles/tests/test_normalize_selection.py
+++ b/extensions/positron-python/python_files/tests/test_normalize_selection.py
@@ -5,7 +5,7 @@
import importlib
import textwrap
-# __file__ = "/Users/anthonykim/Desktop/vscode-python/pythonFiles/normalizeSelection.py"
+# __file__ = "/Users/anthonykim/Desktop/vscode-python/python_files/normalizeSelection.py"
# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__))))
import normalizeSelection
diff --git a/extensions/positron-python/pythonFiles/tests/test_shell_integration.py b/extensions/positron-python/python_files/tests/test_shell_integration.py
similarity index 86%
rename from extensions/positron-python/pythonFiles/tests/test_shell_integration.py
rename to extensions/positron-python/python_files/tests/test_shell_integration.py
index 896df416ece..c5911aad2d1 100644
--- a/extensions/positron-python/pythonFiles/tests/test_shell_integration.py
+++ b/extensions/positron-python/python_files/tests/test_shell_integration.py
@@ -13,7 +13,7 @@ def test_decoration_success():
if sys.platform != "win32":
assert (
result
- == "\x1b]633;D;0\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
+ == "\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07"
)
else:
pass
@@ -28,7 +28,7 @@ def test_decoration_failure():
if sys.platform != "win32":
assert (
result
- == "\x1b]633;D;1\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
+ == "\x1b]633;E;None\x07\x1b]633;D;1\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07"
)
else:
pass
diff --git a/extensions/positron-python/pythonFiles/tests/test_smart_selection.py b/extensions/positron-python/python_files/tests/test_smart_selection.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/test_smart_selection.py
rename to extensions/positron-python/python_files/tests/test_smart_selection.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/README.md
similarity index 99%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/README.md
index e30e96142d0..8840cda1e83 100644
--- a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md
+++ b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/README.md
@@ -1,7 +1,7 @@
## Directory Structure
```
-pythonFiles/tests/testing_tools/adapter/.data/
+python_files/tests/testing_tools/adapter/.data/
tests/ # test root
test_doctest.txt
test_pytest.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/mod.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/mod.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/mod.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/mod.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_42.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_42.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_foo.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_foo.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_foo.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_foo.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/testspam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/testspam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/testspam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/testspam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/notests/tests/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/notests/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/notests/tests/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/notests/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/simple/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/simple/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/simple/tests/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/simple/tests/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/syntax-error/tests/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/syntax-error/tests/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/__init__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/__init__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/test_cli.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/test_cli.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/test_cli.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/test_cli.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/test_discovery.py
similarity index 96%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/test_discovery.py
index 83eeaa1f906..55a0e65102a 100644
--- a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py
+++ b/extensions/positron-python/python_files/tests/testing_tools/adapter/pytest/test_discovery.py
@@ -224,7 +224,7 @@ def _fix_fileid(*args):
# dependency injection
_normcase=normcase,
_pathsep=pathsep,
- )
+ ),
)
def _normalize_test_id(*args):
@@ -234,7 +234,7 @@ def _normalize_test_id(*args):
# dependency injection
_fix_fileid=_fix_fileid,
_pathsep=pathsep,
- )
+ ),
)
def _iter_nodes(*args):
@@ -245,7 +245,7 @@ def _iter_nodes(*args):
_normalize_test_id=_normalize_test_id,
_normcase=normcase,
_pathsep=pathsep,
- )
+ ),
)
def _parse_node_id(*args):
@@ -254,7 +254,7 @@ def _parse_node_id(*args):
**dict(
# dependency injection
_iter_nodes=_iter_nodes,
- )
+ ),
)
##########
@@ -264,7 +264,7 @@ def _split_fspath(*args):
**dict(
# dependency injection
_normcase=normcase,
- )
+ ),
)
##########
@@ -275,7 +275,7 @@ def _matches_relfile(*args):
# dependency injection
_normcase=normcase,
_pathsep=pathsep,
- )
+ ),
)
def _is_legacy_wrapper(*args):
@@ -284,7 +284,7 @@ def _is_legacy_wrapper(*args):
**dict(
# dependency injection
_pathsep=pathsep,
- )
+ ),
)
def _get_location(*args):
@@ -295,7 +295,7 @@ def _get_location(*args):
_matches_relfile=_matches_relfile,
_is_legacy_wrapper=_is_legacy_wrapper,
_pathsep=pathsep,
- )
+ ),
)
##########
@@ -307,7 +307,7 @@ def _parse_item(item):
_parse_node_id=_parse_node_id,
_split_fspath=_split_fspath,
_get_location=_get_location,
- )
+ ),
)
return _parse_item
@@ -347,9 +347,7 @@ def test_basic(self):
("discovered.__getitem__", (0,), None),
]
- parents, tests = _discovery.discover(
- [], _pytest_main=stubpytest.main, _plugin=plugin
- )
+ parents, tests = _discovery.discover([], _pytest_main=stubpytest.main, _plugin=plugin)
actual_calls = unique(stub.calls, lambda k: k[0])
expected_calls = unique(calls, lambda k: k[0])
@@ -389,9 +387,7 @@ def test_no_tests_found(self):
("discovered.__getitem__", (0,), None),
]
- parents, tests = _discovery.discover(
- [], _pytest_main=pytest.main, _plugin=plugin
- )
+ parents, tests = _discovery.discover([], _pytest_main=pytest.main, _plugin=plugin)
actual_calls = unique(stub.calls, lambda k: k[0])
expected_calls = unique(calls, lambda k: k[0])
@@ -414,9 +410,7 @@ def test_found_with_collection_error(self):
("discovered.__getitem__", (0,), None),
]
- parents, tests = _discovery.discover(
- [], _pytest_main=pytest.main, _plugin=plugin
- )
+ parents, tests = _discovery.discover([], _pytest_main=pytest.main, _plugin=plugin)
actual_calls = unique(stub.calls, lambda k: k[0])
expected_calls = unique(calls, lambda k: k[0])
@@ -845,9 +839,7 @@ def test_finish(self):
func="SpamTests.test_spam",
sub=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests",
),
@@ -920,9 +912,7 @@ def test_doctest(self):
relfile=adapter_util.fix_relpath(doctestfile),
func=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(doctestfile), 1
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(doctestfile), 1),
markers=[],
parentid="./x/test_doctest.txt",
),
@@ -972,9 +962,7 @@ def test_doctest(self):
relfile=adapter_util.fix_relpath(relfile),
func=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=[],
parentid="./x/y/z/test_eggs.py",
),
@@ -999,9 +987,7 @@ def test_doctest(self):
relfile=adapter_util.fix_relpath(relfile),
func=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 28
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 28),
markers=[],
parentid="./x/y/z/test_eggs.py",
),
@@ -1062,9 +1048,7 @@ def test_nested_brackets(self):
func="SpamTests.test_spam",
sub=["[a-[b]-c]"],
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests::test_spam",
),
@@ -1126,9 +1110,7 @@ def test_nested_suite(self):
func="SpamTests.Ham.Eggs.test_spam",
sub=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests::Ham::Eggs",
),
@@ -1479,9 +1461,7 @@ def test_mysterious_parens(self):
func="SpamTests.test_spam",
sub=[],
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests",
),
@@ -1537,9 +1517,7 @@ def test_mysterious_colons(self):
func="SpamTests.test_spam",
sub=[],
),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(relfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests",
),
@@ -1607,9 +1585,7 @@ def test_imported_test(self):
func="SpamTests.test_spam",
sub=None,
),
- source="{}:{}".format(
- adapter_util.fix_relpath(srcfile), 13
- ),
+ source="{}:{}".format(adapter_util.fix_relpath(srcfile), 13),
markers=None,
parentid="./x/y/z/test_eggs.py::SpamTests",
),
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test___main__.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/test___main__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test___main__.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/test___main__.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_discovery.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_discovery.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_discovery.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/test_discovery.py
index cf3b8fb3139..2fe4db7caa3 100644
--- a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_discovery.py
+++ b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_discovery.py
@@ -5,7 +5,7 @@
import unittest
-from testing_tools.adapter.discovery import DiscoveredTests, fix_nodeid
+from testing_tools.adapter.discovery import DiscoveredTests
from testing_tools.adapter.info import ParentInfo, SingleTestInfo, SingleTestPath
from testing_tools.adapter.util import fix_path, fix_relpath
@@ -252,9 +252,7 @@ def test_add_test_simple(self):
# missing "./":
parentid=relfile,
)
- expected = test._replace(
- id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid)
- )
+ expected = test._replace(id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid))
discovered = DiscoveredTests()
before = list(discovered), discovered.parents
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_functional.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_functional.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_functional.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/test_functional.py
index a78d36a5fdc..45c85ee951d 100644
--- a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_functional.py
+++ b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_functional.py
@@ -48,9 +48,7 @@ def _run_adapter(cmd, tool, *cliargs, **kwargs):
argv.insert(4, "--no-hide-stdio")
kwds["stderr"] = subprocess.STDOUT
argv.append("--cache-clear")
- print(
- "running {!r}".format(" ".join(arg.rpartition(CWD + "/")[-1] for arg in argv))
- )
+ print("running {!r}".format(" ".join(arg.rpartition(CWD + "/")[-1] for arg in argv)))
output = subprocess.check_output(argv, universal_newlines=True, **kwds)
return output
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_report.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_report.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_report.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/test_report.py
diff --git a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_util.py b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_util.py
similarity index 98%
rename from extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_util.py
rename to extensions/positron-python/python_files/tests/testing_tools/adapter/test_util.py
index 822ba2ed1b2..8a7cd475a1c 100644
--- a/extensions/positron-python/pythonFiles/tests/testing_tools/adapter/test_util.py
+++ b/extensions/positron-python/python_files/tests/testing_tools/adapter/test_util.py
@@ -11,7 +11,6 @@
import sys
import unittest
-import pytest
# Pytest 3.7 and later uses pathlib/pathlib2 for path resolution.
try:
@@ -260,9 +259,7 @@ def test_fix_fileid(self):
)
for fileid, rootdir, _os_path, expected in tests:
pathsep = _os_path.sep
- with self.subTest(
- r"for {} (with rootdir {!r}): {!r}".format(pathsep, rootdir, fileid)
- ):
+ with self.subTest(r"for {} (with rootdir {!r}): {!r}".format(pathsep, rootdir, fileid)):
fixed = fix_fileid(
fileid,
rootdir,
diff --git a/extensions/positron-python/pythonFiles/tests/tree_comparison_helper.py b/extensions/positron-python/python_files/tests/tree_comparison_helper.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/tree_comparison_helper.py
rename to extensions/positron-python/python_files/tests/tree_comparison_helper.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_empty.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_empty.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_empty.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_empty.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_error/file_one.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_error/file_one.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_error/file_two.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_error/file_two.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_error/file_two.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_error/file_two.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_simple.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_simple.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/discovery_simple.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/discovery_simple.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_fail_simple.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/test_fail_simple.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_fail_simple.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/test_fail_simple.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_subtest.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/test_subtest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_subtest.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/test_subtest.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_two_classes.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/test_two_classes.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/test_two_classes.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/test_two_classes.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
similarity index 95%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
index 4f3f77e1056..52641360b52 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
@@ -7,7 +7,6 @@
# and the two tests with their outcome as "success".
-
class DiscoveryA(unittest.TestCase):
"""Test class for the two file pattern test. It is pattern *test.py
@@ -19,4 +18,4 @@ def test_one_a(self) -> None:
self.assertGreater(2, 1)
def test_two_a(self) -> None:
- self.assertNotEqual(2, 1)
\ No newline at end of file
+ self.assertNotEqual(2, 1)
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
similarity index 93%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
index a912699383c..06b6a818537 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
@@ -6,10 +6,10 @@
# The test_ids_multiple_runs function should return a dictionary with a "success" status,
# and the two tests with their outcome as "success".
-class DiscoveryB(unittest.TestCase):
+class DiscoveryB(unittest.TestCase):
def test_one_b(self) -> None:
self.assertGreater(2, 1)
def test_two_b(self) -> None:
- self.assertNotEqual(2, 1)
\ No newline at end of file
+ self.assertNotEqual(2, 1)
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
similarity index 81%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
index 2e616077ec4..f562474b596 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
@@ -6,17 +6,16 @@
# files in the same folder. The cwd is set to the parent folder. This should return
# a dictionary with a "success" status and the two tests with their outcome as "success".
+
def add(a, b):
return a + b
class TestAddFunction(unittest.TestCase):
-
- def test_add_positive_numbers(self):
+ def test_add_positive_numbers(self):
result = add(2, 3)
self.assertEqual(result, 5)
-
- def test_add_negative_numbers(self):
+ def test_add_negative_numbers(self):
result = add(-2, -3)
- self.assertEqual(result, -5)
\ No newline at end of file
+ self.assertEqual(result, -5)
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
similarity index 94%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
index 4028e25825d..8ac3988a325 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
@@ -6,6 +6,7 @@
# files in the same folder. The cwd is set to the parent folder. This should return
# a dictionary with a "success" status and the two tests with their outcome as "success".
+
def subtract(a, b):
return a - b
@@ -15,7 +16,6 @@ def test_subtract_positive_numbers(self):
result = subtract(5, 3)
self.assertEqual(result, 2)
-
def test_subtract_negative_numbers(self):
result = subtract(-2, -3)
- self.assertEqual(result, 1)
\ No newline at end of file
+ self.assertEqual(result, 1)
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/__init__.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/__init__.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_decorated_tree.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_decorated_tree.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_decorated_tree.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_decorated_tree.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/file_one.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/file_one.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/file_one.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/file_one.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_simple_cases.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_simple_cases.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_simple_cases.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_simple_cases.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_simple_tree.py b/extensions/positron-python/python_files/tests/unittestadapter/.data/utils_simple_tree.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/.data/utils_simple_tree.py
rename to extensions/positron-python/python_files/tests/unittestadapter/.data/utils_simple_tree.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/__init__.py b/extensions/positron-python/python_files/tests/unittestadapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/__init__.py
rename to extensions/positron-python/python_files/tests/unittestadapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/conftest.py b/extensions/positron-python/python_files/tests/unittestadapter/conftest.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/conftest.py
rename to extensions/positron-python/python_files/tests/unittestadapter/conftest.py
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/expected_discovery_test_output.py b/extensions/positron-python/python_files/tests/unittestadapter/expected_discovery_test_output.py
similarity index 79%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/expected_discovery_test_output.py
rename to extensions/positron-python/python_files/tests/unittestadapter/expected_discovery_test_output.py
index 1007a8f42df..9fca67a3a57 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/expected_discovery_test_output.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/expected_discovery_test_output.py
@@ -14,20 +14,14 @@
"type_": TestNodeTypeEnum.folder,
"children": [
{
- "path": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"
- ),
+ "path": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"),
"name": "unittest_skip_file.py",
"type_": TestNodeTypeEnum.file,
"children": [],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"
- ),
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"),
},
{
- "path": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- ),
+ "path": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"),
"name": "unittest_skip_function.py",
"type_": TestNodeTypeEnum.file,
"children": [
@@ -41,30 +35,22 @@
{
"name": "testadd1",
"path": os.fspath(
- TEST_DATA_PATH
- / "unittest_skip"
- / "unittest_skip_function.py"
+ TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
),
"lineno": "13",
"type_": TestNodeTypeEnum.test,
"id_": os.fspath(
- TEST_DATA_PATH
- / "unittest_skip"
- / "unittest_skip_function.py"
+ TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
)
+ "\\SimpleTest\\testadd1",
"runID": "unittest_skip_function.SimpleTest.testadd1",
}
],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- )
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py")
+ "\\SimpleTest",
}
],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- ),
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"),
},
],
"id_": os.fspath(TEST_DATA_PATH / "unittest_skip"),
@@ -88,9 +74,7 @@
"name": "test_outer_folder",
"type_": TestNodeTypeEnum.folder,
"path": os.fsdecode(
- pathlib.PurePath(
- TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
- )
+ pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder")
),
"children": [
{
@@ -145,9 +129,7 @@
},
],
"id_": os.fsdecode(
- pathlib.PurePath(
- TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
- )
+ pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder")
),
}
],
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_discovery.py b/extensions/positron-python/python_files/tests/unittestadapter/test_discovery.py
similarity index 87%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/test_discovery.py
rename to extensions/positron-python/python_files/tests/unittestadapter/test_discovery.py
index a68774d3f2d..462b9cf9b0f 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_discovery.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/test_discovery.py
@@ -7,6 +7,7 @@
from typing import List
import pytest
+
from unittestadapter.discovery import discover_tests
from unittestadapter.pvsc_utils import TestNodeTypeEnum, parse_unittest_args
@@ -14,8 +15,9 @@
sys.path.append(os.fspath(script_dir))
-from . import expected_discovery_test_output
-from tests.tree_comparison_helper import is_same_tree
+from tests.tree_comparison_helper import is_same_tree # noqa: E402
+
+from . import expected_discovery_test_output # noqa: E402
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
@@ -105,22 +107,14 @@ def test_simple_discovery() -> None:
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_one",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_one",
},
{
"name": "test_two",
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_two",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_two",
},
],
"id_": file_path + "\\" + "DiscoverySimple",
@@ -168,22 +162,14 @@ def test_simple_discovery_with_top_dir_calculated() -> None:
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_one",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_one",
},
{
"name": "test_two",
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_two",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_two",
},
],
"id_": file_path + "\\" + "DiscoverySimple",
@@ -251,22 +237,14 @@ def test_error_discovery() -> None:
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoveryErrorTwo"
- + "\\"
- + "test_one",
+ "id_": file_path + "\\" + "DiscoveryErrorTwo" + "\\" + "test_one",
},
{
"name": "test_two",
"path": file_path,
"type_": TestNodeTypeEnum.test,
"lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoveryErrorTwo"
- + "\\"
- + "test_two",
+ "id_": file_path + "\\" + "DiscoveryErrorTwo" + "\\" + "test_two",
},
],
"id_": file_path + "\\" + "DiscoveryErrorTwo",
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_execution.py b/extensions/positron-python/python_files/tests/unittestadapter/test_execution.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/test_execution.py
rename to extensions/positron-python/python_files/tests/unittestadapter/test_execution.py
index 7d11c656b57..519c13bc2e5 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_execution.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/test_execution.py
@@ -10,7 +10,7 @@
script_dir = pathlib.Path(__file__).parent.parent
sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-from unittestadapter.execution import run_tests
+from unittestadapter.execution import run_tests # noqa: E402
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
diff --git a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_utils.py b/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py
similarity index 99%
rename from extensions/positron-python/pythonFiles/tests/unittestadapter/test_utils.py
rename to extensions/positron-python/python_files/tests/unittestadapter/test_utils.py
index d5f6fbbe9f1..f650f12252f 100644
--- a/extensions/positron-python/pythonFiles/tests/unittestadapter/test_utils.py
+++ b/extensions/positron-python/python_files/tests/unittestadapter/test_utils.py
@@ -19,8 +19,7 @@
script_dir = pathlib.Path(__file__).parent.parent
sys.path.append(os.fspath(script_dir))
-from tests.tree_comparison_helper import is_same_tree
-
+from tests.tree_comparison_helper import is_same_tree # noqa: E402
TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
diff --git a/extensions/positron-python/pythonFiles/tests/util.py b/extensions/positron-python/python_files/tests/util.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/tests/util.py
rename to extensions/positron-python/python_files/tests/util.py
diff --git a/extensions/positron-python/pythonFiles/unittestadapter/__init__.py b/extensions/positron-python/python_files/unittestadapter/__init__.py
similarity index 100%
rename from extensions/positron-python/pythonFiles/unittestadapter/__init__.py
rename to extensions/positron-python/python_files/unittestadapter/__init__.py
diff --git a/extensions/positron-python/pythonFiles/unittestadapter/discovery.py b/extensions/positron-python/python_files/unittestadapter/discovery.py
similarity index 92%
rename from extensions/positron-python/pythonFiles/unittestadapter/discovery.py
rename to extensions/positron-python/python_files/unittestadapter/discovery.py
index db06004e02c..298fe027d1d 100644
--- a/extensions/positron-python/pythonFiles/unittestadapter/discovery.py
+++ b/extensions/positron-python/python_files/unittestadapter/discovery.py
@@ -13,11 +13,12 @@
sys.path.append(os.fspath(script_dir))
sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-from testing_tools import socket_manager
-from typing_extensions import Literal, NotRequired, TypedDict
+from typing_extensions import Literal, NotRequired, TypedDict # noqa: E402
+
+from testing_tools import socket_manager # noqa: E402
# If I use from utils then there will be an import error in test_discovery.py.
-from unittestadapter.pvsc_utils import (
+from unittestadapter.pvsc_utils import ( # noqa: E402
TestNode,
build_test_tree,
parse_unittest_args,
@@ -97,9 +98,7 @@ def discover_tests(
# Get abspath of top level directory for build_test_tree.
top_level_dir = os.path.abspath(top_level_dir)
- tests, error = build_test_tree(
- suite, top_level_dir
- ) # test tree built successfully here.
+ tests, error = build_test_tree(suite, top_level_dir) # test tree built successfully here.
except Exception:
error.append(traceback.format_exc())
@@ -115,9 +114,7 @@ def discover_tests(
return payload
-def post_response(
- payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str
-) -> None:
+def post_response(payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str) -> None:
# Build the request data (it has to be a POST request or the Node side will not process it), and send it.
addr = ("localhost", port)
data = json.dumps(payload)
diff --git a/extensions/positron-python/pythonFiles/unittestadapter/execution.py b/extensions/positron-python/python_files/unittestadapter/execution.py
similarity index 94%
rename from extensions/positron-python/pythonFiles/unittestadapter/execution.py
rename to extensions/positron-python/python_files/unittestadapter/execution.py
index 22451c25bf1..6b925290647 100644
--- a/extensions/positron-python/pythonFiles/unittestadapter/execution.py
+++ b/extensions/positron-python/python_files/unittestadapter/execution.py
@@ -17,13 +17,12 @@
sys.path.append(os.fspath(script_dir))
sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-from testing_tools import process_json_util, socket_manager
-from typing_extensions import Literal, NotRequired, TypeAlias, TypedDict
-from unittestadapter.pvsc_utils import parse_unittest_args
+from typing_extensions import Literal, NotRequired, TypeAlias, TypedDict # noqa: E402
-ErrorType = Union[
- Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]
-]
+from testing_tools import process_json_util, socket_manager # noqa: E402
+from unittestadapter.pvsc_utils import parse_unittest_args # noqa: E402
+
+ErrorType = Union[Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]]
testPort = 0
testUuid = 0
START_DIR = ""
@@ -172,6 +171,11 @@ def run_tests(
locals: Optional[bool] = None,
) -> PayloadDict:
cwd = os.path.abspath(start_dir)
+ if "/" in start_dir: # is a subdir
+ parent_dir = os.path.dirname(start_dir)
+ sys.path.insert(0, parent_dir)
+ else:
+ sys.path.insert(0, cwd)
status = TestExecutionStatus.error
error = None
payload: PayloadDict = {"cwd": cwd, "status": status, "result": None}
@@ -243,9 +247,7 @@ def send_run_data(raw_data, port, uuid):
post_response(payload, port, uuid)
-def post_response(
- payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str
-) -> None:
+def post_response(payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str) -> None:
# Build the request data (it has to be a POST request or the Node side will not process it), and send it.
addr = ("localhost", port)
global __socket
@@ -285,9 +287,7 @@ def post_response(
) = parse_unittest_args(argv[index + 1 :])
run_test_ids_port = os.environ.get("RUN_TEST_IDS_PORT")
- run_test_ids_port_int = (
- int(run_test_ids_port) if run_test_ids_port is not None else 0
- )
+ run_test_ids_port_int = int(run_test_ids_port) if run_test_ids_port is not None else 0
if run_test_ids_port_int == 0:
print("Error[vscode-unittest]: RUN_TEST_IDS_PORT env var is not set.")
# get data from socket
@@ -308,9 +308,7 @@ def post_response(
try:
# Try to parse the buffer as JSON
- test_ids_from_buffer = process_json_util.process_rpc_json(
- buffer.decode("utf-8")
- )
+ test_ids_from_buffer = process_json_util.process_rpc_json(buffer.decode("utf-8"))
# Clear the buffer as complete JSON object is received
buffer = b""
break
diff --git a/extensions/positron-python/pythonFiles/unittestadapter/pvsc_utils.py b/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py
similarity index 95%
rename from extensions/positron-python/pythonFiles/unittestadapter/pvsc_utils.py
rename to extensions/positron-python/python_files/unittestadapter/pvsc_utils.py
index 5632e69b09c..de4f23957b8 100644
--- a/extensions/positron-python/pythonFiles/unittestadapter/pvsc_utils.py
+++ b/extensions/positron-python/python_files/unittestadapter/pvsc_utils.py
@@ -14,7 +14,7 @@
sys.path.append(os.fspath(script_dir))
sys.path.append(os.fspath(script_dir / "lib" / "python"))
-from typing_extensions import TypedDict
+from typing_extensions import TypedDict # noqa: E402
# Types
@@ -91,9 +91,7 @@ def build_test_node(path: str, name: str, type_: TestNodeTypeEnum) -> TestNode:
return {"path": path, "name": name, "type_": type_, "children": [], "id_": id_gen}
-def get_child_node(
- name: str, path: str, type_: TestNodeTypeEnum, root: TestNode
-) -> TestNode:
+def get_child_node(name: str, path: str, type_: TestNodeTypeEnum, root: TestNode) -> TestNode:
"""Find a child node in a test tree given its name, type and path. If the node doesn't exist, create it.
Path is required to distinguish between nodes with the same name and type."""
try:
@@ -154,9 +152,7 @@ def build_test_tree(
"""
error = []
directory_path = pathlib.PurePath(top_level_directory)
- root = build_test_node(
- top_level_directory, directory_path.name, TestNodeTypeEnum.folder
- )
+ root = build_test_node(top_level_directory, directory_path.name, TestNodeTypeEnum.folder)
for test_case in get_test_case(suite):
test_id = test_case.id()
@@ -167,9 +163,7 @@ def build_test_tree(
class_name = f"{components[-1]}.py"
# Find/build class node.
file_path = os.fsdecode(os.path.join(directory_path, class_name))
- current_node = get_child_node(
- class_name, file_path, TestNodeTypeEnum.file, root
- )
+ current_node = get_child_node(class_name, file_path, TestNodeTypeEnum.file, root)
else:
# Get the static test path components: filename, class name and function name.
components = test_id.split(".")
diff --git a/extensions/positron-python/pythonFiles/visualstudio_py_testlauncher.py b/extensions/positron-python/python_files/visualstudio_py_testlauncher.py
similarity index 90%
rename from extensions/positron-python/pythonFiles/visualstudio_py_testlauncher.py
rename to extensions/positron-python/python_files/visualstudio_py_testlauncher.py
index 0b0ef3242f6..b085d5ce4e6 100644
--- a/extensions/positron-python/pythonFiles/visualstudio_py_testlauncher.py
+++ b/extensions/positron-python/python_files/visualstudio_py_testlauncher.py
@@ -17,6 +17,7 @@
__author__ = "Microsoft Corporation "
__version__ = "3.0.0.0"
+import contextlib
import json
import os
import signal
@@ -27,7 +28,7 @@
try:
import thread
-except:
+except ModuleNotFoundError:
import _thread as thread
@@ -115,7 +116,7 @@ def close(self):
def readSocket(self):
try:
- data = self.socket.recv(1024)
+ self.socket.recv(1024)
self.callback()
except OSError:
if not self._closed:
@@ -169,9 +170,7 @@ def addUnexpectedSuccess(self, test):
def addSubTest(self, test, subtest, err):
super(VsTestResult, self).addSubTest(test, subtest, err)
- self.sendResult(
- test, "subtest-passed" if err is None else "subtest-failed", err, subtest
- )
+ self.sendResult(test, "subtest-passed" if err is None else "subtest-failed", err, subtest)
def sendResult(self, test, outcome, trace=None, subtest=None):
if _channel is not None:
@@ -199,11 +198,8 @@ def sendResult(self, test, outcome, trace=None, subtest=None):
def stopTests():
try:
os.kill(os.getpid(), signal.SIGUSR1)
- except:
- try:
- os.kill(os.getpid(), signal.SIGTERM)
- except:
- pass
+ except Exception:
+ os.kill(os.getpid(), signal.SIGTERM)
class ExitCommand(Exception):
@@ -226,9 +222,7 @@ def main():
prog="visualstudio_py_testlauncher",
usage="Usage: %prog [
-
-
-
-User Settings
-
-
-
-```
-{3}{4}
-```
-
-
-
diff --git a/extensions/positron-python/resources/report_issue_user_data_template.md b/extensions/positron-python/resources/report_issue_user_data_template.md
new file mode 100644
index 00000000000..037b844511d
--- /dev/null
+++ b/extensions/positron-python/resources/report_issue_user_data_template.md
@@ -0,0 +1,21 @@
+- Python version (& distribution if applicable, e.g. Anaconda): {0}
+- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
+- Value of the `python.languageServer` setting: {2}
+
+
+User Settings
+
+
+```
+{3}{4}
+```
+
+
+
+
+Installed Extensions
+
+|Extension Name|Extension Id|Version|
+|---|---|---|
+{5}
+
diff --git a/extensions/positron-python/scripts/patches/jedi-language-server.patch b/extensions/positron-python/scripts/patches/jedi-language-server.patch
index 948c9638341..25e7a509f87 100644
--- a/extensions/positron-python/scripts/patches/jedi-language-server.patch
+++ b/extensions/positron-python/scripts/patches/jedi-language-server.patch
@@ -1,7 +1,7 @@
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
index 4f3ba7bd5..52524daa2 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/jedi_utils.py
@@ -12,9 +12,9 @@ from inspect import Parameter
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Union
@@ -42,10 +42,10 @@ index 4f3ba7bd5..52524daa2 100644
"""Get LSP Diagnostic from Jedi SyntaxError."""
return Diagnostic(
range=Range(
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
index ba6eaf9fe..28266bd95 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi_language_server/__init__.py
@@ -1,4 +1,3 @@
"""Jedi Language Server."""
-from importlib.metadata import version
diff --git a/extensions/positron-python/scripts/patches/jedi.patch b/extensions/positron-python/scripts/patches/jedi.patch
index eabb923f86a..077a5374ce2 100644
--- a/extensions/positron-python/scripts/patches/jedi.patch
+++ b/extensions/positron-python/scripts/patches/jedi.patch
@@ -1,7 +1,7 @@
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
index e0f23d19b..f30731476 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/api/replstartup.py
@@ -17,13 +17,13 @@ Then you will be able to use Jedi completer in your Python interpreter::
..dex ..sert
@@ -19,10 +19,10 @@ index e0f23d19b..f30731476 100644
# Note: try not to do many things here, as it will contaminate global
# namespace of the interpreter.
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
index f044e2ee1..beec3f0cf 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/jedi/inference/compiled/subprocess/__main__.py
@@ -9,12 +9,9 @@ del sys.path[0]
diff --git a/extensions/positron-python/scripts/patches/parso.patch b/extensions/positron-python/scripts/patches/parso.patch
index 3121436e935..52ec34819b8 100644
--- a/extensions/positron-python/scripts/patches/parso.patch
+++ b/extensions/positron-python/scripts/patches/parso.patch
@@ -2,10 +2,10 @@ We append `-Positron` to the `_VERSION_TAG` so that our cache directories don't
installation in the user's environment. The vendored parso has a different import path than the user's,
so using the same cache can cause unexpected errors.
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/parso/cache.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/parso/cache.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/parso/cache.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/parso/cache.py
index 5592a9fdd..98b903aaa 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/parso/cache.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/parso/cache.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/parso/cache.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/parso/cache.py
@@ -49,7 +49,7 @@ are regarded as incompatible.
- A __slot__ of a class is changed.
"""
diff --git a/extensions/positron-python/scripts/patches/pydantic.patch b/extensions/positron-python/scripts/patches/pydantic.patch
index 4302de1b042..0be76d478ef 100644
--- a/extensions/positron-python/scripts/patches/pydantic.patch
+++ b/extensions/positron-python/scripts/patches/pydantic.patch
@@ -1,7 +1,7 @@
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
index 0c529620f..ce9df7a36 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
@@ -33,7 +33,7 @@ from typing import Callable, Dict, Type, Union, cast, overload
import hypothesis.strategies as st
@@ -46,10 +46,10 @@ index 0c529620f..ce9df7a36 100644
st.tuples(
st.integers(0, 255),
st.integers(0, 255),
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
index ce9df7a36..93ff17077 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pydantic/_hypothesis_plugin.py
@@ -34,7 +34,7 @@ import hypothesis.strategies as st
import pydantic
diff --git a/extensions/positron-python/scripts/patches/pygments.patch b/extensions/positron-python/scripts/patches/pygments.patch
index 5e4968342f4..7603a9b8bb2 100644
--- a/extensions/positron-python/scripts/patches/pygments.patch
+++ b/extensions/positron-python/scripts/patches/pygments.patch
@@ -1,7 +1,7 @@
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/cmdline.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/cmdline.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/cmdline.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/cmdline.py
index 435231e65..b75a9d7f4 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/cmdline.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/cmdline.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/cmdline.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/cmdline.py
@@ -469,11 +469,11 @@ def main_inner(parser, argns):
outfile = UnclosingTextIOWrapper(outfile, encoding=fmter.encoding)
fmter.encoding = None
@@ -16,10 +16,10 @@ index 435231e65..b75a9d7f4 100644
outfile, convert=None, strip=None, autoreset=False, wrap=True)
# When using the LaTeX formatter and the option `escapeinside` is
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/__main__.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/__main__.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/__main__.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/__main__.py
index 5eb2c747a..b8b833ec4 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/__main__.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/__main__.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/__main__.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/__main__.py
@@ -9,9 +9,9 @@
"""
@@ -32,10 +32,10 @@ index 5eb2c747a..b8b833ec4 100644
+ sys.exit(main(sys.argv))
except KeyboardInterrupt:
sys.exit(1)
-diff --git a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/sphinxext.py b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
+diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/sphinxext.py b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
index f935688f1..4c293489f 100644
---- a/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
-+++ b/extensions/positron-python/pythonFiles/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
+--- a/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
++++ b/extensions/positron-python/python_files/positron/positron_ipykernel/_vendor/pygments/sphinxext.py
@@ -91,7 +91,7 @@ class PygmentsDoc(Directive):
The columns are the lexer name, the extensions handled by this lexer
(or "None"), the aliases and a link to the lexer class."""
diff --git a/extensions/positron-python/scripts/vendor.py b/extensions/positron-python/scripts/vendor.py
index a57614a1b20..fbfaa1a64a8 100644
--- a/extensions/positron-python/scripts/vendor.py
+++ b/extensions/positron-python/scripts/vendor.py
@@ -25,9 +25,11 @@ def main() -> None:
cfg = Configuration(
base_directory=project_path,
- destination=Path("pythonFiles/positron/positron_ipykernel/_vendor/"),
+ destination=Path("python_files/positron/positron_ipykernel/_vendor/"),
namespace="positron_ipykernel._vendor",
- requirements=Path("pythonFiles/jedilsp_requirements/requirements.txt"),
+ requirements=Path(
+ "python_files/jedilsp_requirements/requirements.txt"
+ ),
patches_dir=Path("scripts/patches"),
substitutions=[
# Fix pygments.lexers._mapping strings, via: https://github.com/pypa/pip/blob/main/pyproject.toml
@@ -151,7 +153,9 @@ def run(args: List[str], cwd: Optional[str] = None) -> None:
if retcode is not None:
break
if retcode:
- raise VendoringError(f"Command exited with non-zero exit code: {retcode}")
+ raise VendoringError(
+ f"Command exited with non-zero exit code: {retcode}"
+ )
def detect_vendored_libs(destination: Path) -> List[str]:
diff --git a/extensions/positron-python/src/client/activation/jedi/languageClientFactory.ts b/extensions/positron-python/src/client/activation/jedi/languageClientFactory.ts
index c3ef8d9623f..70bd65da8d0 100644
--- a/extensions/positron-python/src/client/activation/jedi/languageClientFactory.ts
+++ b/extensions/positron-python/src/client/activation/jedi/languageClientFactory.ts
@@ -21,7 +21,7 @@ export class JediLanguageClientFactory implements ILanguageClientFactory {
clientOptions: LanguageClientOptions,
): Promise {
// Just run the language server using a module
- const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'run-jedi-language-server.py');
+ const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'run-jedi-language-server.py');
const interpreter = await this.interpreterService.getActiveInterpreter(resource);
const serverOptions: ServerOptions = {
command: interpreter ? interpreter.path : 'python',
diff --git a/extensions/positron-python/src/client/activation/jedi/manager.ts b/extensions/positron-python/src/client/activation/jedi/manager.ts
index 672e9a1b33f..bafdcc735a1 100644
--- a/extensions/positron-python/src/client/activation/jedi/manager.ts
+++ b/extensions/positron-python/src/client/activation/jedi/manager.ts
@@ -68,7 +68,7 @@ export class JediLanguageServerManager implements ILanguageServerManager {
try {
// Version is actually hardcoded in our requirements.txt.
const requirementsTxt = await fs.readFile(
- path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'jedilsp_requirements', 'requirements.txt'),
+ path.join(EXTENSION_ROOT_DIR, 'python_files', 'jedilsp_requirements', 'requirements.txt'),
'utf-8',
);
diff --git a/extensions/positron-python/src/client/activation/languageClientMiddlewareBase.ts b/extensions/positron-python/src/client/activation/languageClientMiddlewareBase.ts
index 5f7b6fa7265..f1e102a4081 100644
--- a/extensions/positron-python/src/client/activation/languageClientMiddlewareBase.ts
+++ b/extensions/positron-python/src/client/activation/languageClientMiddlewareBase.ts
@@ -87,10 +87,7 @@ export class LanguageClientMiddlewareBase implements Middleware {
const settingDict: LSPObject & { pythonPath: string; _envPYTHONPATH: string } = settings[
i
] as LSPObject & { pythonPath: string; _envPYTHONPATH: string };
- settingDict.pythonPath =
- (await this.getPythonPathOverride(uri)) ??
- (await interpreterService.getActiveInterpreter(uri))?.path ??
- 'python';
+ settingDict.pythonPath = (await interpreterService.getActiveInterpreter(uri))?.path ?? 'python';
const env = await envService.getEnvironmentVariables(uri);
const envPYTHONPATH = env.PYTHONPATH;
@@ -106,11 +103,6 @@ export class LanguageClientMiddlewareBase implements Middleware {
},
};
- // eslint-disable-next-line class-methods-use-this
- protected async getPythonPathOverride(_uri: Uri | undefined): Promise {
- return undefined;
- }
-
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function
protected configurationHook(_item: ConfigurationItem, _settings: LSPObject): void {}
diff --git a/extensions/positron-python/src/client/activation/node/languageClientMiddleware.ts b/extensions/positron-python/src/client/activation/node/languageClientMiddleware.ts
index fbc534f17e1..1a5da3d1a34 100644
--- a/extensions/positron-python/src/client/activation/node/languageClientMiddleware.ts
+++ b/extensions/positron-python/src/client/activation/node/languageClientMiddleware.ts
@@ -1,104 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { Uri } from 'vscode';
-import { ConfigurationItem, LanguageClient, LSPObject } from 'vscode-languageclient/node';
-import { IJupyterExtensionDependencyManager, IWorkspaceService } from '../../common/application/types';
+import { IJupyterExtensionDependencyManager } from '../../common/application/types';
import { IServiceContainer } from '../../ioc/types';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-import { traceLog } from '../../logging';
import { LanguageClientMiddleware } from '../languageClientMiddleware';
-import { LspInteractiveWindowMiddlewareAddon } from './lspInteractiveWindowMiddlewareAddon';
import { LanguageServerType } from '../types';
-import { LspNotebooksExperiment } from './lspNotebooksExperiment';
-
export class NodeLanguageClientMiddleware extends LanguageClientMiddleware {
- private readonly lspNotebooksExperiment: LspNotebooksExperiment;
-
- private readonly jupyterExtensionIntegration: JupyterExtensionIntegration;
-
- private readonly workspaceService: IWorkspaceService;
-
- public constructor(
- serviceContainer: IServiceContainer,
- private getClient: () => LanguageClient | undefined,
- serverVersion?: string,
- ) {
+ public constructor(serviceContainer: IServiceContainer, serverVersion?: string) {
super(serviceContainer, LanguageServerType.Node, serverVersion);
- this.workspaceService = serviceContainer.get(IWorkspaceService);
-
- this.lspNotebooksExperiment = serviceContainer.get(LspNotebooksExperiment);
this.setupHidingMiddleware(serviceContainer);
-
- this.jupyterExtensionIntegration = serviceContainer.get(
- JupyterExtensionIntegration,
- );
- if (!this.notebookAddon) {
- this.notebookAddon = new LspInteractiveWindowMiddlewareAddon(
- this.getClient,
- this.jupyterExtensionIntegration,
- );
- }
}
// eslint-disable-next-line class-methods-use-this
protected shouldCreateHidingMiddleware(_: IJupyterExtensionDependencyManager): boolean {
return false;
}
-
- protected async onExtensionChange(jupyterDependencyManager: IJupyterExtensionDependencyManager): Promise {
- if (jupyterDependencyManager && jupyterDependencyManager.isJupyterExtensionInstalled) {
- await this.lspNotebooksExperiment.onJupyterInstalled();
- }
-
- if (!this.notebookAddon) {
- this.notebookAddon = new LspInteractiveWindowMiddlewareAddon(
- this.getClient,
- this.jupyterExtensionIntegration,
- );
- }
- }
-
- protected async getPythonPathOverride(uri: Uri | undefined): Promise {
- if (!uri) {
- return undefined;
- }
-
- const jupyterPythonPathFunction = this.jupyterExtensionIntegration.getJupyterPythonPathFunction();
- if (!jupyterPythonPathFunction) {
- return undefined;
- }
-
- const result = await jupyterPythonPathFunction(uri);
-
- if (result) {
- traceLog(`Jupyter provided interpreter path override: ${result}`);
- }
-
- return result;
- }
-
- // eslint-disable-next-line class-methods-use-this
- protected configurationHook(item: ConfigurationItem, settings: LSPObject): void {
- if (item.section === 'editor') {
- if (this.workspaceService) {
- // Get editor.formatOnType using Python language id so [python] setting
- // will be honored if present.
- const editorConfig = this.workspaceService.getConfiguration(
- item.section,
- undefined,
- /* languageSpecific */ true,
- );
-
- const settingDict: LSPObject & { formatOnType?: boolean } = settings as LSPObject & {
- formatOnType: boolean;
- };
-
- settingDict.formatOnType = editorConfig.get('formatOnType');
- }
- }
- }
}
diff --git a/extensions/positron-python/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts b/extensions/positron-python/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts
deleted file mode 100644
index 0a40915d98e..00000000000
--- a/extensions/positron-python/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { Disposable, NotebookCell, NotebookDocument, TextDocument, TextDocumentChangeEvent, Uri } from 'vscode';
-import { Converter } from 'vscode-languageclient/lib/common/codeConverter';
-import {
- DidChangeNotebookDocumentNotification,
- LanguageClient,
- Middleware,
- NotebookCellKind,
- NotebookDocumentChangeEvent,
-} from 'vscode-languageclient/node';
-import * as proto from 'vscode-languageserver-protocol';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-
-type TextContent = Required['cells']>['textContent']>[0];
-
-/**
- * Detects the input box text documents of Interactive Windows and makes them appear to be
- * the last cell of their corresponding notebooks.
- */
-export class LspInteractiveWindowMiddlewareAddon implements Middleware, Disposable {
- constructor(
- private readonly getClient: () => LanguageClient | undefined,
- private readonly jupyterExtensionIntegration: JupyterExtensionIntegration,
- ) {
- // Make sure a bunch of functions are bound to this. VS code can call them without a this context
- this.didOpen = this.didOpen.bind(this);
- this.didChange = this.didChange.bind(this);
- this.didClose = this.didClose.bind(this);
- }
-
- public dispose(): void {
- // Nothing to dispose at the moment
- }
-
- // Map of document URIs to NotebookDocuments for all known notebooks.
- private notebookDocumentMap: Map = new Map();
-
- // Map of document URIs to TextDocuments that should be linked to a notebook
- // whose didOpen we're expecting to see in the future.
- private unlinkedTextDocumentMap: Map = new Map();
-
- public async didOpen(document: TextDocument, next: (ev: TextDocument) => Promise): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(document.uri);
- if (!notebookUri) {
- await next(document);
- return;
- }
-
- const notebookDocument = this.notebookDocumentMap.get(notebookUri.toString());
- if (!notebookDocument) {
- this.unlinkedTextDocumentMap.set(notebookUri.toString(), document);
- return;
- }
-
- try {
- const result: NotebookDocumentChangeEvent = {
- cells: {
- structure: {
- array: {
- start: notebookDocument.cellCount,
- deleteCount: 0,
- cells: [{ kind: NotebookCellKind.Code, document: document.uri.toString() }],
- },
- didOpen: [
- {
- uri: document.uri.toString(),
- languageId: document.languageId,
- version: document.version,
- text: document.getText(),
- },
- ],
- didClose: undefined,
- },
- },
- };
-
- await this.getClient()?.sendNotification(DidChangeNotebookDocumentNotification.type, {
- notebookDocument: { version: notebookDocument.version, uri: notebookUri.toString() },
- change: result,
- });
- } catch (error) {
- this.getClient()?.error('Sending DidChangeNotebookDocumentNotification failed', error);
- throw error;
- }
- }
-
- public async didChange(
- event: TextDocumentChangeEvent,
- next: (ev: TextDocumentChangeEvent) => Promise,
- ): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(event.document.uri);
- if (!notebookUri) {
- await next(event);
- return;
- }
-
- const notebookDocument = this.notebookDocumentMap.get(notebookUri.toString());
- if (notebookDocument) {
- const client = this.getClient();
- if (client) {
- client.sendNotification(proto.DidChangeNotebookDocumentNotification.type, {
- notebookDocument: { uri: notebookUri.toString(), version: notebookDocument.version },
- change: {
- cells: {
- textContent: [
- LspInteractiveWindowMiddlewareAddon._asTextContentChange(
- event,
- client.code2ProtocolConverter,
- ),
- ],
- },
- },
- });
- }
- }
- }
-
- private static _asTextContentChange(event: TextDocumentChangeEvent, c2pConverter: Converter): TextContent {
- const params = c2pConverter.asChangeTextDocumentParams(event, event.document.uri, event.document.version);
- return { document: params.textDocument, changes: params.contentChanges };
- }
-
- public async didClose(document: TextDocument, next: (ev: TextDocument) => Promise): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(document.uri);
- if (!notebookUri) {
- await next(document);
- return;
- }
-
- this.unlinkedTextDocumentMap.delete(notebookUri.toString());
- }
-
- public async didOpenNotebook(
- notebookDocument: NotebookDocument,
- cells: NotebookCell[],
- next: (notebookDocument: NotebookDocument, cells: NotebookCell[]) => Promise,
- ): Promise {
- this.notebookDocumentMap.set(notebookDocument.uri.toString(), notebookDocument);
-
- const relatedTextDocument = this.unlinkedTextDocumentMap.get(notebookDocument.uri.toString());
- if (relatedTextDocument) {
- const newCells = [
- ...cells,
- {
- index: notebookDocument.cellCount,
- notebook: notebookDocument,
- kind: NotebookCellKind.Code,
- document: relatedTextDocument,
- metadata: {},
- outputs: [],
- executionSummary: undefined,
- },
- ];
-
- this.unlinkedTextDocumentMap.delete(notebookDocument.uri.toString());
-
- await next(notebookDocument, newCells);
- } else {
- await next(notebookDocument, cells);
- }
- }
-
- public async didCloseNotebook(
- notebookDocument: NotebookDocument,
- cells: NotebookCell[],
- next: (notebookDocument: NotebookDocument, cells: NotebookCell[]) => Promise,
- ): Promise {
- this.notebookDocumentMap.delete(notebookDocument.uri.toString());
-
- await next(notebookDocument, cells);
- }
-
- notebooks = {
- didOpen: this.didOpenNotebook.bind(this),
- didClose: this.didCloseNotebook.bind(this),
- };
-
- private getNotebookUriForTextDocumentUri(textDocumentUri: Uri): Uri | undefined {
- const getNotebookUriFunction = this.jupyterExtensionIntegration.getGetNotebookUriForTextDocumentUriFunction();
- if (!getNotebookUriFunction) {
- return undefined;
- }
-
- return getNotebookUriFunction(textDocumentUri);
- }
-}
diff --git a/extensions/positron-python/src/client/activation/node/lspNotebooksExperiment.ts b/extensions/positron-python/src/client/activation/node/lspNotebooksExperiment.ts
deleted file mode 100644
index de0acde0600..00000000000
--- a/extensions/positron-python/src/client/activation/node/lspNotebooksExperiment.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { inject, injectable } from 'inversify';
-import { IExtensionSingleActivationService } from '../types';
-import { traceVerbose } from '../../logging';
-import { IJupyterExtensionDependencyManager } from '../../common/application/types';
-import { IServiceContainer } from '../../ioc/types';
-import { sleep } from '../../common/utils/async';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-
-@injectable()
-export class LspNotebooksExperiment implements IExtensionSingleActivationService {
- public readonly supportedWorkspaceTypes = { untrustedWorkspace: true, virtualWorkspace: true };
-
- private isJupyterInstalled = false;
-
- constructor(
- @inject(IServiceContainer) private readonly serviceContainer: IServiceContainer,
- @inject(IJupyterExtensionDependencyManager) jupyterDependencyManager: IJupyterExtensionDependencyManager,
- ) {
- this.isJupyterInstalled = jupyterDependencyManager.isJupyterExtensionInstalled;
- }
-
- // eslint-disable-next-line class-methods-use-this
- public activate(): Promise {
- return Promise.resolve();
- }
-
- public async onJupyterInstalled(): Promise {
- if (this.isJupyterInstalled) {
- return;
- }
-
- await this.waitForJupyterToRegisterPythonPathFunction();
-
- this.isJupyterInstalled = true;
- }
-
- private async waitForJupyterToRegisterPythonPathFunction(): Promise {
- const jupyterExtensionIntegration = this.serviceContainer.get(
- JupyterExtensionIntegration,
- );
-
- let success = false;
- for (let tryCount = 0; tryCount < 20; tryCount += 1) {
- const jupyterPythonPathFunction = jupyterExtensionIntegration.getJupyterPythonPathFunction();
- if (jupyterPythonPathFunction) {
- traceVerbose(`Jupyter called registerJupyterPythonPathFunction`);
- success = true;
- break;
- }
-
- await sleep(500);
- }
-
- if (!success) {
- traceVerbose(`Timed out waiting for Jupyter to call registerJupyterPythonPathFunction`);
- }
- }
-}
diff --git a/extensions/positron-python/src/client/activation/node/manager.ts b/extensions/positron-python/src/client/activation/node/manager.ts
index b85d8fe6ed1..5a66e4abecd 100644
--- a/extensions/positron-python/src/client/activation/node/manager.ts
+++ b/extensions/positron-python/src/client/activation/node/manager.ts
@@ -116,11 +116,7 @@ export class NodeLanguageServerManager implements ILanguageServerManager {
@traceDecoratorVerbose('Starting language server')
protected async startLanguageServer(): Promise {
const options = await this.analysisOptions.getAnalysisOptions();
- this.middleware = new NodeLanguageClientMiddleware(
- this.serviceContainer,
- () => this.languageServerProxy.languageClient,
- this.lsVersion,
- );
+ this.middleware = new NodeLanguageClientMiddleware(this.serviceContainer, this.lsVersion);
options.middleware = this.middleware;
// Make sure the middleware is connected if we restart and we we're already connected.
diff --git a/extensions/positron-python/src/client/activation/node/pylanceApi.ts b/extensions/positron-python/src/client/activation/node/pylanceApi.ts
index 72f20db140e..4b3d21d7527 100644
--- a/extensions/positron-python/src/client/activation/node/pylanceApi.ts
+++ b/extensions/positron-python/src/client/activation/node/pylanceApi.ts
@@ -18,7 +18,6 @@ export interface PylanceApi {
};
notebook?: {
registerJupyterPythonPathFunction(func: (uri: Uri) => Promise): void;
- registerGetNotebookUriForTextDocumentUriFunction(func: (textDocumentUri: Uri) => Uri | undefined): void;
getCompletionItems(
document: TextDocument,
position: Position,
diff --git a/extensions/positron-python/src/client/activation/serviceRegistry.ts b/extensions/positron-python/src/client/activation/serviceRegistry.ts
index 7bfea039962..5e1828e5831 100644
--- a/extensions/positron-python/src/client/activation/serviceRegistry.ts
+++ b/extensions/positron-python/src/client/activation/serviceRegistry.ts
@@ -17,7 +17,6 @@ import { LoadLanguageServerExtension } from './common/loadLanguageServerExtensio
import { PartialModeStatusItem } from './partialModeStatus';
import { ILanguageServerWatcher } from '../languageServer/types';
import { LanguageServerWatcher } from '../languageServer/watcher';
-import { LspNotebooksExperiment } from './node/lspNotebooksExperiment';
export function registerTypes(serviceManager: IServiceManager): void {
serviceManager.addSingleton(IExtensionActivationService, PartialModeStatusItem);
@@ -36,6 +35,4 @@ export function registerTypes(serviceManager: IServiceManager): void {
serviceManager.addSingleton(ILanguageServerWatcher, LanguageServerWatcher);
serviceManager.addBinding(ILanguageServerWatcher, IExtensionActivationService);
- serviceManager.addSingleton(LspNotebooksExperiment, LspNotebooksExperiment);
- serviceManager.addBinding(LspNotebooksExperiment, IExtensionSingleActivationService);
}
diff --git a/extensions/positron-python/src/client/api/types.ts b/extensions/positron-python/src/client/api/types.ts
index 4de554bf5a2..873d5e802d5 100644
--- a/extensions/positron-python/src/client/api/types.ts
+++ b/extensions/positron-python/src/client/api/types.ts
@@ -16,7 +16,7 @@ export interface PythonExtension {
/**
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
* Users can append another array of strings of what they want to execute along with relevant arguments to Python.
- * E.g `['/Users/..../pythonVSCode/pythonFiles/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
+ * E.g `['/Users/..../pythonVSCode/python_files/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
* @param host
* @param port
* @param waitUntilDebuggerAttaches Defaults to `true`.
@@ -268,6 +268,7 @@ export type KnownEnvironmentTools =
| 'Venv'
| 'VirtualEnvWrapper'
| 'Pyenv'
+ | 'Hatch'
| 'Unknown';
/**
diff --git a/extensions/positron-python/src/client/common/application/commands/reportIssueCommand.ts b/extensions/positron-python/src/client/common/application/commands/reportIssueCommand.ts
index d18299e6698..f5f1f0ac0c0 100644
--- a/extensions/positron-python/src/client/common/application/commands/reportIssueCommand.ts
+++ b/extensions/positron-python/src/client/common/application/commands/reportIssueCommand.ts
@@ -19,6 +19,7 @@ import { EventName } from '../../../telemetry/constants';
import { EnvironmentType } from '../../../pythonEnvironments/info';
import { PythonSettings } from '../../configSettings';
import { SystemVariables } from '../../variables/systemVariables';
+import { getExtensions } from '../../vscodeApis/extensionsApi';
/**
* Allows the user to report an issue related to the Python extension using our template.
@@ -48,6 +49,8 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
private templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
+ private userDataTemplatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_user_data_template.md');
+
public async openReportIssue(): Promise {
const settings: IPythonSettings = this.configurationService.getSettings();
const argSettings = JSON.parse(await fs.readFile(this.argSettingsPath, 'utf8'));
@@ -86,6 +89,7 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
}
});
const template = await fs.readFile(this.templatePath, 'utf8');
+ const userTemplate = await fs.readFile(this.userDataTemplatePath, 'utf8');
const interpreter = await this.interpreterService.getActiveInterpreter();
const pythonVersion = interpreter?.version?.raw ?? '';
const languageServer =
@@ -97,14 +101,25 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
hasMultipleFolders && userSettings !== ''
? `Multiroot scenario, following user settings may not apply:${os.EOL}`
: '';
+
+ const installedExtensions = getExtensions()
+ .filter((extension) => !extension.id.startsWith('vscode.'))
+ .sort((a, b) => a.packageJSON.displayName.localeCompare(b.packageJSON.displayName))
+ .map(
+ (extension) =>
+ `|${extension.packageJSON.displayName}|${extension.id}|${extension.packageJSON.version}|`,
+ );
+
await this.commandManager.executeCommand('workbench.action.openIssueReporter', {
extensionId: 'ms-python.python',
- issueBody: template.format(
+ issueBody: template,
+ data: userTemplate.format(
pythonVersion,
virtualEnvKind,
languageServer,
hasMultipleFoldersText,
userSettings,
+ installedExtensions.join('\n'),
),
});
sendTelemetryEvent(EventName.USE_REPORT_ISSUE_COMMAND, undefined, {});
diff --git a/extensions/positron-python/src/client/common/experiments/groups.ts b/extensions/positron-python/src/client/common/experiments/groups.ts
index 5e302c926cc..d43f376ddc8 100644
--- a/extensions/positron-python/src/client/common/experiments/groups.ts
+++ b/extensions/positron-python/src/client/common/experiments/groups.ts
@@ -19,10 +19,6 @@ export enum DiscoveryUsingWorkers {
export enum EnableTestAdapterRewrite {
experiment = 'pythonTestAdapter',
}
-// Experiment to enable smart shift+enter, advance cursor.
-export enum EnableREPLSmartSend {
- experiment = 'pythonREPLSmartSend',
-}
// Experiment to recommend installing the tensorboard extension.
export enum RecommendTensobardExtension {
diff --git a/extensions/positron-python/src/client/common/persistentState.ts b/extensions/positron-python/src/client/common/persistentState.ts
index ea86b2e145b..e82299bfc67 100644
--- a/extensions/positron-python/src/client/common/persistentState.ts
+++ b/extensions/positron-python/src/client/common/persistentState.ts
@@ -6,7 +6,7 @@
import { inject, injectable, named } from 'inversify';
import { Memento } from 'vscode';
import { IExtensionSingleActivationService } from '../activation/types';
-import { traceError, traceVerbose, traceWarn } from '../logging';
+import { traceError } from '../logging';
import { ICommandManager } from './application/types';
import { Commands } from './constants';
import {
@@ -92,12 +92,8 @@ export class PersistentState implements IPersistentState {
// Due to a VSCode bug sometimes the changes are not reflected in the storage, atleast not immediately.
// It is noticed however that if we reset the storage first and then update it, it works.
// https://github.com/microsoft/vscode/issues/171827
- traceVerbose('Storage update failed for key', this.key, ' retrying by resetting first');
await this.updateValue(undefined as any, false);
await this.updateValue(newValue, false);
- if (JSON.stringify(this.value) != JSON.stringify(newValue)) {
- traceWarn('Retry failed, storage update failed for key', this.key);
- }
}
} catch (ex) {
traceError('Error while updating storage for key:', this.key, ex);
diff --git a/extensions/positron-python/src/client/common/process/internal/scripts/constants.ts b/extensions/positron-python/src/client/common/process/internal/scripts/constants.ts
index 4448f7e639c..6954592ed3d 100644
--- a/extensions/positron-python/src/client/common/process/internal/scripts/constants.ts
+++ b/extensions/positron-python/src/client/common/process/internal/scripts/constants.ts
@@ -5,4 +5,4 @@ import * as path from 'path';
import { EXTENSION_ROOT_DIR } from '../../../constants';
// It is simpler to hard-code it instead of using vscode.ExtensionContext.extensionPath.
-export const _SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'pythonFiles');
+export const _SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'python_files');
diff --git a/extensions/positron-python/src/client/common/process/internal/scripts/index.ts b/extensions/positron-python/src/client/common/process/internal/scripts/index.ts
index 2644fd0d00f..f2c905c0288 100644
--- a/extensions/positron-python/src/client/common/process/internal/scripts/index.ts
+++ b/extensions/positron-python/src/client/common/process/internal/scripts/index.ts
@@ -7,7 +7,7 @@ import { _SCRIPTS_DIR } from './constants';
const SCRIPTS_DIR = _SCRIPTS_DIR;
// "scripts" contains everything relevant to the scripts found under
-// the top-level "pythonFiles" directory. Each of those scripts has
+// the top-level "python_files" directory. Each of those scripts has
// a function in this module which matches the script's filename.
// Each function provides the commandline arguments that should be
// used when invoking a Python executable, whether through spawn/exec
@@ -18,7 +18,7 @@ const SCRIPTS_DIR = _SCRIPTS_DIR;
// into the corresponding object or objects. "parse()" takes a single
// string as the stdout text and returns the relevant data.
//
-// Some of the scripts are located in subdirectories of "pythonFiles".
+// Some of the scripts are located in subdirectories of "python_files".
// For each of those subdirectories there is a sub-module where
// those scripts' functions may be found.
//
diff --git a/extensions/positron-python/src/client/common/terminal/service.ts b/extensions/positron-python/src/client/common/terminal/service.ts
index cf63603a2e9..c3b90181d56 100644
--- a/extensions/positron-python/src/client/common/terminal/service.ts
+++ b/extensions/positron-python/src/client/common/terminal/service.ts
@@ -31,7 +31,7 @@ export class TerminalService implements ITerminalService, Disposable {
private terminalHelper: ITerminalHelper;
private terminalActivator: ITerminalActivator;
private terminalAutoActivator: ITerminalAutoActivation;
- private readonly envVarScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pythonrc.py');
+ private readonly envVarScript = path.join(EXTENSION_ROOT_DIR, 'python_files', 'pythonrc.py');
public get onDidCloseTerminal(): Event {
return this.terminalClosed.event.bind(this.terminalClosed);
}
diff --git a/extensions/positron-python/src/client/common/vscodeApis/extensionsApi.ts b/extensions/positron-python/src/client/common/vscodeApis/extensionsApi.ts
index ece424847a1..4e1664a3dfa 100644
--- a/extensions/positron-python/src/client/common/vscodeApis/extensionsApi.ts
+++ b/extensions/positron-python/src/client/common/vscodeApis/extensionsApi.ts
@@ -32,3 +32,8 @@ export function isExtensionDisabled(extensionId: string): boolean {
export function isInsider(): boolean {
return vscode.env.appName.includes('Insider');
}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function getExtensions(): readonly vscode.Extension[] {
+ return vscode.extensions.all;
+}
diff --git a/extensions/positron-python/src/client/debugger/extension/adapter/factory.ts b/extensions/positron-python/src/client/debugger/extension/adapter/factory.ts
index ecbd8afcc28..cfc8cf91aba 100644
--- a/extensions/positron-python/src/client/debugger/extension/adapter/factory.ts
+++ b/extensions/positron-python/src/client/debugger/extension/adapter/factory.ts
@@ -93,7 +93,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac
const debuggerAdapterPathToUse = path.join(
EXTENSION_ROOT_DIR,
- 'pythonFiles',
+ 'python_files',
'lib',
'python',
'debugpy',
diff --git a/extensions/positron-python/src/client/debugger/extension/adapter/remoteLaunchers.ts b/extensions/positron-python/src/client/debugger/extension/adapter/remoteLaunchers.ts
index f42f101f852..80e0289e3ad 100644
--- a/extensions/positron-python/src/client/debugger/extension/adapter/remoteLaunchers.ts
+++ b/extensions/positron-python/src/client/debugger/extension/adapter/remoteLaunchers.ts
@@ -7,7 +7,7 @@ import * as path from 'path';
import { EXTENSION_ROOT_DIR } from '../../../common/constants';
import '../../../common/extensions';
-const pathToPythonLibDir = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python');
+const pathToPythonLibDir = path.join(EXTENSION_ROOT_DIR, 'python_files', 'lib', 'python');
const pathToDebugger = path.join(pathToPythonLibDir, 'debugpy');
type RemoteDebugOptions = {
diff --git a/extensions/positron-python/src/client/environmentApi.ts b/extensions/positron-python/src/client/environmentApi.ts
index da6a132b2b4..5b77ecde1a9 100644
--- a/extensions/positron-python/src/client/environmentApi.ts
+++ b/extensions/positron-python/src/client/environmentApi.ts
@@ -32,6 +32,7 @@ import {
Resource,
} from './api/types';
import { buildEnvironmentCreationApi } from './pythonEnvironments/creation/createEnvApi';
+import { EnvironmentKnownCache } from './environmentKnownCache';
type ActiveEnvironmentChangeEvent = {
resource: WorkspaceFolder | undefined;
@@ -120,14 +121,27 @@ export function buildEnvironmentApi(
const disposables = serviceContainer.get(IDisposableRegistry);
const extensions = serviceContainer.get(IExtensions);
const envVarsProvider = serviceContainer.get(IEnvironmentVariablesProvider);
+ let knownCache: EnvironmentKnownCache;
+
+ function initKnownCache() {
+ const knownEnvs = discoveryApi
+ .getEnvs()
+ .filter((e) => filterUsingVSCodeContext(e))
+ .map((e) => updateReference(e));
+ return new EnvironmentKnownCache(knownEnvs);
+ }
function sendApiTelemetry(apiName: string, args?: unknown) {
extensions
.determineExtensionFromCallStack()
.then((info) => {
- sendTelemetryEvent(EventName.PYTHON_ENVIRONMENTS_API, undefined, {
- apiName,
- extensionId: info.extensionId,
- });
+ const p = Math.random();
+ if (p <= 0.001) {
+ // Only send API telemetry 1% of the time, as it can be chatty.
+ sendTelemetryEvent(EventName.PYTHON_ENVIRONMENTS_API, undefined, {
+ apiName,
+ extensionId: info.extensionId,
+ });
+ }
traceVerbose(`Extension ${info.extensionId} accessed ${apiName} with args: ${JSON.stringify(args)}`);
})
.ignoreErrors();
@@ -139,10 +153,15 @@ export function buildEnvironmentApi(
// Filter out environments that are not in the current workspace.
return;
}
+ if (!knownCache) {
+ knownCache = initKnownCache();
+ }
if (e.old) {
if (e.new) {
+ const newEnv = updateReference(e.new);
+ knownCache.updateEnv(convertEnvInfo(e.old), newEnv);
traceVerbose('Python API env change detected', env.id, 'update');
- onEnvironmentsChanged.fire({ type: 'update', env: convertEnvInfoAndGetReference(e.new) });
+ onEnvironmentsChanged.fire({ type: 'update', env: newEnv });
reportInterpretersChanged([
{
path: getEnvPath(e.new.executable.filename, e.new.location).path,
@@ -150,8 +169,10 @@ export function buildEnvironmentApi(
},
]);
} else {
+ const oldEnv = updateReference(e.old);
+ knownCache.updateEnv(oldEnv, undefined);
traceVerbose('Python API env change detected', env.id, 'remove');
- onEnvironmentsChanged.fire({ type: 'remove', env: convertEnvInfoAndGetReference(e.old) });
+ onEnvironmentsChanged.fire({ type: 'remove', env: oldEnv });
reportInterpretersChanged([
{
path: getEnvPath(e.old.executable.filename, e.old.location).path,
@@ -160,8 +181,10 @@ export function buildEnvironmentApi(
]);
}
} else if (e.new) {
+ const newEnv = updateReference(e.new);
+ knownCache.addEnv(newEnv);
traceVerbose('Python API env change detected', env.id, 'add');
- onEnvironmentsChanged.fire({ type: 'add', env: convertEnvInfoAndGetReference(e.new) });
+ onEnvironmentsChanged.fire({ type: 'add', env: newEnv });
reportInterpretersChanged([
{
path: getEnvPath(e.new.executable.filename, e.new.location).path,
@@ -179,6 +202,9 @@ export function buildEnvironmentApi(
onEnvironmentsChanged,
onEnvironmentVariablesChanged,
);
+ if (!knownCache!) {
+ knownCache = initKnownCache();
+ }
const environmentApi: PythonExtension['environments'] = {
getEnvironmentVariables: (resource?: Resource) => {
@@ -234,11 +260,9 @@ export function buildEnvironmentApi(
return resolveEnvironment(path, discoveryApi);
},
get known(): Environment[] {
- sendApiTelemetry('known');
- return discoveryApi
- .getEnvs()
- .filter((e) => filterUsingVSCodeContext(e))
- .map((e) => convertEnvInfoAndGetReference(e));
+ // Do not send telemetry for "known", as this may be called 1000s of times so it can significant:
+ // sendApiTelemetry('known');
+ return knownCache.envs;
},
async refreshEnvironments(options?: RefreshOptions) {
if (!workspace.isTrusted) {
@@ -318,6 +342,8 @@ function convertKind(kind: PythonEnvKind): EnvironmentTools | undefined {
return 'Pipenv';
case PythonEnvKind.Poetry:
return 'Poetry';
+ case PythonEnvKind.Hatch:
+ return 'Hatch';
case PythonEnvKind.VirtualEnvWrapper:
return 'VirtualEnvWrapper';
case PythonEnvKind.VirtualEnv:
@@ -351,7 +377,7 @@ export function convertEnvInfo(env: PythonEnvInfo): Environment {
return convertedEnv as Environment;
}
-function convertEnvInfoAndGetReference(env: PythonEnvInfo): Environment {
+function updateReference(env: PythonEnvInfo): Environment {
return getEnvReference(convertEnvInfo(env));
}
diff --git a/extensions/positron-python/src/client/environmentKnownCache.ts b/extensions/positron-python/src/client/environmentKnownCache.ts
new file mode 100644
index 00000000000..287f5bab343
--- /dev/null
+++ b/extensions/positron-python/src/client/environmentKnownCache.ts
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { Environment } from './api/types';
+
+/**
+ * Workaround temp cache until types are consolidated.
+ */
+export class EnvironmentKnownCache {
+ private _envs: Environment[] = [];
+
+ constructor(envs: Environment[]) {
+ this._envs = envs;
+ }
+
+ public get envs(): Environment[] {
+ return this._envs;
+ }
+
+ public addEnv(env: Environment): void {
+ const found = this._envs.find((e) => env.id === e.id);
+ if (!found) {
+ this._envs.push(env);
+ }
+ }
+
+ public updateEnv(oldValue: Environment, newValue: Environment | undefined): void {
+ const index = this._envs.findIndex((e) => oldValue.id === e.id);
+ if (index !== -1) {
+ if (newValue === undefined) {
+ this._envs.splice(index, 1);
+ } else {
+ this._envs[index] = newValue;
+ }
+ }
+ }
+}
diff --git a/extensions/positron-python/src/client/interpreter/autoSelection/index.ts b/extensions/positron-python/src/client/interpreter/autoSelection/index.ts
index 4310374fc00..5ad5362e821 100644
--- a/extensions/positron-python/src/client/interpreter/autoSelection/index.ts
+++ b/extensions/positron-python/src/client/interpreter/autoSelection/index.ts
@@ -209,6 +209,7 @@ export class InterpreterAutoSelectionService implements IInterpreterAutoSelectio
});
}
+ await this.envTypeComparer.initialize(resource);
const inExperiment = this.experimentService.inExperimentSync(DiscoveryUsingWorkers.experiment);
const workspaceUri = this.interpreterHelper.getActiveWorkspaceUri(resource);
let recommendedInterpreter: PythonEnvironment | undefined;
diff --git a/extensions/positron-python/src/client/interpreter/configuration/environmentTypeComparer.ts b/extensions/positron-python/src/client/interpreter/configuration/environmentTypeComparer.ts
index 053f27d3a80..86392d84f35 100644
--- a/extensions/positron-python/src/client/interpreter/configuration/environmentTypeComparer.ts
+++ b/extensions/positron-python/src/client/interpreter/configuration/environmentTypeComparer.ts
@@ -11,10 +11,17 @@ import { Resource } from '../../common/types';
import { Architecture } from '../../common/utils/platform';
import { isActiveStateEnvironmentForWorkspace } from '../../pythonEnvironments/common/environmentManagers/activestate';
import { isParentPath } from '../../pythonEnvironments/common/externalDependencies';
-import { EnvironmentType, PythonEnvironment, virtualEnvTypes } from '../../pythonEnvironments/info';
+import {
+ EnvironmentType,
+ PythonEnvironment,
+ virtualEnvTypes,
+ workspaceVirtualEnvTypes,
+} from '../../pythonEnvironments/info';
import { PythonVersion } from '../../pythonEnvironments/info/pythonVersion';
import { IInterpreterHelper } from '../contracts';
import { IInterpreterComparer } from './types';
+import { getActivePyenvForDirectory } from '../../pythonEnvironments/common/environmentManagers/pyenv';
+import { arePathsSame } from '../../common/platform/fs-paths';
// --- Start Positron ---
import { getPyenvDir } from '../../pythonEnvironments/common/environmentManagers/pyenv';
@@ -36,6 +43,8 @@ export enum EnvLocationHeuristic {
export class EnvironmentTypeComparer implements IInterpreterComparer {
private workspaceFolderPath: string;
+ private preferredPyenvInterpreterPath = new Map();
+
constructor(@inject(IInterpreterHelper) private readonly interpreterHelper: IInterpreterHelper) {
this.workspaceFolderPath = this.interpreterHelper.getActiveWorkspaceUri(undefined)?.folderUri.fsPath ?? '';
}
@@ -64,6 +73,18 @@ export class EnvironmentTypeComparer implements IInterpreterComparer {
return envLocationComparison;
}
+ if (a.envType === EnvironmentType.Pyenv && b.envType === EnvironmentType.Pyenv) {
+ const preferredPyenv = this.preferredPyenvInterpreterPath.get(this.workspaceFolderPath);
+ if (preferredPyenv) {
+ if (arePathsSame(preferredPyenv, b.path)) {
+ return 1;
+ }
+ if (arePathsSame(preferredPyenv, a.path)) {
+ return -1;
+ }
+ }
+ }
+
// Check environment type.
const envTypeComparison = compareEnvironmentType(a, b);
if (envTypeComparison !== 0) {
@@ -95,6 +116,16 @@ export class EnvironmentTypeComparer implements IInterpreterComparer {
return nameA > nameB ? 1 : -1;
}
+ public async initialize(resource: Resource): Promise {
+ const workspaceUri = this.interpreterHelper.getActiveWorkspaceUri(resource);
+ const cwd = workspaceUri?.folderUri.fsPath;
+ if (!cwd) {
+ return;
+ }
+ const preferredPyenvInterpreter = await getActivePyenvForDirectory(cwd);
+ this.preferredPyenvInterpreterPath.set(cwd, preferredPyenvInterpreter);
+ }
+
public getRecommended(interpreters: PythonEnvironment[], resource: Resource): PythonEnvironment | undefined {
// When recommending an intepreter for a workspace, we either want to return a local one
// or fallback on a globally-installed interpreter, and we don't want want to suggest a global environment
@@ -121,8 +152,8 @@ export class EnvironmentTypeComparer implements IInterpreterComparer {
if (getEnvLocationHeuristic(i, workspaceUri?.folderUri.fsPath || '') === EnvLocationHeuristic.Local) {
return true;
}
- if (virtualEnvTypes.includes(i.envType)) {
- // We're not sure if these envs were created for the workspace, so do not recommend them.
+ if (!workspaceVirtualEnvTypes.includes(i.envType) && virtualEnvTypes.includes(i.envType)) {
+ // These are global virtual envs so we're not sure if these envs were created for the workspace, skip them.
return false;
}
if (i.version?.major === 2) {
@@ -265,10 +296,17 @@ export function getEnvLocationHeuristic(environment: PythonEnvironment, workspac
*/
function compareEnvironmentType(a: PythonEnvironment, b: PythonEnvironment): number {
// --- Start Positron ---
- if (!a.type && !b.type && a.envType !== EnvironmentType.Pyenv && b.envType !== EnvironmentType.Pyenv) {
- // Don't lump Pyenv environments together with all other global interpreters.
- // --- End Positron ---
- // Return 0 if two global interpreters are being compared.
+ // if (!a.type && !b.type && a.envType !== EnvironmentType.Pyenv && b.envType !== EnvironmentType.Pyenv) {
+ // Don't lump Pyenv environments together with all other global interpreters.
+ // --- End Positron ---
+ if (!a.type && !b.type) {
+ if (a.envType === EnvironmentType.Pyenv && b.envType !== EnvironmentType.Pyenv) {
+ return -1;
+ }
+ if (a.envType !== EnvironmentType.Pyenv && b.envType === EnvironmentType.Pyenv) {
+ return 1;
+ }
+
return 0;
}
const envTypeByPriority = getPrioritizedEnvironmentType();
@@ -281,6 +319,7 @@ function getPrioritizedEnvironmentType(): EnvironmentType[] {
EnvironmentType.Poetry,
EnvironmentType.Pipenv,
EnvironmentType.VirtualEnvWrapper,
+ EnvironmentType.Hatch,
EnvironmentType.Venv,
EnvironmentType.VirtualEnv,
EnvironmentType.ActiveState,
diff --git a/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/commands/setInterpreter.ts b/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/commands/setInterpreter.ts
index 5487f459a7a..5d01cbaafb7 100644
--- a/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/commands/setInterpreter.ts
+++ b/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/commands/setInterpreter.ts
@@ -74,6 +74,7 @@ export namespace EnvGroups {
export const Pyenv = 'Pyenv';
export const Venv = 'Venv';
export const Poetry = 'Poetry';
+ export const Hatch = 'Hatch';
export const VirtualEnvWrapper = 'VirtualEnvWrapper';
export const ActiveState = 'ActiveState';
export const Recommended = Common.recommended;
diff --git a/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/interpreterSelector.ts b/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/interpreterSelector.ts
index 8c94abe2c8b..6b33245bb90 100644
--- a/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/interpreterSelector.ts
+++ b/extensions/positron-python/src/client/interpreter/configuration/interpreterSelector/interpreterSelector.ts
@@ -5,7 +5,7 @@
import { inject, injectable } from 'inversify';
import { Disposable, Uri } from 'vscode';
-import { arePathsSame } from '../../../common/platform/fs-paths';
+import { arePathsSame, isParentPath } from '../../../common/platform/fs-paths';
import { IPathUtils, Resource } from '../../../common/types';
import { getEnvPath } from '../../../pythonEnvironments/base/info/env';
import { PythonEnvironment } from '../../../pythonEnvironments/info';
@@ -45,6 +45,13 @@ export class InterpreterSelector implements IInterpreterSelector {
workspaceUri?: Uri,
useDetailedName = false,
): IInterpreterQuickPickItem {
+ if (!useDetailedName) {
+ const workspacePath = workspaceUri?.fsPath;
+ if (workspacePath && isParentPath(interpreter.path, workspacePath)) {
+ // If interpreter is in the workspace, then display the full path.
+ useDetailedName = true;
+ }
+ }
const path =
interpreter.envPath && getEnvPath(interpreter.path, interpreter.envPath).pathType === 'envFolderPath'
? interpreter.envPath
diff --git a/extensions/positron-python/src/client/interpreter/configuration/types.ts b/extensions/positron-python/src/client/interpreter/configuration/types.ts
index 815de29045d..08518d4d12d 100644
--- a/extensions/positron-python/src/client/interpreter/configuration/types.ts
+++ b/extensions/positron-python/src/client/interpreter/configuration/types.ts
@@ -58,6 +58,7 @@ export interface ISpecialQuickPickItem extends QuickPickItem {
export const IInterpreterComparer = Symbol('IInterpreterComparer');
export interface IInterpreterComparer {
+ initialize(resource: Resource): Promise;
compare(a: PythonEnvironment, b: PythonEnvironment): number;
getRecommended(interpreters: PythonEnvironment[], resource: Resource): PythonEnvironment | undefined;
}
diff --git a/extensions/positron-python/src/client/interpreter/interpreterPathCommand.ts b/extensions/positron-python/src/client/interpreter/interpreterPathCommand.ts
index 8402374d50d..0dce208c9bf 100644
--- a/extensions/positron-python/src/client/interpreter/interpreterPathCommand.ts
+++ b/extensions/positron-python/src/client/interpreter/interpreterPathCommand.ts
@@ -46,6 +46,8 @@ export class InterpreterPathCommand implements IExtensionSingleActivationService
workspaceFolderUri = undefined;
}
- return (await this.interpreterService.getActiveInterpreter(workspaceFolderUri))?.path ?? 'python';
+ const interpreterPath =
+ (await this.interpreterService.getActiveInterpreter(workspaceFolderUri))?.path ?? 'python';
+ return interpreterPath.toCommandArgumentForPythonExt();
}
}
diff --git a/extensions/positron-python/src/client/jupyter/jupyterIntegration.ts b/extensions/positron-python/src/client/jupyter/jupyterIntegration.ts
index dbfd1bdf568..a385248bff0 100644
--- a/extensions/positron-python/src/client/jupyter/jupyterIntegration.ts
+++ b/extensions/positron-python/src/client/jupyter/jupyterIntegration.ts
@@ -34,7 +34,7 @@ type PythonApiForJupyterExtension = {
*/
getSuggestions(resource: Resource): Promise;
/**
- * Returns path to where `debugpy` is. In python extension this is `/pythonFiles/lib/python`.
+ * Returns path to where `debugpy` is. In python extension this is `/python_files/lib/python`.
*/
getDebuggerPath(): Promise;
/**
@@ -57,14 +57,6 @@ type PythonApiForJupyterExtension = {
* @param func : The function that Python should call when requesting the Python path.
*/
registerJupyterPythonPathFunction(func: (uri: Uri) => Promise): void;
-
- /**
- * Call to provide a function that the Python extension can call to request the notebook
- * document URI related to a particular text document URI, or undefined if there is no
- * associated notebook.
- * @param func : The function that Python should call when requesting the notebook URI.
- */
- registerGetNotebookUriForTextDocumentUriFunction(func: (textDocumentUri: Uri) => Uri | undefined): void;
};
type JupyterExtensionApi = {
@@ -81,10 +73,6 @@ export class JupyterExtensionIntegration {
private pylanceExtension: Extension | undefined;
- private jupyterPythonPathFunction: ((uri: Uri) => Promise) | undefined;
-
- private getNotebookUriForTextDocumentUriFunction: ((textDocumentUri: Uri) => Uri | undefined) | undefined;
-
constructor(
@inject(IExtensions) private readonly extensions: IExtensions,
@inject(IInterpreterSelector) private readonly interpreterSelector: IInterpreterSelector,
@@ -123,8 +111,6 @@ export class JupyterExtensionIntegration {
getCondaVersion: () => this.condaService.getCondaVersion(),
registerJupyterPythonPathFunction: (func: (uri: Uri) => Promise) =>
this.registerJupyterPythonPathFunction(func),
- registerGetNotebookUriForTextDocumentUriFunction: (func: (textDocumentUri: Uri) => Uri | undefined) =>
- this.registerGetNotebookUriForTextDocumentUriFunction(func),
});
return undefined;
}
@@ -169,28 +155,9 @@ export class JupyterExtensionIntegration {
}
private registerJupyterPythonPathFunction(func: (uri: Uri) => Promise) {
- this.jupyterPythonPathFunction = func;
-
const api = this.getPylanceApi();
if (api) {
api.notebook!.registerJupyterPythonPathFunction(func);
}
}
-
- public getJupyterPythonPathFunction(): ((uri: Uri) => Promise) | undefined {
- return this.jupyterPythonPathFunction;
- }
-
- public registerGetNotebookUriForTextDocumentUriFunction(func: (textDocumentUri: Uri) => Uri | undefined): void {
- this.getNotebookUriForTextDocumentUriFunction = func;
-
- const api = this.getPylanceApi();
- if (api) {
- api.notebook!.registerGetNotebookUriForTextDocumentUriFunction(func);
- }
- }
-
- public getGetNotebookUriForTextDocumentUriFunction(): ((textDocumentUri: Uri) => Uri | undefined) | undefined {
- return this.getNotebookUriForTextDocumentUriFunction;
- }
}
diff --git a/extensions/positron-python/src/client/positron/manager.ts b/extensions/positron-python/src/client/positron/manager.ts
index ed2ef10c80e..6510da79cc2 100644
--- a/extensions/positron-python/src/client/positron/manager.ts
+++ b/extensions/positron-python/src/client/positron/manager.ts
@@ -110,7 +110,7 @@ export class PythonRuntimeManager implements positron.LanguageRuntimeManager {
}
const command = extraData.pythonPath;
- const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'positron', 'positron_language_server.py');
+ const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'positron', 'positron_language_server.py');
const args = [
command,
lsScriptPath,
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/info/env.ts b/extensions/positron-python/src/client/pythonEnvironments/base/info/env.ts
index aa213167820..b77acde5333 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/info/env.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/info/env.ts
@@ -160,7 +160,7 @@ export function setEnvDisplayString(env: PythonEnvInfo): void {
function buildEnvDisplayString(env: PythonEnvInfo, getAllDetails = false): string {
// main parts
- const shouldDisplayKind = getAllDetails || env.searchLocation || globallyInstalledEnvKinds.includes(env.kind);
+ const shouldDisplayKind = getAllDetails || globallyInstalledEnvKinds.includes(env.kind);
const shouldDisplayArch = !virtualEnvKinds.includes(env.kind);
const displayNameParts: string[] = ['Python'];
if (env.version && !isVersionEmpty(env.version)) {
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/info/envKind.ts b/extensions/positron-python/src/client/pythonEnvironments/base/info/envKind.ts
index ff53a57d2f4..77ed7f22533 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/info/envKind.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/info/envKind.ts
@@ -15,6 +15,7 @@ export function getKindDisplayName(kind: PythonEnvKind): string {
[PythonEnvKind.MicrosoftStore, 'Microsoft Store'],
[PythonEnvKind.Pyenv, 'pyenv'],
[PythonEnvKind.Poetry, 'Poetry'],
+ [PythonEnvKind.Hatch, 'Hatch'],
[PythonEnvKind.Custom, 'custom'],
// For now we treat OtherGlobal like Unknown.
[PythonEnvKind.Venv, 'venv'],
@@ -39,12 +40,13 @@ export function getKindDisplayName(kind: PythonEnvKind): string {
* Remarks: This is the order of detection based on how the various distributions and tools
* configure the environment, and the fall back for identification.
* Top level we have the following environment types, since they leave a unique signature
- * in the environment or * use a unique path for the environments they create.
+ * in the environment or use a unique path for the environments they create.
* 1. Conda
* 2. Microsoft Store
* 3. PipEnv
* 4. Pyenv
* 5. Poetry
+ * 6. Hatch
*
* Next level we have the following virtual environment tools. The are here because they
* are consumed by the tools above, and can also be used independently.
@@ -61,6 +63,7 @@ export function getPrioritizedEnvKinds(): PythonEnvKind[] {
PythonEnvKind.MicrosoftStore,
PythonEnvKind.Pipenv,
PythonEnvKind.Poetry,
+ PythonEnvKind.Hatch,
PythonEnvKind.Venv,
PythonEnvKind.VirtualEnvWrapper,
PythonEnvKind.VirtualEnv,
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/info/index.ts b/extensions/positron-python/src/client/pythonEnvironments/base/info/index.ts
index e55031fe807..a0bf01c27c9 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/info/index.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/info/index.ts
@@ -15,6 +15,7 @@ export enum PythonEnvKind {
MicrosoftStore = 'global-microsoft-store',
Pyenv = 'global-pyenv',
Poetry = 'poetry',
+ Hatch = 'hatch',
ActiveState = 'activestate',
Custom = 'global-custom',
OtherGlobal = 'global-other',
@@ -44,6 +45,7 @@ export interface EnvPathType {
export const virtualEnvKinds = [
PythonEnvKind.Poetry,
+ PythonEnvKind.Hatch,
PythonEnvKind.Pipenv,
PythonEnvKind.Venv,
PythonEnvKind.VirtualEnvWrapper,
@@ -194,7 +196,7 @@ type _PythonEnvInfo = PythonEnvBaseInfo & PythonBuildInfo;
* @prop distro - the installed Python distro that this env is using or belongs to
* @prop display - the text to use when showing the env to users
* @prop detailedDisplayName - display name containing all details
- * @prop searchLocation - the root under which a locator found this env, if any
+ * @prop searchLocation - the project to which this env is related to, if any
*/
export type PythonEnvInfo = _PythonEnvInfo & {
distro: PythonDistroInfo;
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locator.ts
index 3fd5194c37d..58798627678 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locator.ts
@@ -20,7 +20,7 @@ export type PythonEnvUpdatedEvent = {
/**
* The iteration index of The env info that was previously provided.
*/
- index?: number;
+ index: number;
/**
* The env info that was previously provided.
*/
@@ -144,6 +144,7 @@ export type BasicEnvInfo = {
executablePath: string;
source?: PythonEnvSource[];
envPath?: string;
+ searchLocation?: Uri;
};
/**
@@ -243,7 +244,7 @@ export interface IDiscoveryAPI {
resolveEnv(path: string): Promise;
}
-interface IEmitter {
+export interface IEmitter {
fire(e: E): void;
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locatorUtils.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locatorUtils.ts
index faeaa84bedf..6af8c0ee1b6 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locatorUtils.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locatorUtils.ts
@@ -95,8 +95,6 @@ export async function getEnvs(iterator: IPythonEnvsIterator imp
await this.disposables.dispose();
}
- public iterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator {
- const iterator = this.doIterEnvs(query);
- const it = this._iterEnvs(iterator, query);
- it.onUpdated = iterator.onUpdated;
- return it;
- }
-
- private async *_iterEnvs(
- iterator: IPythonEnvsIterator,
- query?: PythonLocatorQuery,
- ): IPythonEnvsIterator {
+ public async *iterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator {
await this.activate();
+ const iterator = this.doIterEnvs(query);
if (query?.envPath) {
let result = await iterator.next();
while (!result.done) {
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsCollectionCache.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsCollectionCache.ts
index dadab2512e1..456e8adfa9a 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsCollectionCache.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsCollectionCache.ts
@@ -245,6 +245,10 @@ export class PythonEnvInfoCache extends PythonEnvsWatcher();
if (iterator.onUpdated !== undefined) {
- iterator.onUpdated(async (event) => {
+ const listener = iterator.onUpdated(async (event) => {
if (isProgressEvent(event)) {
switch (event.stage) {
case ProgressReportStage.discoveryFinished:
state.done = true;
- // listener.dispose();
+ listener.dispose();
break;
case ProgressReportStage.allPathsDiscovered:
if (!query) {
@@ -164,10 +164,6 @@ export class EnvsCollectionService extends PythonEnvsWatcher {
+ const listener = iterator.onUpdated((event) => {
if (isProgressEvent(event)) {
if (event.stage === ProgressReportStage.discoveryFinished) {
state.done = true;
- // For super slow locators such as Windows registry, we expect updates even after discovery
- // is "officially" finished, hence do not dispose listeners.
- // listener.dispose();
+ listener.dispose();
} else {
didUpdate.fire(event);
}
@@ -69,11 +67,15 @@ async function* iterEnvsIterator(
const oldEnv = seen[event.index];
seen[event.index] = event.update;
didUpdate.fire({ index: event.index, old: oldEnv, update: event.update });
- } else if (event.update) {
- didUpdate.fire({ update: event.update });
+ } else {
+ // This implies a problem in a downstream locator
+ traceVerbose(`Expected already iterated env, got ${event.old} (#${event.index})`);
}
+ state.pending -= 1;
checkIfFinishedAndNotify(state, didUpdate);
});
+ } else {
+ didUpdate.fire({ stage: ProgressReportStage.discoveryStarted });
}
let result = await iterator.next();
@@ -89,8 +91,10 @@ async function* iterEnvsIterator(
}
result = await iterator.next();
}
- state.done = true;
- checkIfFinishedAndNotify(state, didUpdate);
+ if (iterator.onUpdated === undefined) {
+ state.done = true;
+ checkIfFinishedAndNotify(state, didUpdate);
+ }
}
async function resolveDifferencesInBackground(
@@ -124,8 +128,8 @@ function checkIfFinishedAndNotify(
) {
if (state.done && state.pending === 0) {
didUpdate.fire({ stage: ProgressReportStage.discoveryFinished });
+ didUpdate.dispose();
traceVerbose(`Finished with environment reducer`);
- state.done = false; // No need to notify again.
}
}
@@ -133,9 +137,24 @@ function resolveEnvCollision(oldEnv: BasicEnvInfo, newEnv: BasicEnvInfo): BasicE
const [env] = sortEnvInfoByPriority(oldEnv, newEnv);
const merged = cloneDeep(env);
merged.source = uniq((oldEnv.source ?? []).concat(newEnv.source ?? []));
+ merged.searchLocation = getMergedSearchLocation(oldEnv, newEnv);
return merged;
}
+function getMergedSearchLocation(oldEnv: BasicEnvInfo, newEnv: BasicEnvInfo): Uri | undefined {
+ if (oldEnv.searchLocation && newEnv.searchLocation) {
+ // Choose the deeper project path of the two, as that can be used to signify
+ // that the environment is related to both the projects.
+ if (isParentPath(oldEnv.searchLocation.fsPath, newEnv.searchLocation.fsPath)) {
+ return oldEnv.searchLocation;
+ }
+ if (isParentPath(newEnv.searchLocation.fsPath, oldEnv.searchLocation.fsPath)) {
+ return newEnv.searchLocation;
+ }
+ }
+ return oldEnv.searchLocation ?? newEnv.searchLocation;
+}
+
/**
* Selects an environment based on the environment selection priority. This should
* match the priority in the environment identifier.
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsResolver.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsResolver.ts
index 752f5778c73..a7a25cc41c5 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsResolver.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/composite/envsResolver.ts
@@ -3,7 +3,7 @@
import { cloneDeep } from 'lodash';
import { Event, EventEmitter } from 'vscode';
-import { identifyEnvironment } from '../../../common/environmentIdentifier';
+import { isIdentifierRegistered, identifyEnvironment } from '../../../common/environmentIdentifier';
import { IEnvironmentInfoService } from '../../info/environmentInfoService';
import { PythonEnvInfo, PythonEnvKind } from '../../info';
import { getEnvPath, setEnvDisplayString } from '../../info/env';
@@ -81,15 +81,13 @@ export class PythonEnvsResolver implements IResolvingLocator {
const seen: PythonEnvInfo[] = [];
if (iterator.onUpdated !== undefined) {
- iterator.onUpdated(async (event) => {
+ const listener = iterator.onUpdated(async (event) => {
state.pending += 1;
if (isProgressEvent(event)) {
if (event.stage === ProgressReportStage.discoveryFinished) {
didUpdate.fire({ stage: ProgressReportStage.allPathsDiscovered });
state.done = true;
- // For super slow locators such as Windows registry, we expect updates even after discovery
- // is "officially" finished, hence do not dispose listeners.
- // listener.dispose();
+ listener.dispose();
} else {
didUpdate.fire(event);
}
@@ -97,14 +95,15 @@ export class PythonEnvsResolver implements IResolvingLocator {
throw new Error(
'Unsupported behavior: `undefined` environment updates are not supported from downstream locators in resolver',
);
- } else if (event.index && seen[event.index] !== undefined) {
+ } else if (event.index !== undefined && seen[event.index] !== undefined) {
const old = seen[event.index];
await setKind(event.update, environmentKinds);
seen[event.index] = await resolveBasicEnv(event.update);
didUpdate.fire({ old, index: event.index, update: seen[event.index] });
this.resolveInBackground(event.index, state, didUpdate, seen).ignoreErrors();
} else {
- didUpdate.fire({ update: await this.resolveEnv(event.update.executablePath) });
+ // This implies a problem in a downstream locator
+ traceVerbose(`Expected already iterated env, got ${event.old} (#${event.index})`);
}
state.pending -= 1;
checkIfFinishedAndNotify(state, didUpdate);
@@ -157,6 +156,10 @@ async function setKind(env: BasicEnvInfo, environmentKinds: Map Promise {
- const { kind, source } = env;
+ const { kind, source, searchLocation } = env;
const resolvers = getResolvers();
const resolverForKind = resolvers.get(kind)!;
const resolvedEnv = await resolverForKind(env);
- resolvedEnv.searchLocation = getSearchLocation(resolvedEnv);
+ resolvedEnv.searchLocation = getSearchLocation(resolvedEnv, searchLocation);
resolvedEnv.source = uniq(resolvedEnv.source.concat(source ?? []));
if (getOSType() === OSType.Windows && resolvedEnv.source?.includes(PythonEnvSource.WindowsRegistry)) {
// We can update env further using information we can get from the Windows registry.
@@ -87,7 +87,11 @@ async function getEnvType(env: PythonEnvInfo) {
return undefined;
}
-function getSearchLocation(env: PythonEnvInfo): Uri | undefined {
+function getSearchLocation(env: PythonEnvInfo, searchLocation: Uri | undefined): Uri | undefined {
+ if (searchLocation) {
+ // A search location has already been established by the downstream locators, simply use that.
+ return searchLocation;
+ }
const folders = getWorkspaceFolderPaths();
const isRootedEnv = folders.some((f) => isParentPath(env.executable.filename, f) || isParentPath(env.location, f));
if (isRootedEnv) {
@@ -109,7 +113,7 @@ async function updateEnvUsingRegistry(env: PythonEnvInfo): Promise {
let interpreters = getRegistryInterpretersSync();
if (!interpreters) {
traceError('Expected registry interpreter cache to be initialized already');
- interpreters = await getRegistryInterpreters(true);
+ interpreters = await getRegistryInterpreters();
}
const data = interpreters.find((i) => arePathsSame(i.interpreterPath, env.executable.filename));
if (data) {
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts
index 651a43ff886..a58bfdd65b2 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts
@@ -6,8 +6,6 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator';
import { Conda, getCondaEnvironmentsTxt } from '../../../common/environmentManagers/conda';
import { traceError, traceVerbose } from '../../../../logging';
import { FSWatchingLocator } from './fsWatchingLocator';
-import { DiscoveryUsingWorkers } from '../../../../common/experiments/groups';
-import { inExperiment } from '../../../common/externalDependencies';
export class CondaEnvironmentLocator extends FSWatchingLocator {
public readonly providerId: string = 'conda-envs';
@@ -21,11 +19,8 @@ export class CondaEnvironmentLocator extends FSWatchingLocator {
}
// eslint-disable-next-line class-methods-use-this
- public async *doIterEnvs(
- _: unknown,
- useWorkerThreads = inExperiment(DiscoveryUsingWorkers.experiment),
- ): IPythonEnvsIterator {
- const conda = await Conda.getConda(undefined, useWorkerThreads);
+ public async *doIterEnvs(_: unknown): IPythonEnvsIterator {
+ const conda = await Conda.getConda();
if (conda === undefined) {
traceVerbose(`Couldn't locate the conda binary.`);
return;
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/fsWatchingLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/fsWatchingLocator.ts
index 7565913f0a7..71bd30f7cfd 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/fsWatchingLocator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/fsWatchingLocator.ts
@@ -105,9 +105,7 @@ export abstract class FSWatchingLocator extends LazyResourceBasedLocator {
}
// Start the FS watchers.
- traceVerbose('Getting roots');
let roots = await this.getRoots();
- traceVerbose('Found roots');
if (typeof roots === 'string') {
roots = [roots];
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts
index 71f3d69e906..cc623be8392 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts
@@ -3,6 +3,7 @@
import { toLower, uniq, uniqBy } from 'lodash';
import * as path from 'path';
+import { Uri } from 'vscode';
import { chain, iterable } from '../../../../common/utils/async';
import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform';
import { PythonEnvKind } from '../../info';
@@ -10,7 +11,7 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator';
import { FSWatchingLocator } from './fsWatchingLocator';
import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils';
import { pathExists, untildify } from '../../../common/externalDependencies';
-import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv';
+import { getProjectDir, isPipenvEnvironment } from '../../../common/environmentManagers/pipenv';
import {
isVenvEnvironment,
isVirtualenvEnvironment,
@@ -57,6 +58,18 @@ async function getGlobalVirtualEnvDirs(): Promise {
return [OSType.Windows, OSType.OSX].includes(getOSType()) ? uniqBy(venvDirs, toLower) : uniq(venvDirs);
}
+async function getSearchLocation(env: BasicEnvInfo): Promise {
+ if (env.kind === PythonEnvKind.Pipenv) {
+ // Pipenv environments are created only for a specific project, so they must only
+ // appear if that particular project is being queried.
+ const project = await getProjectDir(path.dirname(path.dirname(env.executablePath)));
+ if (project) {
+ return Uri.file(project);
+ }
+ }
+ return undefined;
+}
+
/**
* Gets the virtual environment kind for a given interpreter path.
* This only checks for environments created using venv, virtualenv,
@@ -123,8 +136,9 @@ export class GlobalVirtualEnvironmentLocator extends FSWatchingLocator {
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
const kind = await getVirtualEnvKind(filename);
+ const searchLocation = await getSearchLocation({ kind, executablePath: filename });
try {
- yield { kind, executablePath: filename };
+ yield { kind, executablePath: filename, searchLocation };
traceVerbose(`Global Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/hatchLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/hatchLocator.ts
new file mode 100644
index 00000000000..f7746a8c5a2
--- /dev/null
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/hatchLocator.ts
@@ -0,0 +1,57 @@
+'use strict';
+
+import { PythonEnvKind } from '../../info';
+import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator';
+import { LazyResourceBasedLocator } from '../common/resourceBasedLocator';
+import { Hatch } from '../../../common/environmentManagers/hatch';
+import { asyncFilter } from '../../../../common/utils/arrayUtils';
+import { pathExists } from '../../../common/externalDependencies';
+import { traceError, traceVerbose } from '../../../../logging';
+import { chain, iterable } from '../../../../common/utils/async';
+import { getInterpreterPathFromDir } from '../../../common/commonUtils';
+
+/**
+ * Gets all default virtual environment locations to look for in a workspace.
+ */
+async function getVirtualEnvDirs(root: string): Promise {
+ const hatch = await Hatch.getHatch(root);
+ const envDirs = (await hatch?.getEnvList()) ?? [];
+ return asyncFilter(envDirs, pathExists);
+}
+
+/**
+ * Finds and resolves virtual environments created using Hatch.
+ */
+export class HatchLocator extends LazyResourceBasedLocator {
+ public readonly providerId: string = 'hatch';
+
+ public constructor(private readonly root: string) {
+ super();
+ }
+
+ protected doIterEnvs(): IPythonEnvsIterator {
+ async function* iterator(root: string) {
+ const envDirs = await getVirtualEnvDirs(root);
+ const envGenerators = envDirs.map((envDir) => {
+ async function* generator() {
+ traceVerbose(`Searching for Hatch virtual envs in: ${envDir}`);
+ const filename = await getInterpreterPathFromDir(envDir);
+ if (filename !== undefined) {
+ try {
+ yield { executablePath: filename, kind: PythonEnvKind.Hatch };
+ traceVerbose(`Hatch Virtual Environment: [added] ${filename}`);
+ } catch (ex) {
+ traceError(`Failed to process environment: ${filename}`, ex);
+ }
+ }
+ }
+ return generator();
+ });
+
+ yield* iterable(chain(envGenerators));
+ traceVerbose(`Finished searching for Hatch envs`);
+ }
+
+ return iterator(this.root);
+ }
+}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts
index 4084c7a5cfb..ab1a8cf7744 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts
@@ -4,6 +4,7 @@
'use strict';
import * as path from 'path';
+import { Uri } from 'vscode';
import { chain, iterable } from '../../../../common/utils/async';
import { PythonEnvKind } from '../../info';
import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator';
@@ -59,7 +60,7 @@ export class PoetryLocator extends LazyResourceBasedLocator {
// We should extract the kind here to avoid doing is*Environment()
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
- yield { executablePath: filename, kind };
+ yield { executablePath: filename, kind, searchLocation: Uri.file(root) };
traceVerbose(`Poetry Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
diff --git a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts
index c6ba64cdb46..a574116f185 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts
@@ -3,76 +3,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { EventEmitter } from 'vscode';
import { PythonEnvKind, PythonEnvSource } from '../../info';
-import {
- BasicEnvInfo,
- IPythonEnvsIterator,
- Locator,
- ProgressNotificationEvent,
- ProgressReportStage,
- PythonEnvUpdatedEvent,
-} from '../../locator';
+import { BasicEnvInfo, IPythonEnvsIterator, Locator, PythonLocatorQuery, IEmitter } from '../../locator';
import { getRegistryInterpreters } from '../../../common/windowsUtils';
import { traceError, traceVerbose } from '../../../../logging';
import { isMicrosoftStoreDir } from '../../../common/environmentManagers/microsoftStoreEnv';
-import { inExperiment } from '../../../common/externalDependencies';
+import { PythonEnvsChangedEvent } from '../../watcher';
import { DiscoveryUsingWorkers } from '../../../../common/experiments/groups';
+import { inExperiment } from '../../../common/externalDependencies';
+
+export const WINDOWS_REG_PROVIDER_ID = 'windows-registry';
export class WindowsRegistryLocator extends Locator {
- public readonly providerId: string = 'windows-registry';
+ public readonly providerId: string = WINDOWS_REG_PROVIDER_ID;
// eslint-disable-next-line class-methods-use-this
public iterEnvs(
- _?: unknown,
+ query?: PythonLocatorQuery,
useWorkerThreads = inExperiment(DiscoveryUsingWorkers.experiment),
): IPythonEnvsIterator {
- const didUpdate = new EventEmitter | ProgressNotificationEvent>();
- const iterator = useWorkerThreads ? iterEnvsIterator(didUpdate) : oldIterEnvsIterator();
if (useWorkerThreads) {
- iterator.onUpdated = didUpdate.event;
+ /**
+ * Windows registry is slow and often not necessary, so notify completion immediately, but use watcher
+ * change events to signal for any new envs which are found.
+ */
+ if (query?.providerId === this.providerId) {
+ // Query via change event, so iterate all envs.
+ return iterateEnvs();
+ }
+ return iterateEnvsLazily(this.emitter);
}
- return iterator;
+ return iterateEnvs();
}
}
-/**
- * Windows registry is slow and often not necessary, so notify completion immediately, while still updating lazily as we find stuff.
- * To accomplish this, use an empty iterator while lazily firing environments using updates.
- */
-async function* iterEnvsIterator(
- didUpdate: EventEmitter | ProgressNotificationEvent>,
-): IPythonEnvsIterator {
- updateLazily(didUpdate).ignoreErrors();
+async function* iterateEnvsLazily(changed: IEmitter): IPythonEnvsIterator {
+ loadAllEnvs(changed).ignoreErrors();
}
-async function updateLazily(didUpdate: EventEmitter | ProgressNotificationEvent>) {
+async function loadAllEnvs(changed: IEmitter) {
traceVerbose('Searching for windows registry interpreters');
- const interpreters = await getRegistryInterpreters(true);
- for (const interpreter of interpreters) {
- try {
- // Filter out Microsoft Store app directories. We have a store app locator that handles this.
- // The python.exe available in these directories might not be python. It can be a store install
- // shortcut that takes you to microsoft store.
- if (isMicrosoftStoreDir(interpreter.interpreterPath)) {
- continue;
- }
- const env: BasicEnvInfo = {
- kind: PythonEnvKind.OtherGlobal,
- executablePath: interpreter.interpreterPath,
- source: [PythonEnvSource.WindowsRegistry],
- };
- didUpdate.fire({ update: env });
- } catch (ex) {
- traceError(`Failed to process environment: ${interpreter}`, ex);
- }
- }
- didUpdate.fire({ stage: ProgressReportStage.discoveryFinished });
+ await getRegistryInterpreters();
+ changed.fire({ providerId: WINDOWS_REG_PROVIDER_ID });
traceVerbose('Finished searching for windows registry interpreters');
}
-async function* oldIterEnvsIterator(): IPythonEnvsIterator {
- const interpreters = await getRegistryInterpreters(false);
+async function* iterateEnvs(): IPythonEnvsIterator {
+ const interpreters = await getRegistryInterpreters(); // Value should already be loaded at this point, so this returns immediately.
for (const interpreter of interpreters) {
try {
// Filter out Microsoft Store app directories. We have a store app locator that handles this.
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/commonUtils.ts b/extensions/positron-python/src/client/pythonEnvironments/common/commonUtils.ts
index 85462531e5e..4bd94e0402a 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/commonUtils.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/commonUtils.ts
@@ -5,7 +5,7 @@ import * as fs from 'fs';
import * as path from 'path';
import { convertFileType, DirEntry, FileType, getFileFilter, getFileType } from '../../common/utils/filesystem';
import { getOSType, OSType } from '../../common/utils/platform';
-import { traceError } from '../../logging';
+import { traceError, traceVerbose } from '../../logging';
import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info';
import { comparePythonVersionSpecificity } from '../base/info/env';
import { parseVersion } from '../base/info/pythonVersion';
@@ -246,8 +246,11 @@ export async function getPythonVersionFromPath(interpreterPath: string, hint?: s
versionA = UNKNOWN_PYTHON_VERSION;
}
const versionB = interpreterPath ? await getPythonVersionFromNearByFiles(interpreterPath) : UNKNOWN_PYTHON_VERSION;
+ traceVerbose('Best effort version B for', interpreterPath, JSON.stringify(versionB));
const versionC = interpreterPath ? await getPythonVersionFromPyvenvCfg(interpreterPath) : UNKNOWN_PYTHON_VERSION;
+ traceVerbose('Best effort version C for', interpreterPath, JSON.stringify(versionC));
const versionD = interpreterPath ? await getPythonVersionFromConda(interpreterPath) : UNKNOWN_PYTHON_VERSION;
+ traceVerbose('Best effort version D for', interpreterPath, JSON.stringify(versionD));
let version = UNKNOWN_PYTHON_VERSION;
for (const v of [versionA, versionB, versionC, versionD]) {
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentIdentifier.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentIdentifier.ts
index 2dbc8b2b93d..880eed52598 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentIdentifier.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentIdentifier.ts
@@ -17,8 +17,9 @@ import {
import { isMicrosoftStoreEnvironment } from './environmentManagers/microsoftStoreEnv';
import { isActiveStateEnvironment } from './environmentManagers/activestate';
+const notImplemented = () => Promise.resolve(false);
+
function getIdentifiers(): Map Promise> {
- const notImplemented = () => Promise.resolve(false);
const defaultTrue = () => Promise.resolve(true);
const identifier: Map Promise> = new Map();
Object.values(PythonEnvKind).forEach((k) => {
@@ -39,6 +40,15 @@ function getIdentifiers(): Map Promise
return identifier;
}
+export function isIdentifierRegistered(kind: PythonEnvKind): boolean {
+ const identifiers = getIdentifiers();
+ const identifier = identifiers.get(kind);
+ if (identifier === notImplemented) {
+ return false;
+ }
+ return true;
+}
+
/**
* Returns environment type.
* @param {string} path : Absolute path to the python interpreter binary or path to environment.
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/conda.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/conda.ts
index 1cb2e490aef..bb844f45a0f 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/conda.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/conda.ts
@@ -10,7 +10,6 @@ import {
readFile,
onDidChangePythonSetting,
exec,
- inExperiment,
} from '../externalDependencies';
import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../../base/info';
@@ -25,7 +24,6 @@ import { OUTPUT_MARKER_SCRIPT } from '../../../common/process/internal/scripts';
import { splitLines } from '../../../common/stringUtils';
import { SpawnOptions } from '../../../common/process/types';
import { sleep } from '../../../common/utils/async';
-import { DiscoveryUsingWorkers } from '../../../common/experiments/groups';
export const AnacondaCompanyName = 'Anaconda, Inc.';
export const CONDAPATH_SETTING_KEY = 'condaPath';
@@ -274,11 +272,7 @@ export class Conda {
private readonly useWorkerThreads?: boolean,
) {
if (this.useWorkerThreads === undefined) {
- try {
- this.useWorkerThreads = inExperiment(DiscoveryUsingWorkers.experiment);
- } catch {
- this.useWorkerThreads = false; // Temporarily support for legacy tests
- }
+ this.useWorkerThreads = false;
}
this.shellCommand = shellCommand ?? command;
onDidChangePythonSetting(CONDAPATH_SETTING_KEY, () => {
@@ -286,9 +280,9 @@ export class Conda {
});
}
- public static async getConda(shellPath?: string, useWorkerThreads?: boolean): Promise {
+ public static async getConda(shellPath?: string): Promise {
if (Conda.condaPromise.get(shellPath) === undefined || isTestExecution()) {
- Conda.condaPromise.set(shellPath, Conda.locate(shellPath, useWorkerThreads));
+ Conda.condaPromise.set(shellPath, Conda.locate(shellPath));
}
return Conda.condaPromise.get(shellPath);
}
@@ -299,15 +293,7 @@ export class Conda {
*
* @return A Conda instance corresponding to the binary, if successful; otherwise, undefined.
*/
- private static async locate(shellPath?: string, useWorkerThread?: boolean): Promise {
- let useWorkerThreads: boolean;
- if (useWorkerThread === undefined) {
- try {
- useWorkerThreads = inExperiment(DiscoveryUsingWorkers.experiment);
- } catch {
- useWorkerThreads = false; // Temporarily support for legacy tests
- }
- }
+ private static async locate(shellPath?: string): Promise {
traceVerbose(`Searching for conda.`);
const home = getUserHomeDir();
let customCondaPath: string | undefined = 'conda';
@@ -334,7 +320,7 @@ export class Conda {
}
async function* getCandidatesFromRegistry() {
- const interps = await getRegistryInterpreters(useWorkerThreads);
+ const interps = await getRegistryInterpreters();
const candidates = interps
.filter((interp) => interp.interpreterPath && interp.distroOrgName === 'ContinuumAnalytics')
.map((interp) => path.join(path.win32.dirname(interp.interpreterPath), suffix));
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/hatch.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/hatch.ts
new file mode 100644
index 00000000000..6d7a13ea155
--- /dev/null
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/hatch.ts
@@ -0,0 +1,116 @@
+import { isTestExecution } from '../../../common/constants';
+import { exec, pathExists } from '../externalDependencies';
+import { traceVerbose } from '../../../logging';
+import { cache } from '../../../common/utils/decorators';
+import { getOSType, OSType } from '../../../common/utils/platform';
+
+/** Wraps the "Hatch" utility, and exposes its functionality.
+ */
+export class Hatch {
+ /**
+ * Locating Hatch binary can be expensive, since it potentially involves spawning or
+ * trying to spawn processes; so we only do it once per session.
+ */
+ private static hatchPromise: Map> = new Map<
+ string,
+ Promise
+ >();
+
+ /**
+ * Creates a Hatch service corresponding to the corresponding "hatch" command.
+ *
+ * @param command - Command used to run hatch. This has the same meaning as the
+ * first argument of spawn() - i.e. it can be a full path, or just a binary name.
+ * @param cwd - The working directory to use as cwd when running hatch.
+ */
+ constructor(public readonly command: string, private cwd: string) {
+ this.fixCwd();
+ }
+
+ /**
+ * Returns a Hatch instance corresponding to the binary which can be used to run commands for the cwd.
+ *
+ * Every directory is a valid Hatch project, so this should always return a Hatch instance.
+ */
+ public static async getHatch(cwd: string): Promise {
+ if (Hatch.hatchPromise.get(cwd) === undefined || isTestExecution()) {
+ Hatch.hatchPromise.set(cwd, Hatch.locate(cwd));
+ }
+ return Hatch.hatchPromise.get(cwd);
+ }
+
+ private static async locate(cwd: string): Promise {
+ // First thing this method awaits on should be hatch command execution,
+ // hence perform all operations before that synchronously.
+ const hatchPath = 'hatch';
+ traceVerbose(`Probing Hatch binary ${hatchPath}`);
+ const hatch = new Hatch(hatchPath, cwd);
+ const virtualenvs = await hatch.getEnvList();
+ if (virtualenvs !== undefined) {
+ traceVerbose(`Found hatch binary ${hatchPath}`);
+ return hatch;
+ }
+ traceVerbose(`Failed to find Hatch binary ${hatchPath}`);
+
+ // Didn't find anything.
+ traceVerbose(`No Hatch binary found`);
+ return undefined;
+ }
+
+ /**
+ * Retrieves list of Python environments known to Hatch for this working directory.
+ * Returns `undefined` if we failed to spawn in some way.
+ *
+ * Corresponds to "hatch env show --json". Swallows errors if any.
+ */
+ public async getEnvList(): Promise {
+ return this.getEnvListCached(this.cwd);
+ }
+
+ /**
+ * Method created to facilitate caching. The caching decorator uses function arguments as cache key,
+ * so pass in cwd on which we need to cache.
+ */
+ @cache(30_000, true, 10_000)
+ private async getEnvListCached(_cwd: string): Promise {
+ const envInfoOutput = await exec(this.command, ['env', 'show', '--json'], {
+ cwd: this.cwd,
+ throwOnStdErr: true,
+ }).catch(traceVerbose);
+ if (!envInfoOutput) {
+ return undefined;
+ }
+ const envPaths = await Promise.all(
+ Object.keys(JSON.parse(envInfoOutput.stdout)).map(async (name) => {
+ const envPathOutput = await exec(this.command, ['env', 'find', name], {
+ cwd: this.cwd,
+ throwOnStdErr: true,
+ }).catch(traceVerbose);
+ if (!envPathOutput) return undefined;
+ const dir = envPathOutput.stdout.trim();
+ return (await pathExists(dir)) ? dir : undefined;
+ }),
+ );
+ return envPaths.flatMap((r) => (r ? [r] : []));
+ }
+
+ /**
+ * Due to an upstream hatch issue on Windows https://github.com/pypa/hatch/issues/1350,
+ * 'hatch env find default' does not handle case-insensitive paths as cwd, which are valid on Windows.
+ * So we need to pass the case-exact path as cwd.
+ * It has been observed that only the drive letter in `cwd` is lowercased here. Unfortunately,
+ * there's no good way to get case of the drive letter correctly without using Win32 APIs:
+ * https://stackoverflow.com/questions/33086985/how-to-obtain-case-exact-path-of-a-file-in-node-js-on-windows
+ * So we do it manually.
+ */
+ private fixCwd(): void {
+ if (getOSType() === OSType.Windows) {
+ if (/^[a-z]:/.test(this.cwd)) {
+ // Replace first character by the upper case version of the character.
+ const a = this.cwd.split(':');
+ a[0] = a[0].toUpperCase();
+ this.cwd = a.join(':');
+ }
+ }
+ }
+}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts
index d8b1b2ff649..c8651533ed4 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts
@@ -70,7 +70,7 @@ async function getPipfileIfLocal(interpreterPath: string): Promise {
+export async function getProjectDir(envFolder: string): Promise {
// Global pipenv environments have a .project file with the absolute path to the project
// See https://github.com/pypa/pipenv/blob/v2018.6.25/CHANGELOG.rst#features--improvements
// This is the layout we expect
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/poetry.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/poetry.ts
index 48199b5bdc8..5e5fa241620 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/poetry.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/poetry.ts
@@ -10,7 +10,7 @@ import {
isParentPath,
pathExists,
pathExistsSync,
- readFileSync,
+ readFile,
shellExecute,
} from '../externalDependencies';
import { getEnvironmentDirFromPath } from '../commonUtils';
@@ -63,7 +63,7 @@ async function isLocalPoetryEnvironment(interpreterPath: string): Promise {
// Following check should be performed synchronously so we trigger poetry execution as soon as possible.
- if (!hasValidPyprojectToml(cwd)) {
+ if (!(await hasValidPyprojectToml(cwd))) {
// This check is not expensive and may change during a session, so we need not cache it.
return undefined;
}
@@ -325,12 +325,12 @@ export async function isPoetryEnvironmentRelatedToFolder(
*
* @param folder Folder to look for pyproject.toml file in.
*/
-function hasValidPyprojectToml(folder: string): boolean {
+async function hasValidPyprojectToml(folder: string): Promise {
const pyprojectToml = path.join(folder, 'pyproject.toml');
if (!pathExistsSync(pyprojectToml)) {
return false;
}
- const content = readFileSync(pyprojectToml);
+ const content = await readFile(pyprojectToml);
if (!content.includes('[tool.poetry]')) {
return false;
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts
index 229df897051..3d6c276cc86 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts
@@ -1,6 +1,7 @@
import * as path from 'path';
import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform';
-import { arePathsSame, isParentPath, pathExists } from '../externalDependencies';
+import { arePathsSame, isParentPath, pathExists, shellExecute } from '../externalDependencies';
+import { traceVerbose } from '../../../logging';
export function getPyenvDir(): string {
// Check if the pyenv environment variables exist: PYENV on Windows, PYENV_ROOT on Unix.
@@ -20,6 +21,26 @@ export function getPyenvDir(): string {
return pyenvDir;
}
+async function getPyenvBinary(): Promise {
+ const pyenvDir = getPyenvDir();
+ const pyenvBin = path.join(pyenvDir, 'bin', 'pyenv');
+ if (await pathExists(pyenvBin)) {
+ return pyenvBin;
+ }
+ return 'pyenv';
+}
+
+export async function getActivePyenvForDirectory(cwd: string): Promise {
+ const pyenvBin = await getPyenvBinary();
+ try {
+ const pyenvInterpreterPath = await shellExecute(`${pyenvBin} which python`, { cwd });
+ return pyenvInterpreterPath.stdout.trim();
+ } catch (ex) {
+ traceVerbose(ex);
+ return undefined;
+ }
+}
+
export function getPyenvVersionsDir(): string {
return path.join(getPyenvDir(), 'versions');
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/externalDependencies.ts b/extensions/positron-python/src/client/pythonEnvironments/common/externalDependencies.ts
index 4c970e5d7f3..387c04790c3 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/externalDependencies.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/externalDependencies.ts
@@ -11,7 +11,6 @@ import { chain, iterable } from '../../common/utils/async';
import { getOSType, OSType } from '../../common/utils/platform';
import { IServiceContainer } from '../../ioc/types';
import { traceError, traceVerbose } from '../../logging';
-import { DiscoveryUsingWorkers } from '../../common/experiments/groups';
let internalServiceContainer: IServiceContainer;
export function initializeExternalDependencies(serviceContainer: IServiceContainer): void {
@@ -21,7 +20,7 @@ export function initializeExternalDependencies(serviceContainer: IServiceContain
// processes
export async function shellExecute(command: string, options: ShellOptions = {}): Promise> {
- const useWorker = inExperiment(DiscoveryUsingWorkers.experiment);
+ const useWorker = false;
const service = await internalServiceContainer.get(IProcessServiceFactory).create();
options = { ...options, useWorker };
return service.shellExec(command, options);
@@ -31,7 +30,7 @@ export async function exec(
file: string,
args: string[],
options: SpawnOptions = {},
- useWorker = inExperiment(DiscoveryUsingWorkers.experiment),
+ useWorker = false,
): Promise> {
const service = await internalServiceContainer.get(IProcessServiceFactory).create();
options = { ...options, useWorker };
diff --git a/extensions/positron-python/src/client/pythonEnvironments/common/windowsUtils.ts b/extensions/positron-python/src/client/pythonEnvironments/common/windowsUtils.ts
index e9210371be0..fe15f71522a 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/common/windowsUtils.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/common/windowsUtils.ts
@@ -126,15 +126,15 @@ export function getRegistryInterpretersSync(): IRegistryInterpreterData[] | unde
let registryInterpretersPromise: Promise | undefined;
-export async function getRegistryInterpreters(useWorkerThreads: boolean): Promise {
+export async function getRegistryInterpreters(): Promise {
if (!isTestExecution() && registryInterpretersPromise !== undefined) {
return registryInterpretersPromise;
}
- registryInterpretersPromise = getRegistryInterpretersImpl(useWorkerThreads);
+ registryInterpretersPromise = getRegistryInterpretersImpl();
return registryInterpretersPromise;
}
-async function getRegistryInterpretersImpl(useWorkerThreads: boolean): Promise {
+async function getRegistryInterpretersImpl(useWorkerThreads = false): Promise {
let registryData: IRegistryInterpreterData[] = [];
for (const arch of ['x64', 'x86']) {
diff --git a/extensions/positron-python/src/client/pythonEnvironments/creation/installedPackagesDiagnostic.ts b/extensions/positron-python/src/client/pythonEnvironments/creation/installedPackagesDiagnostic.ts
index a46a32ce827..0a96ff08801 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/creation/installedPackagesDiagnostic.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/creation/installedPackagesDiagnostic.ts
@@ -29,7 +29,6 @@ async function setContextForActiveEditor(diagnosticCollection: DiagnosticCollect
}
// undefined here in the logs means no file was selected
- traceVerbose(`Clearing context for python dependencies not installed: ${doc?.uri.fsPath}`);
await executeCommand('setContext', DEPS_NOT_INSTALLED_KEY, false);
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/index.ts b/extensions/positron-python/src/client/pythonEnvironments/index.ts
index 5a5fceffa69..d3f6166295d 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/index.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/index.ts
@@ -28,6 +28,7 @@ import { MicrosoftStoreLocator } from './base/locators/lowLevel/microsoftStoreLo
import { getEnvironmentInfoService } from './base/info/environmentInfoService';
import { registerNewDiscoveryForIOC } from './legacyIOC';
import { PoetryLocator } from './base/locators/lowLevel/poetryLocator';
+import { HatchLocator } from './base/locators/lowLevel/hatchLocator';
import { createPythonEnvironments } from './api';
import {
createCollectionCache as createCache,
@@ -39,6 +40,8 @@ import { traceError } from '../logging';
import { ActiveStateLocator } from './base/locators/lowLevel/activeStateLocator';
import { CustomWorkspaceLocator } from './base/locators/lowLevel/customWorkspaceLocator';
+const PYTHON_ENV_INFO_CACHE_KEY = 'PYTHON_ENV_INFO_CACHEv2';
+
/**
* Set up the Python environments component (during extension activation).'
*/
@@ -68,7 +71,7 @@ export async function activate(api: IDiscoveryAPI, ext: ExtensionState): Promise
*/
const folders = vscode.workspace.workspaceFolders;
// Trigger discovery if environment cache is empty.
- const wasTriggered = getGlobalStorage(ext.context, 'PYTHON_ENV_INFO_CACHE', []).get().length > 0;
+ const wasTriggered = getGlobalStorage(ext.context, PYTHON_ENV_INFO_CACHE_KEY, []).get().length > 0;
if (!wasTriggered) {
api.triggerRefresh().ignoreErrors();
folders?.forEach(async (folder) => {
@@ -186,6 +189,7 @@ function createWorkspaceLocator(ext: ExtensionState): WorkspaceLocators {
(root: vscode.Uri) => [
new WorkspaceVirtualEnvironmentLocator(root.fsPath),
new PoetryLocator(root.fsPath),
+ new HatchLocator(root.fsPath),
new CustomWorkspaceLocator(root.fsPath),
],
// Add an ILocator factory func here for each kind of workspace-rooted locator.
@@ -225,7 +229,7 @@ function putIntoStorage(storage: IPersistentStorage, envs: Pyth
}
async function createCollectionCache(ext: ExtensionState): Promise {
- const storage = getGlobalStorage(ext.context, 'PYTHON_ENV_INFO_CACHE', []);
+ const storage = getGlobalStorage(ext.context, PYTHON_ENV_INFO_CACHE_KEY, []);
const cache = await createCache({
get: () => getFromStorage(storage),
store: async (e) => putIntoStorage(storage, e),
diff --git a/extensions/positron-python/src/client/pythonEnvironments/info/index.ts b/extensions/positron-python/src/client/pythonEnvironments/info/index.ts
index 17e8958f631..716d4bcd938 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/info/index.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/info/index.ts
@@ -19,15 +19,20 @@ export enum EnvironmentType {
Venv = 'Venv',
MicrosoftStore = 'MicrosoftStore',
Poetry = 'Poetry',
+ Hatch = 'Hatch',
VirtualEnvWrapper = 'VirtualEnvWrapper',
ActiveState = 'ActiveState',
Global = 'Global',
System = 'System',
}
+/**
+ * These envs are only created for a specific workspace, which we're able to detect.
+ */
+export const workspaceVirtualEnvTypes = [EnvironmentType.Poetry, EnvironmentType.Pipenv];
export const virtualEnvTypes = [
- EnvironmentType.Poetry,
- EnvironmentType.Pipenv,
+ ...workspaceVirtualEnvTypes,
+ EnvironmentType.Hatch, // This is also a workspace virtual env, but we're not treating it as such as of today.
EnvironmentType.Venv,
EnvironmentType.VirtualEnvWrapper,
EnvironmentType.Conda,
@@ -115,6 +120,9 @@ export function getEnvironmentTypeName(environmentType: EnvironmentType): string
case EnvironmentType.Poetry: {
return 'Poetry';
}
+ case EnvironmentType.Hatch: {
+ return 'Hatch';
+ }
case EnvironmentType.VirtualEnvWrapper: {
return 'virtualenvwrapper';
}
diff --git a/extensions/positron-python/src/client/pythonEnvironments/legacyIOC.ts b/extensions/positron-python/src/client/pythonEnvironments/legacyIOC.ts
index 31de503a0f3..4ef0894a470 100644
--- a/extensions/positron-python/src/client/pythonEnvironments/legacyIOC.ts
+++ b/extensions/positron-python/src/client/pythonEnvironments/legacyIOC.ts
@@ -38,6 +38,7 @@ const convertedKinds = new Map(
[PythonEnvKind.VirtualEnv]: EnvironmentType.VirtualEnv,
[PythonEnvKind.Pipenv]: EnvironmentType.Pipenv,
[PythonEnvKind.Poetry]: EnvironmentType.Poetry,
+ [PythonEnvKind.Hatch]: EnvironmentType.Hatch,
[PythonEnvKind.Venv]: EnvironmentType.Venv,
[PythonEnvKind.VirtualEnvWrapper]: EnvironmentType.VirtualEnvWrapper,
[PythonEnvKind.ActiveState]: EnvironmentType.ActiveState,
diff --git a/extensions/positron-python/src/client/telemetry/index.ts b/extensions/positron-python/src/client/telemetry/index.ts
index bdb098be520..3237bafc224 100644
--- a/extensions/positron-python/src/client/telemetry/index.ts
+++ b/extensions/positron-python/src/client/telemetry/index.ts
@@ -3,11 +3,9 @@
// Licensed under the MIT License.
import TelemetryReporter from '@vscode/extension-telemetry';
-
-import * as path from 'path';
-import * as fs from 'fs-extra';
+import type * as vscodeTypes from 'vscode';
import { DiagnosticCodes } from '../application/diagnostics/constants';
-import { AppinsightsKey, EXTENSION_ROOT_DIR, isTestExecution, isUnitTestExecution } from '../common/constants';
+import { AppinsightsKey, isTestExecution, isUnitTestExecution, PVSC_EXTENSION_ID } from '../common/constants';
import type { TerminalShellType } from '../common/terminal/types';
import { StopWatch } from '../common/utils/stopWatch';
import { isPromise } from '../common/utils/async';
@@ -39,14 +37,20 @@ function isTelemetrySupported(): boolean {
}
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+let packageJSON: any;
+
/**
* Checks if the telemetry is disabled
* @returns {boolean}
*/
export function isTelemetryDisabled(): boolean {
- const packageJsonPath = path.join(EXTENSION_ROOT_DIR, 'package.json');
- const packageJson = fs.readJSONSync(packageJsonPath);
- return !packageJson.enableTelemetry;
+ if (!packageJSON) {
+ const vscode = require('vscode') as typeof vscodeTypes;
+ const pythonExtension = vscode.extensions.getExtension(PVSC_EXTENSION_ID)!;
+ packageJSON = pythonExtension.packageJSON;
+ }
+ return !packageJSON.enableTelemetry;
}
const sharedProperties: Record = {};
diff --git a/extensions/positron-python/src/client/telemetry/pylance.ts b/extensions/positron-python/src/client/telemetry/pylance.ts
index 67be7428c7b..c0a3edb013c 100644
--- a/extensions/positron-python/src/client/telemetry/pylance.ts
+++ b/extensions/positron-python/src/client/telemetry/pylance.ts
@@ -27,7 +27,8 @@
"errorstack" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"lsversion" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"method" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
- "modulehash" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
+ "modulehash" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
+ "resultLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
/* __GDPR__
@@ -313,6 +314,15 @@
"typeevaltime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
+/* __GDPR__
+ "language_server/server_side_request" : {
+ "duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
+ "lsversion" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
+ "method" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
+ "modulehash" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
+ "resultLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
+ }
+*/
/* __GDPR__
"language_server/settings" : {
"addimportexactmatchonly" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
diff --git a/extensions/positron-python/src/client/terminals/codeExecution/helper.ts b/extensions/positron-python/src/client/terminals/codeExecution/helper.ts
index 48a435c8710..880da969d69 100644
--- a/extensions/positron-python/src/client/terminals/codeExecution/helper.ts
+++ b/extensions/positron-python/src/client/terminals/codeExecution/helper.ts
@@ -20,8 +20,7 @@ import { IInterpreterService } from '../../interpreter/contracts';
import { IServiceContainer } from '../../ioc/types';
import { ICodeExecutionHelper } from '../types';
import { traceError } from '../../logging';
-import { IConfigurationService, IExperimentService, Resource } from '../../common/types';
-import { EnableREPLSmartSend } from '../../common/experiments/groups';
+import { IConfigurationService, Resource } from '../../common/types';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
@@ -93,8 +92,7 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
const startLineVal = activeEditor?.selection?.start.line ?? 0;
const endLineVal = activeEditor?.selection?.end.line ?? 0;
const emptyHighlightVal = activeEditor?.selection?.isEmpty ?? true;
- const smartSendExperimentEnabledVal = pythonSmartSendEnabled(this.serviceContainer);
- let smartSendSettingsEnabledVal = false;
+ let smartSendSettingsEnabledVal = true;
const configuration = this.serviceContainer.get(IConfigurationService);
if (configuration) {
const pythonSettings = configuration.getSettings(this.activeResourceService.getActiveResource());
@@ -107,7 +105,6 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
startLine: startLineVal,
endLine: endLineVal,
emptyHighlight: emptyHighlightVal,
- smartSendExperimentEnabled: smartSendExperimentEnabledVal,
smartSendSettingsEnabled: smartSendSettingsEnabledVal,
});
observable.proc?.stdin?.write(input);
@@ -117,12 +114,7 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
const result = await normalizeOutput.promise;
const object = JSON.parse(result);
- if (
- activeEditor?.selection &&
- smartSendExperimentEnabledVal &&
- smartSendSettingsEnabledVal &&
- object.normalized !== 'deprecated'
- ) {
+ if (activeEditor?.selection && smartSendSettingsEnabledVal && object.normalized !== 'deprecated') {
const lineOffset = object.nextBlockLineno - activeEditor!.selection.start.line - 1;
await this.moveToNextBlock(lineOffset, activeEditor);
}
@@ -145,16 +137,15 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
*/
// eslint-disable-next-line class-methods-use-this
private async moveToNextBlock(lineOffset: number, activeEditor?: TextEditor): Promise {
- if (pythonSmartSendEnabled(this.serviceContainer)) {
- if (activeEditor?.selection?.isEmpty) {
- await this.commandManager.executeCommand('cursorMove', {
- to: 'down',
- by: 'line',
- value: Number(lineOffset),
- });
- await this.commandManager.executeCommand('cursorEnd');
- }
+ if (activeEditor?.selection?.isEmpty) {
+ await this.commandManager.executeCommand('cursorMove', {
+ to: 'down',
+ by: 'line',
+ value: Number(lineOffset),
+ });
+ await this.commandManager.executeCommand('cursorEnd');
}
+
return Promise.resolve();
}
@@ -314,9 +305,3 @@ function getMultiLineSelectionText(textEditor: TextEditor): string {
// ↑<---------------- To here
return selectionText;
}
-
-function pythonSmartSendEnabled(serviceContainer: IServiceContainer): boolean {
- const experiment = serviceContainer.get(IExperimentService);
-
- return experiment ? experiment.inExperimentSync(EnableREPLSmartSend.experiment) : false;
-}
diff --git a/extensions/positron-python/src/client/terminals/envCollectionActivation/service.ts b/extensions/positron-python/src/client/terminals/envCollectionActivation/service.ts
index aaa4ccf23be..b7ec224828d 100644
--- a/extensions/positron-python/src/client/terminals/envCollectionActivation/service.ts
+++ b/extensions/positron-python/src/client/terminals/envCollectionActivation/service.ts
@@ -26,13 +26,13 @@ import {
IPathUtils,
} from '../../common/types';
import { Interpreters } from '../../common/utils/localize';
-import { traceError, traceInfo, traceVerbose, traceWarn } from '../../logging';
+import { traceError, traceInfo, traceLog, traceVerbose, traceWarn } from '../../logging';
import { IInterpreterService } from '../../interpreter/contracts';
import { defaultShells } from '../../interpreter/activation/service';
import { IEnvironmentActivationService } from '../../interpreter/activation/types';
import { EnvironmentType, PythonEnvironment } from '../../pythonEnvironments/info';
import { getSearchPathEnvVarNames } from '../../common/utils/exec';
-import { EnvironmentVariables } from '../../common/variables/types';
+import { EnvironmentVariables, IEnvironmentVariablesProvider } from '../../common/variables/types';
import { TerminalShellType } from '../../common/terminal/types';
import { OSType } from '../../common/utils/platform';
import { normCase } from '../../common/platform/fs-paths';
@@ -81,6 +81,8 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
@inject(ITerminalDeactivateService) private readonly terminalDeactivateService: ITerminalDeactivateService,
@inject(IPathUtils) private readonly pathUtils: IPathUtils,
@inject(IShellIntegrationService) private readonly shellIntegrationService: IShellIntegrationService,
+ @inject(IEnvironmentVariablesProvider)
+ private readonly environmentVariablesProvider: IEnvironmentVariablesProvider,
) {
this.separator = platform.osType === OSType.Windows ? ';' : ':';
this.progressService = new ProgressService(this.shell);
@@ -119,6 +121,13 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
this,
this.disposables,
);
+ this.environmentVariablesProvider.onDidEnvironmentVariablesChange(
+ async (r: Resource) => {
+ await this._applyCollection(r).ignoreErrors();
+ },
+ this,
+ this.disposables,
+ );
this.applicationEnvironment.onDidChangeShell(
async (shell: string) => {
this.processEnvVars = undefined;
@@ -213,7 +222,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
if (value !== undefined) {
if (key === 'PS1') {
// We cannot have the full PS1 without executing in terminal, which we do not. Hence prepend it.
- traceVerbose(
+ traceLog(
`Prepending environment variable ${key} in collection with ${value} ${JSON.stringify(
defaultPrependOptions,
)}`,
@@ -233,7 +242,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
if (deactivate) {
value = `${deactivate}${this.separator}${value}`;
}
- traceVerbose(
+ traceLog(
`Prepending environment variable ${key} in collection with ${value} ${JSON.stringify(
options,
)}`,
@@ -246,7 +255,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
if (deactivate) {
value = `${deactivate}${this.separator}${value}`;
}
- traceVerbose(
+ traceLog(
`Prepending environment variable ${key} in collection to ${value} ${JSON.stringify(
options,
)}`,
@@ -259,7 +268,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
applyAtShellIntegration: true,
applyAtProcessCreation: true,
};
- traceVerbose(
+ traceLog(
`Setting environment variable ${key} in collection to ${value} ${JSON.stringify(options)}`,
);
envVarCollection.replace(key, value, options);
@@ -329,6 +338,8 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
}
private async getPS1(shell: string, resource: Resource, env: EnvironmentVariables) {
+ // PS1 returned by shell is not predictable: #22078
+ // Hence calculate it ourselves where possible. Should no longer be needed once #22128 is available.
const customShellType = identifyShellFromShellPath(shell);
if (this.noPromptVariableShells.includes(customShellType)) {
return env.PS1;
@@ -338,7 +349,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
const interpreter = await this.interpreterService.getActiveInterpreter(resource);
const shouldSetPS1 = shouldPS1BeSet(interpreter?.type, env);
if (shouldSetPS1) {
- const prompt = getPromptForEnv(interpreter);
+ const prompt = getPromptForEnv(interpreter, env);
if (prompt) {
return prompt;
}
@@ -447,7 +458,7 @@ function shouldSkip(env: string) {
].includes(env);
}
-function getPromptForEnv(interpreter: PythonEnvironment | undefined) {
+function getPromptForEnv(interpreter: PythonEnvironment | undefined, env: EnvironmentVariables) {
if (!interpreter) {
return undefined;
}
@@ -456,6 +467,9 @@ function getPromptForEnv(interpreter: PythonEnvironment | undefined) {
// If conda base environment is selected, it can lead to "(base)" appearing twice if we return the env name.
return undefined;
}
+ if (interpreter.type === PythonEnvType.Virtual && env.VIRTUAL_ENV_PROMPT) {
+ return `(${env.VIRTUAL_ENV_PROMPT}) `;
+ }
return `(${interpreter.envName}) `;
}
if (interpreter.envPath) {
diff --git a/extensions/positron-python/src/client/terminals/envCollectionActivation/shellIntegrationService.ts b/extensions/positron-python/src/client/terminals/envCollectionActivation/shellIntegrationService.ts
index cba2ccbc686..8ab3d84122b 100644
--- a/extensions/positron-python/src/client/terminals/envCollectionActivation/shellIntegrationService.ts
+++ b/extensions/positron-python/src/client/terminals/envCollectionActivation/shellIntegrationService.ts
@@ -57,7 +57,6 @@ export class ShellIntegrationService implements IShellIntegrationService {
}
this.appShell.onDidWriteTerminalData(
(e) => {
- traceVerbose(e.data); // Log this temporarily for analysis
if (e.data.includes('\x1b]633;A\x07') || e.data.includes('\x1b]133;A\x07')) {
let { shell } = this.appEnvironment;
if ('shellPath' in e.terminal.creationOptions && e.terminal.creationOptions.shellPath) {
diff --git a/extensions/positron-python/src/client/testing/common/debugLauncher.ts b/extensions/positron-python/src/client/testing/common/debugLauncher.ts
index 85076461f22..f05fa6bc937 100644
--- a/extensions/positron-python/src/client/testing/common/debugLauncher.ts
+++ b/extensions/positron-python/src/client/testing/common/debugLauncher.ts
@@ -87,7 +87,7 @@ export class DebugLauncher implements ITestDebugLauncher {
debugConfig.rules = [];
}
debugConfig.rules.push({
- path: path.join(EXTENSION_ROOT_DIR, 'pythonFiles'),
+ path: path.join(EXTENSION_ROOT_DIR, 'python_files'),
include: false,
});
@@ -219,7 +219,7 @@ export class DebugLauncher implements ITestDebugLauncher {
);
}
}
- const pluginPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles');
+ const pluginPath = path.join(EXTENSION_ROOT_DIR, 'python_files');
// check if PYTHONPATH is already set in the environment variables
if (launchArgs.env) {
const additionalPythonPath = [pluginPath];
diff --git a/extensions/positron-python/src/client/testing/testController/common/types.ts b/extensions/positron-python/src/client/testing/testController/common/types.ts
index e51270eb4f9..685f36af007 100644
--- a/extensions/positron-python/src/client/testing/testController/common/types.ts
+++ b/extensions/positron-python/src/client/testing/testController/common/types.ts
@@ -228,7 +228,7 @@ export interface ITestExecutionAdapter {
): Promise;
}
-// Same types as in pythonFiles/unittestadapter/utils.py
+// Same types as in python_files/unittestadapter/utils.py
export type DiscoveredTestType = 'folder' | 'file' | 'class' | 'test';
export type DiscoveredTestCommon = {
diff --git a/extensions/positron-python/src/client/testing/testController/common/utils.ts b/extensions/positron-python/src/client/testing/testController/common/utils.ts
index 0e81154a899..e98fa99b9bd 100644
--- a/extensions/positron-python/src/client/testing/testController/common/utils.ts
+++ b/extensions/positron-python/src/client/testing/testController/common/utils.ts
@@ -359,14 +359,25 @@ export function splitTestNameWithRegex(testName: string): [string, string] {
* @param args - Readonly array of strings to be converted to a map.
* @returns A map representation of the input strings.
*/
-export const argsToMap = (args: ReadonlyArray): { [key: string]: string | null | undefined } => {
- const map: { [key: string]: string | null } = {};
+export const argsToMap = (args: ReadonlyArray): { [key: string]: Array | null | undefined } => {
+ const map: { [key: string]: Array | null } = {};
for (const arg of args) {
const delimiter = arg.indexOf('=');
if (delimiter === -1) {
+ // If no delimiter is found, the entire string becomes a key with a value of null.
map[arg] = null;
} else {
- map[arg.slice(0, delimiter)] = arg.slice(delimiter + 1);
+ const key = arg.slice(0, delimiter);
+ const value = arg.slice(delimiter + 1);
+ if (map[key]) {
+ // add to the array
+ const arr = map[key] as string[];
+ arr.push(value);
+ map[key] = arr;
+ } else {
+ // create a new array
+ map[key] = [value];
+ }
}
}
@@ -383,7 +394,7 @@ export const argsToMap = (args: ReadonlyArray): { [key: string]: string
* @param map - The map to be converted to an array of strings.
* @returns An array of strings representation of the input map.
*/
-export const mapToArgs = (map: { [key: string]: string | null | undefined }): string[] => {
+export const mapToArgs = (map: { [key: string]: Array | null | undefined }): string[] => {
const out: string[] = [];
for (const key of Object.keys(map)) {
const value = map[key];
@@ -391,8 +402,14 @@ export const mapToArgs = (map: { [key: string]: string | null | undefined }): st
// eslint-disable-next-line no-continue
continue;
}
-
- out.push(value === null ? key : `${key}=${value}`);
+ if (value === null) {
+ out.push(key);
+ } else {
+ const values = Array.isArray(value) ? (value as string[]) : [value];
+ for (const v of values) {
+ out.push(`${key}=${v}`);
+ }
+ }
}
return out;
@@ -407,13 +424,18 @@ export const mapToArgs = (map: { [key: string]: string | null | undefined }): st
* @returns The updated map.
*/
export function addArgIfNotExist(
- map: { [key: string]: string | null | undefined },
+ map: { [key: string]: Array | null | undefined },
argKey: string,
argValue: string | null,
-): { [key: string]: string | null | undefined } {
+): { [key: string]: Array | null | undefined } {
// Only add the argument if it doesn't exist in the map.
if (map[argKey] === undefined) {
- map[argKey] = argValue;
+ // if null then set to null, otherwise set to an array with the value
+ if (argValue === null) {
+ map[argKey] = null;
+ } else {
+ map[argKey] = [argValue];
+ }
}
return map;
@@ -426,6 +448,6 @@ export function addArgIfNotExist(
* @param argKey - The argument key to be checked.
* @returns True if the argument key exists in the map, false otherwise.
*/
-export function argKeyExists(map: { [key: string]: string | null | undefined }, argKey: string): boolean {
+export function argKeyExists(map: { [key: string]: Array | null | undefined }, argKey: string): boolean {
return map[argKey] !== undefined;
}
diff --git a/extensions/positron-python/src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts b/extensions/positron-python/src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts
index ab44c96821e..2d0dab76508 100644
--- a/extensions/positron-python/src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts
+++ b/extensions/positron-python/src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts
@@ -67,7 +67,7 @@ export class PytestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
}
async runPytestDiscovery(uri: Uri, uuid: string, executionFactory?: IPythonExecutionFactory): Promise {
- const relativePathToPytest = 'pythonFiles';
+ const relativePathToPytest = 'python_files';
const fullPluginPath = path.join(EXTENSION_ROOT_DIR, relativePathToPytest);
const settings = this.configSettings.getSettings(uri);
let pytestArgsMap = argsToMap(settings.testing.pytestArgs);
diff --git a/extensions/positron-python/src/client/testing/testController/pytest/pytestExecutionAdapter.ts b/extensions/positron-python/src/client/testing/testController/pytest/pytestExecutionAdapter.ts
index d366bdfc971..de519548d68 100644
--- a/extensions/positron-python/src/client/testing/testController/pytest/pytestExecutionAdapter.ts
+++ b/extensions/positron-python/src/client/testing/testController/pytest/pytestExecutionAdapter.ts
@@ -103,7 +103,7 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
debugLauncher?: ITestDebugLauncher,
deferredTillEOT?: Deferred,
): Promise {
- const relativePathToPytest = 'pythonFiles';
+ const relativePathToPytest = 'python_files';
const fullPluginPath = path.join(EXTENSION_ROOT_DIR, relativePathToPytest);
const settings = this.configSettings.getSettings(uri);
const { pytestArgs } = settings.testing;
diff --git a/extensions/positron-python/src/client/testing/testController/unittest/testDiscoveryAdapter.ts b/extensions/positron-python/src/client/testing/testController/unittest/testDiscoveryAdapter.ts
index 75e29afc971..8cc44b3783c 100644
--- a/extensions/positron-python/src/client/testing/testController/unittest/testDiscoveryAdapter.ts
+++ b/extensions/positron-python/src/client/testing/testController/unittest/testDiscoveryAdapter.ts
@@ -83,7 +83,7 @@ export class UnittestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
}
function buildDiscoveryCommand(args: string[]): TestDiscoveryCommand {
- const discoveryScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'unittestadapter', 'discovery.py');
+ const discoveryScript = path.join(EXTENSION_ROOT_DIR, 'python_files', 'unittestadapter', 'discovery.py');
return {
script: discoveryScript,
diff --git a/extensions/positron-python/src/client/testing/testController/unittest/testExecutionAdapter.ts b/extensions/positron-python/src/client/testing/testController/unittest/testExecutionAdapter.ts
index d90581a9311..85fd01f093a 100644
--- a/extensions/positron-python/src/client/testing/testController/unittest/testExecutionAdapter.ts
+++ b/extensions/positron-python/src/client/testing/testController/unittest/testExecutionAdapter.ts
@@ -109,7 +109,7 @@ export class UnittestTestExecutionAdapter implements ITestExecutionAdapter {
}
function buildExecutionCommand(args: string[]): TestExecutionCommand {
- const executionScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'unittestadapter', 'execution.py');
+ const executionScript = path.join(EXTENSION_ROOT_DIR, 'python_files', 'unittestadapter', 'execution.py');
return {
script: executionScript,
diff --git a/extensions/positron-python/src/test/activation/node/lspInteractiveWindowMiddlewareAddon.unit.test.ts b/extensions/positron-python/src/test/activation/node/lspInteractiveWindowMiddlewareAddon.unit.test.ts
deleted file mode 100644
index 32d9198ef7b..00000000000
--- a/extensions/positron-python/src/test/activation/node/lspInteractiveWindowMiddlewareAddon.unit.test.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-/* eslint-disable @typescript-eslint/no-empty-function */
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-'use strict';
-
-import { NotebookCell, NotebookCellKind, NotebookDocument, TextDocument, Uri } from 'vscode';
-import { expect } from 'chai';
-import { anything, capture, instance, mock, verify, when } from 'ts-mockito';
-import { LanguageClient } from 'vscode-languageclient/node';
-import { LspInteractiveWindowMiddlewareAddon } from '../../../client/activation/node/lspInteractiveWindowMiddlewareAddon';
-import { JupyterExtensionIntegration } from '../../../client/jupyter/jupyterIntegration';
-import { IExtensions } from '../../../client/common/types';
-import { ICondaService, IInterpreterDisplay } from '../../../client/interpreter/contracts';
-import { IInterpreterSelector } from '../../../client/interpreter/configuration/types';
-import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types';
-import { IContextKeyManager, IWorkspaceService } from '../../../client/common/application/types';
-import { MockMemento } from '../../mocks/mementos';
-
-suite('Pylance Language Server - Interactive Window LSP Notebooks', () => {
- const languageClientMock = mock();
- let languageClient: LanguageClient;
- let jupyterApi: JupyterExtensionIntegration;
- let middleware: LspInteractiveWindowMiddlewareAddon;
-
- setup(() => {
- languageClient = instance(languageClientMock);
- jupyterApi = new JupyterExtensionIntegration(
- mock(),
- mock(),
- mock(),
- new MockMemento(),
- mock(),
- mock(),
- mock(),
- mock(),
- );
- jupyterApi.registerGetNotebookUriForTextDocumentUriFunction(getNotebookUriFunction);
- });
- teardown(() => {
- middleware?.dispose();
- });
-
- test('Unrelated document open should be forwarded to next handler unchanged', async () => {
- middleware = makeMiddleware();
-
- const uri = Uri.from({ scheme: 'file', path: 'test.py' });
- const textDocument = createTextDocument(uri);
-
- let nextCalled = false;
- await middleware.didOpen(textDocument, async (_) => {
- nextCalled = true;
- });
-
- return expect(nextCalled).to.be.true;
- });
-
- test('Notebook-related textDocument/didOpen should be swallowed', async () => {
- middleware = makeMiddleware();
-
- const uri = Uri.from({ scheme: 'test-input', path: 'Test' });
- const textDocument = createTextDocument(uri);
-
- let nextCalled = false;
- await middleware.didOpen(textDocument, async (_) => {
- nextCalled = true;
- });
-
- return expect(nextCalled).to.be.false;
- });
-
- test('Notebook-related document should be added at end of cells in notebookDocument/didOpen', async () => {
- middleware = makeMiddleware();
-
- const uri = Uri.from({ scheme: 'test-input', path: 'Test' });
- const textDocument = createTextDocument(uri);
-
- await middleware.didOpen(textDocument, async (_) => {});
-
- const cellCount = 2;
- const [notebookDocument, cells] = createNotebookDocument(getNotebookUriFunction(uri)!, cellCount);
- await middleware.notebooks.didOpen(notebookDocument, cells, async (_, nextCells) => {
- expect(nextCells.length).to.be.equals(cellCount + 1);
- expect(nextCells[cellCount]).to.deep.equal({
- index: cellCount,
- notebook: notebookDocument,
- kind: NotebookCellKind.Code,
- document: textDocument,
- metadata: {},
- outputs: [],
- executionSummary: undefined,
- });
- });
- });
-
- test('Notebook-related document opened after notebook causes notebookDocument/didChange', async () => {
- middleware = makeMiddleware();
-
- const uri = Uri.from({ scheme: 'test-input', path: 'Test' });
- const textDocument = createTextDocument(uri);
-
- const cellCount = 2;
- const [notebookDocument, cells] = createNotebookDocument(getNotebookUriFunction(uri)!, cellCount);
- await middleware.notebooks.didOpen(notebookDocument, cells, async (_) => {});
-
- await middleware.didOpen(textDocument, async (_) => {});
-
- verify(languageClientMock.sendNotification(anything(), anything())).once();
- const message = capture(languageClientMock.sendNotification).last()[1];
-
- expect(message.notebookDocument.uri).to.equal(notebookDocument.uri.toString());
- expect(message.change.cells.structure).to.deep.equal({
- array: {
- start: notebookDocument.cellCount,
- deleteCount: 0,
- cells: [{ kind: NotebookCellKind.Code, document: textDocument.uri.toString() }],
- },
- didOpen: [
- {
- uri: textDocument.uri.toString(),
- languageId: textDocument.languageId,
- version: textDocument.version,
- text: textDocument.getText(),
- },
- ],
- didClose: undefined,
- });
- });
-
- function makeMiddleware(): LspInteractiveWindowMiddlewareAddon {
- return new LspInteractiveWindowMiddlewareAddon(() => languageClient, jupyterApi);
- }
-
- function getNotebookUriFunction(textDocumentUri: Uri): Uri | undefined {
- if (textDocumentUri.scheme === 'test-input') {
- return textDocumentUri.with({ scheme: 'test-notebook' });
- }
-
- return undefined;
- }
-
- function createTextDocument(uri: Uri): TextDocument {
- const textDocumentMock = mock();
- when(textDocumentMock.uri).thenReturn(uri);
- when(textDocumentMock.languageId).thenReturn('python');
- when(textDocumentMock.version).thenReturn(11);
-
- return instance(textDocumentMock);
- }
-
- function createNotebookDocument(uri: Uri, cellCount: number): [NotebookDocument, NotebookCell[]] {
- const notebookDocumentMock = mock();
- when(notebookDocumentMock.uri).thenReturn(uri);
- when(notebookDocumentMock.notebookType).thenReturn('jupyter');
- when(notebookDocumentMock.version).thenReturn(20);
- when(notebookDocumentMock.cellCount).thenReturn(cellCount);
-
- const notebookDocument = instance(notebookDocumentMock);
-
- const cells: NotebookCell[] = [];
- for (let i = 0; i < cellCount; i = i + 1) {
- cells.push({
- index: i,
- notebook: notebookDocument,
- kind: NotebookCellKind.Code,
- document: createTextDocument(Uri.from({ scheme: 'test-cell', path: `cell${i}` })),
- metadata: {},
- outputs: [],
- executionSummary: undefined,
- });
- }
-
- return [notebookDocument, cells];
- }
-});
diff --git a/extensions/positron-python/src/test/api.functional.test.ts b/extensions/positron-python/src/test/api.functional.test.ts
index 74293f55256..851d56c00e0 100644
--- a/extensions/positron-python/src/test/api.functional.test.ts
+++ b/extensions/positron-python/src/test/api.functional.test.ts
@@ -19,7 +19,7 @@ import { IServiceContainer, IServiceManager } from '../client/ioc/types';
import { IDiscoveryAPI } from '../client/pythonEnvironments/base/locator';
suite('Extension API', () => {
- const debuggerPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python', 'debugpy');
+ const debuggerPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'lib', 'python', 'debugpy');
const debuggerHost = 'somehost';
const debuggerPort = 12345;
@@ -37,6 +37,7 @@ suite('Extension API', () => {
interpreterService = mock(InterpreterService);
environmentVariablesProvider = mock();
discoverAPI = mock();
+ when(discoverAPI.getEnvs()).thenReturn([]);
when(serviceContainer.get(IConfigurationService)).thenReturn(
instance(configurationService),
diff --git a/extensions/positron-python/src/test/common.ts b/extensions/positron-python/src/test/common.ts
index 2ef366a3a47..bbf48f0e14c 100644
--- a/extensions/positron-python/src/test/common.ts
+++ b/extensions/positron-python/src/test/common.ts
@@ -22,7 +22,7 @@ const StreamZip = require('node-stream-zip');
export { sleep } from './core';
-const fileInNonRootWorkspace = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'test', 'pythonFiles', 'dummy.py');
+const fileInNonRootWorkspace = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'test', 'python_files', 'dummy.py');
export const rootWorkspaceUri = getWorkspaceRoot();
export const PYTHON_PATH = getPythonPath();
diff --git a/extensions/positron-python/src/test/common/application/commands/issueTemplateVenv2.md b/extensions/positron-python/src/test/common/application/commands/issueTemplate.md
similarity index 51%
rename from extensions/positron-python/src/test/common/application/commands/issueTemplateVenv2.md
rename to extensions/positron-python/src/test/common/application/commands/issueTemplate.md
index fa9142e5ca4..a95af90ff7f 100644
--- a/extensions/positron-python/src/test/common/application/commands/issueTemplateVenv2.md
+++ b/extensions/positron-python/src/test/common/application/commands/issueTemplate.md
@@ -1,6 +1,5 @@
# Behaviour
-## Expected vs. Actual
XXX
@@ -12,13 +11,9 @@ XXX
**After** creating the issue on GitHub, you can add screenshots and GIFs of what is happening. Consider tools like https://www.cockos.com/licecap/, https://github.com/phw/peek or https://www.screentogif.com/ for GIF creation.
-->
-
+
# Diagnostic data
-- Python version (& distribution if applicable, e.g. Anaconda): 3.9.0
-- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
-- Value of the `python.languageServer` setting: Pylance
-
Output for Python in the Output panel (View→Output, change the drop-down the upper-right of the Output panel to Python)
@@ -32,22 +27,3 @@ XXX
-
-
-
-User Settings
-
-