Invalid pathlib.Path prepended to sys.path inside virtualenv using outside IPython
- Dominant language
- Python
- Stars
- 16.8k
- Forks
- 4.5k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 6
Description
## Software Versions Tested
🐍 Python
3.9.7, 3.10.0rc2
✔️ Passing IPython
7.27.0
❌ Failing IPython
7.28.0
## Issue Description
With fresh installations of the latest Python and IPython I cannot use an IPython installed outside of a virtualenv to import modules inside that virtualenv.
I assume from the `UserWarning`
> Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
that this workflow is supported on a best-effort basis, if at all. I understand if this isn't a high priority issue. That said, it is handy to not install IPython into each virtualenv I use. Historically it has worked quite well in this regard.
As far as I can determine, the cause of the issue is an unexpected `pathlib.Path` instance prepended to `sys.path`.
```python
In [1]: import sys
In [2]: sys.path[0]
Out[2]: PosixPath('/tmp/venv/lib/python3.9/site-packages')
```
Near as I can tell from [the documentation](https://docs.python.org/3/library/sys.html#sys.path) and cursory searching, `sys.path` should only contain `str` instances.
I don't know the IPython codebase well enough to say for sure, but from searching through issues and PRs it seems like this might have been an unanticipated result of #12548 and its 7.x backport #13146.
The issue does **not** seem to be reproducible in [IPython 7.27.0](https://github.com/ipython/ipython/releases/tag/7.27.0), so that would seem to support this claim as the aforementioned backport merged a few days ago prior to the release of [IPython 7.28.0](https://github.com/ipython/ipython/releases/tag/7.28.0).
If that is the case, maybe it would suffice to replace
https://github.com/ipython/ipython/blob/c31fed6f3227cccad94ab318e42058a4a677680f/IPython/core/interactiveshell.py#L946
with something like
```python
sys.path.insert(0, os.fspath(virtual_env))
```
## Steps to Reproduce
1. Install IPython outside a virtualenv.
```shell
pip3.9 install ipython
```
2. Create a virtualenv.
```shell
python3.9 -m venv venv
```
3. Source the virtualenv.
```shell
source ./venv/bin/activate
```
4. Install any new package.
```shell
pip install rich
```
5. Import that package from Python.
```shell
python -c 'import rich'
```
6. Fail to import the same package from IPython.
```shell
ipython -c 'import rich'
/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/site-packages/IPython/core/interactiveshell.py:934: UserWarning: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
warn("Attempting to work in a virtualenv. If you encounter problems, please "
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
in
----> 1 import rich
ModuleNotFoundError: No module named 'rich'
```
## `sys.path` Entry Comparisons
In case it helps, here are diffs of my `sys.path` inside and outside of a virtualenv using Python and IPython.
**Python outside vs. inside a venv**
```diff
'/home/tucker/.pyenv/versions/3.9.7/lib/python39.zip',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
- '/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/site-packages']
+ '/tmp/venv/lib/python3.9/site-packages']
```
**IPython outside vs. inside a venv**
```diff
-['/home/tucker/.pyenv/versions/3.9.7/bin',
+[PosixPath('/tmp/venv/lib/python3.9/site-packages'),
+ '/home/tucker/.pyenv/versions/3.9.7/bin',
'/home/tucker/.pyenv/versions/3.9.7/lib/python39.zip',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/lib-dynload',
'',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/site-packages',
'/home/tucker/.pyenv/versions/3.9.7/lib/python3.9/site-packages/IPython/extensions',
'/home/tucker/.ipython']
```
Contributor guide
Assessment
This issue has not been assessed yet.