Skip to content

Commit

Permalink
Fix most of 0.7 depwarns
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed Sep 20, 2017
1 parent 0550f89 commit f9e1284
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 132 deletions.
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.5
Compat 0.27.0
Compat 0.32.0
Conda 0.2
MacroTools 0.3
165 changes: 82 additions & 83 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import Conda

immutable UseCondaPython <: Exception end

try # make sure deps.jl file is removed on error

#########################################################################

# Fix the environment for running `python`, and setts IO encoding to UTF-8.
Expand All @@ -36,7 +34,7 @@ function pythonenv(cmd::Cmd)
setenv(cmd, env)
end

pyvar(python::AbstractString, mod::AbstractString, var::AbstractString) = chomp(readstring(pythonenv(`$python -c "import $mod; print($mod.$var)"`)))
pyvar(python::AbstractString, mod::AbstractString, var::AbstractString) = chomp(read(pythonenv(`$python -c "import $mod; print($mod.$var)"`), String))

pyconfigvar(python::AbstractString, var::AbstractString) = pyvar(python, "distutils.sysconfig", "get_config_var('$var')")
pyconfigvar(python, var, default) = let v = pyconfigvar(python, var)
Expand Down Expand Up @@ -113,7 +111,7 @@ function find_libpython(python::AbstractString)
print(s, "\n\n")
end
println(STDERR, "---------------------------------- get_config_vars ---------------------------------------")
print(STDERR, readstring(`python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_vars())"`))
print(STDERR, read(`python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_vars())"`, String))
println(STDERR, "--------------------------------- directory contents -------------------------------------")
for libpath in libpaths
if isdir(libpath)
Expand Down Expand Up @@ -142,76 +140,6 @@ include("depsutils.jl")

#########################################################################

const python = try
let py = get(ENV, "PYTHON", isfile("PYTHON") ? readchomp("PYTHON") :
Compat.Sys.islinux() || Sys.ARCH (:i686, :x86_64) ? "python" : ""),
vers = isempty(py) ? v"0.0" : convert(VersionNumber, pyconfigvar(py,"VERSION","0.0"))
if vers < v"2.7"
if isempty(py)
throw(UseCondaPython())
else
error("Python version $vers < 2.7 is not supported")
end
end

# check word size of Python via sys.maxsize, since a common error
# on Windows is to link a 64-bit Julia to a 32-bit Python.
pywordsize = parse(UInt64, pysys(py, "maxsize")) > (UInt64(1)<<32) ? 64 : 32
if pywordsize != Sys.WORD_SIZE
error("$py is $(pywordsize)-bit, but Julia is $(Sys.WORD_SIZE)-bit")
end

py
end
catch e1
if Sys.ARCH in (:i686, :x86_64)
if isa(e1, UseCondaPython)
info("Using the Python distribution in the Conda package by default.\n",
"To use a different Python version, set ENV[\"PYTHON\"]=\"pythoncommand\" and re-run Pkg.build(\"PyCall\").")
else
info( "No system-wide Python was found; got the following error:\n",
"$e1\nusing the Python distribution in the Conda package")
end
abspath(Conda.PYTHONDIR, "python" * (Compat.Sys.iswindows() ? ".exe" : ""))
else
error("No system-wide Python was found; got the following error:\n",
"$e1")
end
end

use_conda = dirname(python) == abspath(Conda.PYTHONDIR)
if use_conda
Conda.add("numpy")
end

const (libpython, libpy_name) = find_libpython(python)
const programname = pysys(python, "executable")

# Get PYTHONHOME, either from the environment or from Python
# itself (if it is not in the environment or if we are using Conda)
PYTHONHOME = if !haskey(ENV, "PYTHONHOME") || use_conda
# PYTHONHOME tells python where to look for both pure python
# and binary modules. When it is set, it replaces both
# `prefix` and `exec_prefix` and we thus need to set it to
# both in case they differ. This is also what the
# documentation recommends. However, they are documented
# to always be the same on Windows, where it causes
# problems if we try to include both.
exec_prefix = pysys(python, "exec_prefix")
Compat.Sys.iswindows() ? exec_prefix : pysys(python, "prefix") * ":" * exec_prefix
else
ENV["PYTHONHOME"]
end

