Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/aot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,20 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Setup python
uses: actions/setup-python@v1
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- run: python --version
- run: python -m pip install --user numpy
- name: Install libpython2.7 for `find_libpython` test
run: sudo apt-get install python2.7-dev
if: ${{ matrix.python-version != '2.7' && matrix.os == 'ubuntu-latest' }}
- name: Setup julia
uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.julia-version }}
arch: ${{ matrix.architecture }}
show-versioninfo: true

- run: julia -e 'using Pkg; pkg"add PackageCompiler@v1"'
- run: julia -e 'using Pkg; pkg"add PackageCompiler"'

- run: aot/compile.jl
- run: aot/assert_has_pycall.jl
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ jobs:
${{ matrix.os }} ${{ matrix.architecture }}
steps:
- uses: actions/checkout@v1
- name: Install libpython2.7 for `find_libpython` test
run: sudo apt-get install python2.7-dev
if: ${{ matrix.python-version != '2.7' && matrix.os == 'ubuntu-latest' }}
- name: Setup julia
uses: julia-actions/setup-julia@v1
with:
Expand Down
52 changes: 30 additions & 22 deletions .github/workflows/system.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,29 @@ jobs:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
architecture: [x64]
python-version: ['3.x']
julia-version:
- '1'
- 'nightly'
include:
- os: macos-latest
architecture: arm64
python-version: '3.x'
julia-version: '1'
- os: macos-latest
architecture: arm64
python-version: '3.x'
julia-version: 'nightly'
- os: macos-latest
architecture: x64 # agent is arm64 (runs under Rosetta)
python-version: '3.x'
julia-version: '1'
- os: macos-latest
architecture: x64 # agent is arm64 (runs under Rosetta)
python-version: '3.x'
julia-version: 'nightly'
# 32 bit Windows:
- os: windows-latest
architecture: x86
Expand All @@ -31,7 +46,7 @@ jobs:
# Sweep python-version and julia-version only on Ubuntu:
- os: ubuntu-latest
architecture: x64
python-version: '3.9'
python-version: '3.10'
julia-version: '1'
- os: ubuntu-latest
architecture: x64
Expand All @@ -41,16 +56,6 @@ jobs:
architecture: x64
python-version: '3.x'
julia-version: '1.4'
# Test Python 2.7 only with a few combinations (TODO: drop 2.7).
# Note that it does not work in macOS:
- os: ubuntu-latest
architecture: x64
python-version: '2.7'
julia-version: '1'
- os: windows-2019
architecture: x64
python-version: '2.7'
julia-version: '1'
fail-fast: false
name: Test
Julia ${{ matrix.julia-version }}
Expand All @@ -59,20 +64,23 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Setup python
uses: actions/setup-python@v1
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- run: python -m pip install --user numpy
- run: python -m pip install virtualenv
# virtualenv test with Python 2.7 is failing for some reason.
# Skipping it for now.
if: ${{ matrix.python-version != '2.7' }}
- name: Install numpy
run: python -m pip install --user numpy
if: ${{ !(matrix.os == 'macos-latest' && matrix.architecture == 'x64') }}
- name: Install numpy (Rosetta)
run: arch -x86_64 python -m pip install --user numpy
if: ${{ matrix.os == 'macos-latest' && matrix.architecture == 'x64' }}
- name: Install virtualenv
run: python -m pip install virtualenv
if: ${{ !(matrix.os == 'macos-latest' && matrix.architecture == 'x64') }}
- name: Install virtualenv (Rosetta)
run: arch -x86_64 python -m pip install virtualenv
if: ${{ matrix.os == 'macos-latest' && matrix.architecture == 'x64' }}
- run: virtualenv --version
if: ${{ matrix.python-version != '2.7' }}
- name: Install libpython2.7 for `find_libpython` test
run: sudo apt-get install python2.7-dev
if: ${{ matrix.python-version != '2.7' && matrix.os == 'ubuntu-latest' }}
- name: Setup julia
uses: julia-actions/setup-julia@v1
with:
Expand Down
8 changes: 4 additions & 4 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ try # make sure deps.jl file is removed on error
(Sys.isunix() && !Sys.isapple()) ?
whichfirst("python3", "python") : "Conda"),
vers = isempty(py) || py == "Conda" ? v"0.0" : vparse(pyconfigvar(py,"VERSION","0.0"))
if vers < v"2.7"
if vers < v"3.3"
if isempty(py) || py == "Conda"
throw(UseCondaPython())
else
error("Python version $vers < 2.7 is not supported")
error("Python version $vers < 3.3 is not supported")
end
end

Expand Down Expand Up @@ -95,8 +95,8 @@ try # make sure deps.jl file is removed on error

@info "PyCall is using $python (Python $pyversion) at $programname, libpython = $libpy_name"

if pyversion < v"2.7"
error("Python 2.7 or later is required for PyCall")
if pyversion < v"3.3"
error("Python 3.3 or later is required for PyCall")
end

