Skip to content

Pythonnet crashes .Net application on exit. #245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dmitriyse opened this issue Jul 22, 2016 · 23 comments
Closed

Pythonnet crashes .Net application on exit. #245

dmitriyse opened this issue Jul 22, 2016 · 23 comments

Comments

@dmitriyse
Copy link
Contributor

dmitriyse commented Jul 22, 2016

If we embed Python.Net into DotNet application, it crashes on Linux.
Crash occurs when application exits.

PythonEngine.Initialize();

try
{
    using (Py.GIL())
    {
        dynamic sysModule = Py.Import("sys");
        Console.WriteLine("Python engine version:");
        Console.WriteLine(sysModule.version);
    }

    // This workaround reduces risk of Mono crash.
    // Problem will be fixed in mono 4.6
    if (Type.GetType("Mono.Runtime") != null)
    {
        Runtime.Py_Main(3, new[] { "/pcfgtest.exe", "-c", "exit" });
    }
    else
    {
        // Program will crash if we will try to do this under Windows.
        //// Runtime.Py_Main(3, new[] { "/pcfgtest.exe", "-c", "exit" });
    }
}
finally
{
    PythonEngine.Shutdown();
}

This is sample of code that produces crash.
Also it contains 'probably workaround".

Console output :

tux@pythonnet:/mnt/Projects/pythonnet/2/src/configtest/bin/Release$ mono pcfgtest.exe
Starting application...
Python.runtime.dll substituted by Python.Runtime-Py35-Linux64.dll.
Python engine version:
3.5.2 (default, Jul  5 2016, 12:43:10)
[GCC 5.4.0 20160609]
Shutting down finalizer thread timed out.
* Assertion at gc.c:867, condition `finalizer_thread_exited' not met

Stacktrace:


Native stacktrace:

        mono() [0x4a77ca]
        /lib/x86_64-linux-gnu/libpthread.so.0(+0x113d0) [0x7f48084463d0]
        /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38) [0x7f4807e8b418]
        /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a) [0x7f4807e8d01a]
        mono() [0x6408c9]
        mono() [0x640ad7]
        mono() [0x640c26]
        mono() [0x5aee5e]
        mono(mono_runtime_cleanup+0xe) [0x5a85de]
        mono() [0x423cf7]
        mono(mono_main+0x10d7) [0x47a087]
        mono() [0x421818]
        /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f4807e76830]
        mono() [0x421c11]

Debug info from gdb:


=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================

Aborted (core dumped)

I tried everything - python 2.7, python 3.5, Mono 4.2, 4.4.
It does not matter, behavior always the same.

Also i tried to build with Py_DEBUG under linux (and pass python library from python3.5-dbg package)
I receive assertions on PythonEngine.Init:

  1. Decref -1 Assertions
  2. td_type != NULL Assertion
@royalstream
Copy link

royalstream commented Oct 6, 2016

YMMV but here's some potentially useful feedback on this issue.

I'm using OS X 10.11.3 and Anaconda Python (see the specific version in the outputs).

Using Mono 4.4.2 I get exactly the same error, even if shrink your code to just this:

public static void Main(string[] args)
{
    Environment.SetEnvironmentVariable("PYTHONHOME", "/Users/steven/anaconda");

    PythonEngine.Initialize();

    try
    {
        using (Py.GIL())
        {
            dynamic sysModule = Py.Import("sys");
            Console.WriteLine("Python engine version:");
            Console.WriteLine(sysModule.version);
        }
    }
    finally
    {
        PythonEngine.Shutdown();
    }
}

The error is the following:

Python engine version:
2.7.12 |Anaconda 4.1.1 (x86_64)| (default, Jul  2 2016, 17:43:17) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)]
Shutting down finalizer thread timed out.
* Assertion at gc.c:867, condition `finalizer_thread_exited' not met

Stacktrace:

Native stacktrace:

    0   mono64                              0x000000010c19966a mono_handle_native_sigsegv + 282
    1   libsystem_platform.dylib            0x00007fff99c93eaa _sigtramp + 26
    2   ???                                 0x00007fff6ec674f2 0x0 + 140735051887858
    3   libsystem_c.dylib                   0x00007fff9fc256e7 abort + 129
    ...

After upgrading to a newer version of Mono (4.6.1) I get a slightly different error description but I suspect deep down the problem remains the same:

