14

I have a python library I am trying to use via IronPython (v2.7 RC1 [2.7.0.30]) invocation from C# application. The library uses NumPy and SciPy quite extensively, which does work with SciPy and NumPy for .NET when ran using ipy from command line like this:

ipy.exe -X:Frames file_from_lib_importing_numpy.py

However, when I invoke IronPython from C# using the code below, an exception is thrown:

ImportException
"No module named mtrand"
   at Microsoft.Scripting.Runtime.LightExceptions.CheckAndThrow(Object value)
   at IronPython.Runtime.Operations.PythonOps.ImportStar(CodeContext context, String fullName, Int32 level)
   at Microsoft.Scripting.Interpreter.ActionCallInstruction3.Run(InterpretedFrame frame)
   ...
   at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink)
   at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)
   at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteFile(String path)
   at Microsoft.Scripting.Hosting.ScriptRuntime.ExecuteFile(String path)
   at Microsoft.Scripting.Hosting.ScriptRuntime.UseFile(String path)
   ...

The C# code (a part of it) that invokes IronPython is as follows:

    ScriptEngine _engine;

    var opts = new Dictionary<string, object>();
    opts["Frames"] = ScriptingRuntimeHelpers.True;
    _engine = Python.CreateEngine(opts);

    var sp = _engine.GetSearchPaths();
    sp.Add(@"c:\Program Files\IronPython 2.7");
    sp.Add(@"c:\Program Files\IronPython 2.7\DLLs");
    sp.Add(@"c:\Program Files\IronPython 2.7\Lib");
    sp.Add(@"c:\Program Files\IronPython 2.7\Lib\site-packages");
    sp.Add(_path);
    _engine.SetSearchPaths(sp);

    var _runtime = _engine.Runtime;
    var scope = _runtime.ExecuteFile(Path.Combine(_path, "mytest.py"));

For testing purposes I am executing the following file 'mytest.py':

    import sys
    sys.path.append(r'c:\Program Files\IronPython 2.7')
    sys.path.append(r'c:\Program Files\IronPython 2.7\DLLs')
    sys.path.append(r'c:\Program Files\IronPython 2.7\Lib')
    sys.path.append(r'c:\Program Files\IronPython 2.7\Lib\site-packages')

    import os, os.path
    cd = os.path.dirname(__file__)
    if not cd in sys.path:
        sys.path.append(os.path.dirname(__file__))

    import numpy as np
    print 'OK'

    x = np.array([1,2])
    print x

Which fails on the line 12 'import numpy as np'. The problem is that the file __init__.py in IronPython 2.7\Lib\site-packages\numpy\random\ contains the following line

from mtrand import *

which fails. Note that the mtrand is not a module, it is a directory. I can not think of anything else I can try to make this work, so I would very much appreciate any help from you. Thank you very much.

denfromufa
  • 5,610
  • 13
  • 81
  • 138
PeterParameter
  • 524
  • 5
  • 16
  • 1
    What is the output of `print sys.path`, *AND* does `sys.path.append(r'c:\Program Files\IronPython 2.7')` after `import sys` give the same results? – Preet Sangha Apr 02 '11 at 22:02
  • You are right, when invoking from C#, the `sys.path` does not contain the paths set up in the application. Furthermore, when I add the line `sys.path.append(r'c:\Program Files\IronPython 2.7')` it fails with "No module named **numpy**". Do I really need to set up the paths in each python file that I want to use from C# app? – PeterParameter Apr 02 '11 at 22:12
  • In other words, what is the purpose of setting up the search paths when they don't propagate into the python runtime? – PeterParameter Apr 02 '11 at 22:22
  • Adding the paths to the python file did not solve the problem - still same exception thrown. The sys.path seems to be set up correctly (contains the appended paths, the Lib and Dll dirs of C# application CWD, and the directory of the file under execution), and numpy at least starts to get imported. – PeterParameter Apr 02 '11 at 22:44

2 Answers2

12

Not the best soultion, but its works for me:

import sys
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\DLLs')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\Lib')
sys.path.append(r'c:\Program Files (x86)\IronPython 2.7\Lib\site-packages')

import clr
clr.AddReference('mtrand.dll')

import numpy
import scipy

print numpy.__version__
print scipy.__version__

I hope it helps.

Vaszil
  • 121
  • 4
  • hmm, and how exactly did you build mtrand.dll? I tried pyc.py script, i.e. running `ipy pyc.py /main:..\..\Lib\site-packages\numpy\random\mtrand\generate_mtrand_c.py /out:mtrand /target:dll` but that wasn't sucessful either – PeterParameter Apr 07 '11 at 21:59
  • 1
    I didn't build it. The installer copy it into the `c:\Program Files (x86)\IronPython 2.7\DLLs` folder. – Vaszil Apr 10 '11 at 07:03
  • 2
    Nice. This worked for me after lots of headaches... If it helps someone I'm calling it within C# like this... var lang = Python.CreateLanguageSetup(null); lang.Options["Frames"] = ScriptingRuntimeHelpers.True; var setup = new ScriptRuntimeSetup(); setup.LanguageSetups.Add(lang); var runtime = new ScriptRuntime(setup); var engine = runtime.GetEngine("py"); engine.ExecuteFile("mytest.py"); – David Rinck Dec 17 '11 at 14:51
  • Worked for me too - however I have no idea why this should be necessary. After all all the DLLs are in the same directory, and the others seem to load without doing AddReference on them. – Sven Jun 10 '15 at 13:09
1

I found that, in my ActivePython V2.7.0.2, this works:

sys.path.append(r'C:\\Examples')
import examples

(assuming examples.py is in C:\Examples). This doesn't (without the r):

sys.path.append('C:\\Examples')
import examples

Because I get this:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named examples

Conclusion: mind the r''!

  • In a string literal prefixed with "**r**" the escape sequences starting with \ are disabled. This is convenient for filepaths since \ is the path separator and you don't want it to start an escape sequence. (r'C:\Examples') == ('C:\\Examples') – Vaszil Sep 04 '14 at 12:40