mrkn / pycall.rb

Calling Python functions from the Ruby language
MIT License
1.05k stars 72 forks source link

Test failure on 3.12 #174

Closed jelly closed 3 months ago

jelly commented 5 months ago

On Python 3.12 the following test fails:

Failures:

  1) PyCall.eval without globals without locals raises an exception occurred in Python side
     Failure/Error: expect { PyCall.eval('raise Exception("abcdef")') }.to raise_error(PyCall::PyError, /abcdef/)

       expected PyCall::PyError with message matching /abcdef/, got #<PyCall::PyError: <class 'SyntaxError'>: invalid syntax (<string>, line 1)> with backtrace:
         # ./lib/pycall/pyobject_wrapper.rb:49:in `eval'
         # ./lib/pycall/pyobject_wrapper.rb:49:in `method_missing'
         # ./lib/pycall.rb:41:in `eval'
         # ./spec/pycall/eval_spec.rb:23:in `block (6 levels) in <top (required)>'
         # ./spec/pycall/eval_spec.rb:23:in `block (5 levels) in <top (required)>'
     # ./spec/pycall/eval_spec.rb:23:in `block (5 levels) in <top (required)>'

Finished in 2.86 seconds (files took 0.2082 seconds to load)
193 examples, 1 failure, 26 pending

Failed examples:

rspec ./spec/pycall/eval_spec.rb:22 # PyCall.eval without globals without locals raises an exception occurred in Python side

Which seems strange as it is valid Python:

Python 3.12.2 (main, Apr  3 2024, 09:31:13) [GCC 13.2.1 20230801] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> raise Exception("abcdef")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: abcdef
felixonmars commented 5 months ago

It seems SyntaxError gets less info on Python 3.12, compared to 3.11:

3.11.8:

> PyCall.eval('raise Exception("abcdef")')
/usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall/pyobject_wrapper.rb:49:in `eval': <class 'SyntaxError'>: ('invalid syntax', ('<string>', 1, 1, 'raise Exception("abcdef")', 1, 6)) (PyCall::PyError)
        from /usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall/pyobject_wrapper.rb:49:in `method_missing'
        from /usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall.rb:41:in `eval'
        from (irb):2:in `<main>'
        from /usr/lib/ruby/gems/3.0.0/gems/irb-1.4.2/exe/irb:11:in `<top (required)>'
        from /usr/bin/irb:25:in `load'
        from /usr/bin/irb:25:in `<main>'

3.12.2:

> PyCall.eval('raise Exception("abcdef")')
/usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall/pyobject_wrapper.rb:49:in `eval': <class 'SyntaxError'>: invalid syntax (<string>, line 1) (PyCall::PyError)
        from /usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall/pyobject_wrapper.rb:49:in `method_missing'
        from /usr/lib/ruby/gems/3.0.0/gems/pycall-1.5.1/lib/pycall.rb:41:in `eval'
        from (irb):2:in `<main>'
        from /usr/lib/ruby/gems/3.0.0/gems/irb-1.4.2/exe/irb:11:in `<top (required)>'
        from /usr/bin/irb:25:in `load'
        from /usr/bin/irb:25:in `<main>'

I'm not sure what caused the change, though.

felixonmars commented 5 months ago

Found one interesting difference:

3.11.8:

irb(main):102:1* begin
irb(main):103:1*   PyCall.eval('raise Exception("abcdef")')
irb(main):104:1* rescue => error
irb(main):105:1*   error.value
irb(main):106:0> end
=> ('invalid syntax', ('<string>', 1, 1, 'raise Exception("abcdef")', 1, 6))

error.value is a tuple.

3.12.2:

irb(main):064:1* begin
irb(main):065:1*   PyCall.eval('raise Exception("abcdef")')
irb(main):066:1* rescue => error
irb(main):067:1*   error.value
irb(main):068:0> end
=> SyntaxError('invalid syntax', ('<string>', 1, 1, 'raise Exception("abcdef")', 1, 6))

error.value is an Object.

This leads to the changes in https://github.com/python/cpython/pull/101607/files#diff-c37c836d0535b79d87b8eb0652c59ac0c2aeb1461bcb2274bee82656cecacad4L421-R475 which makes "value" the new internal exception PyObject instead.