<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get(tag: {str, 'Language'}, normalize=True) -> 'Language': """ Create a Language object from a language tag string. If normalize=True, non-standard or overlong tags will be replaced as they're interpreted. This is recommended. Here are several examples of language codes, which are also test cases. Most language codes are straightforward, but these examples will get pretty obscure toward the end. Language.make(language='en', region='US') Language.make(language='zh', script='Hant') Language.make() This function is idempotent, in case you already have a Language object: Language.make(language='en', region='US') The non-code 'root' is sometimes used to represent the lack of any language information, similar to 'und'. Language.make() By default, getting a Language object will automatically convert deprecated tags: Language.make(language='he') Language.make(language='id') One type of deprecated tag that should be replaced is for sign languages, which used to all be coded as regional variants of a fictitious global sign language called 'sgn'. Of course, there is no global sign language, so sign languages now have their own language codes. Language.make(language='ase') Language.make(language='sgn', region='US') 'en-gb-oed' is a tag that's grandfathered into the standard because it has been used to mean "spell-check this with Oxford English Dictionary spelling", but that tag has the wrong shape. We interpret this as the new standardized tag 'en-gb-oxendict', unless asked not to normalize. Language.make(language='en', region='GB', variants=['oxendict']) Language.make(language='en-gb-oed') 'zh-min-nan' is another oddly-formed tag, used to represent the Southern Min language, which includes Taiwanese as a regional form. It now has its own language code. Language.make(language='nan') There's not much we can do with the vague tag 'zh-min': Language.make(language='zh-min') Occasionally Wiktionary will use 'extlang' tags in strange ways, such as using the tag 'und-ibe' for some unspecified Iberian language. Language.make(extlangs=['ibe']) Here's an example of replacing multiple deprecated tags. The language tag 'sh' (Serbo-Croatian) ended up being politically problematic, and different standards took different steps to address this. The IANA made it into a macrolanguage that contains 'sr', 'hr', and 'bs'. Unicode further decided that it's a legacy tag that should be interpreted as 'sr-Latn', which the language matching rules say is mutually intelligible with all those languages. We complicate the example by adding on the region tag 'QU', an old provisional tag for the European Union, which is now standardized as 'EU'. Language.make(language='sr', script='Latn', region='EU') """

        if isinstance(tag, Language):
            if not normalize:
                # shortcut: we have the tag already
                return tag
            
            # We might need to normalize this tag. Convert it back into a
            # string tag, to cover all the edge cases of normalization in a
            # way that we've already solved.
            tag = tag.to_tag()

        if (tag, normalize) in Language._PARSE_CACHE:
            return Language._PARSE_CACHE[tag, normalize]

        data = {}
        # if the complete tag appears as something to normalize, do the
        # normalization right away. Smash case when checking, because the
        # case normalization that comes from parse_tag() hasn't been applied
        # yet.
        tag_lower = tag.lower()
        if normalize and tag_lower in LANGUAGE_REPLACEMENTS:
            tag = LANGUAGE_REPLACEMENTS[tag_lower]

        components = parse_tag(tag)

        for typ, value in components:
            if typ == 'extlang' and normalize and 'language' in data:
                # smash extlangs when possible
                minitag = '%s-%s' % (data['language'], value)
                norm = LANGUAGE_REPLACEMENTS.get(minitag.lower())
                if norm is not None:
                    data.update(
                        Language.get(norm, normalize).to_dict()
                    )
                else:
                    data.setdefault('extlangs', []).append(value)
            elif typ in {'extlang', 'variant', 'extension'}:
                data.setdefault(typ + 's', []).append(value)
            elif typ == 'language':
                if value == 'und':
                    pass
                elif normalize:
                    replacement = LANGUAGE_REPLACEMENTS.get(value.lower())
                    if replacement is not None:
                        # parse the replacement if necessary -- this helps with
                        # Serbian and Moldovan
                        data.update(
                            Language.get(replacement, normalize).to_dict()
                        )
                    else:
                        data['language'] = value
                else:
                    data['language'] = value
            elif typ == 'region':
                if normalize:
                    data['region'] = REGION_REPLACEMENTS.get(value.lower(), value)
                else:
                    data['region'] = value
            elif typ == 'grandfathered':
                # If we got here, we got a grandfathered tag but we were asked
                # not to normalize it, or the CLDR data doesn't know how to
                # normalize it. The best we can do is set the entire tag as the
                # language.
                data['language'] = value
            else:
                data[typ] = value

        result = Language.make(**data)
        Language._PARSE_CACHE[tag, normalize] = result
        return result