Skip to content

Commit 95d8865

Browse files
authored
Merge branch 'main' into fix-factorial
2 parents de57a10 + 7796f6d commit 95d8865

File tree

5 files changed

+104
-62
lines changed

5 files changed

+104
-62
lines changed

integration_tests/test_str_01.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,6 @@ def test_str_slice():
3737
# TODO:
3838
# assert a[0:5:-1] == ""
3939

40-
def test_str_isalpha():
41-
a: str = "helloworld"
42-
b: str = "hj kl"
43-
c: str = "a12(){}A"
44-
d: str = " "
45-
e: str = ""
46-
res: bool = a.isalpha()
47-
res2: bool = b.isalpha()
48-
res3: bool = c.isalpha()
49-
res4: bool = d.isalpha()
50-
res5: bool = e.isalpha()
51-
assert res == True
52-
assert res2 == False
53-
assert res3 == False
54-
assert res4 == False
55-
assert res5 == False
56-
5740

5841
def test_str_title():
5942
a: str = "hello world"
@@ -69,23 +52,6 @@ def test_str_title():
6952
assert res3 == "Hello World"
7053
assert res4 == "{Hel1O}World"
7154

72-
def test_str_istitle():
73-
a: str = "Hello World"
74-
b: str = "Hj'kl"
75-
c: str = "hELlo wOrlD"
76-
d: str = " Hello"
77-
e: str = " "
78-
res: bool = a.istitle()
79-
res2: bool = b.istitle()
80-
res3: bool = c.istitle()
81-
res4: bool = d.istitle()
82-
res5: bool = e.istitle()
83-
assert res == True
84-
assert res2 == False
85-
assert res3 == False
86-
assert res4 == True
87-
assert res5 == False
88-
8955
def test_str_repeat():
9056
a: str
9157
a = "Xyz"
@@ -160,8 +126,6 @@ def check():
160126
test_str_join_empty_list()
161127
test_constant_str_subscript()
162128
test_str_title()
163-
test_str_istitle()
164-
test_str_isalpha()
165129
test_str_split()
166130

167131
check()

integration_tests/test_str_attributes.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,53 @@ def is_ascii():
306306
assert s.isascii() == True
307307

308308

309+
def is_alpha():
310+
a: str = "helloworld"
311+
b: str = "hj kl"
312+
c: str = "a12(){}A"
313+
d: str = " "
314+
e: str = ""
315+
res: bool = a.isalpha()
316+
res2: bool = b.isalpha()
317+
res3: bool = c.isalpha()
318+
res4: bool = d.isalpha()
319+
res5: bool = e.isalpha()
320+
assert res == True
321+
assert res2 == False
322+
assert res3 == False
323+
assert res4 == False
324+
assert res5 == False
325+
326+
assert "helloworld".isalpha() == True
327+
assert "hj kl".isalpha() == False
328+
assert "a12(){}A".isalpha() == False
329+
assert " ".isalpha() == False
330+
assert "".isalpha() == False
331+
332+
333+
def is_title():
334+
a: str = "Hello World"
335+
b: str = "Hj'kl"
336+
c: str = "hELlo wOrlD"
337+
d: str = " Hello"
338+
e: str = " "
339+
res: bool = a.istitle()
340+
res2: bool = b.istitle()
341+
res3: bool = c.istitle()
342+
res4: bool = d.istitle()
343+
res5: bool = e.istitle()
344+
assert res == True
345+
assert res2 == False
346+
assert res3 == False
347+
assert res4 == True
348+
assert res5 == False
349+
350+
assert "Hello World".istitle() == True
351+
assert "Hj'kl".istitle() == False
352+
assert "hELlo wOrlD".istitle() == False
353+
assert " Hello".istitle() == True
354+
assert " ".istitle() == False
355+
309356
def is_space():
310357
assert "\n".isspace() == True
311358
assert " ".isspace() == True
@@ -320,6 +367,7 @@ def is_space():
320367
assert s.isspace() == False
321368

322369

370+
323371
def check():
324372
capitalize()
325373
lower()
@@ -335,6 +383,8 @@ def check():
335383
is_upper()
336384
is_decimal()
337385
is_ascii()
386+
is_alpha()
387+
is_title()
338388
is_space()
339389

340390

