<commit_before>#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import inspect
import os.path

from robot.utils import getdoc, is_string, Importer


class Languages:

    def __init__(self, languages):
        self.languages = self._get_languages(languages)
        self.setting_headers = set()
        self.variable_headers = set()
        self.test_case_headers = set()
        self.task_headers = set()
        self.keyword_headers = set()
        self.comment_headers = set()
        self.settings = {}
        self.bdd_prefixes = set()
        for lang in self.languages:
            self.setting_headers |= {h.title() for h in lang.setting_headers}
            self.variable_headers |= {h.title() for h in lang.variable_headers}
            self.test_case_headers |= {h.title() for h in lang.test_case_headers}
            self.task_headers |= {h.title() for h in lang.task_headers}
            self.keyword_headers |= {h.title() for h in lang.keyword_headers}
            self.comment_headers |= {h.title() for h in lang.comment_headers}
            self.settings.update(
                {name.title(): lang.settings[name] for name in lang.settings if name}
            )
            self.bdd_prefixes |= {p.title() for p in lang.bdd_prefixes}

    def _get_languages(self, languages):
        languages = self._resolve_languages(languages)
        available = self._get_available_languages()
        returned = []
        for lang in languages:
            normalized = lang.lower().replace('-', '')
            if normalized in available:
                returned.append(available[normalized])
            else:
                returned.extend(self._import_languages(lang))
        return [subclass() for subclass in returned]

    def _resolve_languages(self, languages):
        if not languages:
            languages = []
        if is_string(languages):
            languages = [languages]
        if 'en' not in languages:
            languages.append('en')
        return languages

    def _get_available_languages(self):
        available = {}
        for lang in Language.__subclasses__():
            available[lang.__name__.lower()] = lang
            if lang.__doc__:
                available[lang.__doc__.lower()] = lang
        return available

    def _import_languages(self, lang):
        def is_language(member):
            return (inspect.isclass(member)
                    and issubclass(member, Language)
                    and member is not Language)
        if os.path.exists(lang):
            lang = os.path.abspath(lang)
        module = Importer('language file').import_module(lang)
        return [value for _, value in inspect.getmembers(module, is_language)]

    def translate_setting(self, name):
        return self.settings.get(name, name)

    def __iter__(self):
        return iter(self.languages)