# cache the Python version as a Julia VersionNumber
const pyversion = VersionNumber(pyvar(python, "platform", "python_version()"))

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")
end

# A couple of key strings need to be stored as constants so that
# they persist throughout the life of the program. In Python 3,
# they need to be wchar_t* data.
Expand All @@ -221,15 +149,86 @@ wstringconst(s) = string("Base.cconvert(Cwstring, \"", escape_string(s), "\")")
# to prevent unnecessary recompilation and to minimize
# problems in the unlikely event of read-only directories.
function writeifchanged(filename, str)
if !isfile(filename) || readstring(filename) != str
if !isfile(filename) || read(filename, String) != str
info(abspath(filename), " has been updated")
write(filename, str)
else
info(abspath(filename), " has not changed")
end
end

writeifchanged("deps.jl", """
try # make sure deps.jl file is removed on error
python = try
let py = get(ENV, "PYTHON", isfile("PYTHON") ? readchomp("PYTHON") :
Compat.Sys.islinux() || Sys.ARCH (:i686, :x86_64) ? "python" : ""),
vers = isempty(py) ? v"0.0" : convert(VersionNumber, pyconfigvar(py,"VERSION","0.0"))
if vers < v"2.7"
if isempty(py)
throw(UseCondaPython())
else
error("Python version $vers < 2.7 is not supported")
end
end

# check word size of Python via sys.maxsize, since a common error
# on Windows is to link a 64-bit Julia to a 32-bit Python.
pywordsize = parse(UInt64, pysys(py, "maxsize")) > (UInt64(1)<<32) ? 64 : 32
if pywordsize != Sys.WORD_SIZE
error("$py is $(pywordsize)-bit, but Julia is $(Sys.WORD_SIZE)-bit")
end

py
end
catch e1
if Sys.ARCH in (:i686, :x86_64)
if isa(e1, UseCondaPython)
info("Using the Python distribution in the Conda package by default.\n",
"To use a different Python version, set ENV[\"PYTHON\"]=\"pythoncommand\" and re-run Pkg.build(\"PyCall\").")
else
info( "No system-wide Python was found; got the following error:\n",
"$e1\nusing the Python distribution in the Conda package")
end
abspath(Conda.PYTHONDIR, "python" * (Compat.Sys.iswindows() ? ".exe" : ""))
else
error("No system-wide Python was found; got the following error:\n",
"$e1")
end
end

use_conda = dirname(python) == abspath(Conda.PYTHONDIR)
if use_conda
Conda.add("numpy")
end

(libpython, libpy_name) = find_libpython(python)
programname = pysys(python, "executable")

# Get PYTHONHOME, either from the environment or from Python
# itself (if it is not in the environment or if we are using Conda)
PYTHONHOME = if !haskey(ENV, "PYTHONHOME") || use_conda
# PYTHONHOME tells python where to look for both pure python
# and binary modules. When it is set, it replaces both
# `prefix` and `exec_prefix` and we thus need to set it to
# both in case they differ. This is also what the
# documentation recommends. However, they are documented
# to always be the same on Windows, where it causes
# problems if we try to include both.
exec_prefix = pysys(python, "exec_prefix")
Compat.Sys.iswindows() ? exec_prefix : pysys(python, "prefix") * ":" * exec_prefix
else
ENV["PYTHONHOME"]
end

# cache the Python version as a Julia VersionNumber
pyversion = VersionNumber(pyvar(python, "platform", "python_version()"))

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")
end

writeifchanged("deps.jl", """
const python = "$(escape_string(python))"
const libpython = "$(escape_string(libpy_name))"
const pyprogramname = "$(escape_string(programname))"
Expand All @@ -242,16 +241,16 @@ writeifchanged("deps.jl", """
const conda = $use_conda
""")

# Make subsequent builds (e.g. Pkg.update) use the same Python by default:
writeifchanged("PYTHON", isfile(programname) ? programname : python)
# Make subsequent builds (e.g. Pkg.update) use the same Python by default:
writeifchanged("PYTHON", isfile(programname) ? programname : python)

#########################################################################
#########################################################################

catch

# remove deps.jl (if it exists) on an error, so that PyCall will
# not load until it is properly configured.
isfile("deps.jl") && rm("deps.jl")
rethrow()
# remove deps.jl (if it exists) on an error, so that PyCall will
# not load until it is properly configured.
isfile("deps.jl") && rm("deps.jl")
rethrow()

end
10 changes: 9 additions & 1 deletion src/PyCall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ end
pyimport(name::Symbol) = pyimport(string(name))

# convert expressions like :math or :(scipy.special) into module name strings
modulename(s::QuoteNode) = modulename(s.value)
modulename(s::Symbol) = string(s)
function modulename(e::Expr)
if e.head == :.
Expand Down Expand Up @@ -462,8 +463,15 @@ end
macro pyimport(name, optional_varname...)
mname = modulename(name)
Name = pyimport_name(name, optional_varname)
quoteName = Expr(:quote, Name)
# VERSION 0.7
@static if isdefined(Base, Symbol("@isdefined"))
isdef_check = :(isdefined($__module__, $quoteName))
else
isdef_check = :(isdefined($quoteName))
end
quote
if !isdefined($(Expr(:quote, Name)))
if !$isdef_check
const $(esc(Name)) = pywrap(pyimport($mname))
elseif !isa($(esc(Name)), Module)
error("@pyimport: ", $(Expr(:quote, Name)), " already defined")
Expand Down
10 changes: 5 additions & 5 deletions src/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,13 @@ function convert{K,V}(::Type{Dict{K,V}}, o::PyObject)
end

#########################################################################
# Range: integer ranges are converted to xrange,
# while other ranges (<: AbstractVector) are converted to lists
# AbstractRange: integer ranges are converted to xrange,
# while other ranges (<: AbstractVector) are converted to lists

xrange(start, stop, step) = pycall(pyxrange[], PyObject,
start, stop, step)

function PyObject{T<:Integer}(r::Range{T})
function PyObject{T<:Integer}(r::AbstractRange{T})
s = step(r)
f = first(r)
l = last(r) + s
Expand All @@ -583,7 +583,7 @@ function PyObject{T<:Integer}(r::Range{T})
end
end

function convert{T<:Range}(::Type{T}, o::PyObject)
function convert{T<:AbstractRange}(::Type{T}, o::PyObject)
v = PyVector(o)
len = length(v)
if len == 0
Expand Down Expand Up @@ -722,7 +722,7 @@ function pysequence_query(o::PyObject)
len = @pycheckz ccall((@pysym :PySequence_Size), Int, (PyPtr,), o)
return typetuple([pytype_query(PyObject(ccall((@pysym :PySequence_GetItem), PyPtr, (PyPtr,Int), o,i-1)), PyAny) for i = 1:len])
elseif pyisinstance(o, pyxrange[])
return Range
return AbstractRange
elseif ispybytearray(o)
return Vector{UInt8}
else
Expand Down
2 changes: 1 addition & 1 deletion src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function pyio_initialize()
String(read(pyio_jl(self), nb < 0 ? typemax(Int) : nb)) :
pybytes(read(pyio_jl(self), nb < 0 ? typemax(Int) : nb)))
readall(self) =
@with_ioraise(self[:istextio] ? readstring(pyio_jl(self)) :
@with_ioraise(self[:istextio] ? read(pyio_jl(self), String) :
pybytes(read(pyio_jl(self))))
readinto(self, b) = @with_ioraise(pybytes(readbytes!(pyio_jl(self), b)))
write(self, b) = @with_ioraise(write(pyio_jl(self), b))
Expand Down
2 changes: 1 addition & 1 deletion src/numpy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function npyinitialize()
# Parse __multiarray_api.h to obtain length and meaning of PyArray_API
try
hdrfile = open(joinpath(inc, "numpy", "__multiarray_api.h"))
hdr = readstring(hdrfile);
hdr = read(hdrfile, String)
close(hdrfile)
catch e
error("could not read __multiarray_api.h to parse PyArray_API ", e)
Expand Down
9 changes: 6 additions & 3 deletions src/pybuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ end
function pydecref(o::PyBuffer)
# note that PyBuffer_Release sets o.obj to NULL, and
# is a no-op if o.obj is already NULL
ccall(@pysym(:PyBuffer_Release), Void, (Ptr{PyBuffer},), &o)
# TODO change to `Ref{PyBuffer}` when 0.6 is dropped.
ccall(@pysym(:PyBuffer_Release), Void, (Any,), o)
o
end

Expand Down Expand Up @@ -85,9 +86,10 @@ function Base.stride(b::PyBuffer, d::Integer)
return Int(unsafe_load(b.buf.strides, d))
end

# TODO change to `Ref{PyBuffer}` when 0.6 is dropped.
iscontiguous(b::PyBuffer) =
1 == ccall((@pysym :PyBuffer_IsContiguous), Cint,
(Ptr{PyBuffer}, Cchar), &b, 'A')
(Any, Cchar), b, 'A')

