Repository: joke2k/faker

Issue:
New feature: language_name
Hi. I want to add a new method that would return random language name (e.g. English, Spanish, Dutch). I'm not sure where I should place this method. Initially I wanted to add this to BaseProvider near the language_code method, but this provider has no locale support.
Any thoughts?


Discussion:
This information is conveniently available, including percentages of native speakers, which could allow for semi-realistic generation of data: https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers
Just for posterity, here's a quick language provider (in English names) with distribution based on real-world native speakers.

```python
from collections import OrderedDict
from typing import List

from faker.providers import BaseProvider

# List of languages and numer of (millions) of people who speak them, according to
# https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers
# Faker requires this be an OrderedDict for random_elements to work.
_languages = OrderedDict(
    [
        ("Mandarin Chinese", 918,),
        ("Spanish", 480,),
        ("English", 379,),
        ("Hindi", 341,),
        ("Bengali", 228,),
        ("Portuguese", 221,),
        ("Russian", 154,),
        ("Japanese", 128,),
        ("Western Punjabi", 92,),
        ("Marathi", 83,),
        ("Telugu", 82,),
        ("Wu Chinese", 81,),
        ("Turkish", 79,),
        ("Korean", 77,),
        ("French", 77,),
        ("German", 76,),
        ("Vietnamese", 76,),
        ("Tamil", 75,),
        ("Yue Chinese", 73,),
        ("Urdu", 68,),
        ("Javanese", 68,),
        ("Italian", 64,),
        ("Egyptian Arabic", 64,),
        ("Gujarati", 56,),
        ("Iranian Persian", 52,),
        ("Bhojpuri", 52,),
        ("Min Nan Chinese", 50,),
        ("Hakka Chinese", 48,),
        ("Jin Chinese", 46,),
        ("Hausa", 43,),
        ("Kannada", 43,),
        ("Indonesian", 43,),
        ("Polish", 39,),
        ("Yoruba", 37,),
        ("Xiang Chinese", 37,),
        ("Malayalam", 37,),
        ("Odia", 34,),
        ("Maithili", 33,),
        ("Burmese", 32,),
        ("Eastern Punjabi", 32,),
        ("Sunda", 32,),
        ("Sudanese Arabic", 31,),
        ("Algerian Arabic", 29,),
        ("Moroccan Arabic", 27,),
        ("Ukrainian", 27,),
        ("Igbo", 27,),
        ("Northern Uzbek", 25,),
        ("Sindhi", 24,),
        ("North Levantine Arabic", 24,),
        ("Romanian", 24,),
        ("Tagalog", 23,),
        ("Dutch", 23,),
        ("Saʽidi Arabic", 22,),
        ("Gan Chinese", 22,),
        ("Amharic", 21,),
        ("Northern Pashto", 20,),
        ("Magahi", 20,),
        ("Thai", 20,),
        ("Saraiki", 20,),
        ("Khmer", 16,),
        ("Chhattisgarhi", 16,),
        ("Somali", 16,),
        ("Malay (Malaysian Malay)", 16,),
        ("Cebuano", 15,),
        ("Nepali", 15,),
        ("Mesopotamian Arabic", 15,),
        ("Assamese", 15,),
        ("Sinhalese", 15,),
        ("Northern Kurdish", 14,),
        ("Hejazi Arabic", 14,),
        ("Nigerian Fulfulde", 14,),
        ("Bavarian", 14,),
        ("South Azerbaijani", 13,),
        ("Greek", 13,),
        ("Chittagonian", 13,),
        ("Kazakh", 12,),
        ("Deccan", 12,),
        ("Hungarian", 12,),
        ("Kinyarwanda", 12,),
        ("Zulu", 12,),
        ("South Levantine Arabic", 11,),
        ("Tunisian Arabic", 11,),
        ("Sanaani Spoken Arabic", 11,),
        ("Min Bei Chinese", 11,),
        ("Southern Pashto", 10,),
        ("Rundi", 10,),
        ("Czech", 10,),
        ("Taʽizzi-Adeni Arabic", 10,),
        ("Uyghur", 10,),
        ("Min Dong Chinese", 10,),
        ("Sylheti", 10,),
    ]
)


class LanguageProvider(BaseProvider):
    def languages(self, length: int = None, unique: bool = None) -> List[str]:
        return self.random_elements(_languages, length, unique)

    def language(self) -> str:
        return self.languages(1)[0]
```
If anybody wants to submit a PR, I'll be happy to review it!
I do want to submit pr, but I'm still not sure where to put such generator. It should support localization so the BaseProvider is not an option. I'll probably put it into person provider if nobody comes up with a better idea
I'm not sure either, and I don't have a better idea. Go with `person` 👍 

