prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  WHEN TYPING "-" IN THE NUMBERINPUT, WIDGET FAILS.
  """
  TESTE
  """
  import toga
  from toga.style import Pack
  from toga.style.pack import COLUMN, ROW
  
  
  class TESTE(toga.App):
  
      def startup(self):
          """
          Construct and show the Toga application.
  
          Usually, you would add your application to a main content box.
          We then create a main window (with a name matching the app), and
          show the main window.
          """
  
          # WIDGETS ###############################
          self.number = toga.NumberInput()
          self.pushButton = toga.Button('AHHHH')
          ########################################
  
          # BOX ####################################################
          main_box = toga.Box(style=Pack(direction=COLUMN))
          main_box.add(self.number, self.pushButton)
          #########################################################
  
          # EVENT #####################################################
          self.pushButton.on_press = self.printar
          ##############################################################
  
          # WINDOW #####################################################
          self.main_window = toga.MainWindow(title=self.formal_name)
          self.main_window.content = main_box
          self.main_window.show()
          ##############################################################
  
      def printar(self, widget):
          brasil = float(self.number.value)
          print(brasil)
  
  def main():
      return TESTE()
  
  https://user-images.githubusercontent.com/75274707/195914116-84981cc4-62d4-423c-a51d-0b77b4f6948a.mp4
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/android/toga_android/widgets/numberinput.py`
  Content:
  ```
  1 from decimal import Decimal
  2 
  3 from travertino.size import at_least
  4 
  5 from ..libs.android.text import InputType, TextWatcher
  6 from ..libs.android.util import TypedValue
  7 from ..libs.android.view import Gravity, View__MeasureSpec
  8 from ..libs.android.widget import EditText
  9 from .base import Widget, align
  10 
  11 
  12 def decimal_from_string(s):
  13     """If s is the empty string, return `None`. Otherwise, convert to a `Decimal`,
  14     allowing any exceptions to bubble up."""
  15     if not s:
  16         return None
  17     return Decimal(s)
  18 
  19 
  20 def string_from_decimal(d):
  21     '''Implement the inverse of `decimal_from_string()`. This way, Toga's
  22     `NumericInput` can pass us a `None` or `Decimal`, and we can always place
  23     a String in the Android `EditText`.'''
  24     if d is None:
  25         return ""
  26     return str(d)
  27 
  28 
  29 class TogaNumberInputWatcher(TextWatcher):
  30     def __init__(self, impl):
  31         super().__init__()
  32         self.interface = impl.interface
  33 
  34     def beforeTextChanged(self, _charSequence, _start, _count, _after):
  35         pass
  36 
  37     def afterTextChanged(self, editable):
  38         # Toga `NumberInput` stores the value as a property on the `interface`.
  39         self.interface._value = decimal_from_string(editable.toString())
  40         # Call the user on_change callback, if it exists.
  41         if self.interface.on_change:
  42             self.interface.on_change(widget=self.interface)
  43 
  44     def onTextChanged(self, _charSequence, _start, _before, _count):
  45         pass
  46 
  47 
  48 class NumberInput(Widget):
  49     def create(self):
  50         self.native = EditText(self._native_activity)
  51         self.native.addTextChangedListener(TogaNumberInputWatcher(self))
  52 
  53         # A `NumberInput` in Toga supports signed decimal numbers.
  54         self.native.setInputType(
  55             InputType.TYPE_CLASS_NUMBER
  56             | InputType.TYPE_NUMBER_FLAG_DECIMAL
  57             | InputType.TYPE_NUMBER_FLAG_SIGNED
  58         )
  59 
  60     def set_readonly(self, value):
  61         self.native.setFocusable(not value)
  62 
  63     def set_placeholder(self, value):
  64         # Android EditText's setHint() requires a Python string.
  65         self.native.setHint(value if value is not None else "")
  66 
  67     def set_alignment(self, value):
  68         self.native.setGravity(Gravity.CENTER_VERTICAL | align(value))
  69 
  70     def set_font(self, font):
  71         if font:
  72             font_impl = font.bind(self.interface.factory)
  73             self.native.setTextSize(TypedValue.COMPLEX_UNIT_SP, font_impl.get_size())
  74             self.native.setTypeface(font_impl.get_typeface(), font_impl.get_style())
  75 
  76     def set_value(self, value):
  77         # Store a string in the Android widget. The `afterTextChanged` method
  78         # will call the user on_change handler.
  79         self.native.setText(string_from_decimal(value))
  80 
  81     def set_step(self, step):
  82         self.interface.factory.not_implemented("NumberInput.set_step()")
  83 
  84     def set_max_value(self, value):
  85         self.interface.factory.not_implemented("NumberInput.set_max_value()")
  86 
  87     def set_min_value(self, value):
  88         self.interface.factory.not_implemented("NumberInput.set_min_value()")
  89 
  90     def set_on_change(self, handler):
  91         # No special handling required.
  92         pass
  93 
  94     def rehint(self):
  95         # On Android, EditText's measure() throws NullPointerException if the widget has no
  96         # LayoutParams.
  97         if not self.native.getLayoutParams():
  98             return
  99         self.native.measure(
  100             View__MeasureSpec.UNSPECIFIED, View__MeasureSpec.UNSPECIFIED
  101         )
  102         self.interface.intrinsic.width = at_least(self.native.getMeasuredWidth())
  103         self.interface.intrinsic.height = self.native.getMeasuredHeight()
  104
  ```
  --- 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/src/android/toga_android/widgets/numberinput.py b/src/android/toga_android/widgets/numberinput.py
  --- a/src/android/toga_android/widgets/numberinput.py
  +++ b/src/android/toga_android/widgets/numberinput.py
  @@ -1,4 +1,4 @@
  -from decimal import Decimal
  +from decimal import Decimal, InvalidOperation
   
   from travertino.size import at_least
   
  @@ -10,11 +10,11 @@
   
   
   def decimal_from_string(s):
  -    """If s is the empty string, return `None`. Otherwise, convert to a `Decimal`,
  -    allowing any exceptions to bubble up."""
  -    if not s:
  +    """Convert s to a `Decimal`, returning `None` if it's not a valid number."""
  +    try:
  +        return Decimal(s)
  +    except InvalidOperation:
           return None
  -    return Decimal(s)
   
   
   def string_from_decimal(d):
  
verification_info: {"golden_diff": "diff --git a/src/android/toga_android/widgets/numberinput.py b/src/android/toga_android/widgets/numberinput.py\n--- a/src/android/toga_android/widgets/numberinput.py\n+++ b/src/android/toga_android/widgets/numberinput.py\n@@ -1,4 +1,4 @@\n-from decimal import Decimal\n+from decimal import Decimal, InvalidOperation\n \n from travertino.size import at_least\n \n@@ -10,11 +10,11 @@\n \n \n def decimal_from_string(s):\n-    \"\"\"If s is the empty string, return `None`. Otherwise, convert to a `Decimal`,\n-    allowing any exceptions to bubble up.\"\"\"\n-    if not s:\n+    \"\"\"Convert s to a `Decimal`, returning `None` if it's not a valid number.\"\"\"\n+    try:\n+        return Decimal(s)\n+    except InvalidOperation:\n         return None\n-    return Decimal(s)\n \n \n def string_from_decimal(d):\n", "issue": "WHEN TYPING \"-\" IN THE NUMBERINPUT, WIDGET FAILS.\n\"\"\"\r\nTESTE\r\n\"\"\"\r\nimport toga\r\nfrom toga.style import Pack\r\nfrom toga.style.pack import COLUMN, ROW\r\n\r\n\r\nclass TESTE(toga.App):\r\n\r\n    def startup(self):\r\n        \"\"\"\r\n        Construct and show the Toga application.\r\n\r\n        Usually, you would add your application to a main content box.\r\n        We then create a main window (with a name matching the app), and\r\n        show the main window.\r\n        \"\"\"\r\n\r\n        # WIDGETS ###############################\r\n        self.number = toga.NumberInput()\r\n        self.pushButton = toga.Button('AHHHH')\r\n        ########################################\r\n\r\n        # BOX ####################################################\r\n        main_box = toga.Box(style=Pack(direction=COLUMN))\r\n        main_box.add(self.number, self.pushButton)\r\n        #########################################################\r\n\r\n        # EVENT #####################################################\r\n        self.pushButton.on_press = self.printar\r\n        ##############################################################\r\n\r\n        # WINDOW #####################################################\r\n        self.main_window = toga.MainWindow(title=self.formal_name)\r\n        self.main_window.content = main_box\r\n        self.main_window.show()\r\n        ##############################################################\r\n\r\n    def printar(self, widget):\r\n        brasil = float(self.number.value)\r\n        print(brasil)\r\n\r\ndef main():\r\n    return TESTE()\r\n\r\nhttps://user-images.githubusercontent.com/75274707/195914116-84981cc4-62d4-423c-a51d-0b77b4f6948a.mp4\r\n\r\n\n", "before_files": [{"content": "from decimal import Decimal\n\nfrom travertino.size import at_least\n\nfrom ..libs.android.text import InputType, TextWatcher\nfrom ..libs.android.util import TypedValue\nfrom ..libs.android.view import Gravity, View__MeasureSpec\nfrom ..libs.android.widget import EditText\nfrom .base import Widget, align\n\n\ndef decimal_from_string(s):\n    \"\"\"If s is the empty string, return `None`. Otherwise, convert to a `Decimal`,\n    allowing any exceptions to bubble up.\"\"\"\n    if not s:\n        return None\n    return Decimal(s)\n\n\ndef string_from_decimal(d):\n    '''Implement the inverse of `decimal_from_string()`. This way, Toga's\n    `NumericInput` can pass us a `None` or `Decimal`, and we can always place\n    a String in the Android `EditText`.'''\n    if d is None:\n        return \"\"\n    return str(d)\n\n\nclass TogaNumberInputWatcher(TextWatcher):\n    def __init__(self, impl):\n        super().__init__()\n        self.interface = impl.interface\n\n    def beforeTextChanged(self, _charSequence, _start, _count, _after):\n        pass\n\n    def afterTextChanged(self, editable):\n        # Toga `NumberInput` stores the value as a property on the `interface`.\n        self.interface._value = decimal_from_string(editable.toString())\n        # Call the user on_change callback, if it exists.\n        if self.interface.on_change:\n            self.interface.on_change(widget=self.interface)\n\n    def onTextChanged(self, _charSequence, _start, _before, _count):\n        pass\n\n\nclass NumberInput(Widget):\n    def create(self):\n        self.native = EditText(self._native_activity)\n        self.native.addTextChangedListener(TogaNumberInputWatcher(self))\n\n        # A `NumberInput` in Toga supports signed decimal numbers.\n        self.native.setInputType(\n            InputType.TYPE_CLASS_NUMBER\n            | InputType.TYPE_NUMBER_FLAG_DECIMAL\n            | InputType.TYPE_NUMBER_FLAG_SIGNED\n        )\n\n    def set_readonly(self, value):\n        self.native.setFocusable(not value)\n\n    def set_placeholder(self, value):\n        # Android EditText's setHint() requires a Python string.\n        self.native.setHint(value if value is not None else \"\")\n\n    def set_alignment(self, value):\n        self.native.setGravity(Gravity.CENTER_VERTICAL | align(value))\n\n    def set_font(self, font):\n        if font:\n            font_impl = font.bind(self.interface.factory)\n            self.native.setTextSize(TypedValue.COMPLEX_UNIT_SP, font_impl.get_size())\n            self.native.setTypeface(font_impl.get_typeface(), font_impl.get_style())\n\n    def set_value(self, value):\n        # Store a string in the Android widget. The `afterTextChanged` method\n        # will call the user on_change handler.\n        self.native.setText(string_from_decimal(value))\n\n    def set_step(self, step):\n        self.interface.factory.not_implemented(\"NumberInput.set_step()\")\n\n    def set_max_value(self, value):\n        self.interface.factory.not_implemented(\"NumberInput.set_max_value()\")\n\n    def set_min_value(self, value):\n        self.interface.factory.not_implemented(\"NumberInput.set_min_value()\")\n\n    def set_on_change(self, handler):\n        # No special handling required.\n        pass\n\n    def rehint(self):\n        # On Android, EditText's measure() throws NullPointerException if the widget has no\n        # LayoutParams.\n        if not self.native.getLayoutParams():\n            return\n        self.native.measure(\n            View__MeasureSpec.UNSPECIFIED, View__MeasureSpec.UNSPECIFIED\n        )\n        self.interface.intrinsic.width = at_least(self.native.getMeasuredWidth())\n        self.interface.intrinsic.height = self.native.getMeasuredHeight()\n", "path": "src/android/toga_android/widgets/numberinput.py"}], "after_files": [{"content": "from decimal import Decimal, InvalidOperation\n\nfrom travertino.size import at_least\n\nfrom ..libs.android.text import InputType, TextWatcher\nfrom ..libs.android.util import TypedValue\nfrom ..libs.android.view import Gravity, View__MeasureSpec\nfrom ..libs.android.widget import EditText\nfrom .base import Widget, align\n\n\ndef decimal_from_string(s):\n    \"\"\"Convert s to a `Decimal`, returning `None` if it's not a valid number.\"\"\"\n    try:\n        return Decimal(s)\n    except InvalidOperation:\n        return None\n\n\ndef string_from_decimal(d):\n    '''Implement the inverse of `decimal_from_string()`. This way, Toga's\n    `NumericInput` can pass us a `None` or `Decimal`, and we can always place\n    a String in the Android `EditText`.'''\n    if d is None:\n        return \"\"\n    return str(d)\n\n\nclass TogaNumberInputWatcher(TextWatcher):\n    def __init__(self, impl):\n        super().__init__()\n        self.interface = impl.interface\n\n    def beforeTextChanged(self, _charSequence, _start, _count, _after):\n        pass\n\n    def afterTextChanged(self, editable):\n        # Toga `NumberInput` stores the value as a property on the `interface`.\n        self.interface._value = decimal_from_string(editable.toString())\n        # Call the user on_change callback, if it exists.\n        if self.interface.on_change:\n            self.interface.on_change(widget=self.interface)\n\n    def onTextChanged(self, _charSequence, _start, _before, _count):\n        pass\n\n\nclass NumberInput(Widget):\n    def create(self):\n        self.native = EditText(self._native_activity)\n        self.native.addTextChangedListener(TogaNumberInputWatcher(self))\n\n        # A `NumberInput` in Toga supports signed decimal numbers.\n        self.native.setInputType(\n            InputType.TYPE_CLASS_NUMBER\n            | InputType.TYPE_NUMBER_FLAG_DECIMAL\n            | InputType.TYPE_NUMBER_FLAG_SIGNED\n        )\n\n    def set_readonly(self, value):\n        self.native.setFocusable(not value)\n\n    def set_placeholder(self, value):\n        # Android EditText's setHint() requires a Python string.\n        self.native.setHint(value if value is not None else \"\")\n\n    def set_alignment(self, value):\n        self.native.setGravity(Gravity.CENTER_VERTICAL | align(value))\n\n    def set_font(self, font):\n        if font:\n            font_impl = font.bind(self.interface.factory)\n            self.native.setTextSize(TypedValue.COMPLEX_UNIT_SP, font_impl.get_size())\n            self.native.setTypeface(font_impl.get_typeface(), font_impl.get_style())\n\n    def set_value(self, value):\n        # Store a string in the Android widget. The `afterTextChanged` method\n        # will call the user on_change handler.\n        self.native.setText(string_from_decimal(value))\n\n    def set_step(self, step):\n        self.interface.factory.not_implemented(\"NumberInput.set_step()\")\n\n    def set_max_value(self, value):\n        self.interface.factory.not_implemented(\"NumberInput.set_max_value()\")\n\n    def set_min_value(self, value):\n        self.interface.factory.not_implemented(\"NumberInput.set_min_value()\")\n\n    def set_on_change(self, handler):\n        # No special handling required.\n        pass\n\n    def rehint(self):\n        # On Android, EditText's measure() throws NullPointerException if the widget has no\n        # LayoutParams.\n        if not self.native.getLayoutParams():\n            return\n        self.native.measure(\n            View__MeasureSpec.UNSPECIFIED, View__MeasureSpec.UNSPECIFIED\n        )\n        self.interface.intrinsic.width = at_least(self.native.getMeasuredWidth())\n        self.interface.intrinsic.height = self.native.getMeasuredHeight()\n", "path": "src/android/toga_android/widgets/numberinput.py"}]}