Repository: sympy/sympy
Pull request: Set cwd as the local sympy root in subprocess call to make tests run from different directory.
Set cwd as the local sympy root in subprocess call to make tests run from different directory.
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs

Fixes#17369
closes #17401 as an alternative

#### Brief description of what is fixed or changed

Set cwd as the local sympy root in subprocess call to make tests run from different directory in run_in_subprocess_with_hash_randomization so that it imports from the
same sympy.

#### Release Notes

<!-- BEGIN RELEASE NOTES -->
* other
    * it should now be possible to run tests from any directory
<!-- END RELEASE NOTES -->


Problem statement:
test and doctest scripts do not work from other directories
The `path_hack` in the `test` and `doctest` scripts is supposed to make it so that something like

```
cd bin
./doctest
```

still tests the git SymPy. 

But the problem is that the tests and doctests run in a subprocess by default, which does not inherit the sys.path. So the above will test the globally installed SymPy unless `--no-subprocess` is used. 

The simplest solution would be for `path_hack` to set PYTHONPATH in os.environ so that it gets inherited. Or maybe it should be done in the run_tests_in_subprocess function, I'm not sure.

Hints from issue discussion:
Thinking about it, it should be run_tests_in_subprocess's responsibility to make sure the subprocess test runner tests the same sympy that it is called from. 
I would like to work on this. I was not able to find where ` run_tests_in_subprocess` was defined. Can you help me out?
I remembered the name wrong. It's `run_in_subprocess_with_hash_randomization` in `sympy.utilities.runtests`.
Hi,
Beginner here. Would like to work on this issue. Any leads would help. This would be my first pr.
Thanks in advance.
We need to make it so that run_in_subprocess_with_hash_randomization in sympy.utilities.runtests starts the subprocess Python in such a way so that when it import sympy, it imports the same sympy. I'm not sure what the best way to do this is. Probably the easiest way is to set the PYTHONPATH environment variable in the subprocess call, but you might Google around to see if there is a better way to do it.

Commit message: Discarded PYTHONPATH and used cwd to provide path to subrocess.Popen

Patch to review:
diff --git a/sympy/utilities/runtests.py b/sympy/utilities/runtests.py
index c5494f4b5c8e..b49ade623790 100644
--- a/sympy/utilities/runtests.py
+++ b/sympy/utilities/runtests.py
@@ -15,6 +15,7 @@
 from __future__ import print_function, division
 
 import os
+from os.path import dirname
 import sys
 import platform
 import inspect
@@ -24,6 +25,7 @@
 import linecache
 import time
 from fnmatch import fnmatch
+from os.path import dirname
 from timeit import default_timer as clock
 import doctest as pdoctest  # avoid clashing with our doctest() function
 from doctest import DocTestFinder, DocTestRunner
@@ -32,7 +34,6 @@
 import signal
 import stat
 import tempfile
-
 from sympy.core.cache import clear_cache
 from sympy.core.compatibility import exec_, PY3, string_types, range, unwrap
 from sympy.utilities.misc import find_executable
@@ -210,15 +211,16 @@ def run_in_subprocess_with_hash_randomization(
 
     # First check if the Python version supports hash randomization
     # If it doesn't have this support, it won't reconize the -R flag
+    current_dir = dirname(dirname(os.path.dirname(__file__)))
     p = subprocess.Popen([command, "-RV"], stdout=subprocess.PIPE,
-                         stderr=subprocess.STDOUT)
+                         stderr=subprocess.STDOUT, cwd=current_dir)
     p.communicate()
     if p.returncode != 0:
         return False
 
     hash_seed = os.getenv("PYTHONHASHSEED")
     if not hash_seed:
-        os.environ["PYTHONHASHSEED"] = str(random.randrange(2**32))
+        os.environ["PYTHONHASHSEED"] = str(random.randrange(2 ** 32))
     else:
         if not force:
             return False
@@ -231,7 +233,7 @@ def run_in_subprocess_with_hash_randomization(
                       repr(function_kwargs)))
 
     try:
-        p = subprocess.Popen([command, "-R", "-c", commandstring])
+        p = subprocess.Popen([command, "-R", "-c", commandstring], cwd=current_dir)
         p.communicate()
     except KeyboardInterrupt:
         p.wait()


Code review comments:
diff_hunk: @@ -24,6 +25,7 @@
 import linecache
 import time
 from fnmatch import fnmatch
+from os.path import dirname
path: sympy/utilities/runtests.py
text: @user1:
You seem to have imported dirname twice

diff_hunk: @@ -210,15 +211,16 @@ def run_in_subprocess_with_hash_randomization(
 
     # First check if the Python version supports hash randomization
     # If it doesn't have this support, it won't reconize the -R flag
+    current_dir = dirname(dirname(os.path.dirname(__file__)))
path: sympy/utilities/runtests.py
text: @user1:
I think it would be better to get the directory from the sympy package. This code assumes that it is in this particular file in this particular place in the SymPy code tree but it could get moved.

Something like:
```
import sympy
sympy_root = dirname(dirname(sympy.__file__))
```