Resolving patch:
diff --git a/faker/providers/person/__init__.py b/faker/providers/person/__init__.py
--- a/faker/providers/person/__init__.py
+++ b/faker/providers/person/__init__.py
@@ -10,6 +10,42 @@ class Provider(BaseProvider):
 
     last_names = ['Doe']
 
+    # https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+    language_names = [
+        'Afar', 'Abkhazian', 'Avestan', 'Afrikaans', 'Akan', 'Amharic',
+        'Aragonese', 'Arabic', 'Assamese', 'Avaric', 'Aymara', 'Azerbaijani',
+        'Bashkir', 'Belarusian', 'Bulgarian', 'Bihari languages', 'Bislama',
+        'Bambara', 'Bengali', 'Tibetan', 'Breton', 'Bosnian', 'Catalan',
+        'Chechen', 'Chamorro', 'Corsican', 'Cree', 'Czech', 'Church Slavic',
+        'Chuvash', 'Welsh', 'Danish', 'German', 'Divehi', 'Dzongkha', 'Ewe',
+        'Greek', 'English', 'Esperanto', 'Spanish', 'Estonian', 'Basque',
+        'Persian', 'Fulah', 'Finnish', 'Fijian', 'Faroese', 'French',
+        'Western Frisian', 'Irish', 'Gaelic', 'Galician', 'Guarani',
+        'Gujarati', 'Manx', 'Hausa', 'Hebrew', 'Hindi', 'Hiri Motu',
+        'Croatian', 'Haitian', 'Hungarian', 'Armenian', 'Herero',
+        'Interlingua', 'Indonesian', 'Interlingue', 'Igbo', 'Sichuan Yi',
+        'Inupiaq', 'Ido', 'Icelandic', 'Italian', 'Inuktitut', 'Japanese',
+        'Javanese', 'Georgian', 'Kongo', 'Kikuyu', 'Kuanyama', 'Kazakh',
+        'Kalaallisut', 'Central Khmer', 'Kannada', 'Korean', 'Kanuri',
+        'Kashmiri', 'Kurdish', 'Komi', 'Cornish', 'Kirghiz', 'Latin',
+        'Luxembourgish', 'Ganda', 'Limburgan', 'Lingala', 'Lao', 'Lithuanian',
+        'Luba-Katanga', 'Latvian', 'Malagasy', 'Marshallese', 'Maori',
+        'Macedonian', 'Malayalam', 'Mongolian', 'Marathi', 'Malay', 'Maltese',
+        'Burmese', 'Nauru', 'North Ndebele', 'Nepali',
+        'Ndonga', 'Dutch', 'Norwegian Nynorsk', 'Norwegian', 'South Ndebele',
+        'Navajo', 'Chichewa', 'Occitan', 'Ojibwa', 'Oromo', 'Oriya',
+        'Ossetian', 'Panjabi', 'Pali', 'Polish', 'Pushto', 'Portuguese',
+        'Quechua', 'Romansh', 'Rundi', 'Romanian', 'Russian', 'Kinyarwanda',
+        'Sanskrit', 'Sardinian', 'Sindhi', 'Northern Sami', 'Sango', 'Sinhala',
+        'Slovak', 'Slovenian', 'Samoan', 'Shona', 'Somali', 'Albanian',
+        'Serbian', 'Swati', 'Sotho, Southern', 'Sundanese', 'Swedish',
+        'Swahili', 'Tamil', 'Telugu', 'Tajik', 'Thai', 'Tigrinya', 'Turkmen',
+        'Tagalog', 'Tswana', 'Tonga', 'Turkish', 'Tsonga', 'Tatar', 'Twi',
+        'Tahitian', 'Uighur', 'Ukrainian', 'Urdu', 'Uzbek', 'Venda',
+        'Vietnamese', 'Walloon', 'Wolof', 'Xhosa', 'Yiddish',
+        'Yoruba', 'Zhuang', 'Chinese', 'Zulu',
+    ]
+
     def name(self):
         """
         :example 'John Doe'
@@ -96,3 +132,7 @@ def suffix_female(self):
         if hasattr(self, 'suffixes_female'):
             return self.random_element(self.suffixes_female)
         return self.suffix()
+
+    def language_name(self):
+        """Generate a random i18n language name (e.g. English)."""
+        return self.random_element(self.language_names)
diff --git a/faker/providers/person/ru_RU/__init__.py b/faker/providers/person/ru_RU/__init__.py
--- a/faker/providers/person/ru_RU/__init__.py
+++ b/faker/providers/person/ru_RU/__init__.py
@@ -272,6 +272,35 @@ class Provider(PersonProvider):
 
     middle_names = middle_names_male + middle_names_female
 
+    language_names = (
+        'Афарский', 'Абхазский', 'Авестийский', 'Африкаанс', 'Акан',
+        'Амхарский', 'Арагонский', 'Арабский', 'Ассамский', 'Аварский',
+        'Аймарский', 'Азербайджанский', 'Башкирский', 'Белорусский',
+        'Болгарский', 'Бислама', 'Бенгальский', 'Тибетский', 'Бретонский',
+        'Боснийский', 'Каталанский', 'Чеченский', 'Чаморро', 'Корсиканский',
+        'Кри', 'Чешский', 'Чувашский', 'Валлийский', 'Датский', 'Немецкий',
+        'Греческий', 'Английский', 'Эсперанто', 'Испанский', 'Эстонский',
+        'Персидский', 'Финский', 'Фиджийский', 'Фарси', 'Французский',
+        'Ирландский', 'Гэльский', 'Галийский', 'Иврит', 'Хинди',
+        'Хорватский', 'Гавайский', 'Болгарский', 'Армянский',
+        'Индонезийский', 'Исландский', 'Итальянский', 'Японский',
+        'Яванский', 'Грузинский', 'Казахский', 'Корейский', 'Кашмири',
+        'Курдский', 'Коми', 'Киргизский', 'Латинский', 'Люксембургский',
+        'Лимбургский', 'Лингала', 'Лаосский', 'Литовский', 'Латвийский',
+        'Малагасийский', 'Маршалльский', 'Маори', 'Македонский', 'Малаялам',
+        'Монгольский', 'Маратхи', 'Малайский', 'Мальтийский', 'Непальский',
+        'Нидерландский', 'Норвежский', 'Навахо', 'Оромо', 'Ория',
+        'Осетинский', 'Пали', 'Польский', 'Пушту', 'Португальский',
+        'Романшский', 'Румынский', 'Русский', 'Киньяруанда',
+        'Санскрит', 'Сардинский', 'Санго', 'Сингальский',
+        'Словацкий', 'Словенский', 'Самоанский', 'Сомалийский', 'Албанский',
+        'Сербский', 'Сунданский', 'Шведский', 'Суахили', 'Тамильский',
+        'Телугу', 'Таджикский', 'Тайский', 'Тигринья', 'Туркменский',
+        'Тагальский', 'Тсвана', 'Тонга', 'Турецкий', 'Тсонга', 'Татарский',
+        'Таитянский', 'Уйгурский', 'Украинский', 'Урду', 'Узбекский', 'Венда',
+        'Вьетнамский', 'Идиш', 'Йоруба', 'Китайский', 'Зулу',
+    )
+
     prefixes_male = ('г-н', 'тов.')
 
     prefixes_female = ('г-жа', 'тов.')


Test patch:
diff --git a/tests/providers/test_person.py b/tests/providers/test_person.py
--- a/tests/providers/test_person.py
+++ b/tests/providers/test_person.py
@@ -594,3 +594,7 @@ def test_name_male(self):
         assert middle_name in RuProvider.middle_names_male
         last_name = self.fake.last_name_male()
         assert last_name in RuProvider.last_names_male
+
+    def test_language_name(self):
+        language_name = self.fake.language_name()
+        assert language_name in RuProvider.language_names