# Problem loading python module

**URL:** <https://swi-prolog.discourse.group/t/problem-loading-python-module/7207>\
**Category:** Help!\
**Tags:** janus, python\
**Created:** [January 30, 2024, 8:49am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207 "2024-01-30T08:49:05Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 8:49am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/1 "2024-01-30T08:49:05Z")

</div>

I’m using: SWI-Prolog version 9.1.22-26-g4eb8604da

I want the code to: load the python module numpy

But what I’m getting is:

```prolog
(liftcover) [friguzzi@login02 ~]$ $HOME/bin/swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- py_version.
% Interactive session; added `.` to Python `sys.path`
Deprecated: instead of py_call(Obj:Attr = Value), use py_setattr(Obj,Attr,Value)
% Janus 1.1.3 embeds Python 3.10.8 (main, May 10 2023, 02:53:14) [GCC 11.3.0]
% Janus: using venv from '/leonardo_work/IscrC_NSGP/liftcover'
true.

?- py_module_exists(numpy).
false.

?-
% halt
(liftcover) [friguzzi@login02 ~]$ /leonardo_work/IscrC_NSGP/liftcover/bin/python
Python 3.10.8 (main, May 10 2023, 02:53:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>>

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 9:36am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/2 "2024-01-30T09:36:27Z")

</div>

> [@friguzzi](#):
>
> `Deprecated: instead of py_call(Obj:Attr = Value), use py_setattr(Obj,Attr,Value)`

So, that is still there. Pushed a fix for that. Should be innocent.

> [@friguzzi](#):
>
> ```prolog
> ?- py_module_exists(numpy).
> false.
> 
> ```

But, this does not reproduce. Created a Python virtualenv, activated it, ran `python -m pip install numpy`, started Prolog in the venv and got

```prolog
81 ?- py_version.
% Interactive session; added `.` to Python `sys.path`
% Janus 1.1.3 embeds Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
% Janus: using venv from '/home/janw/venv'
true.

82 ?- py_module_exists(numpy).
true.

```

I’m afraid you need to do a little debugging. py\_module\_exists/1 is written in Prolog, calling some Python stuff.

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 9:50am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/3 "2024-01-30T09:50:55Z")

</div>

I will try to do some debugging. But I also tried

```prolog
(liftcover) [friguzzi@login02 ~]$ $HOME/bin/swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- py_version.
% Interactive session; added `.` to Python `sys.path`
Deprecated: instead of py_call(Obj:Attr = Value), use py_setattr(Obj,Attr,Value)
% Janus 1.1.3 embeds Python 3.10.8 (main, May 10 2023, 02:53:14) [GCC 11.3.0]
% Janus: using venv from '/leonardo_work/IscrC_NSGP/liftcover'
true.

?- py_shell.
Python 3.10.8 (main, May 10 2023, 02:53:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import numpy
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ModuleNotFoundError: No module named 'numpy'
>>>

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 9:56am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/4 "2024-01-30T09:56:36Z")

</div>

So, it is not py\_module\_exists/1 that is to blame. Probably something with setting up the Python virtualenv in Janus. See `janus.pl`. That is what I could find on the internet on how to setup a venv by hand. Works for me (as I showed). Possibly you can find out why it does not for you. Guess you need to compare some possible relevant settings in Python when run on the commandline and using the embedded version.

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 10:02am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/5 "2024-01-30T10:02:25Z")

</div>

The problem was that `numpy` was not installed in the venv but in `site-packages`:  
it was in `/leonardo/home/userexternal/friguzzi/.local/lib/python3.10/site-packages`

From  
[https://www.swi-prolog.org/pldoc/man?section=janus-venv](https://www.swi-prolog.org/pldoc/man?section=janus-venv)  
I see that

> Remove all directories with base name `site-packages` or `dist-packages` from `sys.path`

So exiting from the venv, uninstalling `numpy`, reentering in the venv, installing numpy solved the problem.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 10:18am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/6 "2024-01-30T10:18:01Z")

</div>

Good. That is resolved. Now the question is whether removing the `site-packages` is correct? I recall I observed that behavior from Python itself as well, but possibly I was wrong? The idea is that the embedded Python should behave as the normal Python executable inside the virtual environment.

Well, the embedded python is linked against some specific version of `libpython`, so it may not execute the same version of Python if the venv points to some specific Python. That cannot be avoided AFAIK.

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 10:44am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/7 "2024-01-30T10:44:25Z")

</div>

