Post History
Although the system package manager was involved for your setup, this is really just a special case of a pure Python issue. When you run a program like Pytest that is itself written in Python, gen...
Answer
#3: Post edited
- Although the system package manager was involved for your setup, this is really just a special case of [a pure Python issue](https://software.codidact.com/posts/290550).
When you run a program like Pytest that is itself written in Python, generally the "executable" is just a wrapper that invokes Python to `import` the corresponding library and call some entry-point function. On Linux, these are simply Python scripts with a shebang line; for example, if you do `cat $(which pytest)` you should see something like- ```
- #!/absolute/path/to/some/installation/of/python
- # -*- coding: utf-8 -*-
- import re
- import sys
- from pytest import console_main
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
- sys.exit(console_main())
- ```
- If you use the system package manager to install Pytest, then the Pytest copy that you get will be set up to use the system Python (i.e. the shebang line will specify `/usr/bin/python` or similar), and therefore the code will run in the system Python's environment with the system Python's installed third-party libraries. It has no awareness of your "current" venv (virtual environment) - because there isn't really such a thing in the first place ("activating" a venv doesn't do very much, and isn't strictly required in order to use it anyway), and because *that isn't the copy of Python that's running*. When the system Python runs, its default `sys.path` initialization will include the system packages (including the system-installed Pytest) - *not* anything that you installed into the venv.
- Further, it will *not* work to do something like ``python `which pytest` `` (i.e., running the wrapper executable as a script, with the venv's Python), because then the `import` *of the Pytest library* will fail, because that isn't installed *for the venv*.
- On Linux, you *could* edit the wrapper so that the shebang points at `/usr/bin/env python` instead. This is a brutal hack, of course: it's not portable (on Windows, the wrappers are actual native-code executables that make a Windows system call to launch Python) and it breaks convention. (People often ask why these wrappers aren't generated using relative paths, which along with a tweak to the `activate` script would allow the venv folders to be relocated; the answer, apparently, is that some users depend on being able to copy or symlink the wrappers.)
- <section class="notice is-danger">
- You can *try* arranging for the venv's `site-packages` directory to be added to `sys.path` - for example by using the `PYTHONPATH` environment variable, or by [using one of the configuration file options](https://docs.pytest.org/en/stable/reference/customize.html) for Pytest to [supply a `pythonpath` value](https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath). However, [trying to force Python to "share" libraries from another environment like this is not safe](https://software.codidact.com/posts/291675). It can easily break if the venv's Python is a different version from the system Python, and you won't be able to *prevent* Pytest from accessing the system Python's libraries (which could spoil your test results, e.g. by fixing broken imports in your code that you were trying to detect) without even trickier hacking (i.e. using `PYTHONHOME`).
- </section>
- However, the expected and normal way to solve the problem is exactly what you called a "workaround": install Pytest into the venv that you're using to test your code. (You should also consider doing an "editable" install of the code itself into the venv, so that Pytest can reliably `import` your code for testing without worrying about the current working directory.) As much sense as you might think it makes to reuse a system-installed Pytest, *it really isn't designed to work that way*.
- (Pip *does* have this functionality, BTW; but the UI for it is clumsy and a lot of the rest of the ecosystem is designed with the expectation that each venv will get its own copy of Pip. And besides, this is only possible because Pip doesn't need to `import` anything from the environment it's installing into. If you use the clunky UI and get a system installation of Pip to install into a venv, from Pip's perspective, the venv's `site-packages` is just another directory. But the whole point of Pytest is that it orchestrates running your code.)
- Although the system package manager was involved for your setup, this is really just a special case of [a pure Python issue](https://software.codidact.com/posts/290550).
- When you run a program like Pytest that is itself written in Python, generally the "executable" is just a wrapper that invokes Python to `import` the corresponding library and call some entry-point function. On Linux, these are simply Python scripts with a shebang line; for example, if you do ``cat `which pytest` `` you should see something like
- ```
- #!/absolute/path/to/some/installation/of/python
- # -*- coding: utf-8 -*-
- import re
- import sys
- from pytest import console_main
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
- sys.exit(console_main())
- ```
- If you use the system package manager to install Pytest, then the Pytest copy that you get will be set up to use the system Python (i.e. the shebang line will specify `/usr/bin/python` or similar), and therefore the code will run in the system Python's environment with the system Python's installed third-party libraries. It has no awareness of your "current" venv (virtual environment) - because there isn't really such a thing in the first place ("activating" a venv doesn't do very much, and isn't strictly required in order to use it anyway), and because *that isn't the copy of Python that's running*. When the system Python runs, its default `sys.path` initialization will include the system packages (including the system-installed Pytest) - *not* anything that you installed into the venv.
- Further, it will *not* work to do something like ``python `which pytest` `` (i.e., running the wrapper executable as a script, with the venv's Python), because then the `import` *of the Pytest library* will fail, because that isn't installed *for the venv*.
- On Linux, you *could* edit the wrapper so that the shebang points at `/usr/bin/env python` instead. This is a brutal hack, of course: it's not portable (on Windows, the wrappers are actual native-code executables that make a Windows system call to launch Python) and it breaks convention. (People often ask why these wrappers aren't generated using relative paths, which along with a tweak to the `activate` script would allow the venv folders to be relocated; the answer, apparently, is that some users depend on being able to copy or symlink the wrappers.)
- <section class="notice is-danger">
- You can *try* arranging for the venv's `site-packages` directory to be added to `sys.path` - for example by using the `PYTHONPATH` environment variable, or by [using one of the configuration file options](https://docs.pytest.org/en/stable/reference/customize.html) for Pytest to [supply a `pythonpath` value](https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath). However, [trying to force Python to "share" libraries from another environment like this is not safe](https://software.codidact.com/posts/291675). It can easily break if the venv's Python is a different version from the system Python, and you won't be able to *prevent* Pytest from accessing the system Python's libraries (which could spoil your test results, e.g. by fixing broken imports in your code that you were trying to detect) without even trickier hacking (i.e. using `PYTHONHOME`).
- </section>
- However, the expected and normal way to solve the problem is exactly what you called a "workaround": install Pytest into the venv that you're using to test your code. (You should also consider doing an "editable" install of the code itself into the venv, so that Pytest can reliably `import` your code for testing without worrying about the current working directory.) As much sense as you might think it makes to reuse a system-installed Pytest, *it really isn't designed to work that way*.
- (Pip *does* have this functionality, BTW; but the UI for it is clumsy and a lot of the rest of the ecosystem is designed with the expectation that each venv will get its own copy of Pip. And besides, this is only possible because Pip doesn't need to `import` anything from the environment it's installing into. If you use the clunky UI and get a system installation of Pip to install into a venv, from Pip's perspective, the venv's `site-packages` is just another directory. But the whole point of Pytest is that it orchestrates running your code.)
#2: Post edited
Although the system package manage was involved, this is really just a special case of [a pure Python issue](https://software.codidact.com/posts/290550).- When you run a program like Pytest that is itself written in Python, generally the "executable" is just a wrapper that invokes Python to `import` the corresponding library and call some entry-point function. On Linux, these are simply Python scripts with a shebang line; for example, if you do `cat $(which pytest)` you should see something like
- ```
- #!/absolute/path/to/some/installation/of/python
- # -*- coding: utf-8 -*-
- import re
- import sys
- from pytest import console_main
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
- sys.exit(console_main())
- ```
- If you use the system package manager to install Pytest, then the Pytest copy that you get will be set up to use the system Python (i.e. the shebang line will specify `/usr/bin/python` or similar), and therefore the code will run in the system Python's environment with the system Python's installed third-party libraries. It has no awareness of your "current" venv (virtual environment) - because there isn't really such a thing in the first place ("activating" a venv doesn't do very much, and isn't strictly required in order to use it anyway), and because *that isn't the copy of Python that's running*. When the system Python runs, its default `sys.path` initialization will include the system packages (including the system-installed Pytest) - *not* anything that you installed into the venv.
- Further, it will *not* work to do something like ``python `which pytest` `` (i.e., running the wrapper executable as a script, with the venv's Python), because then the `import` *of the Pytest library* will fail, because that isn't installed *for the venv*.
- On Linux, you *could* edit the wrapper so that the shebang points at `/usr/bin/env python` instead. This is a brutal hack, of course: it's not portable (on Windows, the wrappers are actual native-code executables that make a Windows system call to launch Python) and it breaks convention. (People often ask why these wrappers aren't generated using relative paths, which along with a tweak to the `activate` script would allow the venv folders to be relocated; the answer, apparently, is that some users depend on being able to copy or symlink the wrappers.)
- <section class="notice is-danger">
- You can *try* arranging for the venv's `site-packages` directory to be added to `sys.path` - for example by using the `PYTHONPATH` environment variable, or by [using one of the configuration file options](https://docs.pytest.org/en/stable/reference/customize.html) for Pytest to [supply a `pythonpath` value](https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath). However, [trying to force Python to "share" libraries from another environment like this is not safe](https://software.codidact.com/posts/291675). It can easily break if the venv's Python is a different version from the system Python, and you won't be able to *prevent* Pytest from accessing the system Python's libraries (which could spoil your test results, e.g. by fixing broken imports in your code that you were trying to detect) without even trickier hacking (i.e. using `PYTHONHOME`).
- </section>
- However, the expected and normal way to solve the problem is exactly what you called a "workaround": install Pytest into the venv that you're using to test your code. (You should also consider doing an "editable" install of the code itself into the venv, so that Pytest can reliably `import` your code for testing without worrying about the current working directory.) As much sense as you might think it makes to reuse a system-installed Pytest, *it really isn't designed to work that way*.
- (Pip *does* have this functionality, BTW; but the UI for it is clumsy and a lot of the rest of the ecosystem is designed with the expectation that each venv will get its own copy of Pip. And besides, this is only possible because Pip doesn't need to `import` anything from the environment it's installing into. If you use the clunky UI and get a system installation of Pip to install into a venv, from Pip's perspective, the venv's `site-packages` is just another directory. But the whole point of Pytest is that it orchestrates running your code.)
- Although the system package manager was involved for your setup, this is really just a special case of [a pure Python issue](https://software.codidact.com/posts/290550).
- When you run a program like Pytest that is itself written in Python, generally the "executable" is just a wrapper that invokes Python to `import` the corresponding library and call some entry-point function. On Linux, these are simply Python scripts with a shebang line; for example, if you do `cat $(which pytest)` you should see something like
- ```
- #!/absolute/path/to/some/installation/of/python
- # -*- coding: utf-8 -*-
- import re
- import sys
- from pytest import console_main
- if __name__ == '__main__':
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
- sys.exit(console_main())
- ```
- If you use the system package manager to install Pytest, then the Pytest copy that you get will be set up to use the system Python (i.e. the shebang line will specify `/usr/bin/python` or similar), and therefore the code will run in the system Python's environment with the system Python's installed third-party libraries. It has no awareness of your "current" venv (virtual environment) - because there isn't really such a thing in the first place ("activating" a venv doesn't do very much, and isn't strictly required in order to use it anyway), and because *that isn't the copy of Python that's running*. When the system Python runs, its default `sys.path` initialization will include the system packages (including the system-installed Pytest) - *not* anything that you installed into the venv.
- Further, it will *not* work to do something like ``python `which pytest` `` (i.e., running the wrapper executable as a script, with the venv's Python), because then the `import` *of the Pytest library* will fail, because that isn't installed *for the venv*.
- On Linux, you *could* edit the wrapper so that the shebang points at `/usr/bin/env python` instead. This is a brutal hack, of course: it's not portable (on Windows, the wrappers are actual native-code executables that make a Windows system call to launch Python) and it breaks convention. (People often ask why these wrappers aren't generated using relative paths, which along with a tweak to the `activate` script would allow the venv folders to be relocated; the answer, apparently, is that some users depend on being able to copy or symlink the wrappers.)
- <section class="notice is-danger">
- You can *try* arranging for the venv's `site-packages` directory to be added to `sys.path` - for example by using the `PYTHONPATH` environment variable, or by [using one of the configuration file options](https://docs.pytest.org/en/stable/reference/customize.html) for Pytest to [supply a `pythonpath` value](https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath). However, [trying to force Python to "share" libraries from another environment like this is not safe](https://software.codidact.com/posts/291675). It can easily break if the venv's Python is a different version from the system Python, and you won't be able to *prevent* Pytest from accessing the system Python's libraries (which could spoil your test results, e.g. by fixing broken imports in your code that you were trying to detect) without even trickier hacking (i.e. using `PYTHONHOME`).
- </section>
- However, the expected and normal way to solve the problem is exactly what you called a "workaround": install Pytest into the venv that you're using to test your code. (You should also consider doing an "editable" install of the code itself into the venv, so that Pytest can reliably `import` your code for testing without worrying about the current working directory.) As much sense as you might think it makes to reuse a system-installed Pytest, *it really isn't designed to work that way*.
- (Pip *does* have this functionality, BTW; but the UI for it is clumsy and a lot of the rest of the ecosystem is designed with the expectation that each venv will get its own copy of Pip. And besides, this is only possible because Pip doesn't need to `import` anything from the environment it's installing into. If you use the clunky UI and get a system installation of Pip to install into a venv, from Pip's perspective, the venv's `site-packages` is just another directory. But the whole point of Pytest is that it orchestrates running your code.)
#1: Initial revision
Although the system package manage was involved, this is really just a special case of [a pure Python issue](https://software.codidact.com/posts/290550). When you run a program like Pytest that is itself written in Python, generally the "executable" is just a wrapper that invokes Python to `import` the corresponding library and call some entry-point function. On Linux, these are simply Python scripts with a shebang line; for example, if you do `cat $(which pytest)` you should see something like ``` #!/absolute/path/to/some/installation/of/python # -*- coding: utf-8 -*- import re import sys from pytest import console_main if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(console_main()) ``` If you use the system package manager to install Pytest, then the Pytest copy that you get will be set up to use the system Python (i.e. the shebang line will specify `/usr/bin/python` or similar), and therefore the code will run in the system Python's environment with the system Python's installed third-party libraries. It has no awareness of your "current" venv (virtual environment) - because there isn't really such a thing in the first place ("activating" a venv doesn't do very much, and isn't strictly required in order to use it anyway), and because *that isn't the copy of Python that's running*. When the system Python runs, its default `sys.path` initialization will include the system packages (including the system-installed Pytest) - *not* anything that you installed into the venv. Further, it will *not* work to do something like ``python `which pytest` `` (i.e., running the wrapper executable as a script, with the venv's Python), because then the `import` *of the Pytest library* will fail, because that isn't installed *for the venv*. On Linux, you *could* edit the wrapper so that the shebang points at `/usr/bin/env python` instead. This is a brutal hack, of course: it's not portable (on Windows, the wrappers are actual native-code executables that make a Windows system call to launch Python) and it breaks convention. (People often ask why these wrappers aren't generated using relative paths, which along with a tweak to the `activate` script would allow the venv folders to be relocated; the answer, apparently, is that some users depend on being able to copy or symlink the wrappers.) <section class="notice is-danger"> You can *try* arranging for the venv's `site-packages` directory to be added to `sys.path` - for example by using the `PYTHONPATH` environment variable, or by [using one of the configuration file options](https://docs.pytest.org/en/stable/reference/customize.html) for Pytest to [supply a `pythonpath` value](https://docs.pytest.org/en/stable/reference/reference.html#confval-pythonpath). However, [trying to force Python to "share" libraries from another environment like this is not safe](https://software.codidact.com/posts/291675). It can easily break if the venv's Python is a different version from the system Python, and you won't be able to *prevent* Pytest from accessing the system Python's libraries (which could spoil your test results, e.g. by fixing broken imports in your code that you were trying to detect) without even trickier hacking (i.e. using `PYTHONHOME`). </section> However, the expected and normal way to solve the problem is exactly what you called a "workaround": install Pytest into the venv that you're using to test your code. (You should also consider doing an "editable" install of the code itself into the venv, so that Pytest can reliably `import` your code for testing without worrying about the current working directory.) As much sense as you might think it makes to reuse a system-installed Pytest, *it really isn't designed to work that way*. (Pip *does* have this functionality, BTW; but the UI for it is clumsy and a lot of the rest of the ecosystem is designed with the expectation that each venv will get its own copy of Pip. And besides, this is only possible because Pip doesn't need to `import` anything from the environment it's installing into. If you use the clunky UI and get a system installation of Pip to install into a venv, from Pip's perspective, the venv's `site-packages` is just another directory. But the whole point of Pytest is that it orchestrates running your code.)