lpython

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6577,26 +6577,6 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
65776577
arg.loc = loc;
65786578
arg.m_value = s_var;
65796579
fn_args.push_back(al, arg);
6580-
} else if (attr_name == "isalpha") {
6581-
if (args.size() != 0) {
6582-
throw SemanticError("str.isalpha() takes no arguments",
6583-
loc);
6584-
}
6585-
fn_call_name = "_lpython_str_isalpha";
6586-
ASR::call_arg_t arg;
6587-
arg.loc = loc;
6588-
arg.m_value = s_var;
6589-
fn_args.push_back(al, arg);
6590-
} else if (attr_name == "istitle") {
6591-
if (args.size() != 0) {
6592-
throw SemanticError("str.istitle() takes no arguments",
6593-
loc);
6594-
}
6595-
fn_call_name = "_lpython_str_istitle";
6596-
ASR::call_arg_t arg;
6597-
arg.loc = loc;
6598-
arg.m_value = s_var;
6599-
fn_args.push_back(al, arg);
66006580
} else if (attr_name == "title") {
66016581
if (args.size() != 0) {
66026582
throw SemanticError("str.title() takes no arguments",
@@ -6813,7 +6793,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
68136793
/*
68146794
String Validation Methods i.e all "is" based functions are handled here
68156795
*/
6816-
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
6796+
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title"}; // Database of validation methods supported
68176797
std::string method_name = attr_name.substr(2);
68186798

68196799
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
@@ -7116,7 +7096,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
71167096
* islower() method is limited to English Alphabets currently
71177097
* TODO: We can support other characters from Unicode Library
71187098
*/
7119-
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space"}; // Database of validation methods supported
7099+
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title"}; // Database of validation methods supported
71207100
std::string method_name = attr_name.substr(2);
71217101
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
71227102
throw SemanticError("String method not implemented: " + attr_name, loc);
@@ -7214,6 +7194,57 @@ we will have to use something else.
72147194
tmp = ASR::make_LogicalConstant_t(al, loc, is_space,
72157195
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
72167196
return;
7197+
} else if (attr_name == "isalpha") {
7198+
/*
7199+
* Specification -
7200+
Return True if all characters in the string are alphabets,
7201+
and there is at least one character in the string.
7202+
*/
7203+
bool is_alpha = (s_var.size() != 0);
7204+
for (auto &i : s_var) {
7205+
if (!((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z'))) {
7206+
is_alpha = false;
7207+
break;
7208+
}
7209+
}
7210+
tmp = ASR::make_LogicalConstant_t(al, loc, is_alpha,
7211+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
7212+
return;
7213+
} else if (attr_name == "istitle") {
7214+
/*
7215+
* Specification -
7216+
Returns True if all words in the string are in title case,
7217+
and there is at least one character in the string.
7218+
*/
7219+
bool is_title = (s_var.size() != 0);
7220+
7221+
bool in_word = false; // Represents if we are in a word or not
7222+
bool is_alpha_present = false;
7223+
for (auto &i : s_var) {
7224+
if (i >= 'A' && i <= 'Z') {
7225+
is_alpha_present = true;
7226+
if (in_word) {
7227+
// We have come across an uppercase character in the middle of a word
7228+
is_title = false;
7229+
break;
7230+
} else {
7231+
in_word = true;
7232+
}
7233+
} else if (i >= 'a' && i <= 'z') {
7234+
is_alpha_present = true;
7235+
if (!in_word) {
7236+
//We have come across a lowercase character at the start of a word
7237+
is_title = false;
7238+
break;
7239+
}
7240+
} else {
7241+
in_word = false;
7242+
}
7243+
}
7244+
is_title = is_title && is_alpha_present;
7245+
tmp = ASR::make_LogicalConstant_t(al, loc, is_title,
7246+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
7247+
return;
72177248
} else {
72187249
throw SemanticError("'str' object has no attribute '" + attr_name + "'", loc);
72197250
}

src/runtime/lpython_builtin.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -764,9 +764,7 @@ def _lpython_str_istitle(s: str) -> bool:
764764
ch: str
765765
only_whitespace: bool = True
766766
for ch in s:
767-
if (ch == ' ' or ch == '\t' or ch == '\n') and word_start:
768-
continue # Found a space character at the start of a word
769-
elif ch.isalpha() and (ord('A') <= ord(ch) and ord(ch) <= ord('Z')):
767+
if ch.isalpha() and (ord('A') <= ord(ch) and ord(ch) <= ord('Z')):
770768
only_whitespace = False
771769
if word_start:
772770
word_start = False

0 commit comments

Comments
 (0)