diff --git a/Project.toml b/Project.toml index a8f07fed..5f71ff03 100644 --- a/Project.toml +++ b/Project.toml @@ -25,7 +25,8 @@ julia = "1" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Aqua", "Test"] +test = ["Aqua", "Random", "Test"] diff --git a/src/concrete/import.jl b/src/concrete/import.jl index 0d86f387..8d4af26e 100644 --- a/src/concrete/import.jl +++ b/src/concrete/import.jl @@ -13,3 +13,11 @@ pyimport((m,k)::Pair) = (m_=pyimport(m); k_=pygetattr(m_,k); pydel!(m_); k_) pyimport((m,ks)::Pair{<:Any,<:Tuple}) = (m_=pyimport(m); ks_=map(k->pygetattr(m_,k), ks); pydel!(m_); ks_) pyimport(m1, m2, ms...) = map(pyimport, (m1, m2, ms...)) export pyimport + +""" + pymoduleexists(m) + +Check if module `m` can be found, without actually importing it. +""" +pymoduleexists(m::AbstractString) = pyconvert(Bool, pyimport("importlib.util").find_spec(m) != Py(nothing)) +export pymoduleexists diff --git a/src/jlwrap/array.jl b/src/jlwrap/array.jl index bbbe6d67..cd693b6e 100644 --- a/src/jlwrap/array.jl +++ b/src/jlwrap/array.jl @@ -314,7 +314,7 @@ function init_jlwrap_array() @property def __array_interface__(self): return self._jl_callmethod($(pyjl_methodnum(pyjlarray_array_interface))) - def __array__(self): + def __array__(self, dtype=None): # convert to an array-like object arr = self if not (hasattr(arr, "__array_interface__") or hasattr(arr, "__array_struct__")): @@ -326,7 +326,7 @@ function init_jlwrap_array() # convert to a numpy array if numpy is available try: import numpy - arr = numpy.array(arr) + arr = numpy.array(arr, dtype=dtype) except ImportError: pass return arr diff --git a/test/concrete.jl b/test/concrete.jl index a7b68fb5..a4a53f97 100644 --- a/test/concrete.jl +++ b/test/concrete.jl @@ -1,4 +1,7 @@ @testset "import" begin + @test pymoduleexists("sys") + @test pymoduleexists("os") + @test !pymoduleexists(randstring(32)) sys = pyimport("sys") os = pyimport("os") @test pyeq(Bool, sys.__name__, "sys") diff --git a/test/jlwrap.jl b/test/jlwrap.jl index c4dd3dc7..89ebe348 100644 --- a/test/jlwrap.jl +++ b/test/jlwrap.jl @@ -5,3 +5,19 @@ x4 = pyconvert(Vector{Int}, x3) @test x1 == x4 end + +@testset "dtypes" begin + if !pymoduleexists("numpy") + PythonCall.C.CondaPkg.add("numpy") + end + np = pyimport("numpy"); + y = range(-5,5,length=11) + arr = np.asarray(y) + @test pyconvert(Int, arr.size) == 11 + @test pyconvert(String, arr.dtype.name) == "float64" + @test all(iszero.(pyconvert(Any, arr) .- y)) + arr32 = np.asarray(y, dtype=np.float32) + @test pyconvert(Int, arr32.size) == 11 + @test pyconvert(String, arr32.dtype.name) == "float32" + @test all(iszero.(pyconvert(Any, arr32) .- y)) +end diff --git a/test/runtests.jl b/test/runtests.jl index 8054e997..d0ef4092 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,4 @@ -using PythonCall, Test, Dates, Aqua +using PythonCall, Test, Dates, Random, Aqua # The unbound_args test fails on methods with signature like foo(::Type{Tuple{Vararg{V}}}) where V # Seems like a bug.