#############################################################################
# pybuffer constant values from Include/object.h
Expand All @@ -105,8 +107,9 @@ const PyBUF_INDIRECT = convert(Cint, 0x0100) | PyBUF_STRIDES
# construct a PyBuffer from a PyObject, if possible
function PyBuffer(o::Union{PyObject,PyPtr}, flags=PyBUF_SIMPLE)
b = PyBuffer()
# TODO change to `Ref{PyBuffer}` when 0.6 is dropped.
@pycheckz ccall((@pysym :PyObject_GetBuffer), Cint,
(PyPtr, Ptr{PyBuffer}, Cint), o, &b, flags)
(PyPtr, Any, Cint), o, b, flags)
return b
end

Expand Down
2 changes: 1 addition & 1 deletion src/pyclass.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Multiple dispatch works, too:
"""
macro pydef(class_expr)
class_name, _, _ = parse_pydef_toplevel(class_expr)
:(const $(esc(class_name)) = @pydef_object($(esc(class_expr))))
esc(:(const $class_name = $PyCall.@pydef_object($class_expr)))
end

"""
Expand Down
22 changes: 13 additions & 9 deletions src/pyinit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ const pyxrange = Ref{PyPtr}(0)

#########################################################################

type EmptyStringList
x::Int32
ptr::Ptr{Int32}
function EmptyStringList()
obj = new(0)
obj.ptr = pointer_from_objref(obj)
return obj
end
end
Base.unsafe_convert(::Type{Ptr{UInt32}}, x::EmptyStringList) =
Ptr{UInt32}(pointer_from_objref(x) + fieldoffset(EmptyStringList, 2))

