prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  NumberPrompt Locale Not Fully Implemented
  ## Version
  v4.5
  
  ## Describe the bug
  Found this bug while investigating for parity with regards to this [`NumberPrompt` bug filed in the dotnet repo](https://github.com/microsoft/botbuilder-dotnet/issues/2288)
  * in constructor, `default_locale` attribute is set, but never used in `NumberPrompt`'s implementation (not in `on_prompt()` nor `on_recognize()`
  * `on_recognize()` does allow you to pass in `locale` via `Activity`, however locale will not be used if only `default_locale` is specified
  * "`English`" is used as string to specify locale, when we should be using the constants provided by the python recognizers-text repo
  
  * Separately, there's definitely a lack of unit test coverage for this feature (only 2 tests written)
  
  ## Expected behavior
  * implement use of `default_locale`
  * implement use of recognizers-text constants to specify locale
  
  
  
  [bug]
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py`
  Content:
  ```
  1 # Copyright (c) Microsoft Corporation. All rights reserved.
  2 # Licensed under the MIT License.
  3 
  4 from typing import Dict
  5 from recognizers_number import recognize_number
  6 from botbuilder.core.turn_context import TurnContext
  7 from botbuilder.schema import ActivityTypes
  8 from .prompt import Prompt
  9 from .prompt_options import PromptOptions
  10 from .prompt_recognizer_result import PromptRecognizerResult
  11 
  12 
  13 class NumberPrompt(Prompt):
  14     # TODO: PromptValidator
  15     def __init__(self, dialog_id: str, validator: object, default_locale: str):
  16         super(NumberPrompt, self).__init__(dialog_id, validator)
  17         self.default_locale = default_locale
  18 
  19     async def on_prompt(
  20         self,
  21         turn_context: TurnContext,
  22         state: Dict[str, object],
  23         options: PromptOptions,
  24         is_retry: bool,
  25     ):
  26         if not turn_context:
  27             raise TypeError("NumberPrompt.on_prompt(): turn_context cannot be None.")
  28         if not options:
  29             raise TypeError("NumberPrompt.on_prompt(): options cannot be None.")
  30 
  31         if is_retry and options.retry_prompt is not None:
  32             turn_context.send_activity(options.retry_prompt)
  33         else:
  34             if options.prompt is not None:
  35                 await turn_context.send_activity(options.prompt)
  36 
  37     async def on_recognize(
  38         self,
  39         turn_context: TurnContext,
  40         state: Dict[str, object],
  41         options: PromptOptions,
  42     ) -> PromptRecognizerResult:
  43         if not turn_context:
  44             raise TypeError("NumberPrompt.on_recognize(): turn_context cannot be None.")
  45 
  46         result = PromptRecognizerResult()
  47         if turn_context.activity.type == ActivityTypes.message:
  48             message = turn_context.activity
  49 
  50             # TODO: Fix constant English with correct constant from text recognizer
  51             culture = (
  52                 turn_context.activity.locale
  53                 if turn_context.activity.locale is not None
  54                 else "English"
  55             )
  56 
  57             results = recognize_number(message.text, culture)
  58             if results:
  59                 result.succeeded = True
  60                 result.value = results[0].resolution["value"]
  61 
  62         return result
  63
  ```
  
  Path: `libraries/botbuilder-dialogs/setup.py`
  Content:
  ```
  1 # Copyright (c) Microsoft Corporation. All rights reserved.
  2 # Licensed under the MIT License.
  3 
  4 import os
  5 from setuptools import setup
  6 
  7 REQUIRES = [
  8     "recognizers-text-date-time>=1.0.1a0",
  9     "recognizers-text-number-with-unit>=1.0.1a0",
  10     "recognizers-text-number>=1.0.1a0",
  11     "recognizers-text>=1.0.1a0",
  12     "recognizers-text-choice>=1.0.1a0",
  13     "grapheme>=0.5.0",
  14     "emoji>=0.5.2",
  15     "botbuilder-schema>=4.4.0b1",
  16     "botframework-connector>=4.4.0b1",
  17     "botbuilder-core>=4.4.0b1",
  18 ]
  19 
  20 TEST_REQUIRES = ["aiounittest>=1.1.0"]
  21 
  22 root = os.path.abspath(os.path.dirname(__file__))
  23 
  24 with open(os.path.join(root, "botbuilder", "dialogs", "about.py")) as f:
  25     package_info = {}
  26     info = f.read()
  27     exec(info, package_info)
  28 
  29 with open(os.path.join(root, "README.rst"), encoding="utf-8") as f:
  30     long_description = f.read()
  31 
  32 setup(
  33     name=package_info["__title__"],
  34     version=package_info["__version__"],
  35     url=package_info["__uri__"],
  36     author=package_info["__author__"],
  37     description=package_info["__description__"],
  38     keywords=["BotBuilderDialogs", "bots", "ai", "botframework", "botbuilder"],
  39     long_description=long_description,
  40     long_description_content_type="text/x-rst",
  41     license=package_info["__license__"],
  42     packages=[
  43         "botbuilder.dialogs",
  44         "botbuilder.dialogs.prompts",
  45         "botbuilder.dialogs.choices",
  46     ],
  47     install_requires=REQUIRES + TEST_REQUIRES,
  48     tests_require=TEST_REQUIRES,
  49     include_package_data=True,
  50     classifiers=[
  51         "Programming Language :: Python :: 3.7",
  52         "Intended Audience :: Developers",
  53         "License :: OSI Approved :: MIT License",
  54         "Operating System :: OS Independent",
  55         "Development Status :: 3 - Alpha",
  56         "Topic :: Scientific/Engineering :: Artificial Intelligence",
  57     ],
  58 )
  59
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py
  --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py
  +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py
  @@ -1,18 +1,29 @@
   # Copyright (c) Microsoft Corporation. All rights reserved.
   # Licensed under the MIT License.
   
  -from typing import Dict
  +from typing import Callable, Dict
  +
  +from babel.numbers import parse_decimal
   from recognizers_number import recognize_number
  +from recognizers_text import Culture, ModelResult
  +
   from botbuilder.core.turn_context import TurnContext
   from botbuilder.schema import ActivityTypes
  -from .prompt import Prompt
  +
  +from .prompt import Prompt, PromptValidatorContext
   from .prompt_options import PromptOptions
   from .prompt_recognizer_result import PromptRecognizerResult
   
   
   class NumberPrompt(Prompt):
  -    # TODO: PromptValidator
  -    def __init__(self, dialog_id: str, validator: object, default_locale: str):
  +    # TODO: PromptValidator needs to be fixed
  +    # Does not accept answer as intended (times out)
  +    def __init__(
  +        self,
  +        dialog_id: str,
  +        validator: Callable[[PromptValidatorContext], bool] = None,
  +        default_locale: str = None,
  +    ):
           super(NumberPrompt, self).__init__(dialog_id, validator)
           self.default_locale = default_locale
   
  @@ -30,9 +41,8 @@
   
           if is_retry and options.retry_prompt is not None:
               turn_context.send_activity(options.retry_prompt)
  -        else:
  -            if options.prompt is not None:
  -                await turn_context.send_activity(options.prompt)
  +        elif options.prompt is not None:
  +            await turn_context.send_activity(options.prompt)
   
       async def on_recognize(
           self,
  @@ -46,17 +56,25 @@
           result = PromptRecognizerResult()
           if turn_context.activity.type == ActivityTypes.message:
               message = turn_context.activity
  +            culture = self._get_culture(turn_context)
  +            results: [ModelResult] = recognize_number(message.text, culture)
   
  -            # TODO: Fix constant English with correct constant from text recognizer
  -            culture = (
  -                turn_context.activity.locale
  -                if turn_context.activity.locale is not None
  -                else "English"
  -            )
  -
  -            results = recognize_number(message.text, culture)
               if results:
                   result.succeeded = True
  -                result.value = results[0].resolution["value"]
  +                result.value = parse_decimal(
  +                    results[0].resolution["value"], locale=culture.replace("-", "_")
  +                )
   
           return result
  +
  +    def _get_culture(self, turn_context: TurnContext):
  +        culture = (
  +            turn_context.activity.locale
  +            if turn_context.activity.locale
  +            else self.default_locale
  +        )
  +
  +        if not culture:
  +            culture = Culture.English
  +
  +        return culture
  diff --git a/libraries/botbuilder-dialogs/setup.py b/libraries/botbuilder-dialogs/setup.py
  --- a/libraries/botbuilder-dialogs/setup.py
  +++ b/libraries/botbuilder-dialogs/setup.py
  @@ -12,6 +12,7 @@
       "recognizers-text-choice>=1.0.1a0",
       "grapheme>=0.5.0",
       "emoji>=0.5.2",
  +    "babel>=2.7.0",
       "botbuilder-schema>=4.4.0b1",
       "botframework-connector>=4.4.0b1",
       "botbuilder-core>=4.4.0b1",
  
verification_info: {"golden_diff": "diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py\n--- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py\n+++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py\n@@ -1,18 +1,29 @@\n # Copyright (c) Microsoft Corporation. All rights reserved.\n # Licensed under the MIT License.\n \n-from typing import Dict\n+from typing import Callable, Dict\n+\n+from babel.numbers import parse_decimal\n from recognizers_number import recognize_number\n+from recognizers_text import Culture, ModelResult\n+\n from botbuilder.core.turn_context import TurnContext\n from botbuilder.schema import ActivityTypes\n-from .prompt import Prompt\n+\n+from .prompt import Prompt, PromptValidatorContext\n from .prompt_options import PromptOptions\n from .prompt_recognizer_result import PromptRecognizerResult\n \n \n class NumberPrompt(Prompt):\n-    # TODO: PromptValidator\n-    def __init__(self, dialog_id: str, validator: object, default_locale: str):\n+    # TODO: PromptValidator needs to be fixed\n+    # Does not accept answer as intended (times out)\n+    def __init__(\n+        self,\n+        dialog_id: str,\n+        validator: Callable[[PromptValidatorContext], bool] = None,\n+        default_locale: str = None,\n+    ):\n         super(NumberPrompt, self).__init__(dialog_id, validator)\n         self.default_locale = default_locale\n \n@@ -30,9 +41,8 @@\n \n         if is_retry and options.retry_prompt is not None:\n             turn_context.send_activity(options.retry_prompt)\n-        else:\n-            if options.prompt is not None:\n-                await turn_context.send_activity(options.prompt)\n+        elif options.prompt is not None:\n+            await turn_context.send_activity(options.prompt)\n \n     async def on_recognize(\n         self,\n@@ -46,17 +56,25 @@\n         result = PromptRecognizerResult()\n         if turn_context.activity.type == ActivityTypes.message:\n             message = turn_context.activity\n+            culture = self._get_culture(turn_context)\n+            results: [ModelResult] = recognize_number(message.text, culture)\n \n-            # TODO: Fix constant English with correct constant from text recognizer\n-            culture = (\n-                turn_context.activity.locale\n-                if turn_context.activity.locale is not None\n-                else \"English\"\n-            )\n-\n-            results = recognize_number(message.text, culture)\n             if results:\n                 result.succeeded = True\n-                result.value = results[0].resolution[\"value\"]\n+                result.value = parse_decimal(\n+                    results[0].resolution[\"value\"], locale=culture.replace(\"-\", \"_\")\n+                )\n \n         return result\n+\n+    def _get_culture(self, turn_context: TurnContext):\n+        culture = (\n+            turn_context.activity.locale\n+            if turn_context.activity.locale\n+            else self.default_locale\n+        )\n+\n+        if not culture:\n+            culture = Culture.English\n+\n+        return culture\ndiff --git a/libraries/botbuilder-dialogs/setup.py b/libraries/botbuilder-dialogs/setup.py\n--- a/libraries/botbuilder-dialogs/setup.py\n+++ b/libraries/botbuilder-dialogs/setup.py\n@@ -12,6 +12,7 @@\n     \"recognizers-text-choice>=1.0.1a0\",\n     \"grapheme>=0.5.0\",\n     \"emoji>=0.5.2\",\n+    \"babel>=2.7.0\",\n     \"botbuilder-schema>=4.4.0b1\",\n     \"botframework-connector>=4.4.0b1\",\n     \"botbuilder-core>=4.4.0b1\",\n", "issue": "NumberPrompt Locale Not Fully Implemented\n## Version\r\nv4.5\r\n\r\n## Describe the bug\r\nFound this bug while investigating for parity with regards to this [`NumberPrompt` bug filed in the dotnet repo](https://github.com/microsoft/botbuilder-dotnet/issues/2288)\r\n* in constructor, `default_locale` attribute is set, but never used in `NumberPrompt`'s implementation (not in `on_prompt()` nor `on_recognize()`\r\n* `on_recognize()` does allow you to pass in `locale` via `Activity`, however locale will not be used if only `default_locale` is specified\r\n* \"`English`\" is used as string to specify locale, when we should be using the constants provided by the python recognizers-text repo\r\n\r\n* Separately, there's definitely a lack of unit test coverage for this feature (only 2 tests written)\r\n\r\n## Expected behavior\r\n* implement use of `default_locale`\r\n* implement use of recognizers-text constants to specify locale\r\n\r\n\r\n\r\n[bug]\r\n\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\n\nfrom typing import Dict\nfrom recognizers_number import recognize_number\nfrom botbuilder.core.turn_context import TurnContext\nfrom botbuilder.schema import ActivityTypes\nfrom .prompt import Prompt\nfrom .prompt_options import PromptOptions\nfrom .prompt_recognizer_result import PromptRecognizerResult\n\n\nclass NumberPrompt(Prompt):\n    # TODO: PromptValidator\n    def __init__(self, dialog_id: str, validator: object, default_locale: str):\n        super(NumberPrompt, self).__init__(dialog_id, validator)\n        self.default_locale = default_locale\n\n    async def on_prompt(\n        self,\n        turn_context: TurnContext,\n        state: Dict[str, object],\n        options: PromptOptions,\n        is_retry: bool,\n    ):\n        if not turn_context:\n            raise TypeError(\"NumberPrompt.on_prompt(): turn_context cannot be None.\")\n        if not options:\n            raise TypeError(\"NumberPrompt.on_prompt(): options cannot be None.\")\n\n        if is_retry and options.retry_prompt is not None:\n            turn_context.send_activity(options.retry_prompt)\n        else:\n            if options.prompt is not None:\n                await turn_context.send_activity(options.prompt)\n\n    async def on_recognize(\n        self,\n        turn_context: TurnContext,\n        state: Dict[str, object],\n        options: PromptOptions,\n    ) -> PromptRecognizerResult:\n        if not turn_context:\n            raise TypeError(\"NumberPrompt.on_recognize(): turn_context cannot be None.\")\n\n        result = PromptRecognizerResult()\n        if turn_context.activity.type == ActivityTypes.message:\n            message = turn_context.activity\n\n            # TODO: Fix constant English with correct constant from text recognizer\n            culture = (\n                turn_context.activity.locale\n                if turn_context.activity.locale is not None\n                else \"English\"\n            )\n\n            results = recognize_number(message.text, culture)\n            if results:\n                result.succeeded = True\n                result.value = results[0].resolution[\"value\"]\n\n        return result\n", "path": "libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py"}, {"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\n\nimport os\nfrom setuptools import setup\n\nREQUIRES = [\n    \"recognizers-text-date-time>=1.0.1a0\",\n    \"recognizers-text-number-with-unit>=1.0.1a0\",\n    \"recognizers-text-number>=1.0.1a0\",\n    \"recognizers-text>=1.0.1a0\",\n    \"recognizers-text-choice>=1.0.1a0\",\n    \"grapheme>=0.5.0\",\n    \"emoji>=0.5.2\",\n    \"botbuilder-schema>=4.4.0b1\",\n    \"botframework-connector>=4.4.0b1\",\n    \"botbuilder-core>=4.4.0b1\",\n]\n\nTEST_REQUIRES = [\"aiounittest>=1.1.0\"]\n\nroot = os.path.abspath(os.path.dirname(__file__))\n\nwith open(os.path.join(root, \"botbuilder\", \"dialogs\", \"about.py\")) as f:\n    package_info = {}\n    info = f.read()\n    exec(info, package_info)\n\nwith open(os.path.join(root, \"README.rst\"), encoding=\"utf-8\") as f:\n    long_description = f.read()\n\nsetup(\n    name=package_info[\"__title__\"],\n    version=package_info[\"__version__\"],\n    url=package_info[\"__uri__\"],\n    author=package_info[\"__author__\"],\n    description=package_info[\"__description__\"],\n    keywords=[\"BotBuilderDialogs\", \"bots\", \"ai\", \"botframework\", \"botbuilder\"],\n    long_description=long_description,\n    long_description_content_type=\"text/x-rst\",\n    license=package_info[\"__license__\"],\n    packages=[\n        \"botbuilder.dialogs\",\n        \"botbuilder.dialogs.prompts\",\n        \"botbuilder.dialogs.choices\",\n    ],\n    install_requires=REQUIRES + TEST_REQUIRES,\n    tests_require=TEST_REQUIRES,\n    include_package_data=True,\n    classifiers=[\n        \"Programming Language :: Python :: 3.7\",\n        \"Intended Audience :: Developers\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Operating System :: OS Independent\",\n        \"Development Status :: 3 - Alpha\",\n        \"Topic :: Scientific/Engineering :: Artificial Intelligence\",\n    ],\n)\n", "path": "libraries/botbuilder-dialogs/setup.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\n\nfrom typing import Callable, Dict\n\nfrom babel.numbers import parse_decimal\nfrom recognizers_number import recognize_number\nfrom recognizers_text import Culture, ModelResult\n\nfrom botbuilder.core.turn_context import TurnContext\nfrom botbuilder.schema import ActivityTypes\n\nfrom .prompt import Prompt, PromptValidatorContext\nfrom .prompt_options import PromptOptions\nfrom .prompt_recognizer_result import PromptRecognizerResult\n\n\nclass NumberPrompt(Prompt):\n    # TODO: PromptValidator needs to be fixed\n    # Does not accept answer as intended (times out)\n    def __init__(\n        self,\n        dialog_id: str,\n        validator: Callable[[PromptValidatorContext], bool] = None,\n        default_locale: str = None,\n    ):\n        super(NumberPrompt, self).__init__(dialog_id, validator)\n        self.default_locale = default_locale\n\n    async def on_prompt(\n        self,\n        turn_context: TurnContext,\n        state: Dict[str, object],\n        options: PromptOptions,\n        is_retry: bool,\n    ):\n        if not turn_context:\n            raise TypeError(\"NumberPrompt.on_prompt(): turn_context cannot be None.\")\n        if not options:\n            raise TypeError(\"NumberPrompt.on_prompt(): options cannot be None.\")\n\n        if is_retry and options.retry_prompt is not None:\n            turn_context.send_activity(options.retry_prompt)\n        elif options.prompt is not None:\n            await turn_context.send_activity(options.prompt)\n\n    async def on_recognize(\n        self,\n        turn_context: TurnContext,\n        state: Dict[str, object],\n        options: PromptOptions,\n    ) -> PromptRecognizerResult:\n        if not turn_context:\n            raise TypeError(\"NumberPrompt.on_recognize(): turn_context cannot be None.\")\n\n        result = PromptRecognizerResult()\n        if turn_context.activity.type == ActivityTypes.message:\n            message = turn_context.activity\n            culture = self._get_culture(turn_context)\n            results: [ModelResult] = recognize_number(message.text, culture)\n\n            if results:\n                result.succeeded = True\n                result.value = parse_decimal(\n                    results[0].resolution[\"value\"], locale=culture.replace(\"-\", \"_\")\n                )\n\n        return result\n\n    def _get_culture(self, turn_context: TurnContext):\n        culture = (\n            turn_context.activity.locale\n            if turn_context.activity.locale\n            else self.default_locale\n        )\n\n        if not culture:\n            culture = Culture.English\n\n        return culture\n", "path": "libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/number_prompt.py"}, {"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\n\nimport os\nfrom setuptools import setup\n\nREQUIRES = [\n    \"recognizers-text-date-time>=1.0.1a0\",\n    \"recognizers-text-number-with-unit>=1.0.1a0\",\n    \"recognizers-text-number>=1.0.1a0\",\n    \"recognizers-text>=1.0.1a0\",\n    \"recognizers-text-choice>=1.0.1a0\",\n    \"grapheme>=0.5.0\",\n    \"emoji>=0.5.2\",\n    \"babel>=2.7.0\",\n    \"botbuilder-schema>=4.4.0b1\",\n    \"botframework-connector>=4.4.0b1\",\n    \"botbuilder-core>=4.4.0b1\",\n]\n\nTEST_REQUIRES = [\"aiounittest>=1.1.0\"]\n\nroot = os.path.abspath(os.path.dirname(__file__))\n\nwith open(os.path.join(root, \"botbuilder\", \"dialogs\", \"about.py\")) as f:\n    package_info = {}\n    info = f.read()\n    exec(info, package_info)\n\nwith open(os.path.join(root, \"README.rst\"), encoding=\"utf-8\") as f:\n    long_description = f.read()\n\nsetup(\n    name=package_info[\"__title__\"],\n    version=package_info[\"__version__\"],\n    url=package_info[\"__uri__\"],\n    author=package_info[\"__author__\"],\n    description=package_info[\"__description__\"],\n    keywords=[\"BotBuilderDialogs\", \"bots\", \"ai\", \"botframework\", \"botbuilder\"],\n    long_description=long_description,\n    long_description_content_type=\"text/x-rst\",\n    license=package_info[\"__license__\"],\n    packages=[\n        \"botbuilder.dialogs\",\n        \"botbuilder.dialogs.prompts\",\n        \"botbuilder.dialogs.choices\",\n    ],\n    install_requires=REQUIRES + TEST_REQUIRES,\n    tests_require=TEST_REQUIRES,\n    include_package_data=True,\n    classifiers=[\n        \"Programming Language :: Python :: 3.7\",\n        \"Intended Audience :: Developers\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Operating System :: OS Independent\",\n        \"Development Status :: 3 - Alpha\",\n        \"Topic :: Scientific/Engineering :: Artificial Intelligence\",\n    ],\n)\n", "path": "libraries/botbuilder-dialogs/setup.py"}]}