Python engine version:
2.7.12 |Anaconda 4.1.1 (x86_64)| (default, Jul  2 2016, 17:43:17) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)]
* Assertion at gc.c:910, condition `ret != WAIT_TIMEOUT' not met

Stacktrace:

Native stacktrace:

    0   mono64                              0x000000010e55370a mono_handle_native_sigsegv + 282
    1   libsystem_platform.dylib            0x00007fff99c93eaa _sigtramp + 26
    2   ???                                 0x00007fff51768f20 0x0 + 140734560112416
    3   libsystem_c.dylib                   0x00007fff9fc256e7 abort + 129
    4   mono64                              0x000000010e71301d monoeg_log_default_handler + 125
    5   mono64                              0x000000010e7131e0 monoeg_assertion_message + 192
    ...

Now here's the interesting part:
If I abstain from using dynamic objects, it never crashes anymore (Mono 4.6.1)
In other words, I changed the code to sysModule.GetAttr("version").ToString() and the problem is gone.

Additional Info:

  • I'm actually using F#, not C#, for my development and I was having the same issue.
  • I noticed the problem only happened if I used the FSharp.Interop.Dynamic and Dynamitey libraries. I was about to blame it on those two until I realized the same issue happens with C# if you use dynamic objects.
  • I'm resurrecting an abandoned project from last year. My code didn't change and I don't remember having this issue back then so it could be something that got introduced (in either Mono or Pythonnet) during the last year.
  • I tested this with both pythonnet-2.2.0.dev1 and pythonnet-2.1.0

@den-run-ai
Copy link
Contributor

@royalstream @dmitriyse these issues with finalizer were reported recently in Mono:

https://bugzilla.xamarin.com/show_bug.cgi?id=41833
https://bugzilla.xamarin.com/show_bug.cgi?id=40399
https://bugzilla.xamarin.com/show_bug.cgi?id=42665

Few potential fixes have been made and also workarounds suggested, so have a look there.

But your second issue with WAIT_TIMEOUT is not fixed yet in Mono:

https://bugzilla.xamarin.com/show_bug.cgi?id=44355

If you open a new issue in Mono, then please link it here.

Can you also try explicitly disposing module like mentioned here:

https://mail.python.org/pipermail/pythondotnet/2008-May.txt

@den-run-ai
Copy link
Contributor

With mono 4.2.4.4 and python 2.7:

Setting up mono-complete (4.2.4.4-0wheezy1) ...
Processing triggers for libc-bin (2.19-0ubuntu6.3) ...

I'm getting this error:

dta@dta-Inspiron-N5050 ~/code/issue1 $ '/home/dta/code/issue1/embedpy.exe'
Python engine version:
2.7.6 (default, Jun 22 2015, 18:01:27) 
[GCC 4.8.2]
Shutting down finalizer thread timed out.

@royalstream
Copy link

royalstream commented Oct 14, 2016

Now I'm getting the same error on a different machine but without using Dynamic Objects.
So much for my theory then :|

For the time being I added Process.GetCurrentProcess().Kill() as the last line of my main function, which is absolutely horrible but avoids the crash until this gets fixed in Mono (I don't believe pythonnet is causing it)

@den-run-ai
Copy link
Contributor

@royalstream @dmitriyse can you guys try acquiring the GIL without using Py.GIL()?

@royalstream
Copy link

And how do you do that? sorry for the "noob" question but all the code examples I've seen call Py.GIL()

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Oct 15, 2016

I am using this patched version of Runtime.Shutdown() method:
(No logic, just magic)

       internal static void Shutdown()
        {
            // This workaround reduces risk of Mono or Linux crash.
            // Problem probably will be fixed in mono 4.6
            if (Path.DirectorySeparatorChar == '/' || Type.GetType("Mono.Runtime") != null)
            {
                Runtime.Py_Main(3, new[] { "/some.exe", "-c", "exit" });
            }
            else
            {
                // else
                // Program will crash if we will try to do this under Windows.
                //// Runtime.Py_Main(3, new[] { "/some.exe", "-c", "exit" });
            }

            AssemblyManager.Shutdown();
            Exceptions.Shutdown();
            ImportHook.Shutdown();
            Py_Finalize();
        }

And this problem gone.
This solution works fine, no one issue in last 3 monthes. (On different OS and pythons include conda).

So I am assuming that bug exists in PythonNet.

P.S to use this workaround in UCS4 builds you should apply also apply this patch:
dmitriyse@8638d57

@dmitriyse
Copy link
Contributor Author

As i understand, PY_DEGUB build should be used to ensure valid reference counting, indexes access and so on. I tried to build and run PythonNet with this flag and received violations near in every place. I think that PythonNet in general requires big "Cleanup", and probably this problem will disappear.

@den-run-ai
Copy link
Contributor

den-run-ai commented Oct 15, 2016

@royalstream you could have a look at source code of Py.GIL() ;)

Here is a quick example:

public static void Main(string[] args)
{
    Environment.SetEnvironmentVariable("PYTHONHOME", "/Users/steven/anaconda");

    PythonEngine.Initialize();

    try
    {
            var pylock = PythonEngine.AcquireLock();
            var sysModule = Py.Import("sys");
            Console.WriteLine("Python engine version:");
            Console.WriteLine(sysModule.version);

    }
    finally
    {
          PythonEngine.ReleaseLock(pylock);
          PythonEngine.Shutdown();
    }
}

@den-run-ai
Copy link
Contributor

den-run-ai commented Oct 15, 2016

As i understand, PY_DEGUB build should be used to ensure valid reference counting, indexes access and > so on. I tried to build and run PythonNet with this flag and received violations near in every place. I think > that PythonNet in general requires big "Cleanup", and probably this problem will disappear.

@dmitriyse I always thought that PY_DEGUB is only helpful for debugging purposes of CPython interpreter, because it produces debug build of CPython?

https://docs.python.org/3/c-api/intro.html#debugging-builds

But let's open a separate issue for Py_DEBUG failures.

@royalstream
Copy link

royalstream commented Oct 15, 2016

@royalstream you could have a look at source code of Py.GIL() ;)

Sorry for the misunderstanding, I thought you meant avoiding Py.GIL() and whatever its code was doing.

I am using this patched version of Runtime.Shutdown() method:
(No logic, just magic)

Now I get a really bad malloc/free error, at least on the machine I'm using right now. I'll try this on a different machine next week.

mono(6365,0x7fff78553000) malloc: *** error for object 0x107f661da: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Stacktrace:
  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) object.__icall_wrapper_mono_marshal_free (intptr) <IL 0x00007, 0x000b2>
  at (wrapper managed-to-native) Python.Runtime.Runtime.Py_Main (int,string[]) <IL 0x00091, 0x00499>
  at Python.Runtime.Runtime.Shutdown () <IL 0x00040, 0x001db>
  at Python.Runtime.PythonEngine.Shutdown () <IL 0x0000a, 0x0008b>
  at Testing.main (string[]) [0x00098] in /Users/steven/sharp/Python/Testing/Testing.fs:27
  at (wrapper runtime-invoke) <Module>.runtime_invoke_int_object (object,intptr,intptr,intptr) <IL 0x00057, 0x00335>
Native stacktrace:
    0   mono                                0x0000000104bc374a mono_handle_native_sigsegv + 271
    1   libsystem_platform.dylib            0x00007fff8ac0152a _sigtramp + 26
    2   libpython2.7.dylib                  0x0000000107f9c280 sre_char_info + 165472
    3   libsystem_c.dylib                   0x00007fff908286df abort + 129
    4   libsystem_malloc.dylib              0x00007fff90f80041 szone_size + 0

I'm using Mono 4.6.0 (Stable 4.6.0.245/746756c Mon Sep 19 13:57:55 BST 2016)

@dmitriyse
Copy link
Contributor Author

Looks like you missed this patch.

P.S to use this workaround in UCS4 builds you should apply also apply this patch:
dmitriyse@8638d57

Also you can check binary distro: https://github.com/dmitriyse/pythonnet/releases/tag/v2.2.0-bin-RC
It should quickly show this trick in work. (Supports only Python 3.5 under x64 os)
try mono pyboot.exe

@royalstream
Copy link

royalstream commented Oct 15, 2016

I didn't miss it but it looks like it doesn't apply to my current Python 2.7 installation (which seems to be UCS2):

>>> import sys
>>> print sys.maxunicode
65535

@royalstream
Copy link

royalstream commented Oct 15, 2016

UPDATE: I installed the Python 3.5 version of Anaconda (which is UCS4) and the patch works great, no more crashes.

PS: If I run the unpatched version of Pythonnet I get a SIGSEGV so the patch is definitely helping.

@den-run-ai
Copy link
Contributor

den-run-ai commented Dec 19, 2016

@dmitriyse @royalstream how are you able to embed Anaconda's CPython using pythonnet on Linux? I tried the following and it is failing with System.DllNotFoundException: python3.5m, but import clr works fine:

dta@dta-Inspiron-N5050 ~ $ git clone https://github.com/pythonnet/pythonnet
Cloning into 'pythonnet'...
remote: Counting objects: 3228, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 3228 (delta 0), reused 0 (delta 0), pack-reused 3220
Receiving objects: 100% (3228/3228), 2.63 MiB | 1.28 MiB/s, done.
Resolving deltas: 100% (2226/2226), done.
Checking connectivity... done.
dta@dta-Inspiron-N5050 ~ $ cd pythonnet/
dta@dta-Inspiron-N5050 ~/pythonnet $ which python
/home/dta/anaconda3/bin/python
dta@dta-Inspiron-N5050 ~/pythonnet $ ldd `which python`
	linux-vdso.so.1 =>  (0x00007fff3572f000)
	libpython3.5m.so.1.0 => /home/dta/anaconda3/bin/../lib/libpython3.5m.so.1.0 (0x00007f6b0dcac000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6b0da6d000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6b0d868000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f6b0d665000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6b0d45d000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6b0d156000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6b0cd91000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f6b0e19e000)
dta@dta-Inspiron-N5050 ~/pythonnet $ `which python` setup.py install
running install
running bdist_egg
running egg_info
creating pythonnet.egg-info
writing dependency_links to pythonnet.egg-info/dependency_links.txt
writing pythonnet.egg-info/PKG-INFO
writing top-level names to pythonnet.egg-info/top_level.txt
writing manifest file 'pythonnet.egg-info/SOURCES.txt'
reading manifest file 'pythonnet.egg-info/SOURCES.txt'
writing manifest file 'pythonnet.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_ext
Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 2.8.0.
Updating NuGet.exe to 3.4.4-rtm-final.
Update successful.
MSBuild auto-detection: using msbuild version '4.0' from '/usr/lib/mono/4.5'.
Restoring NuGet package UnmanagedExports.1.2.7.
Restoring NuGet package NUnit.2.6.2.
Adding package 'UnmanagedExports.1.2.7' to folder '/home/dta/pythonnet/packages'
Adding package 'NUnit.2.6.2' to folder '/home/dta/pythonnet/packages'
Added package 'NUnit.2.6.2' to folder '/home/dta/pythonnet/packages'
Added package 'UnmanagedExports.1.2.7' to folder '/home/dta/pythonnet/packages'

NuGet Config files used:
    /home/dta/.config/NuGet/NuGet.Config

Feeds used:
    /home/dta/.local/share/NuGet/Cache
    https://api.nuget.org/v3/index.json

Installed:
    2 package(s) to packages.config projects
clang: warning: /home/dta/anaconda3/include/python3.5m: 'linker' input unused
XBuild Engine Version 12.0
Mono, Version 4.2.4.0
Copyright (C) 2005-2013 Various Mono authors
/home/dta/pythonnet/pythonnet.sln:  warning : The project configuration for project 'clrmodule' corresponding to the solution configuration 'ReleaseMono|x64' was not found.
XBuild Engine Version 12.0
Mono, Version 4.2.4.0
Copyright (C) 2005-2013 Various Mono authors
		Configuration: ReleaseMono Platform: x64
runtime.cs(2050,16): warning CS0472: The result of comparing value type `System.IntPtr' with null is always `true'
/home/dta/pythonnet/pythonnet.sln:  warning : The project configuration for project 'clrmodule' corresponding to the solution configuration 'ReleaseMono|x64' was not found.
Configuration: ReleaseMono Platform: x64
Configuration: ReleaseMono Platform: x64
Configuration: Release Platform: x64
assemblyinfo.cs(13,50): warning CS0618: `System.Security.Permissions.SecurityAction.RequestMinimum' is obsolete: `This requests should not be used'
pythonconsole.cs(18,28): warning CS0219: The variable `a' is assigned but its value is never used
building 'clr' extension
creating build/temp.linux-x86_64-3.5
creating build/temp.linux-x86_64-3.5/src
creating build/temp.linux-x86_64-3.5/src/monoclr
gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/dta/anaconda3/include/python3.5m -c src/monoclr/pynetinit.c -o build/temp.linux-x86_64-3.5/src/monoclr/pynetinit.o -D_REENTRANT -I/usr/lib/pkgconfig/../../include/mono-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
src/monoclr/pynetinit.c: In function ‘main_thread_handler’:
src/monoclr/pynetinit.c:129:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (mblen > wlen)
                   ^
gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/dta/anaconda3/include/python3.5m -c src/monoclr/clrmod.c -o build/temp.linux-x86_64-3.5/src/monoclr/clrmod.o -D_REENTRANT -I/usr/lib/pkgconfig/../../include/mono-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
src/monoclr/clrmod.c:33:18: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 static PyObject *_initclr() {
                  ^
gcc -pthread -shared -L/home/dta/anaconda3/lib -Wl,-rpath=/home/dta/anaconda3/lib,--no-as-needed build/temp.linux-x86_64-3.5/src/monoclr/pynetinit.o build/temp.linux-x86_64-3.5/src/monoclr/clrmod.o -L/home/dta/anaconda3/lib -lpython3.5m -o build/lib.linux-x86_64-3.5/clr.cpython-35m-x86_64-linux-gnu.so -L/usr/lib/pkgconfig/../../lib -lmono-2.0 -lm -lrt -ldl -lpthread -lglib-2.0
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-3.5/clr.cpython-35m-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg
creating stub loader for clr.cpython-35m-x86_64-linux-gnu.so
byte-compiling build/bdist.linux-x86_64/egg/clr.py to clr.cpython-35.pyc
installing package data to build/bdist.linux-x86_64/egg
running install_data
copying /home/dta/pythonnet/build/lib.linux-x86_64-3.5/Python.Runtime.dll -> build/bdist.linux-x86_64/egg/../../../../anaconda3/lib/python3.5/site-packages
copying Python.Runtime.dll.config -> build/bdist.linux-x86_64/egg/../../../../anaconda3/lib/python3.5/site-packages
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying pythonnet.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pythonnet.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pythonnet.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pythonnet.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pythonnet.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
creating dist
creating 'dist/pythonnet-2.2.0-py3.5-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing pythonnet-2.2.0-py3.5-linux-x86_64.egg
removing '/home/dta/anaconda3/lib/python3.5/site-packages/pythonnet-2.2.0-py3.5-linux-x86_64.egg' (and everything under it)
creating /home/dta/anaconda3/lib/python3.5/site-packages/pythonnet-2.2.0-py3.5-linux-x86_64.egg
Extracting pythonnet-2.2.0-py3.5-linux-x86_64.egg to /home/dta/anaconda3/lib/python3.5/site-packages
pythonnet 2.2.0 is already the active version in easy-install.pth

Installed /home/dta/anaconda3/lib/python3.5/site-packages/pythonnet-2.2.0-py3.5-linux-x86_64.egg
Processing dependencies for pythonnet==2.2.0
Finished processing dependencies for pythonnet==2.2.0
dta@dta-Inspiron-N5050 ~/pythonnet $ csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> LoadAssembly("/home/dta/anaconda3/lib/python3.5/site-packages/Python.Runtime.dll") 
csharp> using Python.Runtime;                                                   csharp> PythonEngine.Initialize();                                              System.DllNotFoundException: python3.5m
  at (wrapper managed-to-native) Python.Runtime.Runtime:Py_IsInitialized ()
  at Python.Runtime.Runtime.Initialize () <0x40fc3400 + 0x0001f> in <filename unknown>:0 
  at Python.Runtime.PythonEngine.Initialize () <0x40fc28d0 + 0x0008f> in <filename unknown>:0 
  at <InteractiveExpressionClass>.Host (System.Object& $retval) <0x40fc28b0 + 0x0000b> in <filename unknown>:0 
  at Mono.CSharp.Evaluator.Evaluate (System.String input, System.Object& result, System.Boolean& result_set) <0x40f48d30 + 0x000dd> in <filename unknown>:0 
  at Mono.CSharpShell.Evaluate (System.String input) <0x40f48c30 + 0x00053> in <filename unknown>:0 
csharp> quit                                                                    dta@dta-Inspiron-N5050 ~/pythonnet $ python
Python 3.5.2 |Anaconda custom (64-bit)| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> exit()
dta@dta-Inspiron-N5050 ~/pythonnet $ 

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Dec 19, 2016

probably you need to add "CONDA HOME"\lib to LD_LIBRARY_PATH. Or create symlink from "CONDA HOME"\lib\libpython3.5m.so to <python.runtime.dll location>\libpython3.5m.so

@den-run-ai
Copy link
Contributor

@dmitriyse do you mean to add \lib to search path of $LD_LIBRARY_PATH?

@den-run-ai
Copy link
Contributor

@dmitriyse creating symlink did not resolve this. adding the libpython path to $LD_LIBRARY_PATH did not resolve the issue either.

vmuriart added a commit to vmuriart/pythonnet that referenced this issue Feb 8, 2017
Similar to how `PythonDerivedType` finalizes.

Closes pythonnet#364
Possibly related to pythonnet#245
@vmuriart
Copy link
Contributor

for anyone looking into the LD_LIBRARY_PATH. Here's how it was solved for Travis.

before_install:
  # Set-up dll path for embedded tests
  - PY_LIBDIR=$(python -c 'import sysconfig; print(sysconfig.get_config_var("LIBDIR"))')
  - export LD_LIBRARY_PATH=$PY_LIBDIR:$LD_LIBRARY_PATH

vmuriart added a commit to vmuriart/pythonnet that referenced this issue Feb 27, 2017
`AppDomain unload` was solved by pythonnet#400.
Closes pythonnet#397.

Possibly also solved pythonnet#245.
@vmuriart
Copy link
Contributor

@dmitriyse @royalstream can you verify if the latest master have solved your issue? Between #365 and #400 we should have fixed the issues with shutting down.

@den-run-ai
Copy link
Contributor

@vmuriart do we have any tests in pythonnet now for code snippets provided above, which reproduced the crash:

#245 (comment)

@vmuriart
Copy link
Contributor

Many :). At the beginning of v2.2.2 almost every embedded test produced this error in one way or another. This was one of the reasons we weren't able to run embedded tests before in AppVeyor/Travis.

The tests in initialize in particular make sure that initialize and shutdown work well. Specific to the example listed though, we have other examples that cover it like AssignNone.

@vmuriart
Copy link
Contributor

vmuriart commented Mar 3, 2017

Closing issue. Let us know if the issue is still present after the aforementioned fixes.

@vmuriart vmuriart closed this as completed Mar 3, 2017
yagweb pushed a commit to yagweb/pythonnet that referenced this issue Apr 7, 2017
`AppDomain unload` was solved by pythonnet#400.
Closes pythonnet#397.

Possibly also solved pythonnet#245.
AlexCatarino added a commit to QuantConnect/pythonnet that referenced this issue Jun 1, 2017
* Sanitize how to run tests

* Remove unsupported entry points
* Adds reference to Python.Test by default for all tests
* Remove redundant add_reference
* Avoid some implicit AddReferences that were being done

Not all tests added reference to Python.Test consistently. Solve this by making `run_test` the only supported method.

* Remove dependency on six

Remove six.u(...), six.b(...)

Not needed since dropped older python versions

* Clean-up imports

- Fix py2/py3 range/zip behavior
  - Ensure same functions being used
- Fix Exception/System.Exception name clashes

* Fix nameclash object

* Refactor utility functions

* Rename tests

* Refactor assertRaises

test_exceptions: Add exc_info test & fix Exception nameclash

* Format for pep8 and linters

Fix max min nameclash

* Fix tests comparison to None, True, False, isinstance

- Replace type(()) with tuple to clarify intent

* Rename test fixtures

Can mess with test discovery

* Remove unused `using` from testing and format

* Use unittest.skip(...)

* Cleanup testing format

* XML Docs on test fixtures

* Update CHANGELOG

* Implement Py.SetArgv.

* Add a `Py.Throw` function.

Checks whether an error occurred and in case it has throws a
PythonException.

* Add overload for Initialize to pass specific args.

* Allow the engine to be initialized as a Disposable.

* Use Py.Throw in a few more places.

In particular in Py.Import.

* Add PY3.7 to travis with allow_failure

* Format & Whitespace

*.cs linelength 120
Allman

* Update CHANGELOG

* Change applicable comments to xml-docs

* Update API website on docs & fix section headers

Runtime.cs section headers got changed to docs.

* Alias root.pyHandle to py_clr_module

* Syntax cleanup

* Simple classes cleanup (pythonnet#348)

* Standarize properties used across projects

Console had it owns set of properties going on

* Add pyproj from @denfromufa

Corrected the configs, won't interfere with users without PTVS

* Consolidate output paths

http://stackoverflow.com/questions/30191387/what-are-the-consequences-of-setting-same-output-path-for-all-configurations

* Fix clrmodule config mismapping

* Add PY3 project/sln configs

* Update test PyImport path

Changed when consolidate output paths

* Update runtime.csproj

* Documentation clean-up

* Downgrade to nunit2

* Syntax cleanup

* Update CHANGELOG

* Clarify pynetinit.c, runtime build directives

pynetinit.c:
Clarifiy its intent is for PY3

runtime.cs
Remove unnecessary check for System.Text
Simplifies import section

* Whitespace converter.cs

* Propercase AssemblyInfo

* Refactor nativemethods

* Rename `is32bit` to `Is32Bit` for naming consistency

* Replace UCS2/UCS4 build directive with Runtime.UCS

* Add IsPython2 and IsPython3

* Cleanup runtime config

* Remove extra properties/Organize properties

* Refactor property conditions

* Order Runtime.csproj configuration

To make it easier to verify everything is setup correctly
Simplified the Mono.Unix include condition

* Add pylong lost unit test

Wasn't being referenced in the project

* Replace #if DEBUG with conditional attribute

* Fix and disable StrongNameSigning

It works better if they key is in the right folder and its being referenced when signing.
It breaks InternalsVisibleTo though, disabling till have time to look into it. (not that it was actually enabled)

* Fix debug statement & rename debugprint

* Document nPython/Console usage

Closes pythonnet#358

* Quiet Test Fixture build warnings about unused events.

They will be used (or attempted to be used) from Python.

* Mono dependency removed from Linux build.

* Remove mono dependency from PY2 as well.

* Replace bufLength with size

* Remove arch .il files

* Update CHANGELOG

* Remove Mono.Unix reference from project

Remove duplicate property in Python.Test

* Clean-up deprWarning

* Clean-up attribute names and paranthesis

* Use explicit accessors

* Clean-up code-style

Remove redundant parenthesis, enforce brackets, use keywork types.

* Remove obsoleted & Unenforced PermissionSet

See: http://stackoverflow.com/questions/11625447/securityaction-requestminimum-is-obsolete-in-net-4-0

* Add expire to license shield

Github Cache issue

github/markup#224

* Remove usage of #region

It hides away the code in Visual Studio

* Turn on NUNIT exit code

* Fix GC on PyObject during Finalizing

Similar to how `PythonDerivedType` finalizes.

Closes pythonnet#364
Possibly related to pythonnet#245

* Update CHANGELOG

* Add sys.args tests (pythonnet#301)

* Use NUnit from Nuget to ensure right version.

* Simplify Embedded tests & Add new tests (pythonnet#369)

* Add Tuple tests

* Update AppVeyor comments and show when tests start.

* Rename InitializeTest to pyinitialize

Keep consistent with other test classes.

* Simplify embed_tests

Since the previous bug involving initialize/finalize have been solved,
we can confidently upgrade these test to use simpler format.

Also Remove Assert fail messages
NUnit already says the name of which test failed.

* Add e-mail to remove setup.py warnings

* Update NUnit syntax

Use xUnit2 and nUnit3 friendly syntax

* Use string interpolation

Removed extra newline at beginning from deprecation warning message

* Replace PyString_FromStringAndSize usage to PyString_FromString

* Fix xml-docs build warnings

* Refactor AppVeyor/Travis embedded test_runner

Make it easier to diff and upgrade versions by
breaking into multiple lines and using path completion

Powershell continuation: http://stackoverflow.com/a/2608186/5208670
Powershell options splatting: http://stackoverflow.com/a/24313253/5208670

* Add pytest to CI

pytest on travis initially required `sudo=required` otherwise failed.
Without the sudo flag pytest wasn't being upgraded. Needed to force
upgrade.

pytest-dev/pytest#2240

* Convert unittest to pytest

Needs local imports to work.
Conversion done with unittests2pytests and a couple regex

* Add setup.cfg

Control settings for some add-ons like pytest

* Simpler tox

* Upgrade NUnit to 3.6

* Fix coverage w NUnit3; add OpenCover filter

NUnit3/OpenCover behavior changed.
Filter removes coverage from Embedded test files by
focusing only on types of Python.Runtime.*

* Remove check-manifest

* Add overload tests from pythonnet#131

* Refactor converter.cs & methodbind*.cs (pythonnet#375)

* Cleanup/Comment Python.Runtime.dll.config & travis

We don't need the `*.dll` variant since we don't call for those
in `runtime.cs`

Enable embedded tests on travis

* Add LD_LIBRARY_PATH to travis env

Find dlls for embedded tests on PY3

* Find dll for PY2 travis embedded tests

Copy Python.Runtime.dll.config to embedded tests bin output

* Generalize LD_LIBRARY_PATH

Avoid having to manually update python/travis versions

* Add GetPrecedence reference

* Use builtin miniconda

* Update version (pythonnet#379)

* Update setup.py

* Update clr.py

* StackOverflow/Slack shields (pythonnet#384)

Add StackExchange and Slack shields

Shields got too long for a single line, had to break them up into two lines.
One for build/quality status, the other for social/info.

Add regression number to disabled code.

* Slack integration for Travis and Appveyor (pythonnet#386)

* Add Slack integration for Travis

* Use encrypted string for Travis.

* Add hook for Appveyor.

* Simplify LD_LIBRARY_PATH on Travis

Based from: http://stackoverflow.com/a/24115039/5208670
Moved to own section to separate as a prep-enviroment step

* Rename NUnit vars to generic names

Makes it easier to switch test-runners in the future.
Note the if section is being skipped for NUnit3, but leaving it
in case needed to rollback to NUnit2, or upgrade to XUnit

* Remove python test STDERR redirect

Pytest doesn't need stderr redirect. It behaves

* Clean-up AppVeyor build recipe

Conda automatically updates when doing install. To disable its autoupdate add

    conda config --set auto_update_conda False

* Add requirements.txt and pytest options

Pytest options provide summary for skipped/xfailed tests
and adds color on appveyor

* Quiet sdist output & update comments on AppVeyor

* Add pytest header info & remove unused fixtures

Fixtures came from a different project and I forgot to delete them.
Add custom header to gather environment info with test results.

Remove testdir from pythonpath. pytest handles this on conftest.py

* Move Conda env to PowerShell recipe script

PY_VER removes the `.` it is used on appveyor_build_recipe.ps1

* Use Codecov report flags

Upgrade to Codecov v2.0.6, didn't get released to PyPi.

* Clean-up CI configs

* Update CHANGELOG

* Pass arbitrary .NET object as value of an attr of PyObject by dyn type(pythonnet#373)

* Add Coverity badge

* Clean-up CHANGELOG

* Standardize Python.Test fixture location

Ensures that Python.Test is output to same location on both Linux and Windows
as part of build.

.gitkeep to be ensure folder is part of version control.
Can be removed if any file is added to it.

* Add unittest for Overflow/across AppDomains Exceptions reproduction (pythonnet#393)

First exception shows issue from pythonnet#376

* Re-order Initialize tests

* Add documentation and ref to ReInitialize test

* Split and re-order TestPyTupleIsTupleType test

* Skip PyTuple test with AppDomain issue

This skip removes the issue from all PY3 on Travis/AppVeyor.
PY27 still has issue randomly on both Travis/AppVeyor x86, x64,.

* Clean-up embedded tests

Clean-up embedded tests comments and variable types

Remove TestFixture attribute. Optional since NUnit 2.5

https://nunit.org/index.php?p=testFixture&r=2.6.4

* Fix conda build log stderr->stdout

Recent conda-build update added a new log output to log:info.
Powershell interprets this as an ERROR since its on STDERR.

Prevent accidental auto-update & display INFO before building.
Would have made debugging this psudo-error easier.

* Quiet AppVeyor pip/nuget installs

Reduce verbosity to make relevant information easier to find.
Errors and Warnings are still displayed.

Travis doesn't need this since they have log folding.

* Allow private env:var to force conda build

To trigger conda build, just add/update private env:vars FORCE_CONDA_BUILD
on link below. Easier to debug and no need to edit appveyor yml/ps1

https://ci.appveyor.com/project/USER_NAME/pythonnet/settings/environment

* Update AUTHORS

Add names to a few more contributors

* Rename TearDown to Dispose

Easier for future possible migration to other frameworks

* Relocate Embedded tests fixtures

Each test type should contain its own fixtures.
Reduces weird dependency of each testing framework

* Update LICENSE year & include in recipe

* Update conda-recipe version

Get it from recipe file instead of git-tag.

* Add SharedAssemblyInfo & Update Assembly version

Reset version back down to v2.x from v4.0.0.2

See link below for Semanctic Versioning & .NET
https://codingforsmarties.wordpress.com/2016/01/21/how-to-version-assemblies-destined-for-nuget/

* Add .bumpversion

Configuration based from gh:bumpversion:issues:77#issuecomment-130696156

Usage:
bumpversion major -> increases major and adds `dev` if not present
bumpversion minor -> increases minor and adds `dev` if not present
bumpversion release -> drop the `dev` portion

* Add object overload test

* Add object type to methodbind

* Add more object overload method tests

* Update CHANGELOG

* Enable embedded_tests to Travis w. conditional filters

Add conditional class skip to pytuple for Travis/PY27
Add individual filters to other tests as needed

https://www.amido.com/code/conditional-ignore-nunit-and-the-ability-to-conditionally-ignore-a-test/
http://stackoverflow.com/a/16075029/5208670

* Split blank DefineConstants on `*.csproj`

Visual Studio by default wants to split these.
Any time the csproj is update (new test for example) it splits them.
Splitting them now to not worry about them when reviewing pull_requests.

* Update CHANGELOG

* Fix PythonException GC (pythonnet#400)

Since PythonException doesn't inherit from PyObject, need to reapply
the same fix as from gh:365.

Seen mostly on PY27/Travis on PyTuple tests.
Enable PyTuple tests for PY27/Travis

* Add Eval(...) and Exec(...)

* Keep RunString Public. Fix Assert.AreEqual order

-  Deprecation/Removal should be a separate issue/pr
-  In NUnit/XUnit, expected is the first argument, actual is second. Opposite to how Python does it

* Update CHANGELOG

* Clarify MashalAs on runtime.cs

- Shorten MarshalAsAttribute name
- Put MashalAs'ed argument on own-line
- Flip IF comparison

* Fix runtime Initialize dll nameclash

Looks like dllLocal never changes from IntPtr.Zero

* Update test_sysargv

Previous version didn't test correctly

* Fix the issue of sys.argv being cleared on import clr.

Closes pythonnet#404.

* improve tests.pyproj for intellisense and running tests (pythonnet#395)

* Update tests.pyproj

* Update folder structure

After pytest folders were flatten.
Add code in fixture
Upstream PyImportTest was moved to within Embedded Tests
Add pyproj to editorconfig

* Add case-sensitivity tests

closes #81

* Added branching for ldd command in OSX (pythonnet#406)

* Minor style clean-up runtime/pythonengine

Add missing brackets
Organize using/remove unused
Align arguments

* Fix Py_Main/PySys_SetArgvEx(...) UCS4/PY3 no mem

Based on @dmitriyse work on:
dmitriyse@8a70f09

* Update CHANGELOG, remove extra MarshalAs

* Move PythonBuildDir when not defined

Keep root of solution clean
and out of the way from being imported because its on the `cwd`.

* Update ARCH check

Use sys for x86/x64  check

* Enable TestPyTupleInvalidAppend test

`AppDomain unload` was solved by pythonnet#400.
Closes pythonnet#397.

Possibly also solved pythonnet#245.

* Add tests/refactor existing

* Set language version to 6

Prevent accidental introduction of csharp 7 features.

* Add ICustomMarshaler StrMarshaler

Useful resources
https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler(v=vs.110).aspx
https://limbioliong.wordpress.com/2013/11/03/understanding-custom-marshaling-part-1/
https://github.com/mono/mono/blob/master/mcs/class/Mono.Posix/Mono.Unix/UnixMarshal.cs
http://stackoverflow.com/a/33514037/5208670

* Add ICustomMarshaler StrArrayMarshaler

* Refactor Marshals

* Add ICustomMarshaler Utf8Marshaler

Refactor PyString_FromStringAndSize
Link explains why `MarshalAs(UnmanagedType.LPWStr)` or `CharSet.Unicode` don't work

http://stackoverflow.com/a/25128147/5208670

* Match PyUnicode_AsUnicode signature in UCS2/UCS4

* Refactor GetManagedString

* Remove internal PyUnicode_AS_UNICODE

Its redundant with PyUnicode_AsUnicode now that the signature
is fixed between UCS2/UCS4.

Apply char conversion that work on both UCS2/UCS4

* Refactor Encoding check

This won't change during runtime.

* Remove ExactSpelling

Not needed as Python doesn't define character specific functions

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.exactspelling(v=vs.110).aspx

* Remove CharSet.Ansi

Its default charset used

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.charset(v=vs.110).aspx#Anchor_1

* Remove CharSet.Unicode where not needed

CharSet.Unicode is only needed when args are string type.

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.charset(v=vs.110).aspx

* Remove CallingConvention

* Rename Runtime field `dll` to `PythonDll`

Add remove full qualification

* Remove unneeded unsafe keyword

* Update CHANGELOG

* Add Runtime.CheckExceptionOccurred(...)

Helps refactor exceptions checks

* Replace Py.Throw with Runtime.CheckExceptionOccurred

* Whitespace clean-up Runtime

* Apply consistent name qualification to runtime.cs

* Unify PY3 UCS2/UCS4 unicode methods

CustomMarshal implementation deals w UCS2/4 differences

* Unify PY2 UCS2/UCS4 unicode methods

PyUnicodeEntryPoint is not used for PY3
since it was unified by PEP393.

It could be defined as "PyUnicode_" for PY3 and further unify the code
between PY2/PY3. Not implementing since not all PY3 methods exist in PY2

* Rename internal methods to proper Python API name

- PyUnicode_FromKindAndString to PyUnicode_FromKindAndData
- PyString_AS_STRING to PyString_AsString

* Fix PY27 dll mapping in Linux/macOS

On 5062377 this was fixed for PY3
but left unchanged for PY2.

On linux/macOS the library is aliased `python2.7` while in windows its `python 27`.
Since internally it wasn't mapped to the correct library in Linux/macOS, we had to
remap it again using the dll.config file.

Closes pythonnet#120

* Refactor runtime's dllBase

As long as the API doesn't change on new python minor releases,
all changes needed for new minor versions is isolated to a small
section of code.

* Style clean-up runtime.cs

* Temporary disable Codecov flags

Codecov added a limit of 20 uploads due to current on-going bug
https://docs.codecov.io/blog/week-8-2017

Also fixed flags casing, documentations says has to be lowercase.

* Fix test_multiple_calls_to_initialize

Exception check didn't upgrade syntax from unittests.
Didn't cause issues because test was passing.

* Fix PythonEngine.Version

Add TestPythonEngineProperties.
Ensure PythonEngine properties are working correctly.
Currently only work on 32bit machines.

Closes pythonnet#413

* Add PYTHONPATH/PYTHONHOME default value tests

Current tests crash on 64bit python on windows, and results
get truncated on Linux.

When working, PYTHONHOME should match ENV VAR if set.
AppVeyor has been updated to test against not blank

* Fix get PYTHONHOME/PYTHONPATH marshal

Unlike pythonnet#413, the return type changes between PY2/PY3.
Extended Custom Marshaler to convert IntPtr to Unicode String

* Rename internal StrMarshaler to UcsMarshaler

To clarify that this is meant to be applied on Unicode type IntPtr and not strings like ones.
Made Marshalers internal, don't see a reason to expose it.

* Unset PYTHONHOME in AppVeyor

Its messing with `conda` causing it to fail to start.
Tests in the `pr` pythonnet#415 make this unnecessary.

* Update conda

Update to using conda based on PY36.
Remove reference to deleted `dll.config` file

* Fix PythonEngine PYTHONHOME setter

Keep memory reference & fix PY3 marshal

* Fix set PythonPath, set ProgramName

Note on PythonPath. Its actually mapping to `Py_SetPath` which is
very different from PYTHONPATH env var. There is no test on it
because it should be set to real paths with libraries. Otherwise it
crashes.

2nd Note. `Py_SetPath` doesn't exist on PY27.

* Deprecate public RunString

Had to remove defaults to disambiguate call on `internal RunString`.
Can re-add after removing `public RunString`

Closes pythonnet#401

* Combine Py_DEBUG and PYTHON_WITH_PYDEBUG flags

They both refer to the PyDebug builds but were added at different times.

Closes pythonnet#362

* Remove PYTHON_WITH_WIDE_UNICODE flag

ABIFlags were introduced in PY32, and --with_wide_unicode was removed in PY33.

https://docs.python.org/3/whatsnew/3.3.html#functionality

Closes pythonnet#417

* Refactor PY2/PY3 Marshal in/out String/Unicode

* Refactor runtime.cs

* Fix Py_SetPath not available in PY2

Closes pythonnet#418

* Calculate Runtime fields before Initialization

* Add timing to detect slow tests on pytest

* Rename test classes/files

Make it easier to distinguish if editor tab refers to class or test.

* Add PyTuple Ctor tests

* Define and document Py_IncRef/Py_DecRef

* Add Tests

* Refactor Exception checking on tested classes

* Clean-up Embedded tests

* Add PyList tests

* Add test for pyscript global variable casting

Test for pythonnet#420

* Clean-up README.md example

* Fix typo in README

* Update CHANGELOG.md

* Bump version: 2.3.0.dev1 → 2.3.0 release

* Bump version: 2.3.0.→ 2.4.0.dev0

Can't start at dev1 as bumpversion breaks if we add a minimum start version for dev.

* Build conda recipe on new tags

Ensure that new binaries are generated for releases which are usually not from pull_requests.

Using APPVEYOR_REPO_TAG_NAME because yields shorter syntax
because it's undefined (ie false) when not a tag
and APPVEYOR_REPO_TAG has to be compared to lowercase `true` instead
of `True` like everything else.

Definitions:
APPVEYOR_REPO_TAG_NAME - contains tag name for builds started by tag; otherwise this variable is undefined;
APPVEYOR_REPO_TAG - true if build has started by pushed tag; otherwise false;

https://www.appveyor.com/docs/environment-variables/

* Fix numpy array and README example (pythonnet#427)

* Fix numpy array and README example

Generic Lists were falling through and being classified as `typecode.Object`
To solve this, adding a specific processing branch for `Generic Lists` only
to avoid breaking the changes from 471673a

Closes pythonnet#249

* Update syntax

* Msbuild15 patch (pythonnet#435)

* Update AUTHORS.md

* Update CHANGELOG.md

* Update setup.py

* Update bld.bat

* Create .mention-bot

* WPF DynamicGrid python and XAML layout files (pythonnet#280)

* Support clr.GetClrType() - as in IronPython (pythonnet#433)

* Support clr.GetClrType() - as in IronPython

Implements pythonnet#432

* Tests for clr.GetClrType()

* clr.GetClrType test: ensure bad type raises ArgumentException

* clr.GetClrType - added xml doc comment, updated AUTHORS.md and CHANGELOG.md

* Simplified implementation of clr.GetClrType (taken from IronPython)

* Update .mention-bot

* Update .mention-bot

* Re-add CallingConvention

Closes pythonnet#448

* Allow passing None for nullable args (pythonnet#460)

* Updated CHANGELOG and AUTHORS (pythonnet#462)

* Fixing Travis CI for mono 5.0 (pythonnet#471)

* Fixing setup.py with mono 5.0

* Go back to xbuild

* Trying to figure out the error cause. Apparently xbuild cannot process the Copy section of the pdb file in the projects.

I have commented them out for now, but this is not a real soltion since they are needed in debug versions. Just to se if it fixes the CI.

* Implement named arguments and With semantics in C# embedding side (pythonnet#461)

* Added python "with" construction

* Added some unit tests for new With method

* Renamed With tests for easier grouping

* Support for named arguments to invoke python methods

* Named argument tests cosmetic changed

* Fixed failing test in python 2.7

* Reset line endings in csproj to LF

* Implements Decimal and Datetime support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants