vscode-python: Pytest discovery fails with `'Function' object has no attribute 'fspath'`

Type: Bug

Behaviour

Expected vs. Actual

Test discovery is failing with this exception from https://github.com/microsoft/vscode-python/blob/d3dd832e9b00c38410490087ad0843d8334a8ec8/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py#L182

INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 667, in perform_collect
INTERNALERROR>     hook.pytest_collection_modifyitems(
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 95, in pytest_collection_modifyitems
INTERNALERROR>     test, parents = self.parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 80, in parse_item
INTERNALERROR>     return parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py", line 182, in parse_item
INTERNALERROR>     testroot, relfile = _split_fspath(str(item.fspath), fileid, item)
INTERNALERROR> AttributeError: 'Function' object has no attribute 'fspath'

However, pytest collection itself is working fine:

(distributed-test) gabe ~/distributed ‹main› » pytest --collect-only
...
======================================================================== 3460 tests collected in 7.06s =========================================================================

Steps to reproduce:

Sorry, I don’t have a minimal reproducer. But hopefully I do have a reproducer at least. I’m seeing this with https://github.com/dask/distributed, and can reproduce it with a fresh clone in a fresh environment.

  1. git clone git@github.com:dask/distributed.git
  2. git checkout 601608cba8ce6df3d0780994ed25fa5cf2b30e24 (just to be sure for reproducability; don’t think it’s related to this commit though)
  3. mamba env create -n distributed-test -f continuous_integration/environment-3.9.yaml
  4. conda activate distributed-test
  5. pip install --no-deps -e .
  6. pytest --collect-only (just to confirm)
  7. code .
  8. Click on the testing pane and click refresh. It takes a couple minutes, but eventually test discovery fails, and outputs the error shown above.

Diagnostic data

  • Python version (& distribution if applicable, e.g. Anaconda): 3.9.16
  • Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Conda
  • Value of the python.languageServer setting: Pylance
Output for Python in the Output panel (ViewOutput, change the drop-down the upper-right of the Output panel to Python)

LSP Notebooks experiment is enabled
LSP Notebooks interactive window support is enabled
> ~/miniconda3/envs/distributed-test/bin/python -I ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/get_output_via_markers.py ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/interpreterInfo.py
Python interpreter path: ~/miniconda3/envs/distributed-test/bin/python
Starting Pylance language server.
> conda run -n distributed-test --no-capture-output python ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/get_output_via_markers.py ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/printEnvVariables.py
> conda run -n distributed-test --no-capture-output python ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/get_output_via_markers.py ~/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir . -s --cache-clear
cwd: .
[ERROR 2023-2-10 13:9:37.716]: Error discovering pytest tests:
 [n [Error]: ============================= test session starts ==============================
platform darwin -- Python 3.9.16, pytest-7.2.2, pluggy-1.0.0 -- /Users/gabe/miniconda3/envs/distributed-test/bin/python
cachedir: .pytest_cache
rootdir: /Users/gabe/distributed, configfile: setup.cfg
plugins: timeout-2.1.0, rerunfailures-11.1.2, cov-4.0.0, repeat-0.9.1
timeout: 300.0s
timeout method: thread
timeout func_only: False
collecting ... collected 3460 items / 8 skipped

<Package tests>
  <Module test_dask_scheduler.py>
    <Function test_defaults>
    <Function test_hostport>
    <Function test_no_dashboard>
    <Function test_dashboard>
    <Function test_dashboard_non_standard_ports>
    <Function test_multiple_protocols>

... [I'm deleting a few thousand lines of successful test discovery here] ...

  <Function test_task_releases_resources[long-running-RescheduleEvent]>
  <Function test_task_with_dependencies_acquires_resources>
  <Function test_resumed_task_releases_resources[executing-ExecuteSuccessEvent]>
  <Function test_resumed_task_releases_resources[executing-ExecuteFailureEvent]>
  <Function test_resumed_task_releases_resources[executing-RescheduleEvent]>
  <Function test_resumed_task_releases_resources[long-running-ExecuteSuccessEvent]>
  <Function test_resumed_task_releases_resources[long-running-ExecuteFailureEvent]>
  <Function test_resumed_task_releases_resources[long-running-RescheduleEvent]>
  <Function test_clean_log>
    Test that brand new workers start with a clean log
  <Function test_running_task_in_all_running_tasks[executing]>
  <Function test_running_task_in_all_running_tasks[long-running]>
  <Function test_done_task_not_in_all_running_tasks[executing-ExecuteSuccessEvent]>
  <Function test_done_task_not_in_all_running_tasks[executing-ExecuteFailureEvent]>
  <Function test_done_task_not_in_all_running_tasks[executing-RescheduleEvent]>
  <Function test_done_task_not_in_all_running_tasks[long-running-ExecuteSuccessEvent]>
  <Function test_done_task_not_in_all_running_tasks[long-running-ExecuteFailureEvent]>
  <Function test_done_task_not_in_all_running_tasks[long-running-RescheduleEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[executing-ExecuteSuccessEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[executing-ExecuteFailureEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[executing-RescheduleEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[long-running-ExecuteSuccessEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[long-running-ExecuteFailureEvent]>
  <Function test_done_resumed_task_not_in_all_running_tasks[long-running-RescheduleEvent]>
  <Function test_gather_dep_failure>
    Simulate a task failing to unpickle when it reaches the destination worker after
    a flight.
    
    See also test_worker_memory.py::test_workerstate_fail_to_pickle_flight,
    where the task instead is gathered successfully, but fails to spill.
  <Function test_transfer_incoming_metrics>
  <Function test_throttling_does_not_affect_first_transfer>
  <Function test_message_target_does_not_affect_first_transfer_on_different_worker>
  <Function test_throttle_incoming_transfers_on_count_limit>
  <Function test_throttling_incoming_transfer_on_transfer_bytes_same_worker>
  <Function test_throttling_incoming_transfer_on_transfer_bytes_different_workers>
  <Function test_do_not_throttle_connections_while_below_threshold>
  <Function test_throttle_on_transfer_bytes_regardless_of_threshold>
  <Function test_worker_nbytes[executing]>
  <Function test_worker_nbytes[long-running]>
  <Function test_fetch_count>
  <Function test_task_counter>
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 667, in perform_collect
INTERNALERROR>     hook.pytest_collection_modifyitems(
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 95, in pytest_collection_modifyitems
INTERNALERROR>     test, parents = self.parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 80, in parse_item
INTERNALERROR>     return parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py", line 182, in parse_item
INTERNALERROR>     testroot, relfile = _split_fspath(str(item.fspath), fileid, item)
INTERNALERROR> AttributeError: 'Function' object has no attribute 'fspath'
INTERNALERROR> 
INTERNALERROR> During handling of the above exception, another exception occurred:
INTERNALERROR> 
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 270, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 323, in _main
INTERNALERROR>     config.hook.pytest_collection(session=session)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 334, in pytest_collection
INTERNALERROR>     session.perform_collect()
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/_pytest/main.py", line 671, in perform_collect
INTERNALERROR>     hook.pytest_collection_finish(session=self)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 110, in pytest_collection_finish
INTERNALERROR>     test, parents = self.parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 80, in parse_item
INTERNALERROR>     return parse_item(item)
INTERNALERROR>   File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py", line 182, in parse_item
INTERNALERROR>     testroot, relfile = _split_fspath(str(item.fspath), fileid, item)
INTERNALERROR> AttributeError: 'Function' object has no attribute 'fspath'

======================== 3460 tests collected in 27.25s ========================

Traceback (most recent call last):
  File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/get_output_via_markers.py", line 26, in <module>
    runpy.run_path(module, run_name="__main__")
  File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/runpy.py", line 288, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/Users/gabe/miniconda3/envs/distributed-test/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/run_adapter.py", line 22, in <module>
    main(tool, cmd, subargs, toolargs)
  File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/__main__.py", line 99, in main
    parents, result = run(toolargs, **subargs)
  File "/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 47, in discover
    raise Exception("pytest discovery failed (exit code {})".format(ec))
Exception: pytest discovery failed (exit code 3)
ERROR conda.cli.main_run:execute(47): `conda run python /Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/get_output_via_markers.py /Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir /Users/gabe/distributed -s --cache-clear` failed. (See above for error)

	at ChildProcess.<anonymous> (/Users/gabe/.vscode/extensions/ms-python.python-2023.4.1/out/client/extension.js:2:244860)
	at Object.onceWrapper (node:events:646:26)
	at ChildProcess.emit (node:events:526:28)
	at maybeClose (node:internal/child_process:1092:16)
	at Socket.<anonymous> (node:internal/child_process:451:11)
	at Socket.emit (node:events:526:28)
	at Pipe.<anonymous> (node:net:687:12)]
> conda info --json
Send text to terminal: conda activate distributed-test

User Settings


venvFolders: "<placeholder>"

languageServer: "Pylance"

linting
• flake8Enabled: true

formatting
• provider: "black"

testing
• pytestEnabled: true

Extension version: 2023.4.1 VS Code version: Code 1.76.0 (92da9481c0904c6adfe372c12da3b7748d74bdcb, 2023-03-01T10:23:45.993Z) OS version: Darwin x64 21.6.0 Modes: Sandboxed: No

System Info
Item Value
CPUs Intel® Core™ i9-9980HK CPU @ 2.40GHz (16 x 2400)
GPU Status 2d_canvas: enabled
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
metal: disabled_off
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_renderer: enabled_on
video_decode: enabled
video_encode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: disabled_off
Load (avg) 5, 6, 6
Memory (System) 32.00GB (0.08GB free)
Process Argv . --crash-reporter-id 886611b4-5fa0-474f-bcba-14a7e9edd8e3
Screen Reader no
VM 0%

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 2
  • Comments: 26 (13 by maintainers)

Commits related to this issue

Most upvoted comments

👋 hello again

After (much) investigating, I think I might have found the cause of this issue: it seems to be cause by having the -p no:legacypath flag for pytest in the addopts config.

When I remove that flag, test discovery starts working once again