From 73b7027b8330ea813c4ba83f074bc8937a952d9c Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Sun, 13 Apr 2014 05:28:46 +0300
Subject: [PATCH] objstr: Add str.encode() and bytes.decode() methods.

These largely duplicate str() & bytes() constructors' functionality,
but can be used to achieve Python2 compatibility.
---
 py/makeqstrdata.py |  1 +
 py/objstr.c        | 36 ++++++++++++++++++++++++++++++++++++
 py/qstrdefs.h      |  6 ++++++
 3 files changed, 43 insertions(+)

diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 81b003545..0cc9ba1b6 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -10,6 +10,7 @@ if platform.python_version_tuple()[0] == '2':
     from htmlentitydefs import codepoint2name
 elif platform.python_version_tuple()[0] == '3':
     from html.entities import codepoint2name
+codepoint2name[ord('-')] = 'hyphen';
 
 # add some custom names to map characters that aren't in HTML
 codepoint2name[ord('.')] = 'dot'
diff --git a/py/objstr.c b/py/objstr.c
index e55a2edd5..12627d3cd 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -1298,6 +1298,34 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
     return str_partitioner(self_in, arg, -1);
 }
 
+#if MICROPY_CPYTHON_COMPAT
+// These methods are superfluous in the presense of str() and bytes()
+// constructors.
+// TODO: should accept kwargs too
+STATIC mp_obj_t bytes_decode(uint n_args, const mp_obj_t *args) {
+    mp_obj_t new_args[2];
+    if (n_args == 1) {
+        new_args[0] = args[0];
+        new_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_utf_hyphen_8);
+        args = new_args;
+        n_args++;
+    }
+    return str_make_new(NULL, n_args, 0, args);
+}
+
+// TODO: should accept kwargs too
+STATIC mp_obj_t str_encode(uint n_args, const mp_obj_t *args) {
+    mp_obj_t new_args[2];
+    if (n_args == 1) {
+        new_args[0] = args[0];
+        new_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_utf_hyphen_8);
+        args = new_args;
+        n_args++;
+    }
+    return bytes_make_new(NULL, n_args, 0, args);
+}
+#endif
+
 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);
@@ -1312,6 +1340,10 @@ STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, in
     }
 }
 
+#if MICROPY_CPYTHON_COMPAT
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj, 1, 3, bytes_decode);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj, 1, 3, str_encode);
+#endif
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj, 2, 4, str_rfind);
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj, 2, 4, str_index);
@@ -1327,6 +1359,10 @@ 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_map_elem_t str_locals_dict_table[] = {
+#if MICROPY_CPYTHON_COMPAT
+    { MP_OBJ_NEW_QSTR(MP_QSTR_decode), (mp_obj_t)&bytes_decode_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_encode), (mp_obj_t)&str_encode_obj },
+#endif
     { MP_OBJ_NEW_QSTR(MP_QSTR_find), (mp_obj_t)&str_find_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_rfind), (mp_obj_t)&str_rfind_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&str_index_obj },
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index d52b870e6..7bd8dc653 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -263,3 +263,9 @@ Q(<setcomp>)
 Q(<genexpr>)
 Q(<string>)
 Q(<stdin>)
+
+#if MICROPY_CPYTHON_COMPAT
+Q(encode)
+Q(decode)
+Q(utf-8)
+#endif
-- 
GitLab