> [@jan](#):
>
> Now the question is whether removing the `site-packages` is correct?

I have no idea, I’m no big expert in python

> [@jan](#):
>
> Well, the embedded python is linked against some specific version of `libpython`, so it may not execute the same version of Python if the venv points to some specific Python

Yes, I compiled swipl with the venv activated.

I have another question regarding command line options and python:

```prolog
(liftcover) [friguzzi@login02 fbk237]$ cat testgpu.pl
main :-
  py_version,
  py_module_exists(numpy),
  py_module_exists(cupy).
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl -s testgpu.pl -g "main"
ERROR: -g main: false
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl -s testgpu.pl -t "main"
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

% Interactive session; added `.` to Python `sys.path`
Deprecated: instead of py_call(Obj:Attr = Value), use py_setattr(Obj,Attr,Value)
% Janus 1.1.3 embeds Python 3.10.8 (main, May 10 2023, 02:53:14) [GCC 11.3.0]
% Janus: using venv from '/leonardo_work/IscrC_NSGP/liftcover'
% halt

```

Why the different behavior of -g and -t?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 10:52am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/8 "2024-01-30T10:52:50Z")

</div>

> [@friguzzi](#):
>
> Why the different behavior of -g and -t?

Possibly this?

> [@friguzzi](#):
>
> `% Interactive session; added `.`to Python`sys.path``

Janus, like Python, only adds ‘.’ to the module search path for an interactive session. Else, use py\_add\_lib\_dir/1,2

These days, I normally use initialization/2.

```
:- initialization(main, main).

```

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 10:58am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/9 "2024-01-30T10:58:54Z")

</div>

> [@jan](#):
>
> Possibly this?
> 
> > [@friguzzi](#):
> >
> > `% Interactive session; added `.`to Python`sys.path``

but the modules `numpy` and `cupy` are not in `.`

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 11:14am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/10 "2024-01-30T11:14:26Z")

</div>

> [@friguzzi](#):
>
> but the modules `numpy` and `cupy` are not in `.`

Then I wouldn’t know. Put a call to gtrace/0 at the beginning of your main/0?

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 11:38am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/11 "2024-01-30T11:38:47Z")

</div>

Further information:

```prolog
(liftcover) [friguzzi@login02 fbk237]$ cat testgpu.pl
main :-
  trace,
  py_module_exists(numpy),
  py_module_exists(cupy).

:- initialization(main).

```

```prolog
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl testgpu.pl
   Call: (25) janus:py_module_exists(numpy) ? creep
   Call: (26) error:must_be(atom, numpy) ? skip
   Exit: (26) error:must_be(atom, numpy) ? creep
   Call: (26) janus:py_call(sys:modules:' __contains__'(numpy), @(true)) ? creep
   Call: (28) janus:py_initialize ? creep
   Call: (29) getenv('VIRTUAL_ENV', _4266) ? skip
   Exit: (29) getenv('VIRTUAL_ENV', '/leonardo_work/IscrC_NSGP/liftcover') ? creep
   Call: (29) prolog_to_os_filename(_5888, '/leonardo_work/IscrC_NSGP/liftcover') ? skip
   Exit: (29) prolog_to_os_filename('/leonardo_work/IscrC_NSGP/liftcover', '/leonardo_work/IscrC_NSGP/liftcover') ? creep
   Call: (29) atom_concat('/leonardo_work/IscrC_NSGP/liftcover', '/pyvenv.cfg', _7510) ? skip
   Exit: (29) atom_concat('/leonardo_work/IscrC_NSGP/liftcover', '/pyvenv.cfg', '/leonardo_work/IscrC_NSGP/liftcover/pyvenv.cfg') ? creep
   Call: (29) access_file('/leonardo_work/IscrC_NSGP/liftcover/pyvenv.cfg', read) ? skip
   Exit: (29) access_file('/leonardo_work/IscrC_NSGP/liftcover/pyvenv.cfg', read) ? creep
   Call: (29) current_prolog_flag(executable, _10760) ? skip
   Exit: (29) current_prolog_flag(executable, '/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl') ? creep
   Call: (29) current_prolog_flag(py_argv, _12382) ? skip
   Exit: (29) current_prolog_flag(py_argv, []) ? creep
   Call: (29) janus:py_initialize('/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl', ['-I'], []) ? creep
   Call: (30) janus:py_initialize_('/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl', ['-I'], []) ? creep
   Exit: (30) janus:py_initialize_('/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl', ['-I'], []) ? creep
   Call: (30) absolute_file_name(library('python/janus.py'), _16492, [access(read)]) ? skip
   Exit: (30) absolute_file_name(library('python/janus.py'), '/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python/janus.py', [access(read)]) ? creep
   Call: (30) file_directory_name('/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python/janus.py', _18672) ? skip
   Exit: (30) file_directory_name('/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python/janus.py', '/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python') ? creep
   Call: (30) janus:py_add_lib_dir('/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python', first) ? skip
   Exit: (30) janus:py_add_lib_dir('/leonardo/home/userexternal/friguzzi/lib/swipl/library/ext/swipy/python', first) ? creep
   Call: (30) janus:py_connect_io ? skip
   Exit: (30) janus:py_connect_io ? creep
   Call: (30) janus:repl_add_cwd ? creep
   Call: (31) current_prolog_flag(break_level, _27424) ? creep
   Fail: (31) current_prolog_flag(break_level, _27424) ? creep
   Fail: (30) janus:repl_add_cwd ? creep
   Fail: (29) janus:py_initialize('/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl', ['-I'], []) ? creep
   Fail: (28) janus:py_initialize ? creep
   Fail: (26) janus:py_call(sys:modules:' __contains__'(numpy), @(true)) ? creep
   Redo: (25) janus:py_module_exists(numpy) ? creep
   Call: (26) janus:py_call(importlib:util:find_spec(numpy), _33148) ? creep
   Exit: (26) janus:py_call(importlib:util:find_spec(numpy), @(none)) ? creep
   Call: (26) @(none)\== @(none) ? creep
   Fail: (26) @(none)\== @(none) ? creep
   Fail: (25) janus:py_module_exists(numpy) ? creep
^ Redo: (13) setup_call_cleanup(system:with_mutex('$load_file', '$mt_start_load'('/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl', <clause>(0xd19a90), [expand(false)])), system:'$mt_do_load'(<clause>(0xd19a90), 'testgpu.pl', '/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl', user, [expand(false)]), system:'$mt_end_load'(<clause>(0xd19a90))) ? creep
   Call: (26) push_msg(initialization_failure(user:main, '/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl':7), _38076) ? skip
main :-
   Exit: (26) push_msg(initialization_failure(user:main, '/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl':7), []) ? creep
   Call: (33) prolog:message_prefix_hook(thread, _39834) ? skip
   Fail: (33) prolog:message_prefix_hook(thread, _39834) ? creep
Warning: /leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl:7: Initialization goal failed
   Call: (25) pop_msg([]) ? creep
   Exit: (25) pop_msg([]) ? creep
^ Exit: (18) setup_call_cleanup(system:'$start_run_initialization'([expand(false)], false), system:'$run_initialization_2'('/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl'), system:'$end_run_initialization'(false)) ? creep
^ Exit: (13) setup_call_cleanup(system:with_mutex('$load_file', '$mt_start_load'('/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl', <clause>(0xd19a90), [expand(false)])), system:'$mt_do_load'(<clause>(0xd19a90), 'testgpu.pl', '/leonardo_work/IscrC_NSGP/kg/fbk237/testgpu.pl', user, [expand(false)]), system:'$mt_end_load'(<clause>(0xd19a90))) ? creep
   Call: (14) push_msg(load_file_errors('testgpu.pl', 0, 1), _45226) ? skip
   Exit: (14) push_msg(load_file_errors('testgpu.pl', 0, 1), []) ? creep
   Call: (13) pop_msg([]) ? creep
   Exit: (13) pop_msg([]) ? creep
   Call: (9) push_msg(welcome, _48536) ? skip
   Exit: (9) push_msg(welcome, []) ? creep
   Call: (19) prolog:version_msg(_50330) ? skip
   Fail: (19) prolog:version_msg(_50330) ? creep
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

   Call: (8) pop_msg([]) ? creep
   Exit: (8) pop_msg([]) ? creep
?-
% halt

```

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 11:53am UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/12 "2024-01-30T11:53:49Z")

</div>

I’m confused also by the `-g` and `-t` options:

```prolog
(liftcover) [friguzzi@login02 fbk237]$ cat testgpu.pl
main :-
	% trace,
  py_module_exists(numpy),
  py_module_exists(cupy).

%:- initialization(main).
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl testgpu.pl -g main
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?-
% halt
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl testgpu.pl -t main
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?-
% halt
(liftcover) [friguzzi@login02 fbk237]$ $HOME/bin/swipl testgpu.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-26-g4eb8604da)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- main.
% Interactive session; added `.` to Python `sys.path`
Deprecated: instead of py_call(Obj:Attr = Value), use py_setattr(Obj,Attr,Value)
true.

?-

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 12:18pm UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/13 "2024-01-30T12:18:24Z")

</div>

> [@friguzzi](#):
>
> ```prolog
> Fail: (30) janus:repl_add_cwd ? creep
> Fail: (29) janus:py_initialize('/leonardo/home/userexternal/friguzzi/lib/swipl/bin/x86_64-linux/swipl', ['-I'], []) ? creep
> 
> ```

That is not good. Pushed a fix. With this failure, the virtual env is not properly setup.

> [@friguzzi](#):
>
> I’m confused also by the `-g` and `-t` options:

-g is executed before becoming interactive. -t defines the interactive toplevel. That is the difference: on -t, the repl\_add\_cwd/0 call succeeds and the initialization of Python is properly completed.

P.s. Do not use initialization/1 to run an application. Although it is executed after loading the code that belongs to a file, it still executes in a locked environment as it needs to complete before the call that caused this file to be loaded can complete. That is where `initialization(Goal, main)` comes in. This goal is executed _after_ all `-g goal` and prevents the REPL to start unless `Goal` explicitly re-enables the REPL loop.

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 30, 2024, 3:52pm UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/14 "2024-01-30T15:52:51Z")

</div>

> [@friguzzi](#):
>
> > [@jan](#):
> >
> > Now the question is whether removing the `site-packages` is correct?
> 
> I have no idea, I’m no big expert in python

I thought about it: I think the best would be to have Janus behave as command line Python. So in this case, not removing site-packages.

Another thing that would be useful is to provide a predicate to find out to which Python executable swipl was linked.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 30, 2024, 4:14pm UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/15 "2024-01-30T16:14:08Z")

</div>

> [@friguzzi](#):
>
> I thought about it: I think the best would be to have Janus behave as command line Python. So in this case, not removing site-packages.

I agree, but I think it does. At least, here (Ubuntu 22.04). The first run is before entering the venv, the other two are pyhon and Prolog after entering the venv. That all looks pretty consistent to me. Prolog only add the directory holding `janus.py` to the path.

```prolog
janw (~) 4_> python
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/janw/.local/lib/python3.10/site-packages', '/home/janw/.local/lib/python3.10/cmeel.prefix/lib/python3.10/site-packages', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
>>> 
janw (~) 5_> source venv/bin/activate
(venv) janw (~) 6_> python
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/janw/venv/lib/python3.10/site-packages']
>>> 
(venv) janw (~) 7_> swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.22-35-gdd909bac0-DIRTY)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

    CMake built from "/home/janw/src/swipl-devel/build.pgo"

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

77 ?- py_call(sys:path, L).
% Interactive session; added `.` to Python `sys.path`
L = ['', '/home/janw/src/swipl-devel/build.pgo/home/library/ext/swipy/python', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/janw/venv/lib/python3.10/site-packages'].

```

> [@friguzzi](#):
>
> Another thing that would be useful is to provide a predicate to find out to which Python executable swipl was linked.

py\_version/0 tells the version, but not where it is installed. That is a little hard. The only way to find out is to get the absolute path of `libpython` that is linked in, but there is no nice portable way to get that. On Linux, you can run `ldd` on `janus.so` in the Prolog tree. On MacOS you do the same using `otool -L`. On Windows you probably best call win\_process\_modules/1. In all cases, make sure to have the same environment settings as all dynamic linkers react on the environment.

But, I think the location doesn’t matter too much. The version matters, as well as the Python module search path, which is accessible as `sys.path`. I could be wrong though; I’m not a Python expert (although I learned a few tricks in the past months 🙂 ).

---

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [February 1, 2024, 12:55pm UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/16 "2024-02-01T12:55:14Z")

</div>

The problem is you can create an environment with

```prolog
python -m venv liftcover --system-site-packages

```

so in this case the `site-packages` should not be removed. See [https://docs.python.org/3/library/venv.html#module-venv](https://docs.python.org/3/library/venv.html#module-venv)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 1, 2024, 2:17pm UTC](https://swi-prolog.discourse.group/t/problem-loading-python-module/7207/17 "2024-02-01T14:17:59Z")

</div>

> [@friguzzi](#):
>
> ```prolog
> python -m venv liftcover --system-site-packages
> 
> ```

Thanks. Pushed a patch to take care of this. I now get the same `sys.path` as Python in the venv. For this scenario it is a bit of a pity that one has to take care of setting up the environment yourself when embedding Python ☹ That is what I found on SO, but no comprehensive description of what needs to be done to mimic Python’s default behavior. We’ll have to get there incrementally ☹
