prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  AttributeError: module 'asyncio' has no attribute 'exceptions'
  ```
  Traceback (most recent call last):
    File "/home//.local/bin/pymodbus.server", line 6, in <module>
      from pymodbus.repl.server.main import server
    File "/home//.local/lib/python3.7/site-packages/pymodbus/repl/server/main.py", line 16, in <module>
      CANCELLED_ERROR = asyncio.exceptions.CancelledError
  AttributeError: module 'asyncio' has no attribute 'exceptions'
  ```
  
  in the code 
  
  ```
  if IS_PYTHON3 and PYTHON_VERSION > (3, 7):
      CANCELLED_ERROR = asyncio.exceptions.CancelledError
  else:
      CANCELLED_ERROR = asyncio.CancelledError
  
  ```
  python 3.7 at least 3.7.3 doesn't have `asyncio.exceptions`
  Maybe it was supposed to be >= 3.8.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pymodbus/repl/server/main.py`
  Content:
  ```
  1 """Repl server main.
  2 
  3 Copyright (c) 2020 by RiptideIO
  4 All rights reserved.
  5 """
  6 import sys
  7 import logging
  8 import asyncio
  9 import json
  10 import click
  11 from pymodbus.framer.socket_framer import ModbusSocketFramer
  12 from pymodbus.server.reactive.main import (
  13     ReactiveServer,
  14     DEFAULT_FRAMER,
  15     DEFUALT_HANDLERS,
  16 )
  17 from pymodbus.server.reactive.default_config import DEFUALT_CONFIG
  18 from pymodbus.repl.server.cli import run_repl
  19 
  20 if sys.version_info > (3, 7):
  21     CANCELLED_ERROR = asyncio.exceptions.CancelledError
  22 else:
  23     CANCELLED_ERROR = asyncio.CancelledError  # pylint: disable=invalid-name
  24 
  25 
  26 @click.group("ReactiveModbusServer")
  27 @click.option("--host", default="localhost", help="Host address")
  28 @click.option("--web-port", default=8080, help="Web app port")
  29 @click.option(
  30     "--broadcast-support",
  31     is_flag=True,
  32     default=False,
  33     help="Support broadcast messages",
  34 )
  35 @click.option(
  36     "--repl/--no-repl",
  37     is_flag=True,
  38     default=True,
  39     help="Enable/Disable repl for server",
  40 )
  41 @click.option(
  42     "--verbose", is_flag=True, help="Run with debug logs enabled for pymodbus"
  43 )
  44 @click.pass_context
  45 def server(ctx, host, web_port, broadcast_support, repl, verbose):
  46     """Run server code."""
  47     FORMAT = (  # pylint: disable=invalid-name
  48         "%(asctime)-15s %(threadName)-15s"
  49         " %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
  50     )
  51     pymodbus_logger = logging.getLogger("pymodbus")
  52     logging.basicConfig(format=FORMAT)  # NOSONAR
  53     if verbose:
  54         pymodbus_logger.setLevel(logging.DEBUG)
  55     else:
  56         pymodbus_logger.setLevel(logging.ERROR)
  57 
  58     ctx.obj = {
  59         "repl": repl,
  60         "host": host,
  61         "web_port": web_port,
  62         "broadcast": broadcast_support,
  63     }
  64 
  65 
  66 @server.command("run")
  67 @click.option(
  68     "--modbus-server",
  69     default="tcp",
  70     type=click.Choice(["tcp", "serial", "tls", "udp"], case_sensitive=False),
  71     help="Modbus server",
  72 )
  73 @click.option(
  74     "--modbus-framer",
  75     default="socket",
  76     type=click.Choice(
  77         ["socket", "rtu", "tls", "ascii", "binary"], case_sensitive=False
  78     ),
  79     help="Modbus framer to use",
  80 )
  81 @click.option("--modbus-port", default="5020", help="Modbus port")
  82 @click.option(
  83     "--modbus-unit-id", default=[1], type=int, multiple=True, help="Modbus unit id"
  84 )
  85 @click.option(
  86     "--modbus-config",
  87     type=click.Path(exists=True),
  88     help="Path to additional modbus server config",
  89 )
  90 @click.option(
  91     "-r",
  92     "--randomize",
  93     default=0,
  94     help="Randomize every `r` reads."
  95     " 0=never, 1=always, "
  96     "2=every-second-read, "
  97     "and so on. "
  98     "Applicable IR and DI.",
  99 )
  100 @click.pass_context
  101 def run(
  102     ctx,
  103     modbus_server,
  104     modbus_framer,
  105     modbus_port,
  106     modbus_unit_id,
  107     modbus_config,
  108     randomize,
  109 ):
  110     """Run Reactive Modbus server.
  111 
  112     Exposing REST endpoint for response manipulation.
  113     """
  114     repl = ctx.obj.pop("repl")
  115     web_app_config = ctx.obj
  116     loop = asyncio.get_event_loop()
  117     framer = DEFAULT_FRAMER.get(modbus_framer, ModbusSocketFramer)
  118     if modbus_config:
  119         with open(modbus_config) as my_file:  # pylint: disable=unspecified-encoding
  120             modbus_config = json.load(my_file)
  121     else:
  122         modbus_config = DEFUALT_CONFIG
  123     modbus_config = modbus_config.get(modbus_server, {})
  124     if modbus_server != "serial":
  125         modbus_port = int(modbus_port)
  126         handler = modbus_config.pop("handler", "ModbusConnectedRequestHandler")
  127     else:
  128         handler = modbus_config.pop("handler", "ModbusSingleRequestHandler")
  129     handler = DEFUALT_HANDLERS.get(handler.strip())
  130 
  131     modbus_config["handler"] = handler
  132     modbus_config["randomize"] = randomize
  133     app = ReactiveServer.factory(
  134         modbus_server,
  135         framer,
  136         modbus_port=modbus_port,
  137         unit=modbus_unit_id,
  138         loop=loop,
  139         **web_app_config,
  140         **modbus_config
  141     )
  142     try:
  143         if repl:
  144             loop.run_until_complete(app.run_async())
  145 
  146             loop.run_until_complete(run_repl(app))
  147             loop.run_forever()
  148         else:
  149             app.run()
  150 
  151     except CANCELLED_ERROR:
  152         print("Done!!!!!")
  153 
  154 
  155 if __name__ == "__main__":
  156     server()  # pylint: disable=no-value-for-parameter
  157
  ```
  --- 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/pymodbus/repl/server/main.py b/pymodbus/repl/server/main.py
  --- a/pymodbus/repl/server/main.py
  +++ b/pymodbus/repl/server/main.py
  @@ -3,7 +3,6 @@
   Copyright (c) 2020 by RiptideIO
   All rights reserved.
   """
  -import sys
   import logging
   import asyncio
   import json
  @@ -17,10 +16,7 @@
   from pymodbus.server.reactive.default_config import DEFUALT_CONFIG
   from pymodbus.repl.server.cli import run_repl
   
  -if sys.version_info > (3, 7):
  -    CANCELLED_ERROR = asyncio.exceptions.CancelledError
  -else:
  -    CANCELLED_ERROR = asyncio.CancelledError  # pylint: disable=invalid-name
  +CANCELLED_ERROR = asyncio.exceptions.CancelledError
   
   
   @click.group("ReactiveModbusServer")
  
verification_info: {"golden_diff": "diff --git a/pymodbus/repl/server/main.py b/pymodbus/repl/server/main.py\n--- a/pymodbus/repl/server/main.py\n+++ b/pymodbus/repl/server/main.py\n@@ -3,7 +3,6 @@\n Copyright (c) 2020 by RiptideIO\n All rights reserved.\n \"\"\"\n-import sys\n import logging\n import asyncio\n import json\n@@ -17,10 +16,7 @@\n from pymodbus.server.reactive.default_config import DEFUALT_CONFIG\n from pymodbus.repl.server.cli import run_repl\n \n-if sys.version_info > (3, 7):\n-    CANCELLED_ERROR = asyncio.exceptions.CancelledError\n-else:\n-    CANCELLED_ERROR = asyncio.CancelledError  # pylint: disable=invalid-name\n+CANCELLED_ERROR = asyncio.exceptions.CancelledError\n \n \n @click.group(\"ReactiveModbusServer\")\n", "issue": "AttributeError: module 'asyncio' has no attribute 'exceptions'\n```\r\nTraceback (most recent call last):\r\n  File \"/home//.local/bin/pymodbus.server\", line 6, in <module>\r\n    from pymodbus.repl.server.main import server\r\n  File \"/home//.local/lib/python3.7/site-packages/pymodbus/repl/server/main.py\", line 16, in <module>\r\n    CANCELLED_ERROR = asyncio.exceptions.CancelledError\r\nAttributeError: module 'asyncio' has no attribute 'exceptions'\r\n```\r\n\r\nin the code \r\n\r\n```\r\nif IS_PYTHON3 and PYTHON_VERSION > (3, 7):\r\n    CANCELLED_ERROR = asyncio.exceptions.CancelledError\r\nelse:\r\n    CANCELLED_ERROR = asyncio.CancelledError\r\n\r\n```\r\npython 3.7 at least 3.7.3 doesn't have `asyncio.exceptions`\r\nMaybe it was supposed to be >= 3.8.\r\n\n", "before_files": [{"content": "\"\"\"Repl server main.\n\nCopyright (c) 2020 by RiptideIO\nAll rights reserved.\n\"\"\"\nimport sys\nimport logging\nimport asyncio\nimport json\nimport click\nfrom pymodbus.framer.socket_framer import ModbusSocketFramer\nfrom pymodbus.server.reactive.main import (\n    ReactiveServer,\n    DEFAULT_FRAMER,\n    DEFUALT_HANDLERS,\n)\nfrom pymodbus.server.reactive.default_config import DEFUALT_CONFIG\nfrom pymodbus.repl.server.cli import run_repl\n\nif sys.version_info > (3, 7):\n    CANCELLED_ERROR = asyncio.exceptions.CancelledError\nelse:\n    CANCELLED_ERROR = asyncio.CancelledError  # pylint: disable=invalid-name\n\n\n@click.group(\"ReactiveModbusServer\")\n@click.option(\"--host\", default=\"localhost\", help=\"Host address\")\n@click.option(\"--web-port\", default=8080, help=\"Web app port\")\n@click.option(\n    \"--broadcast-support\",\n    is_flag=True,\n    default=False,\n    help=\"Support broadcast messages\",\n)\n@click.option(\n    \"--repl/--no-repl\",\n    is_flag=True,\n    default=True,\n    help=\"Enable/Disable repl for server\",\n)\n@click.option(\n    \"--verbose\", is_flag=True, help=\"Run with debug logs enabled for pymodbus\"\n)\n@click.pass_context\ndef server(ctx, host, web_port, broadcast_support, repl, verbose):\n    \"\"\"Run server code.\"\"\"\n    FORMAT = (  # pylint: disable=invalid-name\n        \"%(asctime)-15s %(threadName)-15s\"\n        \" %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s\"\n    )\n    pymodbus_logger = logging.getLogger(\"pymodbus\")\n    logging.basicConfig(format=FORMAT)  # NOSONAR\n    if verbose:\n        pymodbus_logger.setLevel(logging.DEBUG)\n    else:\n        pymodbus_logger.setLevel(logging.ERROR)\n\n    ctx.obj = {\n        \"repl\": repl,\n        \"host\": host,\n        \"web_port\": web_port,\n        \"broadcast\": broadcast_support,\n    }\n\n\n@server.command(\"run\")\n@click.option(\n    \"--modbus-server\",\n    default=\"tcp\",\n    type=click.Choice([\"tcp\", \"serial\", \"tls\", \"udp\"], case_sensitive=False),\n    help=\"Modbus server\",\n)\n@click.option(\n    \"--modbus-framer\",\n    default=\"socket\",\n    type=click.Choice(\n        [\"socket\", \"rtu\", \"tls\", \"ascii\", \"binary\"], case_sensitive=False\n    ),\n    help=\"Modbus framer to use\",\n)\n@click.option(\"--modbus-port\", default=\"5020\", help=\"Modbus port\")\n@click.option(\n    \"--modbus-unit-id\", default=[1], type=int, multiple=True, help=\"Modbus unit id\"\n)\n@click.option(\n    \"--modbus-config\",\n    type=click.Path(exists=True),\n    help=\"Path to additional modbus server config\",\n)\n@click.option(\n    \"-r\",\n    \"--randomize\",\n    default=0,\n    help=\"Randomize every `r` reads.\"\n    \" 0=never, 1=always, \"\n    \"2=every-second-read, \"\n    \"and so on. \"\n    \"Applicable IR and DI.\",\n)\n@click.pass_context\ndef run(\n    ctx,\n    modbus_server,\n    modbus_framer,\n    modbus_port,\n    modbus_unit_id,\n    modbus_config,\n    randomize,\n):\n    \"\"\"Run Reactive Modbus server.\n\n    Exposing REST endpoint for response manipulation.\n    \"\"\"\n    repl = ctx.obj.pop(\"repl\")\n    web_app_config = ctx.obj\n    loop = asyncio.get_event_loop()\n    framer = DEFAULT_FRAMER.get(modbus_framer, ModbusSocketFramer)\n    if modbus_config:\n        with open(modbus_config) as my_file:  # pylint: disable=unspecified-encoding\n            modbus_config = json.load(my_file)\n    else:\n        modbus_config = DEFUALT_CONFIG\n    modbus_config = modbus_config.get(modbus_server, {})\n    if modbus_server != \"serial\":\n        modbus_port = int(modbus_port)\n        handler = modbus_config.pop(\"handler\", \"ModbusConnectedRequestHandler\")\n    else:\n        handler = modbus_config.pop(\"handler\", \"ModbusSingleRequestHandler\")\n    handler = DEFUALT_HANDLERS.get(handler.strip())\n\n    modbus_config[\"handler\"] = handler\n    modbus_config[\"randomize\"] = randomize\n    app = ReactiveServer.factory(\n        modbus_server,\n        framer,\n        modbus_port=modbus_port,\n        unit=modbus_unit_id,\n        loop=loop,\n        **web_app_config,\n        **modbus_config\n    )\n    try:\n        if repl:\n            loop.run_until_complete(app.run_async())\n\n            loop.run_until_complete(run_repl(app))\n            loop.run_forever()\n        else:\n            app.run()\n\n    except CANCELLED_ERROR:\n        print(\"Done!!!!!\")\n\n\nif __name__ == \"__main__\":\n    server()  # pylint: disable=no-value-for-parameter\n", "path": "pymodbus/repl/server/main.py"}], "after_files": [{"content": "\"\"\"Repl server main.\n\nCopyright (c) 2020 by RiptideIO\nAll rights reserved.\n\"\"\"\nimport logging\nimport asyncio\nimport json\nimport click\nfrom pymodbus.framer.socket_framer import ModbusSocketFramer\nfrom pymodbus.server.reactive.main import (\n    ReactiveServer,\n    DEFAULT_FRAMER,\n    DEFUALT_HANDLERS,\n)\nfrom pymodbus.server.reactive.default_config import DEFUALT_CONFIG\nfrom pymodbus.repl.server.cli import run_repl\n\nCANCELLED_ERROR = asyncio.exceptions.CancelledError\n\n\n@click.group(\"ReactiveModbusServer\")\n@click.option(\"--host\", default=\"localhost\", help=\"Host address\")\n@click.option(\"--web-port\", default=8080, help=\"Web app port\")\n@click.option(\n    \"--broadcast-support\",\n    is_flag=True,\n    default=False,\n    help=\"Support broadcast messages\",\n)\n@click.option(\n    \"--repl/--no-repl\",\n    is_flag=True,\n    default=True,\n    help=\"Enable/Disable repl for server\",\n)\n@click.option(\n    \"--verbose\", is_flag=True, help=\"Run with debug logs enabled for pymodbus\"\n)\n@click.pass_context\ndef server(ctx, host, web_port, broadcast_support, repl, verbose):\n    \"\"\"Run server code.\"\"\"\n    FORMAT = (  # pylint: disable=invalid-name\n        \"%(asctime)-15s %(threadName)-15s\"\n        \" %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s\"\n    )\n    pymodbus_logger = logging.getLogger(\"pymodbus\")\n    logging.basicConfig(format=FORMAT)  # NOSONAR\n    if verbose:\n        pymodbus_logger.setLevel(logging.DEBUG)\n    else:\n        pymodbus_logger.setLevel(logging.ERROR)\n\n    ctx.obj = {\n        \"repl\": repl,\n        \"host\": host,\n        \"web_port\": web_port,\n        \"broadcast\": broadcast_support,\n    }\n\n\n@server.command(\"run\")\n@click.option(\n    \"--modbus-server\",\n    default=\"tcp\",\n    type=click.Choice([\"tcp\", \"serial\", \"tls\", \"udp\"], case_sensitive=False),\n    help=\"Modbus server\",\n)\n@click.option(\n    \"--modbus-framer\",\n    default=\"socket\",\n    type=click.Choice(\n        [\"socket\", \"rtu\", \"tls\", \"ascii\", \"binary\"], case_sensitive=False\n    ),\n    help=\"Modbus framer to use\",\n)\n@click.option(\"--modbus-port\", default=\"5020\", help=\"Modbus port\")\n@click.option(\n    \"--modbus-unit-id\", default=[1], type=int, multiple=True, help=\"Modbus unit id\"\n)\n@click.option(\n    \"--modbus-config\",\n    type=click.Path(exists=True),\n    help=\"Path to additional modbus server config\",\n)\n@click.option(\n    \"-r\",\n    \"--randomize\",\n    default=0,\n    help=\"Randomize every `r` reads.\"\n    \" 0=never, 1=always, \"\n    \"2=every-second-read, \"\n    \"and so on. \"\n    \"Applicable IR and DI.\",\n)\n@click.pass_context\ndef run(\n    ctx,\n    modbus_server,\n    modbus_framer,\n    modbus_port,\n    modbus_unit_id,\n    modbus_config,\n    randomize,\n):\n    \"\"\"Run Reactive Modbus server.\n\n    Exposing REST endpoint for response manipulation.\n    \"\"\"\n    repl = ctx.obj.pop(\"repl\")\n    web_app_config = ctx.obj\n    loop = asyncio.get_event_loop()\n    framer = DEFAULT_FRAMER.get(modbus_framer, ModbusSocketFramer)\n    if modbus_config:\n        with open(modbus_config) as my_file:  # pylint: disable=unspecified-encoding\n            modbus_config = json.load(my_file)\n    else:\n        modbus_config = DEFUALT_CONFIG\n    modbus_config = modbus_config.get(modbus_server, {})\n    if modbus_server != \"serial\":\n        modbus_port = int(modbus_port)\n        handler = modbus_config.pop(\"handler\", \"ModbusConnectedRequestHandler\")\n    else:\n        handler = modbus_config.pop(\"handler\", \"ModbusSingleRequestHandler\")\n    handler = DEFUALT_HANDLERS.get(handler.strip())\n\n    modbus_config[\"handler\"] = handler\n    modbus_config[\"randomize\"] = randomize\n    app = ReactiveServer.factory(\n        modbus_server,\n        framer,\n        modbus_port=modbus_port,\n        unit=modbus_unit_id,\n        loop=loop,\n        **web_app_config,\n        **modbus_config\n    )\n    try:\n        if repl:\n            loop.run_until_complete(app.run_async())\n\n            loop.run_until_complete(run_repl(app))\n            loop.run_forever()\n        else:\n            app.run()\n\n    except CANCELLED_ERROR:\n        print(\"Done!!!!!\")\n\n\nif __name__ == \"__main__\":\n    server()  # pylint: disable=no-value-for-parameter\n", "path": "pymodbus/repl/server/main.py"}]}