Skip to content

Commit e4035b8

Browse files
carstenbauerstevengj
authored andcommitted
WIP: override get/setproperty and propertynames (#517)
* switch to 0.7/1.0 properties * still support 0.6 * adjust runtests * updated tests * test fix (0.6) * modified tests * added getindex and haskey deprectations; fixed some internal warnings * starequal in pynothing comparisons * separate depwarns for getindex * fix tests introduced in #594 * fixing deprecations... * fixing deprecations again... * fixed all deprecation warnings * deprecate setindex! and fix warnings etc * first (insufficient) modification of README
1 parent b5b458c commit e4035b8

18 files changed

+266
-219
lines changed

README.md

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ without copying them.
1818
## Installation
1919

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

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

141141
@pywith pybuiltin("open")("file.txt","w") as f begin
142-
f[:write]("hello")
142+
f.write("hello")
143143
end
144144

145145
The type of `f` can be specified with `f::T` (for example, to override automatic
@@ -162,18 +162,13 @@ example, using [Biopython](http://biopython.org/wiki/Seq) we can do:
162162
@pyimport Bio.Seq as s
163163
@pyimport Bio.Alphabet as a
164164
my_dna = s.Seq("AGTACACTGGT", a.generic_dna)
165-
my_dna[:find]("ACT")
166-
167-
whereas in Python the last step would have been `my_dna.find("ACT")`.
165+
my_dna.find("ACT")
168166

169167
## Troubleshooting
170168

171169
Here are solutions to some common problems:
172170

173-
* As mentioned above, use `foo[:bar]` and `foo[:bar](...)` rather than `foo.bar` and `foo.bar(...)`,
174-
respectively, to access attributes and methods of Python objects.
175-
176-
* 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"]), "")`.
171+
* 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"), "")`.
177172

178173
## Python object interfaces
179174

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

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

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

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

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

383378
Occasionally, you may need to pass a keyword argument to Python that
@@ -411,15 +406,15 @@ For instance,
411406
@pyimport numpy.polynomial as P
412407
@pydef mutable struct Doubler <: P.Polynomial
413408
function __init__(self, x=10)
414-
self[:x] = x
409+
self.x = x
415410
end
416411
my_method(self, arg1::Number) = arg1 + 20
417-
x2.get(self) = self[:x] * 2
412+
x2.get(self) = self.x * 2
418413
function x2.set!(self, new_val)
419-
self[:x] = new_val / 2
414+
self.x = new_val / 2
420415
end
421416
end
422-
Doubler()[:x2]
417+
Doubler().x2
423418

424419
is essentially equivalent to the following Python code:
425420

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

451446
@pydef mutable struct SampleApp <: tk.Tk
452447
__init__(self, args...; kwargs...) = begin
453-
tk.Tk[:__init__](self, args...; kwargs...)
454-
self[:label] = tk.Label(text="Hello, world!")
455-
self[:label][:pack](padx=10, pady=10)
448+
tk.Tk.__init__(self, args...; kwargs...)
449+
self.label = tk.Label(text="Hello, world!")
450+
self.label.pack(padx=10, pady=10)
456451
end
457452
end
458453

459454
app = SampleApp()
460-
app[:mainloop]()
455+
app.mainloop()
461456

462457
Class variables are also supported:
463458

464459
using PyCall
465460
@pydef mutable struct ObjectCounter
466461
obj_count = 0 # Class variable
467462
function __init__(::PyObject)
468-
ObjectCounter[:obj_count] += 1
463+
ObjectCounter.obj_count += 1
469464
end
470465
end
471466

benchmarks/pywrapfn.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ end
99

1010
function PyWrapFn(o::Union{PyObject, PyPtr}, nargs::Int, returntype::Type=PyObject)
1111
pyargsptr = ccall((@pysym :PyTuple_New), PyPtr, (Int,), nargs)
12-
ret = PyNULL()
13-
optr = o isa PyPtr ? o : o.o
14-
pyincref_(optr)
15-
return PyWrapFn{nargs, returntype}(optr, pyargsptr, ret)
12+
return PyWrapFn{nargs, returntype}(pyincref_(PyPtr(o)), pyargsptr, PyNULL())
1613
end
1714

1815
(pf::PyWrapFn{N, RT})(args...) where {N, RT} =

0 commit comments

Comments
 (0)