Skip to content
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

WIP: override get/setproperty and propertynames #517

Merged
merged 26 commits into from
Jan 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0ca66fd
switch to 0.7/1.0 properties
carstenbauer Oct 27, 2018
c51bd59
still support 0.6
carstenbauer Oct 27, 2018
2ebfa6a
adjust runtests
carstenbauer Oct 27, 2018
89da2c5
updated tests
carstenbauer Oct 31, 2018
da5f08e
test fix (0.6)
carstenbauer Oct 31, 2018
77736c8
modified tests
carstenbauer Oct 31, 2018
5fef94d
added getindex and haskey deprectations; fixed some internal warnings
carstenbauer Jan 20, 2019
bfd11e9
starequal in pynothing comparisons
carstenbauer Jan 20, 2019
a2a4394
separate depwarns for getindex
carstenbauer Jan 22, 2019
ac7b641
Merge commit 'ca792ed' into dotoverride
carstenbauer Jan 22, 2019
c58de0d
Merge commit '31296cd' into dotoverride
carstenbauer Jan 22, 2019
fd08cf9
Merge commit '48d730f' into dotoverride
carstenbauer Jan 22, 2019
2e6da51
Merge commit '8eb62f2' into dotoverride
carstenbauer Jan 22, 2019
c590d92
fix tests introduced in #594
carstenbauer Jan 22, 2019
ca2df13
Merge commit 'fe67ef2' into dotoverride
carstenbauer Jan 22, 2019
edb8778
Merge commit 'e74bf61' into dotoverride
carstenbauer Jan 22, 2019
a34eca5
Merge commit '1e0dce1' into dotoverride
carstenbauer Jan 22, 2019
10c88ea
Merge commit '1b0bbc0' into dotoverride
carstenbauer Jan 22, 2019
efde3b2
Merge commit '093342b' into dotoverride
carstenbauer Jan 22, 2019
3488c27
Merge commit '45cbcee' into dotoverride
carstenbauer Jan 22, 2019
114e222
Merge commit 'b5b458c' into dotoverride
carstenbauer Jan 22, 2019
27f6d10
fixing deprecations...
carstenbauer Jan 22, 2019
a90dce2
fixing deprecations again...
carstenbauer Jan 22, 2019
d7955de
fixed all deprecation warnings
carstenbauer Jan 22, 2019
52e9b13
deprecate setindex! and fix warnings etc
carstenbauer Jan 22, 2019
631bcb0
first (insufficient) modification of README
carstenbauer Jan 22, 2019
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
41 changes: 18 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ without copying them.
## Installation

Within Julia, just use the package manager to run `Pkg.add("PyCall")` to
install the files. Julia 0.7 or later is required.
install the files. Julia 0.7 or later is required.

The latest development version of PyCall is available from
<https://github.com/JuliaPy/PyCall.jl>. If you want to switch to
Expand Down Expand Up @@ -139,7 +139,7 @@ we could call the Newton solver in scipy.optimize via:
A macro exists for mimicking Python's "with statement". For example:

@pywith pybuiltin("open")("file.txt","w") as f begin
f[:write]("hello")
f.write("hello")
end

