17db96d56Sopenharmony_ciimport re 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_cifrom ._functools import method_cache 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci# from jaraco.text 3.5 77db96d56Sopenharmony_ciclass FoldedCase(str): 87db96d56Sopenharmony_ci """ 97db96d56Sopenharmony_ci A case insensitive string class; behaves just like str 107db96d56Sopenharmony_ci except compares equal when the only variation is case. 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci >>> s = FoldedCase('hello world') 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci >>> s == 'Hello World' 157db96d56Sopenharmony_ci True 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci >>> 'Hello World' == s 187db96d56Sopenharmony_ci True 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci >>> s != 'Hello World' 217db96d56Sopenharmony_ci False 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci >>> s.index('O') 247db96d56Sopenharmony_ci 4 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci >>> s.split('O') 277db96d56Sopenharmony_ci ['hell', ' w', 'rld'] 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) 307db96d56Sopenharmony_ci ['alpha', 'Beta', 'GAMMA'] 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci Sequence membership is straightforward. 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci >>> "Hello World" in [s] 357db96d56Sopenharmony_ci True 367db96d56Sopenharmony_ci >>> s in ["Hello World"] 377db96d56Sopenharmony_ci True 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci You may test for set inclusion, but candidate and elements 407db96d56Sopenharmony_ci must both be folded. 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci >>> FoldedCase("Hello World") in {s} 437db96d56Sopenharmony_ci True 447db96d56Sopenharmony_ci >>> s in {FoldedCase("Hello World")} 457db96d56Sopenharmony_ci True 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci String inclusion works as long as the FoldedCase object 487db96d56Sopenharmony_ci is on the right. 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci >>> "hello" in FoldedCase("Hello World") 517db96d56Sopenharmony_ci True 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci But not if the FoldedCase object is on the left: 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci >>> FoldedCase('hello') in 'Hello World' 567db96d56Sopenharmony_ci False 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci In that case, use in_: 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci >>> FoldedCase('hello').in_('Hello World') 617db96d56Sopenharmony_ci True 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci >>> FoldedCase('hello') > FoldedCase('Hello') 647db96d56Sopenharmony_ci False 657db96d56Sopenharmony_ci """ 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci def __lt__(self, other): 687db96d56Sopenharmony_ci return self.lower() < other.lower() 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci def __gt__(self, other): 717db96d56Sopenharmony_ci return self.lower() > other.lower() 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci def __eq__(self, other): 747db96d56Sopenharmony_ci return self.lower() == other.lower() 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci def __ne__(self, other): 777db96d56Sopenharmony_ci return self.lower() != other.lower() 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci def __hash__(self): 807db96d56Sopenharmony_ci return hash(self.lower()) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci def __contains__(self, other): 837db96d56Sopenharmony_ci return super().lower().__contains__(other.lower()) 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci def in_(self, other): 867db96d56Sopenharmony_ci "Does self appear in other?" 877db96d56Sopenharmony_ci return self in FoldedCase(other) 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci # cache lower since it's likely to be called frequently. 907db96d56Sopenharmony_ci @method_cache 917db96d56Sopenharmony_ci def lower(self): 927db96d56Sopenharmony_ci return super().lower() 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci def index(self, sub): 957db96d56Sopenharmony_ci return self.lower().index(sub.lower()) 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci def split(self, splitter=' ', maxsplit=0): 987db96d56Sopenharmony_ci pattern = re.compile(re.escape(splitter), re.I) 997db96d56Sopenharmony_ci return pattern.split(self, maxsplit) 100