writeifchanged("deps.jl", """
Expand Down
23 changes: 3 additions & 20 deletions src/PyCall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -867,23 +867,9 @@ append!(a::PyObject, items::PyObject) =
PyObject(@pycheckn ccall((@pysym :PySequence_InPlaceConcat),
PyPtr, (PyPtr, PyPtr), a, items))

if pyversion >= v"3.3"
function empty!(o::PyObject)
pydecref(pycall(o."clear", PyObject)) # list.clear() was added in 3.3
return o
end
else
function empty!(o::PyObject)
p = _getproperty(o, "clear")
if p != C_NULL # for dict, set, etc.
pydecref(pycall(PyObject(o)."clear", PyObject))
else
for i = length(o)-1:-1:0
delete!(o, i)
end
end
return o
end
function empty!(o::PyObject)
pydecref(pycall(o."clear", PyObject)) # list.clear() was added in 3.3
return o
end

#########################################################################
Expand Down Expand Up @@ -932,9 +918,6 @@ https://github.com/ipython/ipython/blob/5.9.0/IPython/utils/dir2.py
"""
function get_real_method(obj, name)
ispynull(obj) && return nothing
@static if pyversion < v"3"
pyisinstance(obj, @pyglobalobj :PyType_Type) && return nothing
end

canary = try
trygetproperty(obj, "_ipython_canary_method_should_not_exist_", nothing)
Expand Down
68 changes: 21 additions & 47 deletions src/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,10 @@

# conversions from Julia types to PyObject:

@static if pyversion < v"3"
PyObject(i::Unsigned) = PyObject(@pycheckn ccall(@pysym(:PyInt_FromSize_t),
PyPtr, (UInt,), i))
PyObject(i::Integer) = PyObject(@pycheckn ccall(@pysym(:PyInt_FromSsize_t),
PyPtr, (Int,), i))
else
PyObject(i::Unsigned) = PyObject(@pycheckn ccall(@pysym(:PyLong_FromUnsignedLongLong),
PyPtr, (Culonglong,), i))
PyObject(i::Integer) = PyObject(@pycheckn ccall(@pysym(:PyLong_FromLongLong),
PyPtr, (Clonglong,), i))
end
PyObject(i::Unsigned) = PyObject(@pycheckn ccall(@pysym(:PyLong_FromUnsignedLongLong),
PyPtr, (Culonglong,), i))
PyObject(i::Integer) = PyObject(@pycheckn ccall(@pysym(:PyLong_FromLongLong),
PyPtr, (Clonglong,), i))

PyObject(b::Bool) = PyObject(@pycheckn ccall((@pysym :PyBool_FromLong),
PyPtr, (Clong,), b))
Expand All @@ -31,25 +24,17 @@ PyObject(n::Nothing) = pyerr_check("PyObject(nothing)", pyincref(pynothing[]))

# conversions to Julia types from PyObject

@static if pyversion < v"3"
convert(::Type{T}, po::PyObject) where {T<:Integer} =
T(@pycheck ccall(@pysym(:PyInt_AsSsize_t), Int, (PyPtr,), po))
elseif pyversion < v"3.2"
convert(::Type{T}, po::PyObject) where {T<:Integer} =
T(@pycheck ccall(@pysym(:PyLong_AsLongLong), Clonglong, (PyPtr,), po))
else
function convert(::Type{T}, po::PyObject) where {T<:Integer}
overflow = Ref{Cint}()
val = T(@pycheck ccall(@pysym(:PyLong_AsLongLongAndOverflow), Clonglong, (PyPtr, Ref{Cint}), po, overflow))
iszero(overflow[]) || throw(InexactError(:convert, T, po))
return val
end
function convert(::Type{Integer}, po::PyObject)
overflow = Ref{Cint}()
val = @pycheck ccall(@pysym(:PyLong_AsLongLongAndOverflow), Clonglong, (PyPtr, Ref{Cint}), po, overflow)
iszero(overflow[]) || return convert(BigInt, po)
return val
end
function convert(::Type{T}, po::PyObject) where {T<:Integer}
overflow = Ref{Cint}()
val = T(@pycheck ccall(@pysym(:PyLong_AsLongLongAndOverflow), Clonglong, (PyPtr, Ref{Cint}), po, overflow))
iszero(overflow[]) || throw(InexactError(:convert, T, po))
return val
end
function convert(::Type{Integer}, po::PyObject)
overflow = Ref{Cint}()
val = @pycheck ccall(@pysym(:PyLong_AsLongLongAndOverflow), Clonglong, (PyPtr, Ref{Cint}), po, overflow)
iszero(overflow[]) || return convert(BigInt, po)
return val
end

convert(::Type{Bool}, po::PyObject) =
Expand Down Expand Up @@ -78,13 +63,9 @@ end

function PyObject(s::AbstractString)
sb = String(s)
if pyunicode_literals || !isascii(sb)
PyObject(@pycheckn ccall(@pysym(PyUnicode_DecodeUTF8),
PyPtr, (Ptr{UInt8}, Int, Ptr{UInt8}),
sb, sizeof(sb), C_NULL))
else
pybytes(sb)
end
PyObject(@pycheckn ccall(@pysym(PyUnicode_DecodeUTF8),
PyPtr, (Ptr{UInt8}, Int, Ptr{UInt8}),
sb, sizeof(sb), C_NULL))
end

const _ps_ptr= Ptr{UInt8}[C_NULL]
Expand Down Expand Up @@ -713,16 +694,9 @@ include("pydates.jl")
# A type-query function f(o::PyObject) returns the Julia type
# for use with the convert function, or Union{} if there isn't one.

@static if pyversion < v"3"
pyint_query(o::PyObject) = pyisinstance(o, @pyglobalobj :PyInt_Type) ?
(pyisinstance(o, @pyglobalobj :PyBool_Type) ? Bool : Int) :
pyisinstance(o, @pyglobalobj :PyLong_Type) ? BigInt :
pyisinstance(o, npy_integer) ? Int : Union{}
else
pyint_query(o::PyObject) = pyisinstance(o, @pyglobalobj :PyLong_Type) ?
(pyisinstance(o, @pyglobalobj :PyBool_Type) ? Bool : Integer) :
pyisinstance(o, npy_integer) ? Integer : Union{}
end
pyint_query(o::PyObject) = pyisinstance(o, @pyglobalobj :PyLong_Type) ?
(pyisinstance(o, @pyglobalobj :PyBool_Type) ? Bool : Integer) :
pyisinstance(o, npy_integer) ? Integer : Union{}

pyfloat_query(o::PyObject) = pyisinstance(o, @pyglobalobj :PyFloat_Type) || pyisinstance(o, npy_floating) ? Float64 : Union{}

Expand Down
2 changes: 1 addition & 1 deletion src/pyarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function copy(a::PyArray{T,N}) where {T,N}
# `Array`) otherwise we do a regular `copyto!`, such that A[I...] == a[I...]
A = Array{T}(undef, a.dims)
if a.f_contig
ccall(:memcpy, Cvoid, (Ptr{T}, Ptr{T}, Int), A, a, sizeof(T)*length(a))
ccall(:memcpy, Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), A, a, sizeof(T)*length(a))
else
copyto!(A, a)
end
Expand Down
7 changes: 0 additions & 7 deletions src/pyeval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ pynamespace(m::Module) =
return PyDict{String,PyObject,true}(pyincref(@pycheckn ccall((@pysym :PyModule_GetDict), PyPtr, (PyPtr,), pyimport("__main__"))))
else
ns = PyDict{String,PyObject}()
# In Python 2, it looks like `__builtin__` (w/o 's') must
# exist at module namespace. See also:
# http://mail.python.org/pipermail/python-dev/2001-April/014068.html
# https://github.com/ipython/ipython/blob/512d47340c09d184e20811ca46aaa2f862bcbafe/IPython/core/interactiveshell.py#L1295-L1299
if pyversion < v"3"
ns["__builtin__"] = builtin
end
# Following CPython implementation, we introduce
# `__builtins__` in the namespace. See:
# https://docs.python.org/2/library/__builtin__.html
Expand Down
5 changes: 1 addition & 4 deletions src/startup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,7 @@ else
end

