From 3835a01350b385d7c2537e2744980bd75b159a88 Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Tue, 5 Nov 2019 15:05:48 +0100 Subject: [PATCH 1/4] builtin,vm: add implementation for builtin hex function --- builtin/builtin.go | 48 ++++++++++++++++++++++++++++++++++++++++++++- vm/tests/builtin.py | 14 +++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/builtin/builtin.go b/builtin/builtin.go index 145da84c..8f4ef674 100644 --- a/builtin/builtin.go +++ b/builtin/builtin.go @@ -41,7 +41,7 @@ func init() { py.MustNewMethod("globals", py.InternalMethodGlobals, 0, globals_doc), py.MustNewMethod("hasattr", builtin_hasattr, 0, hasattr_doc), // py.MustNewMethod("hash", builtin_hash, 0, hash_doc), - // py.MustNewMethod("hex", builtin_hex, 0, hex_doc), + py.MustNewMethod("hex", builtin_hex, 0, hex_doc), // py.MustNewMethod("id", builtin_id, 0, id_doc), // py.MustNewMethod("input", builtin_input, 0, input_doc), py.MustNewMethod("isinstance", builtin_isinstance, 0, isinstance_doc), @@ -826,6 +826,52 @@ object. The globals and locals are dictionaries, defaulting to the current globals and locals. If only globals is given, locals defaults to it.` +const hex_doc = `hex(number) -> string + +Return the hexadecimal representation of an integer. + + >>> hex(12648430) + '0xc0ffee' +` + +func builtin_hex(self, v py.Object) (py.Object, error) { + var ( + i int64 + err error + ) + switch v := v.(type) { + case *py.BigInt: + // test bigint first to make sure we correctly handle the case + // where int64 isn't large enough. + vv := (*big.Int)(v) + format := "%#x" + if vv.Cmp(big.NewInt(0)) == -1 { + format = "%+#x" + } + str := fmt.Sprintf(format, vv) + return py.String(str), nil + case py.IGoInt64: + i, err = v.GoInt64() + case py.IGoInt: + var vv int + vv, err = v.GoInt() + i = int64(vv) + default: + return nil, py.ExceptionNewf(py.TypeError, "'%s' object cannot be interpreted as an integer", v.Type().Name) + } + + if err != nil { + return nil, err + } + + format := "%#x" + if i < 0 { + format = "%+#x" + } + str := fmt.Sprintf(format, i) + return py.String(str), nil +} + const isinstance_doc = `isinstance(obj, class_or_tuple) -> bool Return whether an object is an instance of a class or of a subclass thereof. diff --git a/vm/tests/builtin.py b/vm/tests/builtin.py index 94f2e3a7..10bd1cf3 100644 --- a/vm/tests/builtin.py +++ b/vm/tests/builtin.py @@ -66,6 +66,20 @@ else: assert False, "SyntaxError not raised" +doc="hex" +assert True, hex( 0)=="0x0" +assert True, hex( 1)=="0x1" +assert True, hex(42)=="0x2a" +assert True, hex( -0)=="0x0" +assert True, hex( -1)=="-0x1" +assert True, hex(-42)=="-0x2a" +assert True, hex( 1<<64) == "0x10000000000000000" +assert True, hex(-1<<64) == "-0x10000000000000000" +assert True, hex( 1<<128) == "0x100000000000000000000000000000000" +assert True, hex(-1<<128) == "-0x100000000000000000000000000000000" +assertRaises(TypeError, hex, 10.0) ## TypeError: 'float' object cannot be interpreted as an integer +assertRaises(TypeError, hex, float(0)) ## TypeError: 'float' object cannot be interpreted as an integer + doc="isinstance" class A: pass From 33d8c20264eb18d74310f7ce2f898ac582d68a7b Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Wed, 6 Nov 2019 18:15:28 +0100 Subject: [PATCH 2/4] builtin,vm: fix builtin-hex test --- builtin/tests/builtin.py | 16 ++++++++++++++++ {vm => builtin}/tests/libtest.py | 0 vm/tests/builtin.py | 14 -------------- 3 files changed, 16 insertions(+), 14 deletions(-) rename {vm => builtin}/tests/libtest.py (100%) diff --git a/builtin/tests/builtin.py b/builtin/tests/builtin.py index 9d0bff95..0da974a2 100644 --- a/builtin/tests/builtin.py +++ b/builtin/tests/builtin.py @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. +from libtest import assertRaises + doc="abs" assert abs(0) == 0 assert abs(10) == 10 @@ -151,6 +153,20 @@ def func(p): ok = True assert ok, "ValueError not raised" +doc="hex" +assert hex( 0)=="0x0", "hex(0)" +assert hex( 1)=="0x1", "hex(1)" +assert hex(42)=="0x2a", "hex(42)" +assert hex( -0)=="0x0", "hex(-0)" +assert hex( -1)=="-0x1", "hex(-1)" +assert hex(-42)=="-0x2a", "hex(-42)" +assert hex( 1<<64) == "0x10000000000000000", "hex(1<<64)" +assert hex(-1<<64) == "-0x10000000000000000", "hex(-1<<64)" +assert hex( 1<<128) == "0x100000000000000000000000000000000", "hex(1<<128)" +assert hex(-1<<128) == "-0x100000000000000000000000000000000", "hex(-1<<128)" +assertRaises(TypeError, hex, 10.0) ## TypeError: 'float' object cannot be interpreted as an integer +assertRaises(TypeError, hex, float(0)) ## TypeError: 'float' object cannot be interpreted as an integer + doc="iter" cnt = 0 def f(): diff --git a/vm/tests/libtest.py b/builtin/tests/libtest.py similarity index 100% rename from vm/tests/libtest.py rename to builtin/tests/libtest.py diff --git a/vm/tests/builtin.py b/vm/tests/builtin.py index 10bd1cf3..94f2e3a7 100644 --- a/vm/tests/builtin.py +++ b/vm/tests/builtin.py @@ -66,20 +66,6 @@ else: assert False, "SyntaxError not raised" -doc="hex" -assert True, hex( 0)=="0x0" -assert True, hex( 1)=="0x1" -assert True, hex(42)=="0x2a" -assert True, hex( -0)=="0x0" -assert True, hex( -1)=="-0x1" -assert True, hex(-42)=="-0x2a" -assert True, hex( 1<<64) == "0x10000000000000000" -assert True, hex(-1<<64) == "-0x10000000000000000" -assert True, hex( 1<<128) == "0x100000000000000000000000000000000" -assert True, hex(-1<<128) == "-0x100000000000000000000000000000000" -assertRaises(TypeError, hex, 10.0) ## TypeError: 'float' object cannot be interpreted as an integer -assertRaises(TypeError, hex, float(0)) ## TypeError: 'float' object cannot be interpreted as an integer - doc="isinstance" class A: pass From f7829295203600ce2167dd4d6d1b5f9776ac1eed Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Wed, 6 Nov 2019 18:16:20 +0100 Subject: [PATCH 3/4] builtin,vm: fix builtin-isinstance test --- builtin/tests/builtin.py | 9 +++++++++ vm/tests/builtin.py | 10 ---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/builtin/tests/builtin.py b/builtin/tests/builtin.py index 0da974a2..e3055928 100644 --- a/builtin/tests/builtin.py +++ b/builtin/tests/builtin.py @@ -167,6 +167,15 @@ def func(p): assertRaises(TypeError, hex, 10.0) ## TypeError: 'float' object cannot be interpreted as an integer assertRaises(TypeError, hex, float(0)) ## TypeError: 'float' object cannot be interpreted as an integer +doc="isinstance" +class A: + pass +a = A() +assert isinstance(1, (str, tuple, int)) +assert isinstance(a, (str, (tuple, (A, )))) +assertRaises(TypeError, isinstance, 1, (A, ), "foo") +assertRaises(TypeError, isinstance, 1, [A, "foo"]) + doc="iter" cnt = 0 def f(): diff --git a/vm/tests/builtin.py b/vm/tests/builtin.py index 94f2e3a7..c50e1dd3 100644 --- a/vm/tests/builtin.py +++ b/vm/tests/builtin.py @@ -1,7 +1,6 @@ # Copyright 2018 The go-python Authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -from libtest import assertRaises doc="eval" assert eval("1+2") == 3 @@ -66,13 +65,4 @@ else: assert False, "SyntaxError not raised" -doc="isinstance" -class A: - pass -a = A() -assert True, isinstance(1, (str, tuple, int)) -assert True, isinstance(a, (str, (tuple, (A, )))) -assertRaises(TypeError, isinstance, 1, (A, ), "foo") -assertRaises(TypeError, isinstance, 1, [A, "foo"]) - doc="finished" From 5f10c9561e5f2a2a431a096bb1b4b03c20f31286 Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Wed, 6 Nov 2019 18:16:51 +0100 Subject: [PATCH 4/4] builtin: remove spurious printout --- builtin/tests/builtin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/builtin/tests/builtin.py b/builtin/tests/builtin.py index e3055928..e88db3a0 100644 --- a/builtin/tests/builtin.py +++ b/builtin/tests/builtin.py @@ -438,7 +438,6 @@ class C: pass try: zip(1,2,3) except TypeError as e: - print(e.args[0]) if e.args[0] != "zip argument #1 must support iteration": raise ok = True