From 1609f855828d2b932542b3a46158619a7c574555 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 Mar 2014 23:41:04 +0000 Subject: Rename test so that it doesn't clash with Python math module. --- tests/basics/math-fun.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/basics/math.py | 49 ------------------------------------------------ 2 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 tests/basics/math-fun.py delete mode 100644 tests/basics/math.py (limited to 'tests') diff --git a/tests/basics/math-fun.py b/tests/basics/math-fun.py new file mode 100644 index 000000000..f5ffbf40d --- /dev/null +++ b/tests/basics/math-fun.py @@ -0,0 +1,49 @@ +# Tests the functions imported from math + +from math import * + +test_values = [-100., -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.] +p_test_values = [0.1, 0.5, 1.23456] +unit_range_test_values = [-1., -0.75, -0.5, -0.25, 0., 0.25, 0.5, 0.75, 1.] +#IEEE_test_values = [1, 0, float('NaN'), float('Inf'), -float('NaN'), -float('Inf')] +#TODO: float('NaN') + +functions = [(sqrt, p_test_values), + (exp, test_values), + (expm1, test_values), + (log, p_test_values), + (log2, p_test_values), + (log10, p_test_values), + (cosh, test_values), + (sinh, test_values), + (tanh, test_values), + (acosh, [1.0, 5.0, 1.0]), + (asinh, test_values), + (atanh, [-0.99, -0.5, 0.0, 0.5, 0.99]), + (cos, test_values), + (sin, test_values), + (tan, test_values), + (acos, unit_range_test_values), + (asin, unit_range_test_values), + (atan, test_values), + (ceil, test_values), + (fabs, test_values), + (floor, test_values), + #(frexp, test_values), + #(isfinite, [1, 0, float('NaN'), float('Inf')]) + (trunc, test_values) + ] + +for function, test_vals in functions: + for value in test_vals: + print("{:8.7f}".format(function(value))) + +binary_functions = [(copysign, [(23., 42.), (-23., 42.), (23., -42.), + (-23., -42.), (1., 0.0), (1., -0.0)]) + ] + +#for function, test_vals in binary_functions: +# for value1, value2 in test_vals: +# print("{:8.7f}".format(function(value1, value2))) + + diff --git a/tests/basics/math.py b/tests/basics/math.py deleted file mode 100644 index f5ffbf40d..000000000 --- a/tests/basics/math.py +++ /dev/null @@ -1,49 +0,0 @@ -# Tests the functions imported from math - -from math import * - -test_values = [-100., -1.23456, -1, -0.5, 0.0, 0.5, 1.23456, 100.] -p_test_values = [0.1, 0.5, 1.23456] -unit_range_test_values = [-1., -0.75, -0.5, -0.25, 0., 0.25, 0.5, 0.75, 1.] -#IEEE_test_values = [1, 0, float('NaN'), float('Inf'), -float('NaN'), -float('Inf')] -#TODO: float('NaN') - -functions = [(sqrt, p_test_values), - (exp, test_values), - (expm1, test_values), - (log, p_test_values), - (log2, p_test_values), - (log10, p_test_values), - (cosh, test_values), - (sinh, test_values), - (tanh, test_values), - (acosh, [1.0, 5.0, 1.0]), - (asinh, test_values), - (atanh, [-0.99, -0.5, 0.0, 0.5, 0.99]), - (cos, test_values), - (sin, test_values), - (tan, test_values), - (acos, unit_range_test_values), - (asin, unit_range_test_values), - (atan, test_values), - (ceil, test_values), - (fabs, test_values), - (floor, test_values), - #(frexp, test_values), - #(isfinite, [1, 0, float('NaN'), float('Inf')]) - (trunc, test_values) - ] - -for function, test_vals in functions: - for value in test_vals: - print("{:8.7f}".format(function(value))) - -binary_functions = [(copysign, [(23., 42.), (-23., 42.), (23., -42.), - (-23., -42.), (1., 0.0), (1., -0.0)]) - ] - -#for function, test_vals in binary_functions: -# for value1, value2 in test_vals: -# print("{:8.7f}".format(function(value1, value2))) - - -- cgit v1.2.3 From 613a8e3edf078c284bd981426cc5a256eabb2323 Mon Sep 17 00:00:00 2001 From: xbe Date: Tue, 18 Mar 2014 00:06:29 -0700 Subject: Implement str.partition and add tests for it. --- py/objstr.c | 27 +++++++++++++++++++++++++++ tests/basics/string_partition.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/basics/string_partition.py (limited to 'tests') diff --git a/py/objstr.c b/py/objstr.c index d660bf952..03711debb 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -520,6 +520,31 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) { return MP_OBJ_NEW_SMALL_INT(num_occurrences); } +STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_STR(self_in)); + if (!MP_OBJ_IS_STR(arg)) { + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); + } + + GET_STR_DATA_LEN(self_in, str, str_len); + GET_STR_DATA_LEN(arg, sep, sep_len); + + if (sep_len == 0) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); + } + + for (machine_uint_t str_index = 0; str_index + sep_len <= str_len; str_index++) { + if (memcmp(&str[str_index], sep, sep_len) == 0) { + mp_obj_t items[] = {mp_obj_new_str(str, str_index, false), arg, + mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false)}; + return mp_obj_new_tuple(3, items); + } + } + mp_obj_t items[] = {mp_obj_new_str(str, str_len, false), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)}; + return mp_obj_new_tuple(3, items); +} + STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { if (flags == BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); @@ -542,6 +567,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); STATIC const mp_method_t str_type_methods[] = { { "find", &str_find_obj }, @@ -552,6 +578,7 @@ STATIC const mp_method_t str_type_methods[] = { { "format", &str_format_obj }, { "replace", &str_replace_obj }, { "count", &str_count_obj }, + { "partition", &str_partition_obj }, { NULL, NULL }, // end-of-list sentinel }; diff --git a/tests/basics/string_partition.py b/tests/basics/string_partition.py new file mode 100644 index 000000000..ad70d0250 --- /dev/null +++ b/tests/basics/string_partition.py @@ -0,0 +1,29 @@ +print("asdf".partition('g')) +print("asdf".partition('a')) +print("asdf".partition('s')) +print("asdf".partition('f')) +print("asdf".partition('d')) +print("asdf".partition('asd')) +print("asdf".partition('sdf')) +print("asdf".partition('as')) +print("asdf".partition('df')) +print("asdf".partition('asdf')) +print("asdf".partition('asdfa')) +print("asdf".partition('fasdf')) +print("asdf".partition('fasdfa')) +print("abba".partition('a')) +print("abba".partition('b')) + +try: + print("asdf".partition(1)) +except TypeError: + print("Raised TypeError") +else: + print("Did not raise TypeError") + +try: + print("asdf".partition('')) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") -- cgit v1.2.3 From 4504ea8007bbc97aef51ced20a9ff3f460cd7caf Mon Sep 17 00:00:00 2001 From: xbe Date: Wed, 19 Mar 2014 00:46:14 -0700 Subject: Implement str.rpartition and add tests for it. --- py/objstr.c | 36 ++++++++++++++++++++++++++++++++++++ tests/basics/string_rpartition.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/basics/string_rpartition.py (limited to 'tests') diff --git a/py/objstr.c b/py/objstr.c index 03711debb..c71993578 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -545,6 +545,40 @@ STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) { return mp_obj_new_tuple(3, items); } +STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_STR(self_in)); + if (!MP_OBJ_IS_STR(arg)) { + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg))); + } + + GET_STR_DATA_LEN(self_in, str, str_len); + GET_STR_DATA_LEN(arg, sep, sep_len); + + if (sep_len == 0) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator")); + } + + if (sep_len > str_len) { + goto not_found; + } + + for (machine_uint_t str_index = str_len; ; str_index--) { + if (memcmp(&str[str_index - sep_len], sep, sep_len) == 0) { + mp_obj_t items[] = {mp_obj_new_str(str, str_index - sep_len, false), arg, + mp_obj_new_str(str + str_index, str_len - str_index, false)}; + return mp_obj_new_tuple(3, items); + } + if (str_index - sep_len == 0) { + break; + } + } + +not_found: ; + mp_obj_t items[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), mp_obj_new_str(str, str_len, false)}; + return mp_obj_new_tuple(3, items); +} + STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { if (flags == BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); @@ -568,6 +602,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition); STATIC const mp_method_t str_type_methods[] = { { "find", &str_find_obj }, @@ -579,6 +614,7 @@ STATIC const mp_method_t str_type_methods[] = { { "replace", &str_replace_obj }, { "count", &str_count_obj }, { "partition", &str_partition_obj }, + { "rpartition", &str_rpartition_obj }, { NULL, NULL }, // end-of-list sentinel }; diff --git a/tests/basics/string_rpartition.py b/tests/basics/string_rpartition.py new file mode 100644 index 000000000..656121c94 --- /dev/null +++ b/tests/basics/string_rpartition.py @@ -0,0 +1,29 @@ +print("asdf".rpartition('g')) +print("asdf".rpartition('a')) +print("asdf".rpartition('s')) +print("asdf".rpartition('f')) +print("asdf".rpartition('d')) +print("asdf".rpartition('asd')) +print("asdf".rpartition('sdf')) +print("asdf".rpartition('as')) +print("asdf".rpartition('df')) +print("asdf".rpartition('asdf')) +print("asdf".rpartition('asdfa')) +print("asdf".rpartition('fasdf')) +print("asdf".rpartition('fasdfa')) +print("abba".rpartition('a')) +print("abba".rpartition('b')) + +try: + print("asdf".rpartition(1)) +except TypeError: + print("Raised TypeError") +else: + print("Did not raise TypeError") + +try: + print("asdf".rpartition('')) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") -- cgit v1.2.3 From 42901554db49cd1204054ea695cea6ee4e368b1e Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 22 Mar 2014 00:02:32 +0200 Subject: objint_longlong: Add regression test for improper inplace op implementation. --- tests/basics/int-long.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/basics/int-long.py b/tests/basics/int-long.py index f867d8037..3567e08b2 100644 --- a/tests/basics/int-long.py +++ b/tests/basics/int-long.py @@ -37,3 +37,10 @@ a <<= 5 print(a) a >>= 1 print(a) + +# Test referential integrity of long ints +a = 0x1ffffffff +b = a +a += 1 +print(a) +print(b) -- cgit v1.2.3 From 1ecea7c7539e73f105fef25da8a3bde7783da755 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 21 Mar 2014 23:46:59 +0200 Subject: py: Make 'bytes' be a proper type, support standard constructor args. --- py/builtin.c | 12 -------- py/objstr.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++- py/runtime.c | 2 +- tests/basics/bytes.py | 28 +++++++++++++++++++ 4 files changed, 105 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/py/builtin.c b/py/builtin.c index 11b86111e..93e91072c 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -375,18 +375,6 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted); -// TODO: This should be type, this is just quick CPython compat hack -STATIC mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) { - if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) { - assert(0); - } - // Currently, MicroPython strings are mix between CPython byte and unicode - // strings. So, conversion is null so far. - return args[0]; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes); - STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) { return mp_obj_new_int((machine_int_t)o_in); } diff --git a/py/objstr.c b/py/objstr.c index 44e84d709..35a948700 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -17,6 +17,8 @@ typedef struct _mp_obj_str_t { const byte *data; } mp_obj_str_t; +const mp_obj_t mp_const_empty_bytes; + // use this macro to extract the string hash #define GET_STR_HASH(str_obj_in, str_hash) uint str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t*)str_obj_in)->hash; } @@ -113,6 +115,75 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ } } +STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + if (n_args == 0) { + return mp_const_empty_bytes; + } + + if (MP_OBJ_IS_STR(args[0])) { + if (n_args < 2 || n_args > 3) { + goto wrong_args; + } + GET_STR_DATA_LEN(args[0], str_data, str_len); + GET_STR_HASH(args[0], str_hash); + mp_obj_str_t *o = str_new(&bytes_type, NULL, str_len); + o->data = str_data; + o->hash = str_hash; + return o; + } + + if (n_args > 1) { + goto wrong_args; + } + + if (MP_OBJ_IS_SMALL_INT(args[0])) { + uint len = MP_OBJ_SMALL_INT_VALUE(args[0]); + byte *data; + + mp_obj_t o = mp_obj_str_builder_start(&bytes_type, len, &data); + memset(data, 0, len); + return mp_obj_str_builder_end(o); + } + + int len; + byte *data; + vstr_t *vstr = NULL; + mp_obj_t o = NULL; + // Try to create array of exact len if initializer len is known + mp_obj_t len_in = mp_obj_len_maybe(args[0]); + if (len_in == MP_OBJ_NULL) { + len = -1; + vstr = vstr_new(); + } else { + len = MP_OBJ_SMALL_INT_VALUE(len_in); + o = mp_obj_str_builder_start(&bytes_type, len, &data); + } + + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { + if (len == -1) { + vstr_add_char(vstr, MP_OBJ_SMALL_INT_VALUE(item)); + } else { + *data++ = MP_OBJ_SMALL_INT_VALUE(item); + } + } + + if (len == -1) { + vstr_shrink(vstr); + // TODO: Optimize, borrow buffer from vstr + len = vstr_len(vstr); + o = mp_obj_str_builder_start(&bytes_type, len, &data); + memcpy(data, vstr_str(vstr), len); + vstr_free(vstr); + } + + return mp_obj_str_builder_end(o); + +wrong_args: + nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments")); +} + // like strstr but with specified length and allows \0 bytes // TODO replace with something more efficient/standard STATIC const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) { @@ -666,11 +737,16 @@ const mp_obj_type_t bytes_type = { { &mp_type_type }, .name = MP_QSTR_bytes, .print = str_print, + .make_new = bytes_make_new, .binary_op = str_binary_op, .getiter = mp_obj_new_bytes_iterator, .methods = str_type_methods, }; +// the zero-length bytes +STATIC const mp_obj_str_t empty_bytes_obj = {{&bytes_type}, 0, 0, NULL}; +const mp_obj_t mp_const_empty_bytes = (mp_obj_t)&empty_bytes_obj; + mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data) { mp_obj_str_t *o = m_new_obj(mp_obj_str_t); o->base.type = type; @@ -682,7 +758,6 @@ mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **da } mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in) { - assert(MP_OBJ_IS_STR(o_in)); mp_obj_str_t *o = o_in; o->hash = qstr_compute_hash(o->data, o->len); byte *p = (byte*)o->data; diff --git a/py/runtime.c b/py/runtime.c index 2ab97ed18..4bcb91c54 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -89,6 +89,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = { // built-in types { MP_QSTR_bool, (mp_obj_t)&bool_type }, + { MP_QSTR_bytes, (mp_obj_t)&bytes_type }, #if MICROPY_ENABLE_FLOAT { MP_QSTR_complex, (mp_obj_t)&mp_type_complex }, #endif @@ -115,7 +116,6 @@ STATIC const mp_builtin_elem_t builtin_table[] = { { MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj }, { MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj }, { MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj }, - { MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj }, { MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj }, { MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj }, { MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj }, diff --git a/tests/basics/bytes.py b/tests/basics/bytes.py index 7d0cf22d4..a084bc399 100644 --- a/tests/basics/bytes.py +++ b/tests/basics/bytes.py @@ -4,8 +4,36 @@ print(str(a)) print(repr(a)) print(a[0], a[2]) print(a[-1]) +print(str(a, "utf-8")) +print(str(a, "utf-8", "ignore")) +try: + str(a, "utf-8", "ignore", "toomuch") +except TypeError: + print("TypeError") s = 0 for i in a: s += i print(s) + + +print(bytes("abc", "utf-8")) +print(bytes("abc", "utf-8", "replace")) +try: + bytes("abc") +except TypeError: + print("TypeError") +try: + bytes("abc", "utf-8", "replace", "toomuch") +except TypeError: + print("TypeError") + +print(bytes(3)) + +print(bytes([3, 2, 1])) +print(bytes(range(5))) + +def gen(): + for i in range(4): + yield i +print(bytes(gen())) -- cgit v1.2.3