Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-sentry-sdk for 
openSUSE:Factory checked in at 2021-08-27 21:44:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sentry-sdk (Old)
 and      /work/SRC/openSUSE:Factory/.python-sentry-sdk.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sentry-sdk"

Fri Aug 27 21:44:03 2021 rev:16 rq:914559 version:1.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sentry-sdk/python-sentry-sdk.changes      
2021-05-07 16:46:07.164217695 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-sentry-sdk.new.1899/python-sentry-sdk.changes
    2021-08-27 21:45:15.238065326 +0200
@@ -1,0 +2,20 @@
+Wed Aug 25 12:00:44 UTC 2021 - Martin Hauke <mar...@gmx.de>
+
+- Update to 1.3.1
+  * Fix detection of contextvars compatibility with Gevent
+    versions >=20.9.0 .
+- Update to 1.3.0
+  * Add support for Sanic versions 20 and 21 .
+- Update to 1.2.0
+  * Fix for AWSLambda Integration to handle other path formats
+    for function initial handler #1139
+  * Fix for worker to set deamon attribute instead of deprecated
+    setDaemon method #1093
+  * Fix for bottle Integration that discards -dev for version
+    extraction #1085
+  * Fix for transport that adds a unified hook for capturing
+    metrics about dropped events #1100
+  * Add Httpx Integration #1119
+  * Add support for china domains in AWSLambda Integration #1051
+
+-------------------------------------------------------------------

Old:
----
  sentry-python-1.1.0.tar.gz

New:
----
  sentry-python-1.3.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sentry-sdk.spec ++++++
--- /var/tmp/diff_new_pack.HXolb6/_old  2021-08-27 21:45:15.770065960 +0200
+++ /var/tmp/diff_new_pack.HXolb6/_new  2021-08-27 21:45:15.774065965 +0200
@@ -20,7 +20,7 @@
 # nothing provides python2-venusian >= 1.0 needed by python2-pyramid
 %define skip_python2 1
 Name:           python-sentry-sdk
-Version:        1.1.0
+Version:        1.3.1
 Release:        0
 Summary:        Python SDK for Sentry.io
 License:        BSD-2-Clause

++++++ sentry-python-1.1.0.tar.gz -> sentry-python-1.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/.craft.yml 
new/sentry-python-1.3.1/.craft.yml
--- old/sentry-python-1.1.0/.craft.yml  2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/.craft.yml  2021-07-27 16:03:41.000000000 +0200
@@ -1,18 +1,12 @@
----
-minVersion: "0.14.0"
-github:
-  owner: getsentry
-  repo: sentry-python
-
+minVersion: 0.23.1
 targets:
   - name: pypi
     includeNames: /^sentry[_\-]sdk.*$/
   - name: github
   - name: gh-pages
   - name: registry
-    type: sdk
-    config:
-      canonical: pypi:sentry-sdk
+    sdks:
+      pypi:sentry-sdk:
   - name: aws-lambda-layer
     includeNames: /^sentry-python-serverless-\d+(\.\d+)*\.zip$/
     layerName: SentryPythonServerlessSDK
@@ -29,11 +23,5 @@
           - python3.7
           - python3.8
     license: MIT
-
 changelog: CHANGELOG.md
 changelogPolicy: simple
-
-statusProvider:
-  name: github
-artifactProvider:
-  name: github
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/.github/dependabot.yml 
new/sentry-python-1.3.1/.github/dependabot.yml
--- old/sentry-python-1.1.0/.github/dependabot.yml      1970-01-01 
01:00:00.000000000 +0100
+++ new/sentry-python-1.3.1/.github/dependabot.yml      2021-07-27 
16:03:41.000000000 +0200
@@ -0,0 +1,43 @@
+version: 2
+updates:
+- package-ecosystem: pip
+  directory: "/"
+  schedule:
+    interval: weekly
+  open-pull-requests-limit: 10
+  allow:
+  - dependency-type: direct
+  - dependency-type: indirect
+  ignore:
+  - dependency-name: pytest
+    versions:
+    - "> 3.7.3"
+  - dependency-name: pytest-cov
+    versions:
+    - "> 2.8.1"
+  - dependency-name: pytest-forked
+    versions:
+    - "> 1.1.3"
+  - dependency-name: sphinx
+    versions:
+    - ">= 2.4.a, < 2.5"
+  - dependency-name: tox
+    versions:
+    - "> 3.7.0"
+  - dependency-name: werkzeug
+    versions:
+    - "> 0.15.5, < 1"
+  - dependency-name: werkzeug
+    versions:
+    - ">= 1.0.a, < 1.1"
+  - dependency-name: mypy
+    versions:
+    - "0.800"
+  - dependency-name: sphinx
+    versions:
+    - 3.4.3
+- package-ecosystem: gitsubmodule
+  directory: "/"
+  schedule:
+    interval: weekly
+  open-pull-requests-limit: 10
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/CHANGELOG.md 
new/sentry-python-1.3.1/CHANGELOG.md
--- old/sentry-python-1.1.0/CHANGELOG.md        2021-05-06 18:58:30.000000000 
+0200
+++ new/sentry-python-1.3.1/CHANGELOG.md        2021-07-27 16:03:41.000000000 
+0200
@@ -20,6 +20,23 @@
 
 A major release `N` implies the previous release `N-1` will no longer receive 
updates. We generally do not backport bugfixes to older versions unless they 
are security relevant. However, feel free to ask for backports of specific 
commits on the bugtracker.
 