class Language:
    setting_headers = set()
    variable_headers = set()
    test_case_headers = set()
    task_headers = set()
    keyword_headers = set()
    comment_headers = set()
    library = None
    resource = None
    variables = None
    documentation = None
    metadata = None
    suite_setup = None
    suite_teardown = None
    test_setup = None
    task_setup = None
    test_teardown = None
    task_teardown = None
    test_template = None
    task_template = None
    test_timeout = None
    task_timeout = None
    test_tags = None
    task_tags = None
    keyword_tags = None
    tags = None
    setup = None
    teardown = None
    template = None
    timeout = None
    arguments = None
    bdd_prefixes = set()

    @classmethod
    def from_name(cls, name):
        normalized = name.lower().replace('-', '')
        for subcls in cls.__subclasses__():
            if normalized in (subcls.__name__.lower(), getdoc(subcls).lower()):
                return subcls()
        raise ValueError(f"No language with name '{name}' found.")

    @property
    def settings(self):
        return {
            self.library: En.library,
            self.resource: En.resource,
            self.variables: En.variables,
            self.documentation: En.documentation,
            self.metadata: En.metadata,
            self.suite_setup: En.suite_setup,
            self.suite_teardown: En.suite_teardown,
            self.test_setup: En.test_setup,
            self.task_setup: En.task_setup,
            self.test_teardown: En.test_teardown,
            self.task_teardown: En.task_teardown,
            self.test_template: En.test_template,
            self.task_template: En.task_template,
            self.test_timeout: En.test_timeout,<commit_msg>API doc to Language.from_name<commit_after>#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import inspect
import os.path

from robot.utils import getdoc, is_string, Importer


class Languages:

    def __init__(self, languages):
        self.languages = self._get_languages(languages)
        self.setting_headers = set()
        self.variable_headers = set()
        self.test_case_headers = set()
        self.task_headers = set()
        self.keyword_headers = set()
        self.comment_headers = set()
        self.settings = {}
        self.bdd_prefixes = set()
        for lang in self.languages:
            self.setting_headers |= {h.title() for h in lang.setting_headers}
            self.variable_headers |= {h.title() for h in lang.variable_headers}
            self.test_case_headers |= {h.title() for h in lang.test_case_headers}
            self.task_headers |= {h.title() for h in lang.task_headers}
            self.keyword_headers |= {h.title() for h in lang.keyword_headers}
            self.comment_headers |= {h.title() for h in lang.comment_headers}
            self.settings.update(
                {name.title(): lang.settings[name] for name in lang.settings if name}
            )
            self.bdd_prefixes |= {p.title() for p in lang.bdd_prefixes}

    def _get_languages(self, languages):
        languages = self._resolve_languages(languages)
        available = self._get_available_languages()
        returned = []
        for lang in languages:
            normalized = lang.lower().replace('-', '')
            if normalized in available:
                returned.append(available[normalized])
            else:
                returned.extend(self._import_languages(lang))
        return [subclass() for subclass in returned]

    def _resolve_languages(self, languages):
        if not languages:
            languages = []
        if is_string(languages):
            languages = [languages]
        if 'en' not in languages:
            languages.append('en')
        return languages

    def _get_available_languages(self):
        available = {}
        for lang in Language.__subclasses__():
            available[lang.__name__.lower()] = lang
            if lang.__doc__:
                available[lang.__doc__.lower()] = lang
        return available

    def _import_languages(self, lang):
        def is_language(member):
            return (inspect.isclass(member)
                    and issubclass(member, Language)
                    and member is not Language)
        if os.path.exists(lang):
            lang = os.path.abspath(lang)
        module = Importer('language file').import_module(lang)
        return [value for _, value in inspect.getmembers(module, is_language)]

    def translate_setting(self, name):
        return self.settings.get(name, name)

    def __iter__(self):
        return iter(self.languages)


class Language:
    setting_headers = set()
    variable_headers = set()
    test_case_headers = set()
    task_headers = set()
    keyword_headers = set()
    comment_headers = set()
    library = None
    resource = None
    variables = None
    documentation = None
    metadata = None
    suite_setup = None
    suite_teardown = None
    test_setup = None
    task_setup = None
    test_teardown = None
    task_teardown = None
    test_template = None
    task_template = None
    test_timeout = None
    task_timeout = None
    test_tags = None
    task_tags = None
    keyword_tags = None
    tags = None
    setup = None
    teardown = None
    template = None
    timeout = None
    arguments = None
    bdd_prefixes = set()

    @classmethod
    def from_name(cls, name):
        """Return langauge class based on given `name`.

        Name is matched both against the class name (language short name)
        and possible docstring (full language name). Matching is case-insensitive
        and hyphen (`-`) is ignored to support, for example, `PT-BR`.

        Raises `ValueError` if no matching langauge is found.
        """
        normalized = name.lower().replace('-', '')
        for subcls in cls.__subclasses__():
            if normalized in (subcls.__name__.lower(), getdoc(subcls).lower()):
                return subcls()
        raise ValueError(f"No language with name '{name}' found.")

    @property
    def settings(self):
        return {
            self.library: En.library,
            self.resource: En.resource,
            self.variables: En.variables,
            self.documentation: En.documentation,
            self.metadata: En.metadata,
            self.suite_setup: En.suite_setup,
            self.suite_teardown: En.suite_teardown,
            self.test_setup: En.test_setup,
            self.task_setup: En.task_setup,
            self.test_teardown: En.test_teardown,
            self.task_teardown: En.task_teardown,
            self.test_template: En.test_template,
            self.task_template: En.task_template,
            self.test_timeout: En.test_timeout,
{'fraction_non_alphanumeric': 0.08979818552119978, 'fraction_numerical': 0.0029624143677096835, 'mean_word_length': 2.3158379373848987, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3367823', 'n_tokens_mistral': 3003, 'n_tokens_neox': 2957, 'n_words': 836}