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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to prevent default type translations #4689

Open
seanpk opened this issue Apr 12, 2024 · 4 comments
Open

Add option to prevent default type translations #4689

seanpk opened this issue Apr 12, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@seanpk
Copy link

seanpk commented Apr 12, 2024

馃殌 Feature

Add an option to runPython (and related functions) to NOT translate values back to JavaScript, but instead provide a PyProxy object.

Motivation

Some Python libraries make types based on enum and expect them as parameters. They do not accept the integer 3 when calling a function, but require that Foo.bar be provide.

Pitch

To solve this, I would like to be able to use runPython for a special case that doesn't do the type translation, e.g.:

const enumValue = pyodide.runPython(`
    import foo
    Foo.bar
  `, { skipTranslation: true })
pyproxyObjectThatTookALotOfWorkToCreate.magicFunction(enumValue)

Alternatives

Without this feature, I don't see how to call the function without moving (nearly) the whole algorithm into a runPython call.

@seanpk seanpk added the enhancement New feature or request label Apr 12, 2024
@hoodmane
Copy link
Member

hoodmane commented Apr 12, 2024

Does this work?

const enumValue = pyodide.runPython(`
   from pyodide.ffi import create_proxy
   create_proxy(Foo.bar)
`);

@seanpk
Copy link
Author

seanpk commented Apr 12, 2024

Unfortunately, no; it is still coming out as an integer. :-(

Looking closer at the library I'm calling, they have implemented a enum.IntEnum, which should be convertible to and from an integer value, and so I'm pretty sure the default behavior of pyodide would be OK. However, in the function I'm calling they're doing an isinstance test so I still need the actual enum object to make it work.

That said, I have found a workaround I think is OK:

const locals = {
  the_magic_object: pyproxyObjectThatTookALotOfWorkToCreate,
  the_enum_int_value: functionThatFiguresOutTheRightValue(),
  ...allTheOtherVarialblesNeededToCallTheFunction
}
const script = `
  from bar import foo
  foo_enum = Foo(the_enum_int_value)
  the_magic_object.magic_function(foo_enum, ...)
`
pyodide.runPython(script, { locals })

It still may be worthwhile being able to disable translations at times, but I'm not blocked until that is decided and figured out.

Thanks!

@hoodmane
Copy link
Member

hoodmane commented Apr 12, 2024

Seems to work for me.

const v = pyodide.runPython(`
   from pyodide.ffi import create_proxy
   from enum import Enum
   class A(Enum):
      v = 1

create_proxy(A.v, roundtrip=False)
`);
const  f = pyodide.runPython(`
   def f(x):
      print("x is A.v?", x is A.v)
   f
`);

f(v)

Prints x is A.v? True

@seanpk
Copy link
Author

seanpk commented Apr 12, 2024

I'll have to try again with the roundtrip=False option.

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

No branches or pull requests

2 participants