+## 1.3.1
+
+- Fix detection of contextvars compatibility with Gevent versions >=20.9.0 
#1157
+
+## 1.3.0
+
+- Add support for Sanic versions 20 and 21 #1146
+
+## 1.2.0
+
+- Fix for `AWSLambda` Integration to handle other path formats for function 
initial handler #1139
+- Fix for worker to set deamon attribute instead of deprecated setDaemon 
method #1093
+- Fix for `bottle` Integration that discards `-dev` for version extraction 
#1085
+- Fix for transport that adds a unified hook for capturing metrics about 
dropped events #1100
+- Add `Httpx` Integration #1119
+- Add support for china domains in `AWSLambda` Integration #1051
+
 ## 1.1.0
 
 - Fix for `AWSLambda` integration returns value of original handler #1106
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/docs/conf.py 
new/sentry-python-1.3.1/docs/conf.py
--- old/sentry-python-1.1.0/docs/conf.py        2021-05-06 18:58:30.000000000 
+0200
+++ new/sentry-python-1.3.1/docs/conf.py        2021-07-27 16:03:41.000000000 
+0200
@@ -5,6 +5,13 @@
 
 import typing
 
+# prevent circular imports
+import sphinx.builders.html
+import sphinx.builders.latex
+import sphinx.builders.texinfo
+import sphinx.builders.text
+import sphinx.ext.autodoc
+
 typing.TYPE_CHECKING = True
 
 #
@@ -22,7 +29,7 @@
 copyright = u"2019, Sentry Team and Contributors"
 author = u"Sentry Team and Contributors"
 
-release = "1.1.0"
+release = "1.3.1"
 version = ".".join(release.split(".")[:2])  # The short X.Y version.
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/docs-requirements.txt 
new/sentry-python-1.3.1/docs-requirements.txt
--- old/sentry-python-1.1.0/docs-requirements.txt       2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/docs-requirements.txt       2021-07-27 
16:03:41.000000000 +0200
@@ -1,4 +1,4 @@
-sphinx==3.5.3
+sphinx==4.1.1
 sphinx-rtd-theme
 sphinx-autodoc-typehints[type_comments]>=1.8.0
 typing-extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/linter-requirements.txt 
new/sentry-python-1.3.1/linter-requirements.txt
--- old/sentry-python-1.1.0/linter-requirements.txt     2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/linter-requirements.txt     2021-07-27 
16:03:41.000000000 +0200
@@ -1,6 +1,6 @@
-black==20.8b1
-flake8==3.9.0
+black==21.7b0
+flake8==3.9.2
 flake8-import-order==0.18.1
 mypy==0.782
-flake8-bugbear==21.3.2
+flake8-bugbear==21.4.3
 pep8-naming==0.11.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/scripts/init_serverless_sdk.py 
new/sentry-python-1.3.1/scripts/init_serverless_sdk.py
--- old/sentry-python-1.1.0/scripts/init_serverless_sdk.py      2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/scripts/init_serverless_sdk.py      2021-07-27 
16:03:41.000000000 +0200
@@ -6,6 +6,8 @@
 'sentry_sdk.integrations.init_serverless_sdk.sentry_lambda_handler'
 """
 import os
+import sys
+import re
 
 import sentry_sdk
 from sentry_sdk._types import MYPY
@@ -23,16 +25,53 @@
 )
 
 
+class AWSLambdaModuleLoader:
+    DIR_PATH_REGEX = r"^(.+)\/([^\/]+)$"
+
+    def __init__(self, sentry_initial_handler):
+        try:
+            module_path, self.handler_name = 
sentry_initial_handler.rsplit(".", 1)
+        except ValueError:
+            raise ValueError("Incorrect AWS Handler path (Not a path)")
+
+        self.extract_and_load_lambda_function_module(module_path)
+
+    def extract_and_load_lambda_function_module(self, module_path):
+        """
+        Method that extracts and loads lambda function module from module_path
+        """
+        py_version = sys.version_info
+
+        if re.match(self.DIR_PATH_REGEX, module_path):
+            # With a path like -> `scheduler/scheduler/event`
+            # `module_name` is `event`, and `module_file_path` is 
`scheduler/scheduler/event.py`
+            module_name = module_path.split(os.path.sep)[-1]
+            module_file_path = module_path + ".py"
+
+            # Supported python versions are 2.7, 3.6, 3.7, 3.8
+            if py_version >= (3, 5):
+                import importlib.util
+                spec = importlib.util.spec_from_file_location(module_name, 
module_file_path)
+                self.lambda_function_module = 
importlib.util.module_from_spec(spec)
+                spec.loader.exec_module(self.lambda_function_module)
+            elif py_version[0] < 3:
+                import imp
+                self.lambda_function_module = imp.load_source(module_name, 
module_file_path)
+            else:
+                raise ValueError("Python version %s is not supported." % 
py_version)
+        else:
+            import importlib
+            self.lambda_function_module = importlib.import_module(module_path)
+
+    def get_lambda_handler(self):
+        return getattr(self.lambda_function_module, self.handler_name)
+
+
 def sentry_lambda_handler(event, context):
     # type: (Any, Any) -> None
     """
     Handler function that invokes a lambda handler which path is defined in