# hashes changed from long to intptr_t in Python 3.2
const Py_hash_t = pyversion < v"3.2" ? Clong : Int

# whether to use unicode for strings by default, ala Python 3
const pyunicode_literals = pyversion >= v"3.0"
const Py_hash_t = Int

if libpython == nothing
macro pysym(func)
Expand Down
14 changes: 4 additions & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ end
pymodule_exists(s::AbstractString) = !ispynull(pyimport_e(s))

# default integer type for PyAny conversions
const PyInt = pyversion < v"3" ? Int : Clonglong
const PyInt = Clonglong

@testset "conversions" begin
# conversion of NumPy scalars before npy_initialized by array conversions (#481)
Expand Down Expand Up @@ -193,11 +193,7 @@ const PyInt = pyversion < v"3" ? Int : Clonglong
@test showable("text/html", py"Issue816()")
@test !showable("text/html", py"Issue816")
@test showable("text/html", py"CallableAsSpecialRepr()")
if PyCall.pyversion_build < v"3"
@test_broken showable("text/html", py"CallableAsSpecialRepr")
else
@test showable("text/html", py"CallableAsSpecialRepr")
end
@test showable("text/html", py"CallableAsSpecialRepr")
end

# in Python 3, we need a specific encoding to write strings or bufferize them
Expand Down Expand Up @@ -279,10 +275,8 @@ const PyInt = pyversion < v"3" ? Int : Clonglong
let i = BigInt(12345678901234567890), o = PyObject(i) # BigInt
@test o - i == 0
@test convert(BigInt, o) == i
if pyversion >= v"3.2"
@test PyAny(o) == i == convert(Integer, o)
@test_throws InexactError convert(Int64, o)
end
@test PyAny(o) == i == convert(Integer, o)
@test_throws InexactError convert(Int64, o)
end

# bigfloat conversion
Expand Down
Loading