The type of `f` can be specified with `f::T` (for example, to override automatic
Expand All @@ -162,18 +162,13 @@ example, using [Biopython](http://biopython.org/wiki/Seq) we can do:
@pyimport Bio.Seq as s
@pyimport Bio.Alphabet as a
my_dna = s.Seq("AGTACACTGGT", a.generic_dna)
my_dna[:find]("ACT")

whereas in Python the last step would have been `my_dna.find("ACT")`.
my_dna.find("ACT")

## Troubleshooting

Here are solutions to some common problems:

* As mentioned above, use `foo[:bar]` and `foo[:bar](...)` rather than `foo.bar` and `foo.bar(...)`,
respectively, to access attributes and methods of Python objects.

* By default, PyCall [doesn't include the current directory in the Python search path](https://github.com/JuliaPy/PyCall.jl/issues/48). If you want to do that (in order to load a Python module from the current directory), just run `pushfirst!(PyVector(pyimport("sys")["path"]), "")`.
* By default, PyCall [doesn't include the current directory in the Python search path](https://github.com/JuliaPy/PyCall.jl/issues/48). If you want to do that (in order to load a Python module from the current directory), just run `pushfirst!(PyVector(pyimport("sys")."path"), "")`.

## Python object interfaces

Expand All @@ -199,9 +194,9 @@ dates/periods, and functions, along with tuples and arrays/lists
thereof, but more are planned. (Julia symbols are converted to Python
strings.)

Given `o::PyObject`, `o[:attribute]` is equivalent to `o.attribute`
Given `o::PyObject`, `o.attribute` in Julia is equivalent to `o.attribute`
in Python, with automatic type conversion. To get an attribute as a
`PyObject` without type conversion, do `o["attribute"]` instead.
`PyObject` without type conversion, do `o."attribute"` instead.
The `keys(o::PyObject)` function returns an array of the available
attribute symbols.

Expand Down Expand Up @@ -338,10 +333,10 @@ and also by providing more type information to the Julia compiler.

* `pyimport(s)`: Import the Python module `s` (a string or symbol) and
return a pointer to it (a `PyObject`). Functions or other symbols
in the module may then be looked up by `s[name]` where `name` is a
in the module may then be looked up by `s.name` where `name` is a
string (for the raw `PyObject`) or symbol (for automatic
type-conversion). Unlike the `@pyimport` macro, this does not
define a Julia module and members cannot be accessed with `s.name`.
define a Julia module.

* `py"..."` evaluates `"..."` as a Python string, equivalent to
Python's [`eval`](https://docs.python.org/2/library/functions.html#eval) function, and returns the result
Expand Down Expand Up @@ -377,7 +372,7 @@ and also by providing more type information to the Julia compiler.
instead use `w.pymember(:member)` (for the `PyAny` conversion) or
`w.pymember("member")` (for the raw `PyObject`). `pywrap` is rather
inefficient since it converts *every* member of `o` at once; you
are generally encouraged to simply access members via `o[:member]`
are generally encouraged to simply access members via `o.member`
rather than using `pywrap`.

Occasionally, you may need to pass a keyword argument to Python that
Expand Down Expand Up @@ -411,15 +406,15 @@ For instance,
@pyimport numpy.polynomial as P
@pydef mutable struct Doubler <: P.Polynomial
function __init__(self, x=10)
self[:x] = x
self.x = x
end
my_method(self, arg1::Number) = arg1 + 20
x2.get(self) = self[:x] * 2
x2.get(self) = self.x * 2
function x2.set!(self, new_val)
self[:x] = new_val / 2
self.x = new_val / 2
end
end
Doubler()[:x2]
Doubler().x2

is essentially equivalent to the following Python code:

Expand Down Expand Up @@ -450,22 +445,22 @@ Here's another example using [Tkinter](https://wiki.python.org/moin/TkInter):

@pydef mutable struct SampleApp <: tk.Tk
__init__(self, args...; kwargs...) = begin
tk.Tk[:__init__](self, args...; kwargs...)
self[:label] = tk.Label(text="Hello, world!")
self[:label][:pack](padx=10, pady=10)
tk.Tk.__init__(self, args...; kwargs...)
self.label = tk.Label(text="Hello, world!")
self.label.pack(padx=10, pady=10)
end
end

app = SampleApp()
app[:mainloop]()
app.mainloop()

Class variables are also supported:

using PyCall
@pydef mutable struct ObjectCounter
obj_count = 0 # Class variable
function __init__(::PyObject)
ObjectCounter[:obj_count] += 1
ObjectCounter.obj_count += 1
end
end

Expand Down
5 changes: 1 addition & 4 deletions benchmarks/pywrapfn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ end

function PyWrapFn(o::Union{PyObject, PyPtr}, nargs::Int, returntype::Type=PyObject)
pyargsptr = ccall((@pysym :PyTuple_New), PyPtr, (Int,), nargs)
ret = PyNULL()
optr = o isa PyPtr ? o : o.o
pyincref_(optr)
return PyWrapFn{nargs, returntype}(optr, pyargsptr, ret)
return PyWrapFn{nargs, returntype}(pyincref_(PyPtr(o)), pyargsptr, PyNULL())
end

(pf::PyWrapFn{N, RT})(args...) where {N, RT} =
Expand Down
Loading