Skip to content

Draft: support slicing pyobjects

Vipul Cariappa requested to merge Vipul-Cariappa/octave-pythonic:slicing into main
  • fix breaking tests
  • Add test cases

This MR tries to implement something similar to #11. Therefore is not MATLAB compatibility. This also raises the question of whether I should continue implementing this?

What problem I am trying to solve?

In Python, a class object can define __call__ and __getitem__/__setitem__ special methods. If a class implements __call__, then that Python instance can be called like any other callable or function. The __getitem__/__setitem__ functions are used to index into a Python object.

If a Python class defines both __call__ and __getitem__/__setitem__ special methods, then there is no means to separately use both of the functionality from Octave. This implementation tries to fix that.

In this implementation, I am using idx.type to deduce which operation to perform. If idx.type is () then, the object is assumed to be a callable and will be called (i.e. executed), if idx.type is {} then, the object will be indexed into (or sliced).


Example:

Python code used:

# myclass.py

class MyClass:
    def __call__(self, *args, **kwargs):
        print(f"From Python: called MyClass.__call__ \n\t{args = },\t{kwargs = }")

    def __getitem__(self, index):
        print(f"From Python: called MyClass.__getitem__ with {index}")

    def __setitem__(self, index, value):
        print(f"From Python: called MyClass.__setitem__ with {index} = {value}")

    def __len__(self):
        return 0

This MR's behaviour:

octave:1> o = py.myclass.MyClass ()
o = [Python object of type myclass.MyClass]

  <myclass.MyClass object at 0x7fa4bc190c10>

octave:2> o(1, 2, 3)
From Python: called MyClass.__call__ 
        args = (1.0, 2.0, 3.0), kwargs = {}
octave:3> o{1, 2, 3}
From Python: called MyClass.__getitem__ with 
        (1.0, 2.0, 3.0)
octave:4> o{1, 2, 3} = 4
From Python: called MyClass.__setitem__ with 
        (1.0, 2.0, 3.0) = 4.0
o = [Python object of type myclass.MyClass]

  <myclass.MyClass object at 0x7fa4bc190c10>

MATLAB's (version R2022b) behavior:

>> o = py.myclass.MyClass ()

o = 

  Python MyClass with no properties.

    <myclass.MyClass object at 0x000002166B707FA0>

>> o(1, 2, 3)
From Python: called MyClass.__call__ 
	args = (1.0, 2.0, 3.0),	kwargs = {}
>> o{1, 2, 3}
Error using indexing
Brace indexing is not supported for variables of this type.
 
>> o{1, 2, 3} = 4
Unable to perform assignment because brace indexing is not supported for variables of this type.
Edited by Vipul Cariappa

Merge request reports