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/builtin/tests/builtin.py b/builtin/tests/builtin.py index 9d0bff95..e88db3a0 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,29 @@ 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="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(): @@ -413,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 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 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"