Mercurial > pytave
annotate @pyobject/pyobject.m @ 217:69abda471c67
Attempt at moving pyobject from octave to python
* @pyobject/pyobject.m: keep ref to __InOct__ in __main__
* pyeval: keep ref to __InOct__ in __main__
* @pyobject/dummy.m: add pycall doctest
* octave_to_python.cc: if we see pyobject, get original from __InOct__
author | Colin Macdonald <cbm@m.fsf.org> |
---|---|
date | Sat, 28 May 2016 10:18:39 -0700 |
parents | 3b2b7db7d709 |
children | 02da92723889 |
rev | line source |
---|---|
209 | 1 %% Copyright (C) 2016 Colin B. Macdonald |
2 %% | |
3 %% This file is part of PyTave. | |
4 %% | |
5 %% OctSymPy is free software; you can redistribute it and/or modify | |
6 %% it under the terms of the GNU General Public License as published | |
7 %% by the Free Software Foundation; either version 3 of the License, | |
8 %% or (at your option) any later version. | |
9 %% | |
10 %% This software is distributed in the hope that it will be useful, | |
11 %% but WITHOUT ANY WARRANTY; without even the implied warranty | |
12 %% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | |
13 %% the GNU General Public License for more details. | |
14 %% | |
15 %% You should have received a copy of the GNU General Public | |
16 %% License along with this software; see the file COPYING. | |
17 %% If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 %% -*- texinfo -*- | |
20 %% @documentencoding UTF-8 | |
21 %% @defun pyobject (@var{s}) | |
22 %% Wrap a Python object. | |
23 %% | |
24 %% TODO: where/how to document classdef classes? | |
25 %% | |
26 %% @seealso{pyexec, pyeval} | |
27 %% @end defun | |
28 | |
29 classdef pyobject < handle | |
30 properties | |
31 id | |
32 end | |
33 | |
34 methods(Static) | |
35 function x = fromPythonVarName(pyvarname) | |
36 % if @var{pyvarname} is a string, its assumed to be a variable | |
37 % name, e.g., previously created with pyexec. This must exist | |
38 % at the time of construction but it can disappear later (we | |
39 % will keep track of the reference). | |
40 if (~ ischar(pyvarname)) | |
41 error('pyobject: currently we only take variable names as input') | |
42 end | |
43 cmd = sprintf ([ ... | |
44 'if not ("__InOct__" in vars() or "__InOct__" in globals()):\n' ... | |
217
69abda471c67
Attempt at moving pyobject from octave to python
Colin Macdonald <cbm@m.fsf.org>
parents:
216
diff
changeset
|
45 ' __InOct__ = dict()\n' ... |
69abda471c67
Attempt at moving pyobject from octave to python
Colin Macdonald <cbm@m.fsf.org>
parents:
216
diff
changeset
|
46 ' # FIXME: make it accessible elsewhere?\n' ... |
69abda471c67
Attempt at moving pyobject from octave to python
Colin Macdonald <cbm@m.fsf.org>
parents:
216
diff
changeset
|
47 ' import __main__\n' ... |
69abda471c67
Attempt at moving pyobject from octave to python
Colin Macdonald <cbm@m.fsf.org>
parents:
216
diff
changeset
|
48 ' __main__.__InOct__ = __InOct__\n' ... |
209 | 49 '__InOct__[hex(id(%s))] = %s' ], ... |
50 pyvarname, pyvarname); | |
51 pyexec (cmd); | |
52 id = pyeval (['hex(id(' pyvarname '))']); | |
53 x = pyobject(id); | |
54 end | |
55 end | |
56 | |
57 | |
58 methods | |
59 function x = pyobject(id) | |
60 % warning: not intended for casual use: you must also insert | |
61 % the object into the Python `__InOct__` dict with key `id`. | |
62 x.id = id; | |
63 end | |
64 | |
65 function delete(x) | |
66 % called on clear of the last reference---for subclasses of | |
67 % handle; not called at all for "value classes". | |
68 % FIXME: #46497 this is never called! | |
69 %save('proof_of_delete', 6, x.id) | |
70 disp ('delete') | |
71 % throws KeyError if it wasn't in there for some reason | |
72 cmd = sprintf ('__InOct__.pop("%s")', x.id); | |
73 pyexec (cmd); | |
74 end | |
75 | |
76 function force_delete (x) | |
77 % Manual workaround for #46497: call right before @code{clear x}. But | |
78 % be careful, @code{x} needs to be the last reference: don't do this: | |
79 % @example | |
80 % d = pyobject (...); | |
81 % d2 = d; | |
82 % force_delete (d) | |
83 % clear d | |
84 % d2 | |
85 % @print{} ... KeyError ... | |
86 % @end example | |
87 delete(x) | |
88 end | |
89 | |
90 dummy (x) | |
216 | 91 display (x) |
209 | 92 |
93 function r = getid (x) | |
94 r = x.id; | |
95 end | |
96 | |
216 | 97 function varargout = disp(x) |
98 s = pyeval (sprintf ('str(__InOct__["%s"])', x.id)); | |
99 if (nargout == 0) | |
100 disp (s) | |
101 else | |
102 varargout = {s}; | |
103 end | |
209 | 104 end |
105 | |
106 function s = whatclass(x) | |
107 s = pyeval (sprintf ('str(__InOct__["%s"].__class__)', x.id)); | |
108 end | |
109 | |
110 function lst = whatmethods(x) | |
111 % filter the output of `dir(x)` | |
112 % properties only: | |
113 % [a for a in dir(x) if not callable(getattr(x, a)) and not a.startswith("__")] | |
114 cmd = sprintf ( ... | |
115 '[a for a in dir(__InOct__["%s"]) if not a.startswith("__")]', ... | |
116 x.id); | |
117 lst = pyeval (cmd); | |
118 end | |
119 | |
120 function r = subsref(x, idx) | |
121 s = ''; | |
122 for i=1:length(idx) | |
123 t = idx(i); | |
124 switch t.type | |
125 case '()' | |
126 if ( ! isempty (t.subs)) | |
127 t | |
128 error('not implemented: function calls with arguments') | |
129 end | |
130 s = sprintf ('%s()', s); | |
131 case '.' | |
132 assert(ischar(t.subs)) | |
133 s = sprintf ('%s.%s', s, t.subs); | |
134 otherwise | |
135 t | |
136 error('not implemented') | |
137 end | |
138 end | |
139 r = pyeval (sprintf ('__InOct__["%s"]%s', x.id, s)); | |
140 end | |
141 | |
213
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
142 function vargout = help(x) |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
143 idx = struct('type', '.', 'subs', '__doc__'); |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
144 s = subsref(x, idx); |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
145 if (nargout == 0) |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
146 disp(s) |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
147 else |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
148 vargout = {s}; |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
149 end |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
150 end |
a54ab59c491d
merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
Colin Macdonald <cbm@m.fsf.org>
parents:
209
diff
changeset
|
151 |
209 | 152 end |
153 end |