From f8b83357e1fe1113b86135aa34b3eea99ef42b1f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 10 Aug 2026 00:09:42 +0200 Subject: [PATCH] Fixing strange behavior of user property generation with Python Problem was that integers are converted to "long long" in Python, which creates Variants rendering "#l1" as parsable strings. These are marked as invalid by the Syntax highlighter of the user properties editor. This patch fixes the user properties editor syntax highlighter to cover all Variant variants and uses "long" type for Variant if possible. --- src/gsi/gsi_test/gsiTest.cc | 4 +++- src/gsi/gsi_test/gsiTest.h | 5 +++++ src/layui/layui/syntax/ur_text.xml | 7 +++++-- src/pya/pya/pyaConvert.cc | 7 ++++++- testdata/python/basic.py | 18 ++++++++++++++++++ testdata/ruby/basic_testcore.rb | 20 ++++++++++++++++++++ 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/gsi/gsi_test/gsiTest.cc b/src/gsi/gsi_test/gsiTest.cc index 04fd26cd7..cc0386946 100644 --- a/src/gsi/gsi_test/gsiTest.cc +++ b/src/gsi/gsi_test/gsiTest.cc @@ -1278,7 +1278,9 @@ static gsi::Class decl_a ("", "A", gsi::method ("ft_str", &A::ft_str) + gsi::method ("ft_cv", &A::ft_cv) + gsi::method ("ft_cptr", &A::ft_cptr) + - gsi::method ("ft_var", &A::ft_var) + gsi::method ("ft_var", &A::ft_var) + + gsi::method ("var2s", &A::var2s) + + gsi::method ("ll_size", &A::ll_size) ); static gsi::Class decl_a_nc (decl_a, "", "A_NC"); diff --git a/src/gsi/gsi_test/gsiTest.h b/src/gsi/gsi_test/gsiTest.h index 310607393..519f7475b 100644 --- a/src/gsi/gsi_test/gsiTest.h +++ b/src/gsi/gsi_test/gsiTest.h @@ -419,6 +419,11 @@ struct A static int sp_i_get (); static void sp_i_set (int v); + // Variant to parsable string for Variant generation tests + static std::string var2s (const tl::Variant &v) { return v.to_parsable_string (); } + // platform specifics: length of "long long" + static size_t ll_size () { return sizeof (long long); } + // feed-through values for full cycle tests // (mainly for string encoding and binary strings) static std::string ft_str (const std::string &v) { return v; } diff --git a/src/layui/layui/syntax/ur_text.xml b/src/layui/layui/syntax/ur_text.xml index 5858a407f..b39ecda2f 100644 --- a/src/layui/layui/syntax/ur_text.xml +++ b/src/layui/layui/syntax/ur_text.xml @@ -13,7 +13,8 @@ - + + @@ -31,7 +32,8 @@ - + + @@ -77,6 +79,7 @@ + diff --git a/src/pya/pya/pyaConvert.cc b/src/pya/pya/pyaConvert.cc index 7d26b8eb8..badd2b791 100644 --- a/src/pya/pya/pyaConvert.cc +++ b/src/pya/pya/pyaConvert.cc @@ -270,7 +270,12 @@ tl::Variant python2c_func::operator() (PyObject *rval) } else if (PyBool_Check (rval)) { return tl::Variant (python2c (rval)); } else if (PyLong_Check (rval)) { - return tl::Variant (python2c (rval)); + long long ll = python2c (rval); + if (ll >= (long long) std::numeric_limits::min () && ll <= (long long) std::numeric_limits::max ()) { + return tl::Variant ((long) ll); + } else { + return tl::Variant (ll); + } #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check (rval)) { return tl::Variant (python2c (rval)); diff --git a/testdata/python/basic.py b/testdata/python/basic.py index 61a0f6db7..9a0c95cb0 100644 --- a/testdata/python/basic.py +++ b/testdata/python/basic.py @@ -3209,6 +3209,24 @@ class BasicTest(unittest.TestCase): self.assertEqual(pya.A.ba_to_ia(b'\x00\x01\x02'), [ 0, 1, 2 ]) + def test_variant_formation(self): + + self.assertEqual(pya.A.var2s(1.5), "##1.5") + self.assertEqual(pya.A.var2s(-17), "#-17") + self.assertEqual(pya.A.var2s("abc"), "'abc'") + self.assertEqual(pya.A.var2s(None), "nil") + self.assertEqual(pya.A.var2s(True), "true") + self.assertEqual(pya.A.var2s(False), "false") + self.assertEqual(pya.A.var2s(pya.DBox(0, 0, 10, 20)), "[dbox:(0,0;10,20)]") + self.assertEqual(pya.A.var2s([ 0.5, "hello" ]), "(##0.5,'hello')") + self.assertEqual(pya.A.var2s(( 0.5, "hello" )), "(##0.5,'hello')") + self.assertEqual(pya.A.var2s([ 0.5, [ 1, 2 ] ]), "(##0.5,(#1,#2))") + self.assertEqual(pya.A.var2s({ 1: 'one', 'two': 17 }), "{#1=>'one','two'=>#17}") + if pya.A.ll_size() == 4: + self.assertEqual(pya.A.var2s(100000000000), "#l100000000000") + else: + self.assertEqual(pya.A.var2s(100000000000), "#100000000000") + # Tests multi-base mixins (only constants and enums available) def test_multiBaseMixins(self): diff --git a/testdata/ruby/basic_testcore.rb b/testdata/ruby/basic_testcore.rb index 7db26da8b..18696086c 100644 --- a/testdata/ruby/basic_testcore.rb +++ b/testdata/ruby/basic_testcore.rb @@ -3165,6 +3165,26 @@ class Basic_TestClass < TestBase end + def test_variant_formation + + assert_equal(RBA::A::var2s(1.5), "##1.5") + assert_equal(RBA::A::var2s(-17), "#-17") + assert_equal(RBA::A::var2s("abc"), "'abc'") + assert_equal(RBA::A::var2s(nil), "nil") + assert_equal(RBA::A::var2s(true), "true") + assert_equal(RBA::A::var2s(false), "false") + assert_equal(RBA::A::var2s(RBA::DBox::new(0, 0, 10, 20)), "[dbox:(0,0;10,20)]") + assert_equal(RBA::A::var2s([ 0.5, "hello" ]), "(##0.5,'hello')") + assert_equal(RBA::A::var2s([ 0.5, [ 1, 2 ] ]), "(##0.5,(#1,#2))") + assert_equal(RBA::A::var2s({ 1 => 'one', 'two' => 17 }), "{#1=>'one','two'=>#17}") + if RBA::A::ll_size == 4 + assert_equal(RBA::A::var2s(100000000000), "#l100000000000") + else + assert_equal(RBA::A::var2s(100000000000), "#100000000000") + end + + end + def test_optional if RBA::B.respond_to?(:int_to_optional)