-    environment vairables as "SENTRY_INITIAL_HANDLER"
+    environment variables as "SENTRY_INITIAL_HANDLER"
     """
-    try:
-        module_name, handler_name = 
os.environ["SENTRY_INITIAL_HANDLER"].rsplit(".", 1)
-    except ValueError:
-        raise ValueError("Incorrect AWS Handler path (Not a path)")
-    lambda_function = __import__(module_name)
-    lambda_handler = getattr(lambda_function, handler_name)
-    return lambda_handler(event, context)
+    module_loader = AWSLambdaModuleLoader(os.environ["SENTRY_INITIAL_HANDLER"])
+    return module_loader.get_lambda_handler()(event, context)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/consts.py 
new/sentry-python-1.3.1/sentry_sdk/consts.py
--- old/sentry-python-1.1.0/sentry_sdk/consts.py        2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/consts.py        2021-07-27 
16:03:41.000000000 +0200
@@ -99,7 +99,7 @@
 del _get_default_options
 
 
-VERSION = "1.1.0"
+VERSION = "1.3.1"
 SDK_INFO = {
     "name": "sentry.python",
     "version": VERSION,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/sentry_sdk/integrations/aws_lambda.py 
new/sentry-python-1.3.1/sentry_sdk/integrations/aws_lambda.py
--- old/sentry-python-1.1.0/sentry_sdk/integrations/aws_lambda.py       
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/integrations/aws_lambda.py       
2021-07-27 16:03:41.000000000 +0200
@@ -400,13 +400,15 @@
         str -- AWS Console URL to logs.
     """
     formatstring = "%Y-%m-%dT%H:%M:%SZ"
