Skip to content

Commit 87e7caa

Browse files
Add isspace API in str (#2373)
1 parent 36fe6cf commit 87e7caa

File tree

63 files changed

+1272
-1232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1272
-1232
lines changed

integration_tests/test_str_attributes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,17 @@ def is_ascii():
276276
s = "123 45 6"
277277
assert s.isascii() == True
278278

279+
280+
def is_space():
281+
assert "\n".isspace() == True
282+
assert " ".isspace() == True
283+
assert "\r".isspace() == True
284+
285+
s:str = " "
286+
assert s.isspace() == True
287+
s = "a"
288+
assert s.isspace() == False
289+
279290
def check():
280291
capitalize()
281292
lower()
@@ -290,5 +301,6 @@ def check():
290301
is_upper()
291302
is_decimal()
292303
is_ascii()
304+
is_space()
293305

294306
check()

src/libasr/string_utils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ std::string str_escape_c(const std::string &s) {
142142
case '\n': o << "\\n"; break;
143143
case '\r': o << "\\r"; break;
144144
case '\t': o << "\\t"; break;
145+
case '\v': o << "\\v"; break;
145146
default:
146147
if ('\x00' <= *c && *c <= '\x1f') {
147148
o << "\\u"

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6651,7 +6651,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
66516651
/*
66526652
String Validation Methods i.e all "is" based functions are handled here
66536653
*/
6654-
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii"}; // Database of validation methods supported
6654+
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
66556655
std::string method_name = attr_name.substr(2);
66566656

66576657
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
@@ -6919,7 +6919,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
69196919
* islower() method is limited to English Alphabets currently
69206920
* TODO: We can support other characters from Unicode Library
69216921
*/
6922-
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii"}; // Database of validation methods supported
6922+
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
69236923
std::string method_name = attr_name.substr(2);
69246924
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
69256925
throw SemanticError("String method not implemented: " + attr_name, loc);
@@ -6999,6 +6999,24 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
69996999
tmp = ASR::make_LogicalConstant_t(al, loc, is_ascii,
70007000
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
70017001
return;
7002+
} else if (attr_name == "isspace") {
7003+
/*
7004+
* Specification:
7005+
Return true if all characters in the input string are considered whitespace
7006+
characters, as defined by CPython. Return false otherwise. For now we use the
7007+
std::isspace function, but if we later discover that it differs from CPython,
7008+
we will have to use something else.
7009+
*/
7010+
bool is_space = true;
7011+
for (char i : s_var) {
7012+
if (!std::isspace(static_cast<unsigned char>(i))) {
7013+
is_space = false;
7014+
break;
7015+
}
7016+
}
7017+
tmp = ASR::make_LogicalConstant_t(al, loc, is_space,
7018+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
7019+
return;
70027020
} else {
70037021
throw SemanticError("'str' object has no attribute '" + attr_name + "'", loc);
70047022
}

src/lpython/semantics/python_comptime_eval.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ struct PythonIntrinsicProcedures {
9292
{"_lpython_str_islower", {m_builtin, &not_implemented}},
9393
{"_lpython_str_isupper", {m_builtin, &not_implemented}},
9494
{"_lpython_str_isdecimal", {m_builtin, &not_implemented}},
95-
{"_lpython_str_isascii", {m_builtin, &not_implemented}}
95+
{"_lpython_str_isascii", {m_builtin, &not_implemented}},
96+
{"_lpython_str_isspace", {m_builtin, &not_implemented}}
9697
};
9798
}
9899

src/runtime/lpython_builtin.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,14 @@ def _lpython_str_isascii(s: str) -> bool:
858858
return False
859859
return True
860860

861+
def _lpython_str_isspace(s:str) -> bool:
862+
ch: str
863+
for ch in s:
864+
if ch != ' ' and ch != '\t' and ch != '\n' and ch != '\r' and ch != '\f' and ch != '\v':
865+
return False
866+
return True
867+
868+
861869
def list(s: str) -> list[str]:
862870
l: list[str] = []
863871
i: i32

tests/reference/asr-array_01_decl-39cf894.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-array_01_decl-39cf894.stdout",
9-
"stdout_hash": "24b1d1f4774489a87a82c51c4f4a797ca363f7efdb011e42936fc6b9",
9+
"stdout_hash": "337d67c221f17230293b36428d0f59e687b3a1d577e9b361298e1257",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

0 commit comments

Comments
 (0)