We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Incorrect language set on Provider during locale fallback
* Faker version: 11.3.0

When faker is initialised with a locale not implemented by some of the built-in providers, it falls back to the DEFAULT_LOCALE for these providers. However, the language set on the provider’s instance in `__lang__` is still the requested locale and not the locale in effect.

This is due to `Factory._find_provider_class` not returning the locale it chose, in: https://github.com/joke2k/faker/blob/001ddee39c33b6b82196fe6a5ecc131bca3b964c/faker/factory.py#L102-L104 to `Factory._get_provider_class` which then proceeds to return the locale value as it was passed in at the first place. Thus, `provider.__lang__` does not contain the found locale (as the variable name `lang_found` would suggest): https://github.com/joke2k/faker/blob/001ddee39c33b6b82196fe6a5ecc131bca3b964c/faker/factory.py#L61

### Expected behavior

`provider.__lang__` should be set to the actual language / locale being used by the provider.

### Actual behavior

`provider.__lang__` is set to the locale that was requested but is not offered by this provider.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `faker/documentor.py`
Content:
```
1 import inspect
2 import warnings
3 
4 from typing import Any, Dict, List, Optional, Tuple, Union
5 
6 from .generator import Generator
7 from .providers import BaseProvider
8 from .proxy import Faker
9 
10 
11 class Documentor:
12     def __init__(self, generator: Union[Generator, Faker]) -> None:
13         """
14         :param generator: a localized Generator with providers filled,
15                           for which to write the documentation
16         :type generator: faker.Generator()
17         """
18         self.generator = generator
19         self.max_name_len: int = 0
20         self.already_generated: List[str] = []
21 
22     def get_formatters(
23         self,
24         locale: Optional[str] = None,
25         excludes: Optional[List[str]] = None,
26         **kwargs: Any,
27     ) -> List[Tuple[BaseProvider, Dict[str, str]]]:
28         self.max_name_len = 0
29         self.already_generated = [] if excludes is None else excludes[:]
30         formatters = []
31         providers: List[BaseProvider] = self.generator.get_providers()
32         for provider in providers[::-1]:  # reverse
33             if locale and provider.__lang__ != locale:
34                 continue
35             formatters.append(
36                 (provider, self.get_provider_formatters(provider, **kwargs)),
37             )
38         return formatters
39 
40     def get_provider_formatters(
41         self,
42         provider: BaseProvider,
43         prefix: str = "fake.",
44         with_args: bool = True,
45         with_defaults: bool = True,
46     ) -> Dict[str, str]:
47         formatters = {}
48 
49         for name, method in inspect.getmembers(provider, inspect.ismethod):
50             # skip 'private' method and inherited methods
51             if name.startswith("_") or name in self.already_generated:
52                 continue
53 
54             arguments = []
55             faker_args: List[str] = []
56             faker_kwargs = {}
57 
58             if name == "binary":
59                 faker_kwargs["length"] = 1024
60             elif name in ["zip", "tar"]:
61                 faker_kwargs.update(
62                     {
63                         "uncompressed_size": 1024,
64                         "min_file_size": 512,
65                     }
66                 )
67 
68             if with_args:
69                 # retrieve all parameter
70                 argspec = inspect.getfullargspec(method)
71 
72                 lst = [x for x in argspec.args if x not in ["self", "cls"]]
73                 for i, arg in enumerate(lst):
74 
75                     if argspec.defaults and with_defaults:
76 
77                         try:
78                             default = argspec.defaults[i]
79                             if isinstance(default, str):
80                                 default = repr(default)
81                             else:
82                                 # TODO check default type
83                                 default = f"{default}"
84 
85                             arg = f"{arg}={default}"
86 
87                         except IndexError:
88                             pass
89 
90                     arguments.append(arg)
91                     if with_args == "first":
92                         break
93 
94                 if with_args != "first":
95                     if argspec.varargs:
96                         arguments.append("*" + argspec.varargs)
97                     if argspec.varkw:
98                         arguments.append("**" + argspec.varkw)
99 
100             # build fake method signature
101             signature = f"{prefix}{name}({', '.join(arguments)})"
102 
103             try:
104                 # make a fake example
105                 example = self.generator.format(name, *faker_args, **faker_kwargs)
106             except (AttributeError, ValueError) as e:
107                 warnings.warn(str(e))
108                 continue
109             formatters[signature] = example
110 
111             self.max_name_len = max(self.max_name_len, len(signature))
112             self.already_generated.append(name)
113 
114         return formatters
115 
116     @staticmethod
117     def get_provider_name(provider_class: BaseProvider) -> str:
118         return provider_class.__provider__
119
```

