Skip to content

Array.CreateInstance(<type>, System.Int32[]) results in 'TypeError: No method matches given arguments' in v2.5.0 #1187

Closed

Description

@pkthong

Environment

  • Pythonnet version: 2.5.0
  • Python version: 3.6.9
  • Operating System: Windows 10

Details

  • Describe what you were trying to get done.

Array.CreateInstance for multi-dimensional arrays worked fine in v2.4.0. After upgrading to v2.5.0+, an error message gets thrown.

  • What commands did you run to trigger this issue?
import numpy as np
import ctypes
import clr, System
from System import Array, Int32
from System.Runtime.InteropServices import GCHandle, GCHandleType
import sys
import os


_MAP_NP_NET = {
    np.dtype('float32'): System.Single,
    np.dtype('float64'): System.Double,
    np.dtype('int8')   : System.SByte,
    np.dtype('int16')  : System.Int16,
    np.dtype('int32')  : System.Int32,
    np.dtype('int64')  : System.Int64,
    np.dtype('uint8')  : System.Byte,
    np.dtype('uint16') : System.UInt16,
    np.dtype('uint32') : System.UInt32,
    np.dtype('uint64') : System.UInt64,
    np.dtype('bool')   : System.Boolean,
}

def asNetArray(npArray):
    dims = npArray.shape
    dtype = npArray.dtype

    netDims = Array.CreateInstance(Int32, npArray.ndim)
    for I in range(npArray.ndim):
        netDims[I] = int(dims[I])

    if not npArray.flags.c_contiguous:
        npArray = npArray.copy(order='C')
    assert npArray.flags.c_contiguous

    try:
        netArray = Array.CreateInstance(_MAP_NP_NET[dtype], netDims)
    except KeyError:
        raise NotImplementedError("asNetArray does not yet support dtype {}".format(dtype))

    try: # Memmove
        destHandle = GCHandle.Alloc(netArray, GCHandleType.Pinned)
        sourcePtr = npArray.__array_interface__['data'][0]
        destPtr = destHandle.AddrOfPinnedObject().ToInt64()
        ctypes.memmove(destPtr, sourcePtr, npArray.nbytes)
    finally:
        if destHandle.IsAllocated: destHandle.Free()
    return netArray

if __name__ == '__main__':
    foo = np.full([1024,1024], 2.5, dtype=np.int32)

    netFoo = asNetArray( foo )
  • If there was a crash, please include the traceback here.
Traceback (most recent call last):
  File "pythonnetUtils.py", line 53, in <module>
    netFoo = asNetArray( foo )
  File "pythonnetUtils.py", line 37, in asNetArray
    netArray = Array.CreateInstance(_MAP_NP_NET[dtype], netDims)
TypeError: No method matches given arguments for CreateInstance: (<class 'CLR.CLR Metatype'>, <class 'System.Int32[]'>)

Activity

  1. changed the title [-]Array.CreateInstance(<type>, System.Int32[]) results in 'TypeError: No method matches given arguments[/-] [+]Array.CreateInstance(<type>, System.Int32[]) results in 'TypeError: No method matches given arguments' in v2.5.0[/+] on Jul 18, 2020
  2. lostmsu commented on Jul 18, 2020

    @lostmsu
    Member

    Hm, @pkthong can you double check your code? When I do str(Int32) in the latest build, I get <class 'System.Int32'>, not <class 'CLR.CLR Metatype'>.

  3. pkthong commented on Jul 21, 2020

    @pkthong
    Author

    Python 3.8.0 (default, Nov 6 2019, 16:00:02) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
    Type "help", "copyright", "credits" or "license" for more information.

    import clr, System
    print(type(System.Int32))
    <class 'CLR.CLR Metatype'>
    print(str(System.Int32))
    <class 'System.Int32'>
    print(clr._version_)
    3.0.0dev

    This at commit-ish (7a9dcfa )

  4. self-assigned this
    on Jul 21, 2020
  5. filmor commented on Jul 21, 2020

    @filmor
    Member

    Hmm, I'll give that a try locally. The "type" it lists there is correct for Python, CLR.CLR Metatype (awful name...) is the Python type for System.Type objects, but it seems like the method binding doesn't make that link anymore.

  6. pkthong commented on Jul 21, 2020

    @pkthong
    Author

    Running through the changes between v2.4.0 and v2.5.0, the last commit that works for the above test is (4a92d80)

  7. filmor commented on Jul 21, 2020

    @filmor
    Member

    Okay, then it's indeed #1106. That change actually improved things, in that it allows "proper" use of params arrays (like CreateInstance uses). You can fix your code by changing

        netArray = Array.CreateInstance(_MAP_NP_NET[dtype], netDims)
    

    to

        netArray = Array.CreateInstance(_MAP_NP_NET[dtype], *netDims)
    

    I'm not yet completely sure whether we want to fix it (we definitely want to keep the feature, maybe we can still allow the direct passing of the array as a fallback), but I acknowledge breakage :)

    /edit: Actually you can even drop the whole copy-to-.net part and replace it by

        netArray = Array.CreateInstance(_MAP_NP_NET[dtype], *npArray.shape)
    
  8. pkthong commented on Jul 21, 2020

    @pkthong
    Author

    The above suggestion seems to execute, yet accessing the array results in a System.AccessViolationException.

    To reproduce this, add the following to the test code.

    netFoo2 = Array.Copy(netFoo)
  9. robbmcleod commented on May 6, 2021

    @robbmcleod

    I've gone over my code snippet from before and made fixes similar to what @filmor suggested, although it needed an additional change to support complex data types. I put together a gist this time:

    https://gist.github.com/robbmcleod/73ca42da5984e6d0e5b6ad28bc4a504e

  10. lostmsu commented on Sep 16, 2022

    @lostmsu
    Member

    I believe this should be fixed in 3.0. Please reopen if not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions