Mercurial > pytave
view @pyobject/subsasgn.m @ 365:087e7bc3697f
Do not automatically convert Python strings to Octave strings (fixes issue #65)
* python_to_octave.cc (pytave::pyobj_to_octvalue): Drop conversion of bytes and
unicode objects.
* __py_struct_from_dict__.cc (F__py_string_value__): New function.
* @pyobject/char.m: Define outside class definition, use __py_string_value__.
* @pyobject/pyobject.m: Delete previous pyobject.char definition.
* @pyobject/methods.m: Apply char conversion to __name__ attribute.
* @py/py.m, @pyobject/cell.m, @pyobject/dummy.m, @pyobject/subsasgn.m,
@pyobject/subsref.m, pyargs.m, pycall.cc, pyeval.cc: Adapt examples and tests
to changes.
author | Mike Miller <mtmiller@octave.org> |
---|---|
date | Thu, 25 Aug 2016 14:06:56 -0700 |
parents | fe6b9e618c98 |
children | 9d7188514f2c |
line wrap: on
line source
## Copyright (C) 2016 Colin B. Macdonald ## ## This file is part of Pytave. ## ## Pytave is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published ## by the Free Software Foundation; either version 3 of the License, ## or (at your option) any later version. ## ## This software is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty ## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ## the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public ## License along with this software; see the file COPYING. ## If not, see <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @documentencoding UTF-8 ## @defop Method @@pyobject subsasgn (@var{x}, @var{idx}, @var{rhs}) ## @defopx Operator @@pyobject {@var{x}.@var{property} =} {@var{rhs}} ## @defopx Operator @@pyobject {@var{x}@{@var{i}@} =} {@var{rhs}} ## @defopx Operator @@pyobject {@var{x}@{@var{i}, @var{j}, @dots{}@} =} {@var{rhs}} ## @defopx Operator @@pyobject {@var{x}@{@var{a}@} =} {@var{rhs}} ## Indexed assignment to Python objects. ## ## @seealso{@@pyobject/subsref} ## @end defop function r = subsasgn(x, idx, rhs) if (nargin != 3) print_usage (); endif ## If rhs is a pyobject but x is not, dispatch to the builtin subsasgn if (! isa (x, "pyobject")) r = builtin ("subsasgn", x, idx, rhs); return; endif switch idx.type case "." assert (ischar (idx.subs)) pycall ("setattr", x, idx.subs, rhs); r = x; case "{}" ## XXX: doesn't support slices or anything like that yet ## Subtract one from index: do this for lists, numpy arrays, etc pyexec ("import collections") pyexec ("import numpy") x_is_list = pycall (pyeval ( "lambda x: isinstance(x, (collections.Sequence, numpy.ndarray))"), x); for i = 1:length (idx.subs) j = idx.subs{i}; if (x_is_list && isindex (j) && isnumeric (j)) idx.subs{i} = cast (j, class (sizemax ())) - 1; endif endfor if (isscalar (idx.subs)) ind = idx.subs{1}; else ind = pycall ("tuple", idx.subs); endif xsi = pycall ("getattr", x, "__setitem__"); # x.__setitem__ pycall (xsi, ind, rhs); r = x; otherwise idx rhs error ("@pyobject/subsasgn: not implemented") endswitch endfunction %!test %! pyexec ("class MyClass: a = 1") %! t = pyeval ("MyClass()"); %! t.b = 6; %! assert (t.b, 6) %!test %! % list indexing %! L = pyeval ("[10., 20.]"); %! L{2} = "Octave"; %! assert (length (L) == 2) %! assert (L{1}, 10) %! assert (char (L{2}), "Octave") %!test %! % dict assignment, adding new keys %! d = pyeval ("dict()"); %! d{"a"} = 3; %! d{"b"} = 4; %! assert (d{"a"}, 3) %! assert (d{"b"}, 4) %!test %! % dict assignment, update existing key %! d = pyeval ("{'a':1}"); %! d{"a"} = 3; %! assert (d{"a"}, 3) %!test %! % dict assignment, other keys (e.g., Issue #10). %! d = pyeval ("dict()"); %! d{"5"} = 10; %! d{5.5} = 11; %! d{5} = 12; %! assert (d{"5"}, 10) %! assert (d{5.5}, 11) %! assert (d{5}, 12) %!test %! % 2D array indexing %! A = pyobject ([1.1 2 3; 4 5 6]); %! A{1, 1} = 10; %! A{1, 3} = 30; %! A{2, 1} = 40; %! assert (A{1, 1}, 10) %! assert (A{1, 3}, 30) %! assert (A{2, 1}, 40) %! assert (A{2, 2}, 5) ## Test of string key assignment, fails in the general case %!xtest %! d = pyobject (struct ()); %! d{"value"} = 1;