To get this out of the way:
I believe the Import::nopythonevals
message will be issued by Import[..., "PythonExpression"]
if there are no usable external evaluators set up. First make sure that you have set up Python correctly (including installing pyzmq
), and registered an external evaluator.
As you can see in my question, I have already done this, yet ExternalEvaluate
was not working.
To cut a long story short, I believe that this is due to a bug in M11.2.0 where Import[..., "PythonExpression"]
attempts to find a Python installation on its own, and does not even look at what installations the user has already registered using RegisterExternalEvaluator
.
In my case, it was trying to use the system Python on OS X. I suspect it failed because I did not have pyzmq
installed for the system Python. I prefer not to modify it, as I use a private installation of Anaconda Python instead.
Here's a workaround to force Import[..., "PythonExpression"]
to use the Python installation that I have already registered:
ExternalEvaluate (* triggers loading the ExternalEvaluate framework *)
(* ExternalEvaluate *)
ExternalEvaluate`ImportExport`Private`$ImporterPythonSession = StartExternalSession["Python" -> "String"] (* this evaluator will be used to handle "PythonExpression" *)
(* ExternalSessionObject["9a23363e-5403-442d-8fbd-39f9aff7dc48"] *)
py = StartExternalSession["Python"]
(* ExternalSessionObject["5022a77c-eedb-4d39-bbb3-c8b6a644ecdf"] *)
ExternalEvaluate[py, "1+1"] (* now everything works fine! *)
(* 2 *)
I hope this information will be useful to others who want to play with ExternalEvaluate
, but do not wish to modify (or even use) their system Python on OS X.

As mentioned by @MichaelE2, an alternative solution is to symlink your preferred Python interpreter in a location that is already being searched by the ExternalEvaluate framework. Currently, on OS X and Linux /usr/local/bin/
is such a location. To see the full list of locations, evaluate
ExternalEvaluate (* load framework *)
ExternalEvaluate`Private`$LanguageHeuristics["Python", "ExecutablePathFunction"]
"Executable"
specification, as inStartExternalSession[<|"System" -> "Python", "Executable" -> "C:\\dev\\bin\\Anaconda\\envs\\1.9.1.post520\\python.exe", "ReturnType" -> "String"|>]
and everything works (Win 64). $\endgroup$ExternalEvaluate
(notStartExternalSession
) will fail if the builtin heuristics of ExternalEvaluate (which are OS-specific) are unable to find a python executable that has zmq set up. If this happens, it does not matter that you have specified an executable manually, or registered one. Importing PythonExpressions will fail regardless. This is why I consider it a bug: when I specify the Python executable manually, the system should use it (not try to find it elsewhere on its own and then fail). $\endgroup$