function __init__()
# issue #189
libpy_handle = libpython === nothing ? C_NULL :
Expand Down Expand Up @@ -87,15 +99,7 @@ function __init__()

if !already_inited
# some modules (e.g. IPython) expect sys.argv to be set
if pyversion.major < 3
argv_s = ""
argv = unsafe_convert(Ptr{UInt8}, argv_s)
ccall(@pysym(:PySys_SetArgvEx), Void, (Cint,Ptr{Ptr{UInt8}},Cint), 1, &argv, 0)
else
argv_s = Cwchar_t[0]
argv = unsafe_convert(Ptr{Cwchar_t}, argv_s)
ccall(@pysym(:PySys_SetArgvEx), Void, (Cint, Ptr{Ptr{Cwchar_t}}, Cint), 1, &argv, 0)
end
ccall(@pysym(:PySys_SetArgvEx), Void, (Cint, Ptr{UInt32}, Cint), 1, EmptyStringList(), 0)

# Some Python code checks sys.ps1 to see if it is running
# interactively, and refuses to be interactive otherwise.
Expand Down
4 changes: 2 additions & 2 deletions src/pyiterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ const jlWrapIteratorType = PyTypeObject()
function jlwrap_iterator(o::Any)
if jlWrapIteratorType.tp_name == C_NULL # lazily initialize
pyjlwrap_type!(jlWrapIteratorType, "PyCall.jlwrap_iterator") do t
t.tp_iter = cfunction(pyincref_, PyPtr, (PyPtr,)) # new reference to same object
t.tp_iternext = cfunction(pyjlwrap_iternext, PyPtr, (PyPtr,))
t.tp_iter = cfunction(pyincref_, PyPtr, Tuple{PyPtr}) # new reference to same object
t.tp_iternext = cfunction(pyjlwrap_iternext, PyPtr, Tuple{PyPtr})
end
end
return pyjlwrap_new(jlWrapIteratorType, (o, Ref(start(o))))
Expand Down
Loading

0 comments on commit f9e1284

Please sign in to comment.