ipython / ipython/ipython

Invalid pathlib.Path prepended to sys.path inside virtualenv using outside IPython

Open
#13,165 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.