Home | History | Annotate | Download | only in test
      1 import unittest
      2 from test import test_support
      3 from _testcapi import getargs_keywords
      4 import warnings
      5 
      6 """
      7 > How about the following counterproposal. This also changes some of
      8 > the other format codes to be a little more regular.
      9 >
     10 > Code C type Range check
     11 >
     12 > b unsigned char 0..UCHAR_MAX
     13 > h signed short SHRT_MIN..SHRT_MAX
     14 > B unsigned char none **
     15 > H unsigned short none **
     16 > k * unsigned long none
     17 > I * unsigned int 0..UINT_MAX
     18 
     19 
     20 > i int INT_MIN..INT_MAX
     21 > l long LONG_MIN..LONG_MAX
     22 
     23 > K * unsigned long long none
     24 > L long long LLONG_MIN..LLONG_MAX
     25 
     26 > Notes:
     27 >
     28 > * New format codes.
     29 >
     30 > ** Changed from previous "range-and-a-half" to "none"; the
     31 > range-and-a-half checking wasn't particularly useful.
     32 
     33 Plus a C API or two, e.g. PyInt_AsLongMask() ->
     34 unsigned long and PyInt_AsLongLongMask() -> unsigned
     35 long long (if that exists).
     36 """
     37 
     38 LARGE = 0x7FFFFFFF
     39 VERY_LARGE = 0xFF0000121212121212121242L
     40 
     41 from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
     42      INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
     43      SHRT_MIN, SHRT_MAX
     44 
     45 # fake, they are not defined in Python's header files
     46 LLONG_MAX = 2**63-1
     47 LLONG_MIN = -2**63
     48 ULLONG_MAX = 2**64-1
     49 
     50 class Long:
     51     def __int__(self):
     52         return 99L
     53 
     54 class Int:
     55     def __int__(self):
     56         return 99
     57 
     58 class Unsigned_TestCase(unittest.TestCase):
     59     def test_b(self):
     60         from _testcapi import getargs_b
     61         # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX)
     62         self.assertRaises(TypeError, getargs_b, 3.14)
     63         self.assertEqual(99, getargs_b(Long()))
     64         self.assertEqual(99, getargs_b(Int()))
     65 
     66         self.assertRaises(OverflowError, getargs_b, -1)
     67         self.assertEqual(0, getargs_b(0))
     68         self.assertEqual(UCHAR_MAX, getargs_b(UCHAR_MAX))
     69         self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1)
     70 
     71         self.assertEqual(42, getargs_b(42))
     72         self.assertEqual(42, getargs_b(42L))
     73         self.assertRaises(OverflowError, getargs_b, VERY_LARGE)
     74 
     75     def test_B(self):
     76         from _testcapi import getargs_B
     77         # B returns 'unsigned char', no range checking
     78         self.assertRaises(TypeError, getargs_B, 3.14)
     79         self.assertEqual(99, getargs_B(Long()))
     80         self.assertEqual(99, getargs_B(Int()))
     81 
     82         self.assertEqual(UCHAR_MAX, getargs_B(-1))
     83         self.assertEqual(UCHAR_MAX, getargs_B(-1L))
     84         self.assertEqual(0, getargs_B(0))
     85         self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX))
     86         self.assertEqual(0, getargs_B(UCHAR_MAX+1))
     87 
     88         self.assertEqual(42, getargs_B(42))
     89         self.assertEqual(42, getargs_B(42L))
     90         self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
     91 
     92     def test_H(self):
     93         from _testcapi import getargs_H
     94         # H returns 'unsigned short', no range checking
     95         self.assertRaises(TypeError, getargs_H, 3.14)
     96         self.assertEqual(99, getargs_H(Long()))
     97         self.assertEqual(99, getargs_H(Int()))
     98 
     99         self.assertEqual(USHRT_MAX, getargs_H(-1))
    100         self.assertEqual(0, getargs_H(0))
    101         self.assertEqual(USHRT_MAX, getargs_H(USHRT_MAX))
    102         self.assertEqual(0, getargs_H(USHRT_MAX+1))
    103 
    104         self.assertEqual(42, getargs_H(42))
    105         self.assertEqual(42, getargs_H(42L))
    106 
    107         self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE))
    108 
    109     def test_I(self):
    110         from _testcapi import getargs_I
    111         # I returns 'unsigned int', no range checking
    112         self.assertRaises(TypeError, getargs_I, 3.14)
    113         self.assertEqual(99, getargs_I(Long()))
    114         self.assertEqual(99, getargs_I(Int()))
    115 
    116         self.assertEqual(UINT_MAX, getargs_I(-1))
    117         self.assertEqual(0, getargs_I(0))
    118         self.assertEqual(UINT_MAX, getargs_I(UINT_MAX))
    119         self.assertEqual(0, getargs_I(UINT_MAX+1))
    120 
    121         self.assertEqual(42, getargs_I(42))
    122         self.assertEqual(42, getargs_I(42L))
    123 
    124         self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE))
    125 
    126     def test_k(self):
    127         from _testcapi import getargs_k
    128         # k returns 'unsigned long', no range checking
    129         # it does not accept float, or instances with __int__
    130         self.assertRaises(TypeError, getargs_k, 3.14)
    131         self.assertRaises(TypeError, getargs_k, Long())
    132         self.assertRaises(TypeError, getargs_k, Int())
    133 
    134         self.assertEqual(ULONG_MAX, getargs_k(-1))
    135         self.assertEqual(0, getargs_k(0))
    136         self.assertEqual(ULONG_MAX, getargs_k(ULONG_MAX))
    137         self.assertEqual(0, getargs_k(ULONG_MAX+1))
    138 
    139         self.assertEqual(42, getargs_k(42))
    140         self.assertEqual(42, getargs_k(42L))
    141 
    142         self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE))
    143 
    144 class Signed_TestCase(unittest.TestCase):
    145     def test_h(self):
    146         from _testcapi import getargs_h
    147         # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX)
    148         self.assertRaises(TypeError, getargs_h, 3.14)
    149         self.assertEqual(99, getargs_h(Long()))
    150         self.assertEqual(99, getargs_h(Int()))
    151 
    152         self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1)
    153         self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN))
    154         self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX))
    155         self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1)
    156 
    157         self.assertEqual(42, getargs_h(42))
    158         self.assertEqual(42, getargs_h(42L))
    159         self.assertRaises(OverflowError, getargs_h, VERY_LARGE)
    160 
    161     def test_i(self):
    162         from _testcapi import getargs_i
    163         # i returns 'int', and does range checking (INT_MIN ... INT_MAX)
    164         self.assertRaises(TypeError, getargs_i, 3.14)
    165         self.assertEqual(99, getargs_i(Long()))
    166         self.assertEqual(99, getargs_i(Int()))
    167 
    168         self.assertRaises(OverflowError, getargs_i, INT_MIN-1)
    169         self.assertEqual(INT_MIN, getargs_i(INT_MIN))
    170         self.assertEqual(INT_MAX, getargs_i(INT_MAX))
    171         self.assertRaises(OverflowError, getargs_i, INT_MAX+1)
    172 
    173         self.assertEqual(42, getargs_i(42))
    174         self.assertEqual(42, getargs_i(42L))
    175         self.assertRaises(OverflowError, getargs_i, VERY_LARGE)
    176 
    177     def test_l(self):
    178         from _testcapi import getargs_l
    179         # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX)
    180         self.assertRaises(TypeError, getargs_l, 3.14)
    181         self.assertEqual(99, getargs_l(Long()))
    182         self.assertEqual(99, getargs_l(Int()))
    183 
    184         self.assertRaises(OverflowError, getargs_l, LONG_MIN-1)
    185         self.assertEqual(LONG_MIN, getargs_l(LONG_MIN))
    186         self.assertEqual(LONG_MAX, getargs_l(LONG_MAX))
    187         self.assertRaises(OverflowError, getargs_l, LONG_MAX+1)
    188 
    189         self.assertEqual(42, getargs_l(42))
    190         self.assertEqual(42, getargs_l(42L))
    191         self.assertRaises(OverflowError, getargs_l, VERY_LARGE)
    192 
    193     def test_n(self):
    194         from _testcapi import getargs_n
    195         # n returns 'Py_ssize_t', and does range checking
    196         # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX)
    197         self.assertRaises(TypeError, getargs_n, 3.14)
    198         self.assertEqual(99, getargs_n(Long()))
    199         self.assertEqual(99, getargs_n(Int()))
    200 
    201         self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1)
    202         self.assertEqual(PY_SSIZE_T_MIN, getargs_n(PY_SSIZE_T_MIN))
    203         self.assertEqual(PY_SSIZE_T_MAX, getargs_n(PY_SSIZE_T_MAX))
    204         self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MAX+1)
    205 
    206         self.assertEqual(42, getargs_n(42))
    207         self.assertEqual(42, getargs_n(42L))
    208         self.assertRaises(OverflowError, getargs_n, VERY_LARGE)
    209 
    210 
    211 class LongLong_TestCase(unittest.TestCase):
    212     def test_L(self):
    213         from _testcapi import getargs_L
    214         # L returns 'long long', and does range checking (LLONG_MIN
    215         # ... LLONG_MAX)
    216         with warnings.catch_warnings():
    217             warnings.filterwarnings(
    218                 "ignore",
    219                 category=DeprecationWarning,
    220                 message=".*integer argument expected, got float",
    221                 module=__name__)
    222             self.assertEqual(3, getargs_L(3.14))
    223         with warnings.catch_warnings():
    224             warnings.filterwarnings(
    225                 "error",
    226                 category=DeprecationWarning,
    227                 message=".*integer argument expected, got float",
    228                 module="unittest")
    229             self.assertRaises(DeprecationWarning, getargs_L, 3.14)
    230 
    231         self.assertRaises(TypeError, getargs_L, "Hello")
    232         self.assertEqual(99, getargs_L(Long()))
    233         self.assertEqual(99, getargs_L(Int()))
    234 
    235         self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1)
    236         self.assertEqual(LLONG_MIN, getargs_L(LLONG_MIN))
    237         self.assertEqual(LLONG_MAX, getargs_L(LLONG_MAX))
    238         self.assertRaises(OverflowError, getargs_L, LLONG_MAX+1)
    239 
    240         self.assertEqual(42, getargs_L(42))
    241         self.assertEqual(42, getargs_L(42L))
    242         self.assertRaises(OverflowError, getargs_L, VERY_LARGE)
    243 
    244     def test_K(self):
    245         from _testcapi import getargs_K
    246         # K return 'unsigned long long', no range checking
    247         self.assertRaises(TypeError, getargs_K, 3.14)
    248         self.assertRaises(TypeError, getargs_K, Long())
    249         self.assertRaises(TypeError, getargs_K, Int())
    250         self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
    251         self.assertEqual(0, getargs_K(0))
    252         self.assertEqual(0, getargs_K(ULLONG_MAX+1))
    253 
    254         self.assertEqual(42, getargs_K(42))
    255         self.assertEqual(42, getargs_K(42L))
    256 
    257         self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
    258 
    259 
    260 class Tuple_TestCase(unittest.TestCase):
    261     def test_tuple(self):
    262         from _testcapi import getargs_tuple
    263 
    264         ret = getargs_tuple(1, (2, 3))
    265         self.assertEqual(ret, (1,2,3))
    266 
    267         # make sure invalid tuple arguments are handled correctly
    268         class seq:
    269             def __len__(self):
    270                 return 2
    271             def __getitem__(self, n):
    272                 raise ValueError
    273         self.assertRaises(TypeError, getargs_tuple, 1, seq())
    274 
    275 class Keywords_TestCase(unittest.TestCase):
    276     def test_positional_args(self):
    277         # using all positional args
    278         self.assertEqual(
    279             getargs_keywords((1,2), 3, (4,(5,6)), (7,8,9), 10),
    280             (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    281             )
    282     def test_mixed_args(self):
    283         # positional and keyword args
    284         self.assertEqual(
    285             getargs_keywords((1,2), 3, (4,(5,6)), arg4=(7,8,9), arg5=10),
    286             (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    287             )
    288     def test_keyword_args(self):
    289         # all keywords
    290         self.assertEqual(
    291             getargs_keywords(arg1=(1,2), arg2=3, arg3=(4,(5,6)), arg4=(7,8,9), arg5=10),
    292             (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    293             )
    294     def test_optional_args(self):
    295         # missing optional keyword args, skipping tuples
    296         self.assertEqual(
    297             getargs_keywords(arg1=(1,2), arg2=3, arg5=10),
    298             (1, 2, 3, -1, -1, -1, -1, -1, -1, 10)
    299             )
    300     def test_required_args(self):
    301         # required arg missing
    302         try:
    303             getargs_keywords(arg1=(1,2))
    304         except TypeError, err:
    305             self.assertEqual(str(err), "Required argument 'arg2' (pos 2) not found")
    306         else:
    307             self.fail('TypeError should have been raised')
    308     def test_too_many_args(self):
    309         try:
    310             getargs_keywords((1,2),3,(4,(5,6)),(7,8,9),10,111)
    311         except TypeError, err:
    312             self.assertEqual(str(err), "function takes at most 5 arguments (6 given)")
    313         else:
    314             self.fail('TypeError should have been raised')
    315     def test_invalid_keyword(self):
    316         # extraneous keyword arg
    317         try:
    318             getargs_keywords((1,2),3,arg5=10,arg666=666)
    319         except TypeError, err:
    320             self.assertEqual(str(err), "'arg666' is an invalid keyword argument for this function")
    321         else:
    322             self.fail('TypeError should have been raised')
    323 
    324 def test_main():
    325     tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase]
    326     try:
    327         from _testcapi import getargs_L, getargs_K
    328     except ImportError:
    329         pass # PY_LONG_LONG not available
    330     else:
    331         tests.append(LongLong_TestCase)
    332     test_support.run_unittest(*tests)
    333 
    334 if __name__ == "__main__":
    335     test_main()
    336