It seems we have two different ways to activate the current opam switch environment. So my questions are:
- Which one is the preferred method?
- What is the difference between the two?
eval $(opam env --switch=$SWITCH --set-switch)
vsopam switch set $SWITCH
Thanks!
Context
I need to change opam envs within python due to my applicaiton (no way around this 100%).
Usually I do:
eval $(opam env --switch={switch} --set-switch)
but this gives an issue (see end).
Thus, going to try:
opam switch set {switch}
are these truly equivalent?
(Note: in python opam switch set {switch}
seems to work, but still like to understand why there are two version)
For context error:
Traceback (most recent call last):
File "/lfs/ampere4/0/brando9/iit-term-synthesis/iit-term-synthesis-src/data_pkg/data_gen.py", line 510, in <module>
main()
File "/lfs/ampere4/0/brando9/iit-term-synthesis/iit-term-synthesis-src/data_pkg/data_gen.py", line 497, in main
asyncio.run(create_dataset(path_2_save_new_dataset_all_splits=args.path_to_save_new_dataset,
File "/dfs/scratch0/brando9/anaconda/envs/iit_synthesis/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/dfs/scratch0/brando9/anaconda/envs/iit_synthesis/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
return future.result()
File "/lfs/ampere4/0/brando9/iit-term-synthesis/iit-term-synthesis-src/data_pkg/data_gen.py", line 437, in create_dataset
coq_proj_data: DataCoqProj = await get_coq_proj_data(coq_proj, split)
File "/lfs/ampere4/0/brando9/iit-term-synthesis/iit-term-synthesis-src/data_pkg/data_gen.py", line 194, in get_coq_proj_data
path2filenames_raw: list[str] = strace_build_coq_project_and_get_filenames(coq_proj)
File "/afs/cs.stanford.edu/u/brando9/pycoq/pycoq/opam.py", line 706, in strace_build_coq_project_and_get_filenames
activate_opam_switch(switch)
File "/afs/cs.stanford.edu/u/brando9/pycoq/pycoq/opam.py", line 892, in activate_opam_switch
raise e
File "/afs/cs.stanford.edu/u/brando9/pycoq/pycoq/opam.py", line 886, in activate_opam_switch
res = subprocess.run(command.split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "/dfs/scratch0/brando9/anaconda/envs/iit_synthesis/lib/python3.9/subprocess.py", line 505, in run
with Popen(*popenargs, **kwargs) as process:
File "/dfs/scratch0/brando9/anaconda/envs/iit_synthesis/lib/python3.9/subprocess.py", line 951, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/dfs/scratch0/brando9/anaconda/envs/iit_synthesis/lib/python3.9/subprocess.py", line 1821, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'eval'
I think it has something to do with calling subprocesses from within python don't fully understand,
Why is subprocess not inheriting the env vars from the main python process but from the mutable subprocesses as more subprocess calls are done?
[quote="Frederic_Loyer, post:22, topic:10957"]
A process can’t change the environment of an other process. Then opam
can’t change the parent process environment (bash or Python).
[/quote]
I've confirmed this. What I do is run opam switch set coq-8.10
from a python subprocess:
# opam_set_switch_via_opam_switch('coq-8.10')
result = subprocess.run(f'opam switch set {switch}'.split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
which the docs says returns a completed process.
Then I compare the contents of the env variables of the subprocess by calling via another subprocess the cmd opam env
and compare it with the main python process by comparing it with os.environ
. I get that the two indeed don't match:
# opam_env_dict: dict = get_variables_from_opam_env_output(py_prints_on=py_prints_on)
result = subprocess.run('opam env'.split(), capture_output=True, text=True)
# ... compare with os.environ
assert uutils.check_dict1_is_in_dict2(opam_env_dict, os.environ, verbose=True)
assert fails
--> k='OPAM_SWITCH_PREFIX' is in dict2 but with different value
dict1[k]='/Users/brandomiranda/.opam/coq-8.10'
dict2[k]='/Users/brandomiranda/.opam/test'
The only thing that confuses me is that it seems that subprocess has it's own process that does remember things. I say this because I would have expected the new subprocess that calls opam env
to not be affected by the first opam switch set coq-8.10
but it seems it was affected. I expected the 2nd subprocess to spawned from the main python and be independent form the process that called opam switch set coq-8.10
.
refs:
- Is there a way to run the bash eval command in python?
- Running `eval $(something)` commands using Python sub-process
- Python check_output call to eval (with arguments) fails
- eval $(opam env): What is the use of eval `opam config env` or eval $(opam env) and their difference?
- https://discuss.ocaml.org/t/is-eval-opam-env-switch-switch-set-switch-equivalent-to-opam-switch-set-switch/10957
- related: https://discuss.ocaml.org/t/if-i-want-to-switch-opam-switch-should-i-use-eval-opam-env-switch-switch-name-set-switch-or-opam-switch-set-switch-name-why-are-there-two-ways-to-do-this/11421/7