Path: `faker/factory.py`
Content:
```
1 import locale as pylocale
2 import logging
3 import sys
4 
5 from importlib import import_module
6 from typing import Any, List, Optional, Tuple
7 
8 from .config import AVAILABLE_LOCALES, DEFAULT_LOCALE, PROVIDERS
9 from .generator import Generator
10 from .utils.loading import list_module
11 
12 logger = logging.getLogger(__name__)
13 
14 # identify if python is being run in interactive mode. If so, disable logging.
15 inREPL = bool(getattr(sys, "ps1", False))
16 if inREPL:
17     logger.setLevel(logging.CRITICAL)
18 else:
19     logger.debug("Not in REPL -> leaving logger event level as is.")
20 
21 
22 class Factory:
23     @classmethod
24     def create(
25         cls,
26         locale: Optional[str] = None,
27         providers: Optional[List[str]] = None,
28         generator: Generator = None,
29         includes: Optional[List[str]] = None,
30         # Should we use weightings (more realistic) or weight every element equally (faster)?
31         # By default, use weightings for backwards compatibility & realism
32         use_weighting: bool = True,
33         **config: Any,
34     ) -> Generator:
35         if includes is None:
36             includes = []
37 
38         # fix locale to package name
39         locale = locale.replace("-", "_") if locale else DEFAULT_LOCALE
40         locale = pylocale.normalize(locale).split(".")[0]
41         if locale not in AVAILABLE_LOCALES:
42             msg = f"Invalid configuration for faker locale `{locale}`"
43             raise AttributeError(msg)
44 
45         config["locale"] = locale
46         config["use_weighting"] = use_weighting
47         providers = providers or PROVIDERS
48 
49         providers += includes
50 
51         faker = generator or Generator(**config)
52 
53         for prov_name in providers:
54             if prov_name == "faker.providers":
55                 continue
56 
57             prov_cls, lang_found = cls._get_provider_class(prov_name, locale)
58             provider = prov_cls(faker)
59             provider.__use_weighting__ = use_weighting
60             provider.__provider__ = prov_name
61             provider.__lang__ = lang_found
62             faker.add_provider(provider)
63 
64         return faker
65 
66     @classmethod
67     def _get_provider_class(cls, provider: str, locale: Optional[str] = "") -> Tuple[Any, Optional[str]]:
68 
69         provider_class = cls._find_provider_class(provider, locale)
70 
71         if provider_class:
72             return provider_class, locale
73 
74         if locale and locale != DEFAULT_LOCALE:
75             # fallback to default locale
76             provider_class = cls._find_provider_class(provider, DEFAULT_LOCALE)
77             if provider_class:
78                 return provider_class, DEFAULT_LOCALE
79 
80         # fallback to no locale
81         provider_class = cls._find_provider_class(provider)
82         if provider_class:
83             return provider_class, None
84 
85         msg = f"Unable to find provider `{provider}` with locale `{locale}`"
86         raise ValueError(msg)
87 
88     @classmethod
89     def _find_provider_class(cls, provider_path: str, locale: Optional[str] = None) -> Any:
90 
91         provider_module = import_module(provider_path)
92 
93         if getattr(provider_module, "localized", False):
94 
95             logger.debug(
96                 "Looking for locale `%s` in provider `%s`.",
97                 locale,
98                 provider_module.__name__,
99             )
100 
101             available_locales = list_module(provider_module)
102             if not locale or locale not in available_locales:
103                 unavailable_locale = locale
104                 locale = getattr(provider_module, "default_locale", DEFAULT_LOCALE)
105                 logger.debug(
106                     "Specified locale `%s` is not available for "
107                     "provider `%s`. Locale reset to `%s` for this "
108                     "provider.",
109                     unavailable_locale,
110                     provider_module.__name__,
111                     locale,
112                 )
113             else:
114                 logger.debug(
115                     "Provider `%s` has been localized to `%s`.",
116                     provider_module.__name__,
117                     locale,
118                 )
119 
120             path = f"{provider_path}.{locale}"
121             provider_module = import_module(path)
122 
123         else:
124 
125             logger.debug(
126                 "Provider `%s` does not feature localization. "
127                 "Specified locale `%s` is not utilized for this "
128                 "provider.",
129                 provider_module.__name__,
130                 locale,
131             )
132 
133             if locale is not None:
134                 provider_module = import_module(provider_path)
135 
136         return provider_module.Provider  # type: ignore
137
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/faker/documentor.py b/faker/documentor.py
--- a/faker/documentor.py
+++ b/faker/documentor.py
@@ -30,7 +30,7 @@
         formatters = []
         providers: List[BaseProvider] = self.generator.get_providers()
         for provider in providers[::-1]:  # reverse
-            if locale and provider.__lang__ != locale:
+            if locale and provider.__lang__ and provider.__lang__ != locale:
                 continue
             formatters.append(
                 (provider, self.get_provider_formatters(provider, **kwargs)),
diff --git a/faker/factory.py b/faker/factory.py
--- a/faker/factory.py
+++ b/faker/factory.py
@@ -54,7 +54,7 @@
             if prov_name == "faker.providers":
                 continue
 
-            prov_cls, lang_found = cls._get_provider_class(prov_name, locale)
+            prov_cls, lang_found, _ = cls._find_provider_class(prov_name, locale)
             provider = prov_cls(faker)
             provider.__use_weighting__ = use_weighting
             provider.__provider__ = prov_name
@@ -64,31 +64,14 @@
         return faker
 
     @classmethod
-    def _get_provider_class(cls, provider: str, locale: Optional[str] = "") -> Tuple[Any, Optional[str]]:
-
-        provider_class = cls._find_provider_class(provider, locale)
-
-        if provider_class:
-            return provider_class, locale
-
-        if locale and locale != DEFAULT_LOCALE:
-            # fallback to default locale
-            provider_class = cls._find_provider_class(provider, DEFAULT_LOCALE)
-            if provider_class:
-                return provider_class, DEFAULT_LOCALE
-
-        # fallback to no locale
-        provider_class = cls._find_provider_class(provider)
-        if provider_class:
-            return provider_class, None
-
-        msg = f"Unable to find provider `{provider}` with locale `{locale}`"
-        raise ValueError(msg)
-
-    @classmethod
-    def _find_provider_class(cls, provider_path: str, locale: Optional[str] = None) -> Any:
+    def _find_provider_class(
+        cls,
+        provider_path: str,
+        locale: Optional[str] = None,
+    ) -> Tuple[Any, Optional[str], Optional[str]]:
 
         provider_module = import_module(provider_path)
+        default_locale = getattr(provider_module, "default_locale", "")
 
         if getattr(provider_module, "localized", False):
 
@@ -101,7 +84,7 @@
             available_locales = list_module(provider_module)
             if not locale or locale not in available_locales:
                 unavailable_locale = locale
-                locale = getattr(provider_module, "default_locale", DEFAULT_LOCALE)
+                locale = default_locale or DEFAULT_LOCALE
                 logger.debug(
                     "Specified locale `%s` is not available for "
                     "provider `%s`. Locale reset to `%s` for this "
@@ -122,15 +105,14 @@
 
         else:
 
-            logger.debug(
-                "Provider `%s` does not feature localization. "
-                "Specified locale `%s` is not utilized for this "
-                "provider.",
-                provider_module.__name__,
-                locale,
-            )
-
-            if locale is not None:
-                provider_module = import_module(provider_path)
+            if locale:
+                logger.debug(
+                    "Provider `%s` does not feature localization. "
+                    "Specified locale `%s` is not utilized for this "
+                    "provider.",
+                    provider_module.__name__,
+                    locale,
+                )
+            locale = default_locale = None
 
-        return provider_module.Provider  # type: ignore
+        return provider_module.Provider, locale, default_locale  # type: ignore

{"golden_diff": "diff --git a/faker/documentor.py b/faker/documentor.py\n--- a/faker/documentor.py\n+++ b/faker/documentor.py\n@@ -30,7 +30,7 @@\n         formatters = []\n         providers: List[BaseProvider] = self.generator.get_providers()\n         for provider in providers[::-1]:  # reverse\n-            if locale and provider.__lang__ != locale:\n+            if locale and provider.__lang__ and provider.__lang__ != locale:\n                 continue\n             formatters.append(\n                 (provider, self.get_provider_formatters(provider, **kwargs)),\ndiff --git a/faker/factory.py b/faker/factory.py\n--- a/faker/factory.py\n+++ b/faker/factory.py\n@@ -54,7 +54,7 @@\n             if prov_name == \"faker.providers\":\n                 continue\n \n-            prov_cls, lang_found = cls._get_provider_class(prov_name, locale)\n+            prov_cls, lang_found, _ = cls._find_provider_class(prov_name, locale)\n             provider = prov_cls(faker)\n             provider.__use_weighting__ = use_weighting\n             provider.__provider__ = prov_name\n@@ -64,31 +64,14 @@\n         return faker\n \n     @classmethod\n-    def _get_provider_class(cls, provider: str, locale: Optional[str] = \"\") -> Tuple[Any, Optional[str]]:\n-\n-        provider_class = cls._find_provider_class(provider, locale)\n-\n-        if provider_class:\n-            return provider_class, locale\n-\n-        if locale and locale != DEFAULT_LOCALE:\n-            # fallback to default locale\n-            provider_class = cls._find_provider_class(provider, DEFAULT_LOCALE)\n-            if provider_class:\n-                return provider_class, DEFAULT_LOCALE\n-\n-        # fallback to no locale\n-        provider_class = cls._find_provider_class(provider)\n-        if provider_class:\n-            return provider_class, None\n-\n-        msg = f\"Unable to find provider `{provider}` with locale `{locale}`\"\n-        raise ValueError(msg)\n-\n-    @classmethod\n-    def _find_provider_class(cls, provider_path: str, locale: Optional[str] = None) -> Any:\n+    def _find_provider_class(\n+        cls,\n+        provider_path: str,\n+        locale: Optional[str] = None,\n+    ) -> Tuple[Any, Optional[str], Optional[str]]:\n \n         provider_module = import_module(provider_path)\n+        default_locale = getattr(provider_module, \"default_locale\", \"\")\n \n         if getattr(provider_module, \"localized\", False):\n \n@@ -101,7 +84,7 @@\n             available_locales = list_module(provider_module)\n             if not locale or locale not in available_locales:\n                 unavailable_locale = locale\n-                locale = getattr(provider_module, \"default_locale\", DEFAULT_LOCALE)\n+                locale = default_locale or DEFAULT_LOCALE\n                 logger.debug(\n                     \"Specified locale `%s` is not available for \"\n                     \"provider `%s`. Locale reset to `%s` for this \"\n@@ -122,15 +105,14 @@\n \n         else:\n \n-            logger.debug(\n-                \"Provider `%s` does not feature localization. \"\n-                \"Specified locale `%s` is not utilized for this \"\n-                \"provider.\",\n-                provider_module.__name__,\n-                locale,\n-            )\n-\n-            if locale is not None:\n-                provider_module = import_module(provider_path)\n+            if locale:\n+                logger.debug(\n+                    \"Provider `%s` does not feature localization. \"\n+                    \"Specified locale `%s` is not utilized for this \"\n+                    \"provider.\",\n+                    provider_module.__name__,\n+                    locale,\n+                )\n+            locale = default_locale = None\n \n-        return provider_module.Provider  # type: ignore\n+        return provider_module.Provider, locale, default_locale  # type: ignore\n", "issue": "Incorrect language set on Provider during locale fallback\n* Faker version: 11.3.0\r\n\r\nWhen faker is initialised with a locale not implemented by some of the built-in providers, it falls back to the DEFAULT_LOCALE for these providers. However, the language set on the provider\u2019s instance in `__lang__` is still the requested locale and not the locale in effect.\r\n\r\nThis is due to `Factory._find_provider_class` not returning the locale it chose, in: https://github.com/joke2k/faker/blob/001ddee39c33b6b82196fe6a5ecc131bca3b964c/faker/factory.py#L102-L104 to `Factory._get_provider_class` which then proceeds to return the locale value as it was passed in at the first place. Thus, `provider.__lang__` does not contain the found locale (as the variable name `lang_found` would suggest): https://github.com/joke2k/faker/blob/001ddee39c33b6b82196fe6a5ecc131bca3b964c/faker/factory.py#L61\r\n\r\n### Expected behavior\r\n\r\n`provider.__lang__` should be set to the actual language / locale being used by the provider.\r\n\r\n### Actual behavior\r\n\r\n`provider.__lang__` is set to the locale that was requested but is not offered by this provider.\n", "before_files": [{"content": "import inspect\nimport warnings\n\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom .generator import Generator\nfrom .providers import BaseProvider\nfrom .proxy import Faker\n\n\nclass Documentor:\n    def __init__(self, generator: Union[Generator, Faker]) -> None:\n        \"\"\"\n        :param generator: a localized Generator with providers filled,\n                          for which to write the documentation\n        :type generator: faker.Generator()\n        \"\"\"\n        self.generator = generator\n        self.max_name_len: int = 0\n        self.already_generated: List[str] = []\n\n    def get_formatters(\n        self,\n        locale: Optional[str] = None,\n        excludes: Optional[List[str]] = None,\n        **kwargs: Any,\n    ) -> List[Tuple[BaseProvider, Dict[str, str]]]:\n        self.max_name_len = 0\n        self.already_generated = [] if excludes is None else excludes[:]\n        formatters = []\n        providers: List[BaseProvider] = self.generator.get_providers()\n        for provider in providers[::-1]:  # reverse\n            if locale and provider.__lang__ != locale:\n                continue\n            formatters.append(\n                (provider, self.get_provider_formatters(provider, **kwargs)),\n            )\n        return formatters\n\n    def get_provider_formatters(\n        self,\n        provider: BaseProvider,\n        prefix: str = \"fake.\",\n        with_args: bool = True,\n        with_defaults: bool = True,\n    ) -> Dict[str, str]:\n        formatters = {}\n\n        for name, method in inspect.getmembers(provider, inspect.ismethod):\n            # skip 'private' method and inherited methods\n            if name.startswith(\"_\") or name in self.already_generated:\n                continue\n\n            arguments = []\n            faker_args: List[str] = []\n            faker_kwargs = {}\n\n            if name == \"binary\":\n                faker_kwargs[\"length\"] = 1024\n            elif name in [\"zip\", \"tar\"]:\n                faker_kwargs.update(\n                    {\n                        \"uncompressed_size\": 1024,\n                        \"min_file_size\": 512,\n                    }\n                )\n\n            if with_args:\n                # retrieve all parameter\n                argspec = inspect.getfullargspec(method)\n\n                lst = [x for x in argspec.args if x not in [\"self\", \"cls\"]]\n                for i, arg in enumerate(lst):\n\n                    if argspec.defaults and with_defaults:\n\n                        try:\n                            default = argspec.defaults[i]\n                            if isinstance(default, str):\n                                default = repr(default)\n                            else:\n                                # TODO check default type\n                                default = f\"{default}\"\n\n                            arg = f\"{arg}={default}\"\n\n                        except IndexError:\n                            pass\n\n                    arguments.append(arg)\n                    if with_args == \"first\":\n                        break\n\n                if with_args != \"first\":\n                    if argspec.varargs:\n                        arguments.append(\"*\" + argspec.varargs)\n                    if argspec.varkw:\n                        arguments.append(\"**\" + argspec.varkw)\n\n            # build fake method signature\n            signature = f\"{prefix}{name}({', '.join(arguments)})\"\n\n            try:\n                # make a fake example\n                example = self.generator.format(name, *faker_args, **faker_kwargs)\n            except (AttributeError, ValueError) as e:\n                warnings.warn(str(e))\n                continue\n            formatters[signature] = example\n\n            self.max_name_len = max(self.max_name_len, len(signature))\n            self.already_generated.append(name)\n\n        return formatters\n\n    @staticmethod\n    def get_provider_name(provider_class: BaseProvider) -> str:\n        return provider_class.__provider__\n", "path": "faker/documentor.py"}, {"content": "import locale as pylocale\nimport logging\nimport sys\n\nfrom importlib import import_module\nfrom typing import Any, List, Optional, Tuple\n\nfrom .config import AVAILABLE_LOCALES, DEFAULT_LOCALE, PROVIDERS\nfrom .generator import Generator\nfrom .utils.loading import list_module\n\nlogger = logging.getLogger(__name__)\n\n# identify if python is being run in interactive mode. If so, disable logging.\ninREPL = bool(getattr(sys, \"ps1\", False))\nif inREPL:\n    logger.setLevel(logging.CRITICAL)\nelse:\n    logger.debug(\"Not in REPL -> leaving logger event level as is.\")\n\n\nclass Factory:\n    @classmethod\n    def create(\n        cls,\n        locale: Optional[str] = None,\n        providers: Optional[List[str]] = None,\n        generator: Generator = None,\n        includes: Optional[List[str]] = None,\n        # Should we use weightings (more realistic) or weight every element equally (faster)?\n        # By default, use weightings for backwards compatibility & realism\n        use_weighting: bool = True,\n        **config: Any,\n    ) -> Generator:\n        if includes is None:\n            includes = []\n\n        # fix locale to package name\n        locale = locale.replace(\"-\", \"_\") if locale else DEFAULT_LOCALE\n        locale = pylocale.normalize(locale).split(\".\")[0]\n        if locale not in AVAILABLE_LOCALES:\n            msg = f\"Invalid configuration for faker locale `{locale}`\"\n            raise AttributeError(msg)\n\n        config[\"locale\"] = locale\n        config[\"use_weighting\"] = use_weighting\n        providers = providers or PROVIDERS\n\n        providers += includes\n\n        faker = generator or Generator(**config)\n\n        for prov_name in providers:\n            if prov_name == \"faker.providers\":\n                continue\n\n            prov_cls, lang_found = cls._get_provider_class(prov_name, locale)\n            provider = prov_cls(faker)\n            provider.__use_weighting__ = use_weighting\n            provider.__provider__ = prov_name\n            provider.__lang__ = lang_found\n            faker.add_provider(provider)\n\n        return faker\n\n    @classmethod\n    def _get_provider_class(cls, provider: str, locale: Optional[str] = \"\") -> Tuple[Any, Optional[str]]:\n\n        provider_class = cls._find_provider_class(provider, locale)\n\n        if provider_class:\n            return provider_class, locale\n\n        if locale and locale != DEFAULT_LOCALE:\n            # fallback to default locale\n            provider_class = cls._find_provider_class(provider, DEFAULT_LOCALE)\n            if provider_class:\n                return provider_class, DEFAULT_LOCALE\n\n        # fallback to no locale\n        provider_class = cls._find_provider_class(provider)\n        if provider_class:\n            return provider_class, None\n\n        msg = f\"Unable to find provider `{provider}` with locale `{locale}`\"\n        raise ValueError(msg)\n\n    @classmethod\n    def _find_provider_class(cls, provider_path: str, locale: Optional[str] = None) -> Any:\n\n        provider_module = import_module(provider_path)\n\n        if getattr(provider_module, \"localized\", False):\n\n            logger.debug(\n                \"Looking for locale `%s` in provider `%s`.\",\n                locale,\n                provider_module.__name__,\n            )\n\n            available_locales = list_module(provider_module)\n            if not locale or locale not in available_locales:\n                unavailable_locale = locale\n                locale = getattr(provider_module, \"default_locale\", DEFAULT_LOCALE)\n                logger.debug(\n                    \"Specified locale `%s` is not available for \"\n                    \"provider `%s`. Locale reset to `%s` for this \"\n                    \"provider.\",\n                    unavailable_locale,\n                    provider_module.__name__,\n                    locale,\n                )\n            else:\n                logger.debug(\n                    \"Provider `%s` has been localized to `%s`.\",\n                    provider_module.__name__,\n                    locale,\n                )\n\n            path = f\"{provider_path}.{locale}\"\n            provider_module = import_module(path)\n\n        else:\n\n            logger.debug(\n                \"Provider `%s` does not feature localization. \"\n                \"Specified locale `%s` is not utilized for this \"\n                \"provider.\",\n                provider_module.__name__,\n                locale,\n            )\n\n            if locale is not None:\n                provider_module = import_module(provider_path)\n\n        return provider_module.Provider  # type: ignore\n", "path": "faker/factory.py"}], "after_files": [{"content": "import inspect\nimport warnings\n\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom .generator import Generator\nfrom .providers import BaseProvider\nfrom .proxy import Faker\n\n\nclass Documentor:\n    def __init__(self, generator: Union[Generator, Faker]) -> None:\n        \"\"\"\n        :param generator: a localized Generator with providers filled,\n                          for which to write the documentation\n        :type generator: faker.Generator()\n        \"\"\"\n        self.generator = generator\n        self.max_name_len: int = 0\n        self.already_generated: List[str] = []\n\n    def get_formatters(\n        self,\n        locale: Optional[str] = None,\n        excludes: Optional[List[str]] = None,\n        **kwargs: Any,\n    ) -> List[Tuple[BaseProvider, Dict[str, str]]]:\n        self.max_name_len = 0\n        self.already_generated = [] if excludes is None else excludes[:]\n        formatters = []\n        providers: List[BaseProvider] = self.generator.get_providers()\n        for provider in providers[::-1]:  # reverse\n            if locale and provider.__lang__ and provider.__lang__ != locale:\n                continue\n            formatters.append(\n                (provider, self.get_provider_formatters(provider, **kwargs)),\n            )\n        return formatters\n\n    def get_provider_formatters(\n        self,\n        provider: BaseProvider,\n        prefix: str = \"fake.\",\n        with_args: bool = True,\n        with_defaults: bool = True,\n    ) -> Dict[str, str]:\n        formatters = {}\n\n        for name, method in inspect.getmembers(provider, inspect.ismethod):\n            # skip 'private' method and inherited methods\n            if name.startswith(\"_\") or name in self.already_generated:\n                continue\n\n            arguments = []\n            faker_args: List[str] = []\n            faker_kwargs = {}\n\n            if name == \"binary\":\n                faker_kwargs[\"length\"] = 1024\n            elif name in [\"zip\", \"tar\"]:\n                faker_kwargs.update(\n                    {\n                        \"uncompressed_size\": 1024,\n                        \"min_file_size\": 512,\n                    }\n                )\n\n            if with_args:\n                # retrieve all parameter\n                argspec = inspect.getfullargspec(method)\n\n                lst = [x for x in argspec.args if x not in [\"self\", \"cls\"]]\n                for i, arg in enumerate(lst):\n\n                    if argspec.defaults and with_defaults:\n\n                        try:\n                            default = argspec.defaults[i]\n                            if isinstance(default, str):\n                                default = repr(default)\n                            else:\n                                # TODO check default type\n                                default = f\"{default}\"\n\n                            arg = f\"{arg}={default}\"\n\n                        except IndexError:\n                            pass\n\n                    arguments.append(arg)\n                    if with_args == \"first\":\n                        break\n\n                if with_args != \"first\":\n                    if argspec.varargs:\n                        arguments.append(\"*\" + argspec.varargs)\n                    if argspec.varkw:\n                        arguments.append(\"**\" + argspec.varkw)\n\n            # build fake method signature\n            signature = f\"{prefix}{name}({', '.join(arguments)})\"\n\n            try:\n                # make a fake example\n                example = self.generator.format(name, *faker_args, **faker_kwargs)\n            except (AttributeError, ValueError) as e:\n                warnings.warn(str(e))\n                continue\n            formatters[signature] = example\n\n            self.max_name_len = max(self.max_name_len, len(signature))\n            self.already_generated.append(name)\n\n        return formatters\n\n    @staticmethod\n    def get_provider_name(provider_class: BaseProvider) -> str:\n        return provider_class.__provider__\n", "path": "faker/documentor.py"}, {"content": "import locale as pylocale\nimport logging\nimport sys\n\nfrom importlib import import_module\nfrom typing import Any, List, Optional, Tuple\n\nfrom .config import AVAILABLE_LOCALES, DEFAULT_LOCALE, PROVIDERS\nfrom .generator import Generator\nfrom .utils.loading import list_module\n\nlogger = logging.getLogger(__name__)\n\n# identify if python is being run in interactive mode. If so, disable logging.\ninREPL = bool(getattr(sys, \"ps1\", False))\nif inREPL:\n    logger.setLevel(logging.CRITICAL)\nelse:\n    logger.debug(\"Not in REPL -> leaving logger event level as is.\")\n\n\nclass Factory:\n    @classmethod\n    def create(\n        cls,\n        locale: Optional[str] = None,\n        providers: Optional[List[str]] = None,\n        generator: Generator = None,\n        includes: Optional[List[str]] = None,\n        # Should we use weightings (more realistic) or weight every element equally (faster)?\n        # By default, use weightings for backwards compatibility & realism\n        use_weighting: bool = True,\n        **config: Any,\n    ) -> Generator:\n        if includes is None:\n            includes = []\n\n        # fix locale to package name\n        locale = locale.replace(\"-\", \"_\") if locale else DEFAULT_LOCALE\n        locale = pylocale.normalize(locale).split(\".\")[0]\n        if locale not in AVAILABLE_LOCALES:\n            msg = f\"Invalid configuration for faker locale `{locale}`\"\n            raise AttributeError(msg)\n\n        config[\"locale\"] = locale\n        config[\"use_weighting\"] = use_weighting\n        providers = providers or PROVIDERS\n\n        providers += includes\n\n        faker = generator or Generator(**config)\n\n        for prov_name in providers:\n            if prov_name == \"faker.providers\":\n                continue\n\n            prov_cls, lang_found, _ = cls._find_provider_class(prov_name, locale)\n            provider = prov_cls(faker)\n            provider.__use_weighting__ = use_weighting\n            provider.__provider__ = prov_name\n            provider.__lang__ = lang_found\n            faker.add_provider(provider)\n\n        return faker\n\n    @classmethod\n    def _find_provider_class(\n        cls,\n        provider_path: str,\n        locale: Optional[str] = None,\n    ) -> Tuple[Any, Optional[str], Optional[str]]:\n\n        provider_module = import_module(provider_path)\n        default_locale = getattr(provider_module, \"default_locale\", \"\")\n\n        if getattr(provider_module, \"localized\", False):\n\n            logger.debug(\n                \"Looking for locale `%s` in provider `%s`.\",\n                locale,\n                provider_module.__name__,\n            )\n\n            available_locales = list_module(provider_module)\n            if not locale or locale not in available_locales:\n                unavailable_locale = locale\n                locale = default_locale or DEFAULT_LOCALE\n                logger.debug(\n                    \"Specified locale `%s` is not available for \"\n                    \"provider `%s`. Locale reset to `%s` for this \"\n                    \"provider.\",\n                    unavailable_locale,\n                    provider_module.__name__,\n                    locale,\n                )\n            else:\n                logger.debug(\n                    \"Provider `%s` has been localized to `%s`.\",\n                    provider_module.__name__,\n                    locale,\n                )\n\n            path = f\"{provider_path}.{locale}\"\n            provider_module = import_module(path)\n\n        else:\n\n            if locale:\n                logger.debug(\n                    \"Provider `%s` does not feature localization. \"\n                    \"Specified locale `%s` is not utilized for this \"\n                    \"provider.\",\n                    provider_module.__name__,\n                    locale,\n                )\n            locale = default_locale = None\n\n        return provider_module.Provider, locale, default_locale  # type: ignore\n", "path": "faker/factory.py"}]}