Skip to content

Commit

Permalink
Implement the Starlark index expression assignment operation (#497)
Browse files Browse the repository at this point in the history
* CSL3-2071 CSL3-2108 - Case Insensitive headers test

* Failing test demonstrating issue with assignment of d["key"] = "one" throwing an exception.

The error message is: Error: can only assign an element in a dictionary or a list, not in a 'MutableStruct'. Let's make the tests pass!

* We introduce StarlarkSetIndexable to allow setIndex, similar to
StarlarkIndexable.

We follow the exact same interface and modifications for
StarlarkIndexable and update the error message to signify that we now
support setIndex on dictionaries, lists, and any implementation of
StarlarkSetIndexable. We also support the equivalent
StarlarkIndexable.Threaded interface for StarlarkSetIndexable,
similary called StarlarkSetIndexable.Threaded.

* Update tests to support usage pattern

* Update LarkyIndexable to support __setitem__ and implement the new StarlarkSetIndexable(.Threaded) interface

* And now, we do not need StarlarkMapping any longer since we can fulfill the exact same interface with LarkyMapping. Delete StarlarkMapping and move the functionality to LarkyMapping

* Fix incorrect test syntax -- there is no .size() in Python, only len(dict) for cardinality checks

* we do not have a base itemview class in larky, so we cannot compare classes to primitives in larky (as we would do in python). as a result, we have to return a raw list on the view instead of an actual view

* We make the final modification to get the test to pass!

---------

Co-authored-by: Sasha Kochniev <[email protected]>
  • Loading branch information
mahmoudimus and kochniev authored May 7, 2024
1 parent e9e4888 commit 676db64
Show file tree
Hide file tree
Showing 10 changed files with 533 additions and 453 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@

import com.google.common.collect.ImmutableList;

import com.verygood.security.larky.parser.StarlarkUtil;

import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkCallable;
import net.starlark.java.eval.StarlarkIndexable;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.StarlarkSetIndexable;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.syntax.TokenKind;


public interface LarkyIndexable extends LarkyObject, StarlarkIndexable.Threaded {
public interface LarkyIndexable extends LarkyObject, StarlarkSetIndexable.Threaded {

default Object get__setitem__() {
return getField(PyProtocols.__SETITEM__);
}

default Object get__getitem__() {
return getField(PyProtocols.__GETITEM__);
Expand All @@ -22,6 +28,17 @@ default Object get__contains__() {
return getField(PyProtocols.__CONTAINS__);
}

@Override
default void setIndex(StarlarkThread starlarkThread, StarlarkSemantics semantics, Object key, Object value) throws EvalException {
final Object __setitem__ = get__setitem__();
if(__setitem__ != null && StarlarkUtil.isCallable(__setitem__)) {
Starlark.checkHashable(key);
this.invoke(starlarkThread, __setitem__, ImmutableList.of(key, value), EMPTY_KWARGS);
return;
}
throw Starlark.errorf("TypeError: '%s' object does not support item assignment", typeName());
}

@Override
default Object getIndex(StarlarkThread starlarkThread, StarlarkSemantics semantics, Object key) throws EvalException {
// The __getitem__ magic method is usually used for list indexing, dictionary lookup, or
Expand Down
Loading

0 comments on commit 676db64

Please sign in to comment.