1+ # Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+ #
4+ # The Universal Permissive License (UPL), Version 1.0
5+ #
6+ # Subject to the condition set forth below, permission is hereby granted to any
7+ # person obtaining a copy of this software, associated documentation and/or
8+ # data (collectively the "Software"), free of charge and under any and all
9+ # copyright rights in the Software, and any and all patent rights owned or
10+ # freely licensable by each licensor hereunder covering either (i) the
11+ # unmodified Software as contributed to or provided by such licensor, or (ii)
12+ # the Larger Works (as defined below), to deal in both
13+ #
14+ # (a) the Software, and
15+ #
16+ # (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+ # one is included with the Software each a "Larger Work" to which the Software
18+ # is contributed by such licensors),
19+ #
20+ # without restriction, including without limitation the rights to copy, create
21+ # derivative works of, display, perform, and distribute the Software and make,
22+ # use, sell, offer for sale, import, export, have made, and have sold the
23+ # Software and the Larger Work(s), and to sublicense the foregoing rights on
24+ # either these or other terms.
25+ #
26+ # This license is subject to the following condition:
27+ #
28+ # The above copyright notice and either this complete permission notice or at a
29+ # minimum a reference to the UPL must be included in all copies or substantial
30+ # portions of the Software.
31+ #
32+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+ # SOFTWARE.
39+
40+ import unittest
41+
42+
43+ class Polymorph :
44+ def __index__ (self ):
45+ return 42
46+ def __int__ (self ):
47+ return 1
48+ def __float__ (self ):
49+ return 3.14
50+ def __str__ (self ):
51+ return "hello"
52+ def __bytes__ (self ):
53+ return b"bytes"
54+
55+
56+ def test_formatting ():
57+ # tests some corner-cases that the standard tests do not cover
58+ assert format (- 12e8 , "0=30,.4f" ) == '-0,000,000,001,200,000,000.0000'
59+ assert b"%(mykey)d" % {b'mykey' : 42 } == b"42"
60+ assert b"%c" % b'q' == b"q"
61+ assert "%-5d" % 42 == "42 "
62+ assert "%.*f" % (- 2 , 2.5 ) == "2"
63+ assert "%.*f" % (True , 2.51 ) == "2.5"
64+ assert "%ld" % 42 == "42"
65+
66+ assert "%c" % Polymorph () == "*"
67+ assert "%d" % Polymorph () == "1"
68+ assert "%x" % Polymorph () == "2a"
69+ assert "%s" % Polymorph () == "hello"
70+ assert "%.2f" % Polymorph () == "3.14"
71+ assert b"%c" % Polymorph () == b"*"
72+ assert b"%s" % Polymorph () == b"bytes"
73+
74+ assert type (bytearray ("hello %d" , "ascii" ) % 42 ) == bytearray
75+ assert type (b"hello %d" % 42 ) == bytes
76+
77+
78+ def test_complex_formatting ():
79+ assert format (3 + 2j , ">20,.4f" ) == " 3.0000+2.0000j"
80+ assert format (3 + 2j , "+.2f" ) == "+3.00+2.00j"
81+ assert format (- 3 + 2j , "+.2f" ) == "-3.00+2.00j"
82+ assert format (3 + 2j , "-.3f" ) == "3.000+2.000j"
83+ assert format (3 - 2j , "-.3f" ) == "3.000-2.000j"
84+ assert format (- 3 - 2j , "-.3f" ) == "-3.000-2.000j"
85+ assert format (3 + 2j , " .1f" ) == " 3.0+2.0j"
86+ assert format (- 3 + 2j , " .1f" ) == "-3.0+2.0j"
87+ assert format (complex (3 ), ".1g" ) == "3+0j"
88+ assert format (3j , ".1g" ) == "0+3j"
89+ assert format (- 3j , ".1g" ) == "-0-3j"
90+ assert format (3j , "" ) == "3j"
91+ assert format (1 + 0j , "" ) == "(1+0j)"
92+ assert format (1 + 2j , "" ) == "(1+2j)"
93+ assert format (complex (1 , float ("NaN" )), "" ) == "(1+nanj)"
94+ assert format (complex (1 , float ("Inf" )), "" ) == "(1+infj)"
95+
96+
97+ class AnyRepr :
98+ def __init__ (self , val ):
99+ self .val = val
100+ def __repr__ (self ):
101+ return self .val
102+
103+
104+ def test_non_ascii_repr ():
105+ assert "%a" % AnyRepr ("\t " ) == "\t "
106+ assert "%a" % AnyRepr ("\\ " ) == "\\ "
107+ assert "%a" % AnyRepr ("\\ " ) == "\\ "
108+ assert "%a" % AnyRepr ("\u0378 " ) == "\\ u0378"
109+ assert "%r" % AnyRepr ("\u0378 " ) == "\u0378 "
110+ assert "%a" % AnyRepr ("\u0374 " ) == "\\ u0374"
111+ assert "%r" % AnyRepr ("\u0374 " ) == "\u0374 "
112+
113+ assert b"%a" % AnyRepr ("\t " ) == b"\t "
114+ assert b"%a" % AnyRepr ("\\ " ) == b"\\ "
115+ assert b"%a" % AnyRepr ("\\ " ) == b"\\ "
116+ assert b"%a" % AnyRepr ("\u0378 " ) == b"\\ u0378"
117+ assert b"%r" % AnyRepr ("\u0378 " ) == b"\\ u0378"
118+ assert b"%a" % AnyRepr ("\u0374 " ) == b"\\ u0374"
119+ assert b"%r" % AnyRepr ("\u0374 " ) == b"\\ u0374"
120+
121+
122+ class FormattingErrorsTest (unittest .TestCase ):
123+ def test_formatting_errors (self ):
124+ self .assertRaises (TypeError , lambda : format (- 12e8 , b"0=30,.4f" ))
125+ self .assertRaises (TypeError , lambda : format (42 , b"0=30,.4f" ))
126+ self .assertRaises (TypeError , lambda : format ("str" , b"0=30,.4f" ))
127+ self .assertRaises (TypeError , lambda : format (3 + 1j , b"0=30,.4f" ))
128+ self .assertRaises (TypeError , lambda : b"hello" % b"world" )
129+ self .assertRaises (TypeError , lambda : b"%f" % "str" )
130+ self .assertRaises (TypeError , lambda : b"%c" % "str" )
131+
132+ self .assertRaises (KeyError , lambda : b"%(mykey)d" % {"mykey" : 42 })
133+ self .assertRaises (KeyError , lambda : "%(mykey)d" % {b"mykey" : 42 })
134+ self .assertRaises (OverflowError , lambda : b"%c" % 260 )
135+
136+ self .assertRaises (ValueError , lambda : format (3 + 2j , "f=30,.4f" ))
137+ self .assertRaises (ValueError , lambda : format (3 + 2j , "0=30,.4f" ))
0 commit comments