Skip to content

Commit

Permalink
Merge pull request #1545 from KLayout/issue-1535
Browse files Browse the repository at this point in the history
Issue #1535 - calling str(x) implicitly in RBA and pya
  • Loading branch information
klayoutmatthias authored Nov 26, 2023
2 parents 6706e31 + ef9d73f commit 0e9849c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
21 changes: 19 additions & 2 deletions src/pya/pya/pyaMarshal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,26 @@ class PythonBasedStringAdaptor
{
public:
PythonBasedStringAdaptor (const PythonPtr &string)
: m_stdstr (python2c<std::string> (string.get ())), m_string (string)
: m_string (string)
{
// .. nothing yet ..
#if PY_MAJOR_VERSION < 3
if (PyString_Check (string.get ())) {
m_stdstr = python2c<std::string> (string.get ());
} else
#else
if (PyBytes_Check (string.get ())) {
m_stdstr = python2c<std::string> (string.get ());
} else
#endif
if (PyUnicode_Check (string.get ()) || PyByteArray_Check (string.get ())) {
m_stdstr = python2c<std::string> (string.get ());
} else {
// use object protocol to get the string through str(...)
PythonRef as_str (PyObject_Str (string.get ()));
if (as_str) {
m_stdstr = python2c<std::string> (as_str.get ());
}
}
}

virtual const char *c_str () const
Expand Down
2 changes: 1 addition & 1 deletion src/rba/rba/rbaMarshal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class RubyBasedStringAdaptor
public:
RubyBasedStringAdaptor (VALUE value)
{
m_string = rba_safe_string_value (value);
m_string = rba_safe_obj_as_string (value);
gc_lock_object (m_string);
}

Expand Down
16 changes: 9 additions & 7 deletions testdata/python/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
# Set this to True to disable some tests involving exceptions
leak_check = "TEST_LEAK_CHECK" in os.environ

class ObjectWithStr:
def __init__(self, s):
self.s = s
def __str__(self):
return self.s

# see test_21
class AEXT(pya.A):
def __init__(self):
Expand Down Expand Up @@ -191,6 +197,7 @@ def test_00(self):
self.assertEqual( a.a1(), -0x80000000 )

self.assertEqual( a.a3("a"), 1 )
self.assertEqual( a.a3(ObjectWithStr("abcde")), 5 ) # implicitly using to_s for string conversion
self.assertEqual( a.a3("ab"), 2 )
self.assertEqual( a.a3("µ"), 2 ) # two UTF8 bytes
if "a3_qstr" in a.__dict__:
Expand Down Expand Up @@ -2279,13 +2286,8 @@ def test_41(self):
self.assertEqual(b.map1_cptr_null() == None, True);
self.assertEqual(b.map1_ptr_null() == None, True);

try:
# error converting 1 or True to string
b.map1 = { 42: 1, -17: True }
error_caught = False
except:
error_caught = True
self.assertEqual(error_caught, True)
b.map1 = { 42: 1, -17: True }
self.assertEqual(map2str(b.map1), "{-17: True, 42: 1}")

b.map1 = { 42: "1", -17: "True" }
self.assertEqual(map2str(b.map1), "{-17: True, 42: 1}")
Expand Down
30 changes: 17 additions & 13 deletions testdata/ruby/basic_testcore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
# safe in multiple inclusions
require File.expand_path('../basic_testcore_defs', __FILE__)


class ObjectWithStr

def initialize(s)
@s = s
end

def to_s
@s
end

end

class Basic_TestClass < TestBase

def test_FIRST
Expand Down Expand Up @@ -85,6 +98,7 @@ def test_FIRST
assert_equal( a.a1, -0x80000000 )

assert_equal( a.a3("a"), 1 )
assert_equal( a.a3(ObjectWithStr::new("abcde")), 5 ) # implicitly using to_s for string conversion
assert_equal( a.a3("ab"), 2 )
assert_equal( a.a3("µ"), 2 ) # two UTF8 bytes
if a.respond_to?(:a3_qstr)
Expand Down Expand Up @@ -2198,19 +2212,9 @@ def test_41
assert_equal(b.map1_cptr_null == nil, true);
assert_equal(b.map1_ptr_null == nil, true);

begin
b.map1 = { 42 => 1, -17 => true }
error = nil
rescue => ex
error = ex.message.split("\n")[0]
end
if error == "can't convert Fixnum into String"
# Ok
elsif error == "no implicit conversion of Fixnum into String" || error == "no implicit conversion of Integer into String"
# Ok
else
assert_equal(error, "")
end
b.map1 = { 42 => 1, -17 => true }
assert_equal(b.map1.inspect, "{-17=>\"true\", 42=>\"1\"}")

b.map1 = { 42 => "1", -17 => "true" }
assert_equal(b.map1.inspect, "{-17=>\"true\", 42=>\"1\"}")

Expand Down

0 comments on commit 0e9849c

Please sign in to comment.