+    region = environ.get("AWS_REGION", "")
 
     url = (
-        "https://console.aws.amazon.com/cloudwatch/home?region={region}";
+        "https://console.{domain}/cloudwatch/home?region={region}";
         "#logEventViewer:group={log_group};stream={log_stream}"
         ";start={start_time};end={end_time}"
     ).format(
-        region=environ.get("AWS_REGION"),
+        domain="amazonaws.cn" if region.startswith("cn-") else 
"aws.amazon.com",
+        region=region,
         log_group=aws_context.log_group_name,
         log_stream=aws_context.log_stream_name,
         start_time=(start_time - timedelta(seconds=1)).strftime(formatstring),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/sentry_sdk/integrations/bottle.py 
new/sentry-python-1.3.1/sentry_sdk/integrations/bottle.py
--- old/sentry-python-1.1.0/sentry_sdk/integrations/bottle.py   2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/integrations/bottle.py   2021-07-27 
16:03:41.000000000 +0200
@@ -57,7 +57,7 @@
         # type: () -> None
 
         try:
-            version = tuple(map(int, BOTTLE_VERSION.split(".")))
+            version = tuple(map(int, BOTTLE_VERSION.replace("-dev", 
"").split(".")))
         except (TypeError, ValueError):
             raise DidNotEnable("Unparsable Bottle version: {}".format(version))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/integrations/httpx.py 
new/sentry-python-1.3.1/sentry_sdk/integrations/httpx.py
--- old/sentry-python-1.1.0/sentry_sdk/integrations/httpx.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/sentry-python-1.3.1/sentry_sdk/integrations/httpx.py    2021-07-27 
16:03:41.000000000 +0200
@@ -0,0 +1,83 @@
+from sentry_sdk import Hub
+from sentry_sdk.integrations import Integration, DidNotEnable
+
+from sentry_sdk._types import MYPY
+
+if MYPY:
+    from typing import Any
+
+
+try:
+    from httpx import AsyncClient, Client, Request, Response  # type: ignore
+except ImportError:
+    raise DidNotEnable("httpx is not installed")
+
+__all__ = ["HttpxIntegration"]
+
+
+class HttpxIntegration(Integration):
+    identifier = "httpx"
+
+    @staticmethod
+    def setup_once():
+        # type: () -> None
+        """
+        httpx has its own transport layer and can be customized when needed,
+        so patch Client.send and AsyncClient.send to support both synchronous 
and async interfaces.
+        """
+        _install_httpx_client()
+        _install_httpx_async_client()
+
+
+def _install_httpx_client():
+    # type: () -> None
+    real_send = Client.send
+
+    def send(self, request, **kwargs):
+        # type: (Client, Request, **Any) -> Response
+        hub = Hub.current
+        if hub.get_integration(HttpxIntegration) is None:
+            return real_send(self, request, **kwargs)
+
+        with hub.start_span(
+            op="http", description="%s %s" % (request.method, request.url)
+        ) as span:
+            span.set_data("method", request.method)
+            span.set_data("url", str(request.url))
+            for key, value in hub.iter_trace_propagation_headers():
+                request.headers[key] = value
+            rv = real_send(self, request, **kwargs)
+
+            span.set_data("status_code", rv.status_code)
+            span.set_http_status(rv.status_code)
+            span.set_data("reason", rv.reason_phrase)
+            return rv
+
+    Client.send = send
+
+
+def _install_httpx_async_client():
+    # type: () -> None
+    real_send = AsyncClient.send
+
+    async def send(self, request, **kwargs):
+        # type: (AsyncClient, Request, **Any) -> Response
+        hub = Hub.current
+        if hub.get_integration(HttpxIntegration) is None:
+            return await real_send(self, request, **kwargs)
+
+        with hub.start_span(
+            op="http", description="%s %s" % (request.method, request.url)
+        ) as span:
+            span.set_data("method", request.method)
+            span.set_data("url", str(request.url))
+            for key, value in hub.iter_trace_propagation_headers():
+                request.headers[key] = value
+            rv = await real_send(self, request, **kwargs)
+
+            span.set_data("status_code", rv.status_code)
+            span.set_http_status(rv.status_code)
+            span.set_data("reason", rv.reason_phrase)
+            return rv
+
+    AsyncClient.send = send
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/integrations/redis.py 
new/sentry-python-1.3.1/sentry_sdk/integrations/redis.py
--- old/sentry-python-1.1.0/sentry_sdk/integrations/redis.py    2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/integrations/redis.py    2021-07-27 
16:03:41.000000000 +0200
@@ -56,7 +56,7 @@
         try:
             _patch_rediscluster()
         except Exception:
-            logger.exception("Error occured while patching `rediscluster` 
library")
+            logger.exception("Error occurred while patching `rediscluster` 
library")
 
 
 def patch_redis_client(cls):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/integrations/sanic.py 
new/sentry-python-1.3.1/sentry_sdk/integrations/sanic.py
--- old/sentry-python-1.1.0/sentry_sdk/integrations/sanic.py    2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/integrations/sanic.py    2021-07-27 
16:03:41.000000000 +0200
@@ -96,14 +96,29 @@
 
         old_router_get = Router.get
 
-        def sentry_router_get(self, request):
-            # type: (Any, Request) -> Any
-            rv = old_router_get(self, request)
+        def sentry_router_get(self, *args):
+            # type: (Any, Union[Any, Request]) -> Any
+            rv = old_router_get(self, *args)
             hub = Hub.current
             if hub.get_integration(SanicIntegration) is not None:
                 with capture_internal_exceptions():
                     with hub.configure_scope() as scope:
-                        scope.transaction = rv[0].__name__
+                        if version >= (21, 3):
+                            # Sanic versions above and including 21.3 append 
the app name to the
+                            # route name, and so we need to remove it from 
Route name so the
+                            # transaction name is consistent across all 
versions
+                            sanic_app_name = self.ctx.app.name
+                            sanic_route = rv[0].name
+
+                            if sanic_route.startswith("%s." % sanic_app_name):
+                                # We add a 1 to the len of the sanic_app_name 
because there is a dot
+                                # that joins app name and the route name
+                                # Format: app_name.route_name
+                                sanic_route = sanic_route[len(sanic_app_name) 
+ 1 :]
+
+                            scope.transaction = sanic_route
+                        else:
+                            scope.transaction = rv[0].__name__
             return rv
 
         Router.get = sentry_router_get
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/tracing.py 
new/sentry-python-1.3.1/sentry_sdk/tracing.py
--- old/sentry-python-1.1.0/sentry_sdk/tracing.py       2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/tracing.py       2021-07-27 
16:03:41.000000000 +0200
@@ -666,7 +666,7 @@
     # type: (Dict[str, Any]) -> bool
     """
     Returns True if either traces_sample_rate or traces_sampler is
-    non-zero/defined, False otherwise.
+    defined, False otherwise.
     """
 
     return bool(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/transport.py 
new/sentry-python-1.3.1/sentry_sdk/transport.py
--- old/sentry-python-1.1.0/sentry_sdk/transport.py     2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/transport.py     2021-07-27 
16:03:41.000000000 +0200
@@ -150,12 +150,14 @@
         # no matter of the status code to update our internal rate limits.
         header = response.headers.get("x-sentry-rate-limits")
         if header:
+            logger.warning("Rate-limited via x-sentry-rate-limits")
             self._disabled_until.update(_parse_rate_limits(header))
 
         # old sentries only communicate global rate limit hits via the
         # retry-after header on 429.  This header can also be emitted on new
         # sentries if a proxy in front wants to globally slow things down.
         elif response.status == 429:
+            logger.warning("Rate-limited via 429")
             self._disabled_until[None] = datetime.utcnow() + timedelta(
                 seconds=self._retry.get_retry_after(response) or 60
             )
@@ -173,12 +175,16 @@
                 "X-Sentry-Auth": str(self._auth.to_header()),
             }
         )
-        response = self._pool.request(
-            "POST",
-            str(self._auth.get_api_url(endpoint_type)),
-            body=body,
-            headers=headers,
-        )
+        try:
+            response = self._pool.request(
+                "POST",
+                str(self._auth.get_api_url(endpoint_type)),
+                body=body,
+                headers=headers,
+            )
+        except Exception:
+            self.on_dropped_event("network")
+            raise
 
         try:
             self._update_rate_limits(response)
@@ -186,6 +192,7 @@
             if response.status == 429:
                 # if we hit a 429.  Something was rate limited but we already
                 # acted on this in `self._update_rate_limits`.
+                self.on_dropped_event("status_429")
                 pass
 
             elif response.status >= 300 or response.status < 200:
@@ -194,9 +201,14 @@
                     response.status,
                     response.data,
                 )
+                self.on_dropped_event("status_{}".format(response.status))
         finally:
             response.close()
 
+    def on_dropped_event(self, reason):
+        # type: (str) -> None
+        pass
+
     def _check_disabled(self, category):
         # type: (str) -> bool
         def _disabled(bucket):
@@ -212,6 +224,7 @@
         # type: (...) -> None
 
         if self._check_disabled("error"):
+            self.on_dropped_event("self_rate_limits")
             return None
 
         body = io.BytesIO()
@@ -325,7 +338,8 @@
                 with capture_internal_exceptions():
                     self._send_event(event)
 
-        self._worker.submit(send_event_wrapper)
+        if not self._worker.submit(send_event_wrapper):
+            self.on_dropped_event("full_queue")
 
     def capture_envelope(
         self, envelope  # type: Envelope
@@ -339,7 +353,8 @@
                 with capture_internal_exceptions():
                     self._send_envelope(envelope)
 
-        self._worker.submit(send_envelope_wrapper)
+        if not self._worker.submit(send_envelope_wrapper):
+            self.on_dropped_event("full_queue")
 
     def flush(
         self,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/utils.py 
new/sentry-python-1.3.1/sentry_sdk/utils.py
--- old/sentry-python-1.1.0/sentry_sdk/utils.py 2021-05-06 18:58:30.000000000 
+0200
+++ new/sentry-python-1.3.1/sentry_sdk/utils.py 2021-07-27 16:03:41.000000000 
+0200
@@ -785,12 +785,24 @@
     Returns whether gevent/eventlet have patched the stdlib in a way where 
thread locals are now more "correct" than contextvars.
     """
     try:
+        import gevent  # type: ignore
         from gevent.monkey import is_object_patched  # type: ignore
 
+        # Get the MAJOR and MINOR version numbers of Gevent
+        version_tuple = tuple([int(part) for part in 
gevent.__version__.split(".")[:2]])
         if is_object_patched("threading", "local"):
-            # Gevent 20.5 is able to patch both thread locals and contextvars,
-            # in that case all is good.
-            if is_object_patched("contextvars", "ContextVar"):
+            # Gevent 20.9.0 depends on Greenlet 0.4.17 which natively handles 
switching
+            # context vars when greenlets are switched, so, Gevent 20.9.0+ is 
all fine.
+            # Ref: 
https://github.com/gevent/gevent/blob/83c9e2ae5b0834b8f84233760aabe82c3ba065b4/src/gevent/monkey.py#L604-L609
+            # Gevent 20.5, that doesn't depend on Greenlet 0.4.17 with native 
support
+            # for contextvars, is able to patch both thread locals and 
contextvars, in
+            # that case, check if contextvars are effectively patched.
+            if (
+                # Gevent 20.9.0+
+                (sys.version_info >= (3, 7) and version_tuple >= (20, 9))
+                # Gevent 20.5.0+ or Python < 3.7
+                or (is_object_patched("contextvars", "ContextVar"))
+            ):
                 return False
 
             return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/sentry_sdk/worker.py 
new/sentry-python-1.3.1/sentry_sdk/worker.py
--- old/sentry-python-1.1.0/sentry_sdk/worker.py        2021-05-06 
18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/sentry_sdk/worker.py        2021-07-27 
16:03:41.000000000 +0200
@@ -66,7 +66,7 @@
                 self._thread = threading.Thread(
                     target=self._target, name="raven-sentry.BackgroundWorker"
                 )
-                self._thread.setDaemon(True)
+                self._thread.daemon = True
                 self._thread.start()
                 self._thread_for_pid = os.getpid()
 
@@ -109,16 +109,13 @@
                 logger.error("flush timed out, dropped %s events", pending)
 
     def submit(self, callback):
-        # type: (Callable[[], None]) -> None
+        # type: (Callable[[], None]) -> bool
         self._ensure_thread()
         try:
             self._queue.put_nowait(callback)
+            return True
         except Full:
-            self.on_full_queue(callback)
-
-    def on_full_queue(self, callback):
-        # type: (Optional[Any]) -> None
-        logger.error("background worker queue full, dropping event")
+            return False
 
     def _target(self):
         # type: () -> None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/setup.py 
new/sentry-python-1.3.1/setup.py
--- old/sentry-python-1.1.0/setup.py    2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/setup.py    2021-07-27 16:03:41.000000000 +0200
@@ -21,7 +21,7 @@
 
 setup(
     name="sentry-sdk",
-    version="1.1.0",
+    version="1.3.1",
     author="Sentry Team and Contributors",
     author_email="he...@sentry.io",
     url="https://github.com/getsentry/sentry-python";,
@@ -53,6 +53,7 @@
         "pyspark": ["pyspark>=2.4.4"],
         "pure_eval": ["pure_eval", "executing", "asttokens"],
         "chalice": ["chalice>=1.16.0"],
+        "httpx": ["httpx>=0.16.0"],
     },
     classifiers=[
         "Development Status :: 5 - Production/Stable",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/aws_lambda/client.py 
new/sentry-python-1.3.1/tests/integrations/aws_lambda/client.py
--- old/sentry-python-1.1.0/tests/integrations/aws_lambda/client.py     
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tests/integrations/aws_lambda/client.py     
2021-07-27 16:03:41.000000000 +0200
@@ -18,7 +18,7 @@
 
 
 def build_no_code_serverless_function_and_layer(
-    client, tmpdir, fn_name, runtime, timeout
+    client, tmpdir, fn_name, runtime, timeout, initial_handler
 ):
     """
     Util function that auto instruments the no code implementation of the 
python
@@ -45,7 +45,7 @@
             Timeout=timeout,
             Environment={
                 "Variables": {
-                    "SENTRY_INITIAL_HANDLER": "test_lambda.test_handler",
+                    "SENTRY_INITIAL_HANDLER": initial_handler,
                     "SENTRY_DSN": "https://123...@example.com/123";,
                     "SENTRY_TRACES_SAMPLE_RATE": "1.0",
                 }
@@ -67,12 +67,27 @@
     syntax_check=True,
     timeout=30,
     layer=None,
+    initial_handler=None,
     subprocess_kwargs=(),
 ):
     subprocess_kwargs = dict(subprocess_kwargs)
 
     with tempfile.TemporaryDirectory() as tmpdir:
-        test_lambda_py = os.path.join(tmpdir, "test_lambda.py")
+        if initial_handler:
+            # If Initial handler value is provided i.e. it is not the default
+            # `test_lambda.test_handler`, then create another dir level so 
that our path is
+            # test_dir.test_lambda.test_handler
+            test_dir_path = os.path.join(tmpdir, "test_dir")
+            python_init_file = os.path.join(test_dir_path, "__init__.py")
+            os.makedirs(test_dir_path)
+            with open(python_init_file, "w"):
+                # Create __init__ file to make it a python package
+                pass
+
+            test_lambda_py = os.path.join(tmpdir, "test_dir", "test_lambda.py")
+        else:
+            test_lambda_py = os.path.join(tmpdir, "test_lambda.py")
+
         with open(test_lambda_py, "w") as f:
             f.write(code)
 
@@ -127,8 +142,13 @@
                 cwd=tmpdir,
                 check=True,
             )
+
+            # Default initial handler
+            if not initial_handler:
+                initial_handler = "test_lambda.test_handler"
+
             build_no_code_serverless_function_and_layer(
-                client, tmpdir, fn_name, runtime, timeout
+                client, tmpdir, fn_name, runtime, timeout, initial_handler
             )
 
         @add_finalizer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/aws_lambda/test_aws.py 
new/sentry-python-1.3.1/tests/integrations/aws_lambda/test_aws.py
--- old/sentry-python-1.1.0/tests/integrations/aws_lambda/test_aws.py   
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tests/integrations/aws_lambda/test_aws.py   
2021-07-27 16:03:41.000000000 +0200
@@ -112,7 +112,9 @@
 
 @pytest.fixture
 def run_lambda_function(request, lambda_client, lambda_runtime):
-    def inner(code, payload, timeout=30, syntax_check=True, layer=None):
+    def inner(
+        code, payload, timeout=30, syntax_check=True, layer=None, 
initial_handler=None
+    ):
         from tests.integrations.aws_lambda.client import run_lambda_function
 
         response = run_lambda_function(
@@ -124,6 +126,7 @@
             timeout=timeout,
             syntax_check=syntax_check,
             layer=layer,
+            initial_handler=initial_handler,
         )
 
         # for better debugging
@@ -621,32 +624,39 @@
     python sdk, with no code changes sentry is able to capture errors
     """
 
-    _, _, response = run_lambda_function(
-        dedent(
-            """
-        import sentry_sdk
+    for initial_handler in [
+        None,
+        "test_dir/test_lambda.test_handler",
+        "test_dir.test_lambda.test_handler",
+    ]:
+        print("Testing Initial Handler ", initial_handler)
+        _, _, response = run_lambda_function(
+            dedent(
+                """
+            import sentry_sdk
 
-        def test_handler(event, context):
-            current_client = sentry_sdk.Hub.current.client
+            def test_handler(event, context):
+                current_client = sentry_sdk.Hub.current.client
 
-            assert current_client is not None
+                assert current_client is not None
 
-            assert len(current_client.options['integrations']) == 1
-            assert isinstance(current_client.options['integrations'][0],
-                              
sentry_sdk.integrations.aws_lambda.AwsLambdaIntegration)
+                assert len(current_client.options['integrations']) == 1
+                assert isinstance(current_client.options['integrations'][0],
+                                  
sentry_sdk.integrations.aws_lambda.AwsLambdaIntegration)
 
-            raise Exception("something went wrong")
-        """
-        ),
-        b'{"foo": "bar"}',
-        layer=True,
-    )
-    assert response["FunctionError"] == "Unhandled"
-    assert response["StatusCode"] == 200
+                raise Exception("something went wrong")
+            """
+            ),
+            b'{"foo": "bar"}',
+            layer=True,
+            initial_handler=initial_handler,
+        )
+        assert response["FunctionError"] == "Unhandled"
+        assert response["StatusCode"] == 200
 
-    assert response["Payload"]["errorType"] != "AssertionError"
+        assert response["Payload"]["errorType"] != "AssertionError"
 
-    assert response["Payload"]["errorType"] == "Exception"
-    assert response["Payload"]["errorMessage"] == "something went wrong"
+        assert response["Payload"]["errorType"] == "Exception"
+        assert response["Payload"]["errorMessage"] == "something went wrong"
 
-    assert "sentry_handler" in response["LogResult"][3].decode("utf-8")
+        assert "sentry_handler" in response["LogResult"][3].decode("utf-8")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/django/myapp/settings.py 
new/sentry-python-1.3.1/tests/integrations/django/myapp/settings.py
--- old/sentry-python-1.1.0/tests/integrations/django/myapp/settings.py 
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tests/integrations/django/myapp/settings.py 
2021-07-27 16:03:41.000000000 +0200
@@ -157,7 +157,7 @@
 
 USE_L10N = True
 
-USE_TZ = True
+USE_TZ = False
 
 TEMPLATE_DEBUG = True
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/django/test_basic.py 
new/sentry-python-1.3.1/tests/integrations/django/test_basic.py
--- old/sentry-python-1.1.0/tests/integrations/django/test_basic.py     
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tests/integrations/django/test_basic.py     
2021-07-27 16:03:41.000000000 +0200
@@ -1,6 +1,7 @@
 from __future__ import absolute_import
 
 import pytest
+import pytest_django
 import json
 
 from werkzeug.test import Client
@@ -21,6 +22,19 @@
 
 from tests.integrations.django.myapp.wsgi import application
 
+# Hack to prevent from experimental feature introduced in version `4.3.0` in 
`pytest-django` that
+# requires explicit database allow from failing the test
+pytest_mark_django_db_decorator = pytest.mark.django_db
+try:
+    pytest_version = tuple(map(int, pytest_django.__version__.split(".")))
+    if pytest_version > (4, 2, 0):
+        pytest_mark_django_db_decorator = 
pytest.mark.django_db(databases="__all__")
+except ValueError:
+    if "dev" in pytest_django.__version__:
+        pytest_mark_django_db_decorator = 
pytest.mark.django_db(databases="__all__")
+except AttributeError:
+    pass
+
 
 @pytest.fixture
 def client():
@@ -245,7 +259,7 @@
 
 
 @pytest.mark.forked
-@pytest.mark.django_db
+@pytest_mark_django_db_decorator
 def test_sql_dict_query_params(sentry_init, capture_events):
     sentry_init(
         integrations=[DjangoIntegration()],
@@ -290,7 +304,7 @@
     ],
 )
 @pytest.mark.forked
-@pytest.mark.django_db
+@pytest_mark_django_db_decorator
 def test_sql_psycopg2_string_composition(sentry_init, capture_events, query):
     sentry_init(
         integrations=[DjangoIntegration()],
@@ -323,7 +337,7 @@
 
 
 @pytest.mark.forked
-@pytest.mark.django_db
+@pytest_mark_django_db_decorator
 def test_sql_psycopg2_placeholders(sentry_init, capture_events):
     sentry_init(
         integrations=[DjangoIntegration()],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/httpx/__init__.py 
new/sentry-python-1.3.1/tests/integrations/httpx/__init__.py
--- old/sentry-python-1.1.0/tests/integrations/httpx/__init__.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/sentry-python-1.3.1/tests/integrations/httpx/__init__.py        
2021-07-27 16:03:41.000000000 +0200
@@ -0,0 +1,3 @@
+import pytest
+
+pytest.importorskip("httpx")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/httpx/test_httpx.py 
new/sentry-python-1.3.1/tests/integrations/httpx/test_httpx.py
--- old/sentry-python-1.1.0/tests/integrations/httpx/test_httpx.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/sentry-python-1.3.1/tests/integrations/httpx/test_httpx.py      
2021-07-27 16:03:41.000000000 +0200
@@ -0,0 +1,66 @@
+import asyncio
+
+import httpx
+
+from sentry_sdk import capture_message, start_transaction
+from sentry_sdk.integrations.httpx import HttpxIntegration
+
+
+def test_crumb_capture_and_hint(sentry_init, capture_events):
+    def before_breadcrumb(crumb, hint):
+        crumb["data"]["extra"] = "foo"
+        return crumb
+
+    sentry_init(integrations=[HttpxIntegration()], 
before_breadcrumb=before_breadcrumb)
+    clients = (httpx.Client(), httpx.AsyncClient())
+    for i, c in enumerate(clients):
+        with start_transaction():
+            events = capture_events()
+
+            url = "https://httpbin.org/status/200";
+            if not asyncio.iscoroutinefunction(c.get):
+                response = c.get(url)
+            else:
+                response = 
asyncio.get_event_loop().run_until_complete(c.get(url))
+
+            assert response.status_code == 200
+            capture_message("Testing!")
+
+            (event,) = events
+            # send request twice so we need get breadcrumb by index
+            crumb = event["breadcrumbs"]["values"][i]
+            assert crumb["type"] == "http"
+            assert crumb["category"] == "httplib"
+            assert crumb["data"] == {
+                "url": url,
+                "method": "GET",
+                "status_code": 200,
+                "reason": "OK",
+                "extra": "foo",
+            }
+
+
+def test_outgoing_trace_headers(sentry_init):
+    sentry_init(traces_sample_rate=1.0, integrations=[HttpxIntegration()])
+    clients = (httpx.Client(), httpx.AsyncClient())
+    for i, c in enumerate(clients):
+        with start_transaction(
+            name="/interactions/other-dogs/new-dog",
+            op="greeting.sniff",
+            # make trace_id difference between transactions
+            trace_id=f"012345678901234567890123456789{i}",
+        ) as transaction:
+            url = "https://httpbin.org/status/200";
+            if not asyncio.iscoroutinefunction(c.get):
+                response = c.get(url)
+            else:
+                response = 
asyncio.get_event_loop().run_until_complete(c.get(url))
+
+            request_span = transaction._span_recorder.spans[-1]
+            assert response.request.headers[
+                "sentry-trace"
+            ] == "{trace_id}-{parent_span_id}-{sampled}".format(
+                trace_id=transaction.trace_id,
+                parent_span_id=request_span.span_id,
+                sampled=1,
+            )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sentry-python-1.1.0/tests/integrations/sanic/test_sanic.py 
new/sentry-python-1.3.1/tests/integrations/sanic/test_sanic.py
--- old/sentry-python-1.1.0/tests/integrations/sanic/test_sanic.py      
2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tests/integrations/sanic/test_sanic.py      
2021-07-27 16:03:41.000000000 +0200
@@ -9,6 +9,7 @@
 from sentry_sdk.integrations.sanic import SanicIntegration
 
 from sanic import Sanic, request, response, __version__ as SANIC_VERSION_RAW
+from sanic.response import HTTPResponse
 from sanic.exceptions import abort
 
 SANIC_VERSION = tuple(map(int, SANIC_VERSION_RAW.split(".")))
@@ -16,7 +17,12 @@
 
 @pytest.fixture
 def app():
-    app = Sanic(__name__)
+    if SANIC_VERSION >= (20, 12):
+        # Build (20.12.0) adds a feature where the instance is stored in an 
internal class
+        # registry for later retrieval, and so add register=False to disable 
that
+        app = Sanic(__name__, register=False)
+    else:
+        app = Sanic(__name__)
 
     @app.route("/message")
     def hi(request):
@@ -166,11 +172,46 @@
         if SANIC_VERSION >= (19,):
             kwargs["app"] = app
 
-        await app.handle_request(
-            request.Request(**kwargs),
-            write_callback=responses.append,
-            stream_callback=responses.append,
-        )
+        if SANIC_VERSION >= (21, 3):
+            try:
+                app.router.reset()
+                app.router.finalize()
+            except AttributeError:
+                ...
+
+            class MockAsyncStreamer:
+                def __init__(self, request_body):
+                    self.request_body = request_body
+                    self.iter = iter(self.request_body)
+                    self.response = b"success"
+
+                def respond(self, response):
+                    responses.append(response)
+                    patched_response = HTTPResponse()
+                    patched_response.send = lambda end_stream: 
asyncio.sleep(0.001)
+                    return patched_response
+
+                def __aiter__(self):
+                    return self
+
+                async def __anext__(self):
+                    try:
+                        return next(self.iter)
+                    except StopIteration:
+                        raise StopAsyncIteration
+
+            patched_request = request.Request(**kwargs)
+            patched_request.stream = MockAsyncStreamer([b"hello", b"foo"])
+
+            await app.handle_request(
+                patched_request,
+            )
+        else:
+            await app.handle_request(
+                request.Request(**kwargs),
+                write_callback=responses.append,
+                stream_callback=responses.append,
+            )
 
         (r,) = responses
         assert r.status == 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sentry-python-1.1.0/tox.ini 
new/sentry-python-1.3.1/tox.ini
--- old/sentry-python-1.1.0/tox.ini     2021-05-06 18:58:30.000000000 +0200
+++ new/sentry-python-1.3.1/tox.ini     2021-07-27 16:03:41.000000000 +0200
@@ -39,6 +39,8 @@
 
     {py3.5,py3.6,py3.7}-sanic-{0.8,18}
     {py3.6,py3.7}-sanic-19
+    {py3.6,py3.7,py3.8}-sanic-20
+    {py3.7,py3.8,py3.9}-sanic-21
 
     # TODO: Add py3.9
     {pypy,py2.7}-celery-3
@@ -83,6 +85,8 @@
 
     {py2.7,py3.6,py3.7,py3.8}-boto3-{1.9,1.10,1.11,1.12,1.13,1.14,1.15,1.16}
 
+    {py3.6,py3.7,py3.8,py3.9}-httpx-{0.16,0.17}
+
 [testenv]
 deps =
     # if you change test-requirements.txt and your change is not being 
reflected
@@ -102,6 +106,7 @@
     django-{1.6,1.7}: pytest-django<3.0
     django-{1.8,1.9,1.10,1.11,2.0,2.1}: pytest-django<4.0
     django-{2.2,3.0,3.1}: pytest-django>=4.0
+    django-{2.2,3.0,3.1}: Werkzeug<2.0
     django-dev: 
git+https://github.com/pytest-dev/pytest-django#egg=pytest-django
 
     django-1.6: Django>=1.6,<1.7
@@ -136,6 +141,9 @@
     sanic-0.8: sanic>=0.8,<0.9
     sanic-18: sanic>=18.0,<19.0
     sanic-19: sanic>=19.0,<20.0
+    sanic-20: sanic>=20.0,<21.0
+    sanic-21: sanic>=21.0,<22.0
+    {py3.7,py3.8,py3.9}-sanic-21: sanic_testing
     {py3.5,py3.6}-sanic: aiocontextvars==0.2.1
     sanic: aiohttp
     py3.5-sanic: ujson<4
@@ -201,7 +209,7 @@
     trytond-5.0: trytond>=5.0,<5.1
     trytond-4.6: trytond>=4.6,<4.7
 
-    trytond-4.8: werkzeug<1.0
+    trytond-{4.6,4.8,5.0,5.2,5.4}: werkzeug<2.0
 
     redis: fakeredis
 
@@ -235,6 +243,9 @@
     boto3-1.15: boto3>=1.15,<1.16
     boto3-1.16: boto3>=1.16,<1.17
 
+    httpx-0.16: httpx>=0.16,<0.17
+    httpx-0.17: httpx>=0.17,<0.18
+
 setenv =
     PYTHONDONTWRITEBYTECODE=1
     TESTPATH=tests
@@ -260,6 +271,7 @@
     pure_eval: TESTPATH=tests/integrations/pure_eval
     chalice: TESTPATH=tests/integrations/chalice
     boto3: TESTPATH=tests/integrations/boto3
+    httpx: TESTPATH=tests/integrations/httpx
 
     COVERAGE_FILE=.coverage-{envname}
 passenv =
@@ -297,9 +309,7 @@
 
     ; https://github.com/pytest-dev/pytest/issues/5532
     {py3.5,py3.6,py3.7,py3.8,py3.9}-flask-{0.10,0.11,0.12}: pip install 
pytest<5
-
-    ; trytond tries to import werkzeug.contrib
-    trytond-5.0: pip install werkzeug<1.0
+    {py3.6,py3.7,py3.8,py3.9}-flask-{0.11}: pip install Werkzeug<2
 
     py.test {env:TESTPATH} {posargs}
 

Reply via email to