from jaraco text 3 5 a case insensitive string class behaves just like str except compares equal when the only variation is case s foldedcase hello world s hello world true hello world s true s hello world false s index o 4 s split o hell w rld sortedmapfoldedcase gamma alpha beta alpha beta gamma sequence membership is straightforward hello world in s true s in hello world true you may test for set inclusion but candidate and elements must both be folded foldedcasehello world in s true s in foldedcasehello world true string inclusion works as long as the foldedcase object is on the right hello in foldedcasehello world true but not if the foldedcase object is on the left foldedcase hello in hello world false in that case use in foldedcase hello in hello world true foldedcase hello foldedcase hello false cache lower since it s likely to be called frequently from jaraco text 3 5 a case insensitive string class behaves just like str except compares equal when the only variation is case s foldedcase hello world s hello world true hello world s true s hello world false s index o 4 s split o hell w rld sorted map foldedcase gamma alpha beta alpha beta gamma sequence membership is straightforward hello world in s true s in hello world true you may test for set inclusion but candidate and elements must both be folded foldedcase hello world in s true s in foldedcase hello world true string inclusion works as long as the foldedcase object is on the right hello in foldedcase hello world true but not if the foldedcase object is on the left foldedcase hello in hello world false in that case use in_ foldedcase hello in_ hello world true foldedcase hello foldedcase hello false cache lower since it s likely to be called frequently
import re

from ._functools import method_cache



class FoldedCase(str):
    

    def __lt__(self, other):
        return self.lower() < other.lower()

    def __gt__(self, other):
        return self.lower() > other.lower()

    def __eq__(self, other):
        return self.lower() == other.lower()

    def __ne__(self, other):
        return self.lower() != other.lower()

    def __hash__(self):
        return hash(self.lower())

    def __contains__(self, other):
        return super().lower().__contains__(other.lower())

    def in_(self, other):
        "Does self appear in other?"
        return self in FoldedCase(other)

    
    @method_cache
    def lower(self):
        return super().lower()

    def index(self, sub):
        return self.lower().index(sub.lower())

    def split(self, splitter=' ', maxsplit=0):
        pattern = re.compile(re.escape(splitter), re.I)
        return pattern.split(self, maxsplit)