Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python collections are not iterable as Java Collections #260

Closed
wdobler opened this issue Mar 20, 2022 · 6 comments
Closed

Python collections are not iterable as Java Collections #260

wdobler opened this issue Mar 20, 2022 · 6 comments

Comments

@wdobler
Copy link

wdobler commented Mar 20, 2022

In graal-22.0.0.2, there is some mismatch between Python collection types and
Java Collections and Iterables.

A Java method that expects a Collection argument cannot iterate over that
argument when it is a Python list or set.
A Java method that expects an Iterable works fine:

from java.org.wd import Log4JConfigurator

from typing import List, Set

loggers_list: List[str] = ["stdout", "file"]
loggers_set: Set[str] = set(loggers_list)


# Works: Python list as Java List
Log4JConfigurator.setupLoggingList(loggers_list)

# Unsupported operation identifier 'iterator' and  object '{'stdout',
# 'file'}'(language: Python, type: set). Identifier is not executable or
# instantiable:
# Log4JConfigurator.setupLoggingSet(loggers_set)

# Unsupported operation identifier 'iterator' and  object '['stdout',
# 'file']'(language: Python, type: list). Identifier is not executable or
# instantiable:
# Log4JConfigurator.setupLoggingCollection(loggers_list)

# Unsupported operation identifier 'iterator' and  object '{'stdout',
# 'file'}'(language: Python, type: set). Identifier is not executable or
# instantiable:
# Log4JConfigurator.setupLoggingCollection(loggers_set)

# These work, too: Python list or set as Java Iterable:
Log4JConfigurator.setupLoggingIterable(loggers_list)
Log4JConfigurator.setupLoggingIterable(loggers_set)
package org.wd;

import java.util.Collection;
import java.util.List;
import java.util.Set;

public class Log4JConfigurator {

    public static void setupLoggingSet(Set<String> loggerNames) {
        System.out.println("setupLoggingSet:");
        for (String logger : loggerNames) {
            System.out.println("  " + logger);
        }
    }

    public static void setupLoggingList(List<String> loggerNames) {
        System.out.println("setupLoggingList:");
        for (String logger : loggerNames) {
            System.out.println("  " + logger);
        }
    }

    public static void setupLoggingCollection(Collection<String> loggerNames) {
        System.out.println("setupLoggingCollection:");
        for (String logger : loggerNames) {
            System.out.println("  " + logger);
        }
    }

    public static void setupLoggingIterable(Iterable<String> loggerNames) {
        System.out.println("setupLoggingIterable:");
        for (String logger : loggerNames) {
            System.out.println("  " + logger);
        }
    }
}

Given that Collection<T> implements Iterable<T>, iterating over arbitrary
Collections should be possible.

@wdobler wdobler changed the title Python collections are not recognized as Java Collections Python collections are not iterable as Java Collections Mar 20, 2022
@msimacek
Copy link
Contributor

Hi @wdobler, thank you for your interest in graalpython. It should indeed be possible to pass python collections to methods taking Collection and Set. The wrappers that make the mapping from Java to python objects are not part of graalpython, but they are provided by the Truffle framework we use for implementing interoperability. I created a request for the Truffle team to add the missing wrappers.

@wdobler
Copy link
Author

wdobler commented May 4, 2022

Thanks for the clarification.

If there is anything I can do myself, I'd be interested to know. Like

  • open an issue on the Truffle issue tracker (where would that be?)
  • playing with the Truffle source code myself (but I would need a pointer to know where to start)

@msimacek
Copy link
Contributor

msimacek commented May 4, 2022

I already opened an issue for Truffle internally. I was told that they plan to add a wrapper for Collection, so the example taking Collection would work. But Set is not on the roadmap yet, as there is no interop API for sets, there's nothing it can call on the python object to know if it's a set or not. If you want to hear that directly from Truffle developers, you can open an issue in graal repository.

If you wanted to play with the code yourself, I think a good starting point would be the PolyglotList class, that's the one handling the mapping from python (or other guest language) objects to Java List, you could use it as a reference for creating wrappers for other things.

@msimacek
Copy link
Contributor

msimacek commented Mar 4, 2024

Truffle added support for mapping Collection as part of oracle/graal@2c17ca6. However, there will be no support for Set since there is not interop set API, so there would be no way to map other operations than iteration.

@msimacek msimacek closed this as completed Mar 4, 2024
@rubyFeedback
Copy link

So I read about this just now due to the blog news here:

https://medium.com/graalvm/whats-new-in-truffle-and-graal-languages-40027a59c401

For instance:

"Improved Array Access. We added the ability to use Value#as(Collection.class) to map guest language arrays (Value#hasArrayElements()) to the Java Collection interface"

GraalVM has very helpful and useful documentation available at:

https://www.graalvm.org/latest/docs/

Do the docs also include one or two example in how to use that specifically? That is the (Value#hasArrayElements()).

I am just asking in the event no example covers that yet; if it is covered then please disregard my question here.

@msimacek
Copy link
Contributor

@rubyFeedback Truffle's javadoc documents the Value#as(Class) method. There is an example for List. Collection should work the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants