@@ -1502,6 +1502,71 @@ STATIC mp_obj_t str_upper(mp_obj_t self_in) {
15021502 return str_caseconv (CASE_UPPER , self_in );
15031503}
15041504
1505+ enum { IS_SPACE , IS_ALPHA , IS_DIGIT , IS_UPPER , IS_LOWER };
1506+
1507+ STATIC mp_obj_t str_uni_istype (int type , mp_obj_t self_in ) {
1508+ GET_STR_DATA_LEN (self_in , self_data , self_len );
1509+
1510+ if (self_len == 0 ) return mp_const_false ; // default to False for empty str
1511+
1512+ typedef bool (* check_function )(unichar );
1513+ check_function f ;
1514+
1515+ if (type != IS_UPPER && type != IS_LOWER ) {
1516+ switch (type ) {
1517+ case IS_SPACE : f = & unichar_isspace ; break ;
1518+ case IS_ALPHA : f = & unichar_isalpha ; break ;
1519+ case IS_DIGIT : f = & unichar_isdigit ; break ;
1520+ default :
1521+ nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "unknown type provided for str_uni_istype" ));
1522+ }
1523+
1524+ for (int i = 0 ; i < self_len ; i ++ ) {
1525+ if (!f (* self_data ++ )) return mp_const_false ;
1526+ }
1527+ } else {
1528+ switch (type ) {
1529+ case IS_UPPER : f = & unichar_isupper ; break ;
1530+ case IS_LOWER : f = & unichar_islower ; break ;
1531+ default :
1532+ nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "unknown type provided for str_uni_istype" ));
1533+ }
1534+
1535+ bool contains_alpha = false;
1536+
1537+ for (int i = 0 ; i < self_len ; i ++ ) { // only check alphanumeric characters
1538+ if (unichar_isalpha (* self_data ++ )) {
1539+ contains_alpha = true;
1540+ if (!f (* (self_data - 1 ))) return mp_const_false ; // we already incremented
1541+ }
1542+ }
1543+
1544+ if (!(contains_alpha )) return mp_const_false ;
1545+ }
1546+
1547+ return mp_const_true ;
1548+ }
1549+
1550+ STATIC mp_obj_t str_isspace (mp_obj_t self_in ) {
1551+ return str_uni_istype (IS_SPACE , self_in );
1552+ }
1553+
1554+ STATIC mp_obj_t str_isalpha (mp_obj_t self_in ) {
1555+ return str_uni_istype (IS_ALPHA , self_in );
1556+ }
1557+
1558+ STATIC mp_obj_t str_isdigit (mp_obj_t self_in ) {
1559+ return str_uni_istype (IS_DIGIT , self_in );
1560+ }
1561+
1562+ STATIC mp_obj_t str_isupper (mp_obj_t self_in ) {
1563+ return str_uni_istype (IS_UPPER , self_in );
1564+ }
1565+
1566+ STATIC mp_obj_t str_islower (mp_obj_t self_in ) {
1567+ return str_uni_istype (IS_LOWER , self_in );
1568+ }
1569+
15051570#if MICROPY_CPYTHON_COMPAT
15061571// These methods are superfluous in the presense of str() and bytes()
15071572// constructors.
@@ -1569,6 +1634,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition);
15691634STATIC MP_DEFINE_CONST_FUN_OBJ_2 (str_rpartition_obj , str_rpartition );
15701635STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_lower_obj , str_lower );
15711636STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_upper_obj , str_upper );
1637+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_isspace_obj , str_isspace );
1638+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_isalpha_obj , str_isalpha );
1639+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_isdigit_obj , str_isdigit );
1640+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_isupper_obj , str_isupper );
1641+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (str_islower_obj , str_islower );
15721642
15731643STATIC const mp_map_elem_t str_locals_dict_table [] = {
15741644#if MICROPY_CPYTHON_COMPAT
@@ -1594,6 +1664,11 @@ STATIC const mp_map_elem_t str_locals_dict_table[] = {
15941664 { MP_OBJ_NEW_QSTR (MP_QSTR_rpartition ), (mp_obj_t )& str_rpartition_obj },
15951665 { MP_OBJ_NEW_QSTR (MP_QSTR_lower ), (mp_obj_t )& str_lower_obj },
15961666 { MP_OBJ_NEW_QSTR (MP_QSTR_upper ), (mp_obj_t )& str_upper_obj },
1667+ { MP_OBJ_NEW_QSTR (MP_QSTR_isspace ), (mp_obj_t )& str_isspace_obj },
1668+ { MP_OBJ_NEW_QSTR (MP_QSTR_isalpha ), (mp_obj_t )& str_isalpha_obj },
1669+ { MP_OBJ_NEW_QSTR (MP_QSTR_isdigit ), (mp_obj_t )& str_isdigit_obj },
1670+ { MP_OBJ_NEW_QSTR (MP_QSTR_isupper ), (mp_obj_t )& str_isupper_obj },
1671+ { MP_OBJ_NEW_QSTR (MP_QSTR_islower ), (mp_obj_t )& str_islower_obj },
15971672};
15981673
15991674STATIC MP_DEFINE_CONST_DICT (str_locals_dict , str_locals_dict_table );
0 commit comments