prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  SQLAlchemy integration fails to parse version `2.0.0rc1`
  ### How do you use Sentry?
  
  Sentry Saas (sentry.io)
  
  ### Version
  
  1.12.1
  
  ### Steps to Reproduce
  
  Call `sentry_sdk.init()` with SQLAlchemy integration and install SQLAlchemy==2.0.0rc1.
  
  ### Expected Result
  
  no error
  
  ### Actual Result
  
  ```
        @staticmethod
        def setup_once():
            # type: () -> None
        
            try:
                version = tuple(map(int, SQLALCHEMY_VERSION.split("b")[0].split(".")))
            except (TypeError, ValueError):
    >           raise DidNotEnable(
                    "Unparsable SQLAlchemy version: {}".format(SQLALCHEMY_VERSION)
                )
    E           sentry_sdk.integrations.DidNotEnable: Unparsable SQLAlchemy version: 2.0.0rc1
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `sentry_sdk/integrations/sqlalchemy.py`
  Content:
  ```
  1 from __future__ import absolute_import
  2 
  3 from sentry_sdk._types import MYPY
  4 from sentry_sdk.hub import Hub
  5 from sentry_sdk.integrations import Integration, DidNotEnable
  6 from sentry_sdk.tracing_utils import record_sql_queries
  7 
  8 try:
  9     from sqlalchemy.engine import Engine  # type: ignore
  10     from sqlalchemy.event import listen  # type: ignore
  11     from sqlalchemy import __version__ as SQLALCHEMY_VERSION  # type: ignore
  12 except ImportError:
  13     raise DidNotEnable("SQLAlchemy not installed.")
  14 
  15 if MYPY:
  16     from typing import Any
  17     from typing import ContextManager
  18     from typing import Optional
  19 
  20     from sentry_sdk.tracing import Span
  21 
  22 
  23 class SqlalchemyIntegration(Integration):
  24     identifier = "sqlalchemy"
  25 
  26     @staticmethod
  27     def setup_once():
  28         # type: () -> None
  29 
  30         try:
  31             version = tuple(map(int, SQLALCHEMY_VERSION.split("b")[0].split(".")))
  32         except (TypeError, ValueError):
  33             raise DidNotEnable(
  34                 "Unparsable SQLAlchemy version: {}".format(SQLALCHEMY_VERSION)
  35             )
  36 
  37         if version < (1, 2):
  38             raise DidNotEnable("SQLAlchemy 1.2 or newer required.")
  39 
  40         listen(Engine, "before_cursor_execute", _before_cursor_execute)
  41         listen(Engine, "after_cursor_execute", _after_cursor_execute)
  42         listen(Engine, "handle_error", _handle_error)
  43 
  44 
  45 def _before_cursor_execute(
  46     conn, cursor, statement, parameters, context, executemany, *args
  47 ):
  48     # type: (Any, Any, Any, Any, Any, bool, *Any) -> None
  49     hub = Hub.current
  50     if hub.get_integration(SqlalchemyIntegration) is None:
  51         return
  52 
  53     ctx_mgr = record_sql_queries(
  54         hub,
  55         cursor,
  56         statement,
  57         parameters,
  58         paramstyle=context and context.dialect and context.dialect.paramstyle or None,
  59         executemany=executemany,
  60     )
  61     context._sentry_sql_span_manager = ctx_mgr
  62 
  63     span = ctx_mgr.__enter__()
  64 
  65     if span is not None:
  66         context._sentry_sql_span = span
  67 
  68 
  69 def _after_cursor_execute(conn, cursor, statement, parameters, context, *args):
  70     # type: (Any, Any, Any, Any, Any, *Any) -> None
  71     ctx_mgr = getattr(
  72         context, "_sentry_sql_span_manager", None
  73     )  # type: Optional[ContextManager[Any]]
  74 
  75     if ctx_mgr is not None:
  76         context._sentry_sql_span_manager = None
  77         ctx_mgr.__exit__(None, None, None)
  78 
  79 
  80 def _handle_error(context, *args):
  81     # type: (Any, *Any) -> None
  82     execution_context = context.execution_context
  83     if execution_context is None:
  84         return
  85 
  86     span = getattr(execution_context, "_sentry_sql_span", None)  # type: Optional[Span]
  87 
  88     if span is not None:
  89         span.set_status("internal_error")
  90 
  91     # _after_cursor_execute does not get called for crashing SQL stmts. Judging
  92     # from SQLAlchemy codebase it does seem like any error coming into this
  93     # handler is going to be fatal.
  94     ctx_mgr = getattr(
  95         execution_context, "_sentry_sql_span_manager", None
  96     )  # type: Optional[ContextManager[Any]]
  97 
  98     if ctx_mgr is not None:
  99         execution_context._sentry_sql_span_manager = None
  100         ctx_mgr.__exit__(None, None, None)
  101
  ```
  --- 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/sentry_sdk/integrations/sqlalchemy.py b/sentry_sdk/integrations/sqlalchemy.py
  --- a/sentry_sdk/integrations/sqlalchemy.py
  +++ b/sentry_sdk/integrations/sqlalchemy.py
  @@ -1,5 +1,7 @@
   from __future__ import absolute_import
   
  +import re
  +
   from sentry_sdk._types import MYPY
   from sentry_sdk.hub import Hub
   from sentry_sdk.integrations import Integration, DidNotEnable
  @@ -28,7 +30,9 @@
           # type: () -> None
   
           try:
  -            version = tuple(map(int, SQLALCHEMY_VERSION.split("b")[0].split(".")))
  +            version = tuple(
  +                map(int, re.split("b|rc", SQLALCHEMY_VERSION)[0].split("."))
  +            )
           except (TypeError, ValueError):
               raise DidNotEnable(
                   "Unparsable SQLAlchemy version: {}".format(SQLALCHEMY_VERSION)
  
verification_info: {"golden_diff": "diff --git a/sentry_sdk/integrations/sqlalchemy.py b/sentry_sdk/integrations/sqlalchemy.py\n--- a/sentry_sdk/integrations/sqlalchemy.py\n+++ b/sentry_sdk/integrations/sqlalchemy.py\n@@ -1,5 +1,7 @@\n from __future__ import absolute_import\n \n+import re\n+\n from sentry_sdk._types import MYPY\n from sentry_sdk.hub import Hub\n from sentry_sdk.integrations import Integration, DidNotEnable\n@@ -28,7 +30,9 @@\n         # type: () -> None\n \n         try:\n-            version = tuple(map(int, SQLALCHEMY_VERSION.split(\"b\")[0].split(\".\")))\n+            version = tuple(\n+                map(int, re.split(\"b|rc\", SQLALCHEMY_VERSION)[0].split(\".\"))\n+            )\n         except (TypeError, ValueError):\n             raise DidNotEnable(\n                 \"Unparsable SQLAlchemy version: {}\".format(SQLALCHEMY_VERSION)\n", "issue": "SQLAlchemy integration fails to parse version `2.0.0rc1`\n### How do you use Sentry?\n\nSentry Saas (sentry.io)\n\n### Version\n\n1.12.1\n\n### Steps to Reproduce\n\nCall `sentry_sdk.init()` with SQLAlchemy integration and install SQLAlchemy==2.0.0rc1.\n\n### Expected Result\n\nno error\n\n### Actual Result\n\n```\r\n      @staticmethod\r\n      def setup_once():\r\n          # type: () -> None\r\n      \r\n          try:\r\n              version = tuple(map(int, SQLALCHEMY_VERSION.split(\"b\")[0].split(\".\")))\r\n          except (TypeError, ValueError):\r\n  >           raise DidNotEnable(\r\n                  \"Unparsable SQLAlchemy version: {}\".format(SQLALCHEMY_VERSION)\r\n              )\r\n  E           sentry_sdk.integrations.DidNotEnable: Unparsable SQLAlchemy version: 2.0.0rc1\r\n```\n", "before_files": [{"content": "from __future__ import absolute_import\n\nfrom sentry_sdk._types import MYPY\nfrom sentry_sdk.hub import Hub\nfrom sentry_sdk.integrations import Integration, DidNotEnable\nfrom sentry_sdk.tracing_utils import record_sql_queries\n\ntry:\n    from sqlalchemy.engine import Engine  # type: ignore\n    from sqlalchemy.event import listen  # type: ignore\n    from sqlalchemy import __version__ as SQLALCHEMY_VERSION  # type: ignore\nexcept ImportError:\n    raise DidNotEnable(\"SQLAlchemy not installed.\")\n\nif MYPY:\n    from typing import Any\n    from typing import ContextManager\n    from typing import Optional\n\n    from sentry_sdk.tracing import Span\n\n\nclass SqlalchemyIntegration(Integration):\n    identifier = \"sqlalchemy\"\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n\n        try:\n            version = tuple(map(int, SQLALCHEMY_VERSION.split(\"b\")[0].split(\".\")))\n        except (TypeError, ValueError):\n            raise DidNotEnable(\n                \"Unparsable SQLAlchemy version: {}\".format(SQLALCHEMY_VERSION)\n            )\n\n        if version < (1, 2):\n            raise DidNotEnable(\"SQLAlchemy 1.2 or newer required.\")\n\n        listen(Engine, \"before_cursor_execute\", _before_cursor_execute)\n        listen(Engine, \"after_cursor_execute\", _after_cursor_execute)\n        listen(Engine, \"handle_error\", _handle_error)\n\n\ndef _before_cursor_execute(\n    conn, cursor, statement, parameters, context, executemany, *args\n):\n    # type: (Any, Any, Any, Any, Any, bool, *Any) -> None\n    hub = Hub.current\n    if hub.get_integration(SqlalchemyIntegration) is None:\n        return\n\n    ctx_mgr = record_sql_queries(\n        hub,\n        cursor,\n        statement,\n        parameters,\n        paramstyle=context and context.dialect and context.dialect.paramstyle or None,\n        executemany=executemany,\n    )\n    context._sentry_sql_span_manager = ctx_mgr\n\n    span = ctx_mgr.__enter__()\n\n    if span is not None:\n        context._sentry_sql_span = span\n\n\ndef _after_cursor_execute(conn, cursor, statement, parameters, context, *args):\n    # type: (Any, Any, Any, Any, Any, *Any) -> None\n    ctx_mgr = getattr(\n        context, \"_sentry_sql_span_manager\", None\n    )  # type: Optional[ContextManager[Any]]\n\n    if ctx_mgr is not None:\n        context._sentry_sql_span_manager = None\n        ctx_mgr.__exit__(None, None, None)\n\n\ndef _handle_error(context, *args):\n    # type: (Any, *Any) -> None\n    execution_context = context.execution_context\n    if execution_context is None:\n        return\n\n    span = getattr(execution_context, \"_sentry_sql_span\", None)  # type: Optional[Span]\n\n    if span is not None:\n        span.set_status(\"internal_error\")\n\n    # _after_cursor_execute does not get called for crashing SQL stmts. Judging\n    # from SQLAlchemy codebase it does seem like any error coming into this\n    # handler is going to be fatal.\n    ctx_mgr = getattr(\n        execution_context, \"_sentry_sql_span_manager\", None\n    )  # type: Optional[ContextManager[Any]]\n\n    if ctx_mgr is not None:\n        execution_context._sentry_sql_span_manager = None\n        ctx_mgr.__exit__(None, None, None)\n", "path": "sentry_sdk/integrations/sqlalchemy.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport re\n\nfrom sentry_sdk._types import MYPY\nfrom sentry_sdk.hub import Hub\nfrom sentry_sdk.integrations import Integration, DidNotEnable\nfrom sentry_sdk.tracing_utils import record_sql_queries\n\ntry:\n    from sqlalchemy.engine import Engine  # type: ignore\n    from sqlalchemy.event import listen  # type: ignore\n    from sqlalchemy import __version__ as SQLALCHEMY_VERSION  # type: ignore\nexcept ImportError:\n    raise DidNotEnable(\"SQLAlchemy not installed.\")\n\nif MYPY:\n    from typing import Any\n    from typing import ContextManager\n    from typing import Optional\n\n    from sentry_sdk.tracing import Span\n\n\nclass SqlalchemyIntegration(Integration):\n    identifier = \"sqlalchemy\"\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n\n        try:\n            version = tuple(\n                map(int, re.split(\"b|rc\", SQLALCHEMY_VERSION)[0].split(\".\"))\n            )\n        except (TypeError, ValueError):\n            raise DidNotEnable(\n                \"Unparsable SQLAlchemy version: {}\".format(SQLALCHEMY_VERSION)\n            )\n\n        if version < (1, 2):\n            raise DidNotEnable(\"SQLAlchemy 1.2 or newer required.\")\n\n        listen(Engine, \"before_cursor_execute\", _before_cursor_execute)\n        listen(Engine, \"after_cursor_execute\", _after_cursor_execute)\n        listen(Engine, \"handle_error\", _handle_error)\n\n\ndef _before_cursor_execute(\n    conn, cursor, statement, parameters, context, executemany, *args\n):\n    # type: (Any, Any, Any, Any, Any, bool, *Any) -> None\n    hub = Hub.current\n    if hub.get_integration(SqlalchemyIntegration) is None:\n        return\n\n    ctx_mgr = record_sql_queries(\n        hub,\n        cursor,\n        statement,\n        parameters,\n        paramstyle=context and context.dialect and context.dialect.paramstyle or None,\n        executemany=executemany,\n    )\n    context._sentry_sql_span_manager = ctx_mgr\n\n    span = ctx_mgr.__enter__()\n\n    if span is not None:\n        context._sentry_sql_span = span\n\n\ndef _after_cursor_execute(conn, cursor, statement, parameters, context, *args):\n    # type: (Any, Any, Any, Any, Any, *Any) -> None\n    ctx_mgr = getattr(\n        context, \"_sentry_sql_span_manager\", None\n    )  # type: Optional[ContextManager[Any]]\n\n    if ctx_mgr is not None:\n        context._sentry_sql_span_manager = None\n        ctx_mgr.__exit__(None, None, None)\n\n\ndef _handle_error(context, *args):\n    # type: (Any, *Any) -> None\n    execution_context = context.execution_context\n    if execution_context is None:\n        return\n\n    span = getattr(execution_context, \"_sentry_sql_span\", None)  # type: Optional[Span]\n\n    if span is not None:\n        span.set_status(\"internal_error\")\n\n    # _after_cursor_execute does not get called for crashing SQL stmts. Judging\n    # from SQLAlchemy codebase it does seem like any error coming into this\n    # handler is going to be fatal.\n    ctx_mgr = getattr(\n        execution_context, \"_sentry_sql_span_manager\", None\n    )  # type: Optional[ContextManager[Any]]\n\n    if ctx_mgr is not None:\n        execution_context._sentry_sql_span_manager = None\n        ctx_mgr.__exit__(None, None, None)\n", "path": "sentry_sdk/integrations/sqlalchemy.py"}]}