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-11-20 02:39:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sentry-sdk (Old)
and /work/SRC/openSUSE:Factory/.python-sentry-sdk.new.1895 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sentry-sdk"
Sat Nov 20 02:39:16 2021 rev:18 rq:932485 version:1.5.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sentry-sdk/python-sentry-sdk.changes
2021-10-27 22:21:34.715210129 +0200
+++
/work/SRC/openSUSE:Factory/.python-sentry-sdk.new.1895/python-sentry-sdk.changes
2021-11-20 02:40:28.592515576 +0100
@@ -1,0 +2,13 @@
+Fri Nov 19 08:41:01 UTC 2021 - ecsos <[email protected]>
+
+- Update to 1.5.0
+ - Also record client outcomes for before send #1211
+ - Add support for implicitly sized envelope items #1229
+ - Fix integration with Apache Beam 2.32, 2.33 #1233
+ - Remove Python 2.7 support for AWS Lambda layers in craft config #1241
+ - Refactor Sanic integration for v21.9 support #1212
+ - AWS Lambda Python 3.9 runtime support #1239
+ - Fix "shutdown_timeout" typing #1256
+- Disable of python36 build, because out of support at 2021-12-23.
+
+-------------------------------------------------------------------
Old:
----
sentry-python-1.4.1.tar.gz
New:
----
sentry-python-1.5.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-sentry-sdk.spec ++++++
--- /var/tmp/diff_new_pack.EX7pwz/_old 2021-11-20 02:40:29.052514058 +0100
+++ /var/tmp/diff_new_pack.EX7pwz/_new 2021-11-20 02:40:29.056514045 +0100
@@ -19,8 +19,9 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
# nothing provides python2-venusian >= 1.0 needed by python2-pyramid
%define skip_python2 1
+%define skip_python36 1
Name: python-sentry-sdk
-Version: 1.4.1
+Version: 1.5.0
Release: 0
Summary: Python SDK for Sentry.io
License: BSD-2-Clause
@@ -37,10 +38,11 @@
BuildRequires: %{python_module certifi}
BuildRequires: %{python_module executing}
BuildRequires: %{python_module falcon >= 1.4}
+BuildRequires: %{python_module httpx >= 0.16.0}
BuildRequires: %{python_module rq >= 0.6}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module tornado >= 5}
-BuildRequires: %{python_module urllib3}
+BuildRequires: %{python_module urllib3 >= 1.10.0}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
# SECTION test requirements
@@ -50,7 +52,7 @@
BuildRequires: %{python_module hypothesis}
BuildRequires: %{python_module jsonschema >= 3.2.0}
BuildRequires: %{python_module pyramid}
-BuildRequires: %{python_module pyrsistent}
+BuildRequires: %{python_module pyrsistent >= 0.16.0}
BuildRequires: %{python_module pytest-cov >= 2.8.1}
BuildRequires: %{python_module pytest-forked >= 1.1.3}
BuildRequires: %{python_module pytest-localserver >= 0.5.0}
@@ -75,10 +77,11 @@
Requires: python-certifi
Requires: python-executing
Requires: python-falcon >= 1.4
+Requires: python-httpx >= 0.16.0
Requires: python-jsonschema
Requires: python-rq >= 0.6
Requires: python-tornado >= 5
-Requires: python-urllib3
+Requires: python-urllib3 >= 1.10.0
# SECTION extra requirements - which rise up buildtime error or missing in
openSUSE
#Requires: python-Django >= 1.8
#Requires: python-sanic >= 0.8
++++++ sentry-python-1.4.1.tar.gz -> sentry-python-1.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/.craft.yml
new/sentry-python-1.5.0/.craft.yml
--- old/sentry-python-1.4.1/.craft.yml 2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/.craft.yml 2021-11-16 19:57:37.000000000 +0100
@@ -18,10 +18,10 @@
# On the other hand, AWS Lambda does not support every Python runtime.
# The supported runtimes are available in the following link:
# https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html
- - python2.7
- python3.6
- python3.7
- python3.8
+ - python3.9
license: MIT
changelog: CHANGELOG.md
changelogPolicy: simple
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/CHANGELOG.md
new/sentry-python-1.5.0/CHANGELOG.md
--- old/sentry-python-1.4.1/CHANGELOG.md 2021-09-22 14:34:25.000000000
+0200
+++ new/sentry-python-1.5.0/CHANGELOG.md 2021-11-16 19:57:37.000000000
+0100
@@ -22,7 +22,25 @@
## Unreleased
-- TBA
+## 1.5.0
+
+- Also record client outcomes for before send #1211
+- Add support for implicitly sized envelope items #1229
+- Fix integration with Apache Beam 2.32, 2.33 #1233
+- Remove Python 2.7 support for AWS Lambda layers in craft config #1241
+- Refactor Sanic integration for v21.9 support #1212
+- AWS Lambda Python 3.9 runtime support #1239
+- Fix "shutdown_timeout" typing #1256
+
+Work in this release contributed by @galuszkak, @kianmeng, @ahopkins,
@razumeiko, @tomscytale, and @seedofjoy. Thank you for your contribution!
+
+## 1.4.3
+
+- Turned client reports on by default.
+
+## 1.4.2
+
+- Made envelope modifications in the HTTP transport non observable #1206
## 1.4.1
@@ -46,7 +64,7 @@
## 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 worker to set daemon 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/docs/conf.py
new/sentry-python-1.5.0/docs/conf.py
--- old/sentry-python-1.4.1/docs/conf.py 2021-09-22 14:34:25.000000000
+0200
+++ new/sentry-python-1.5.0/docs/conf.py 2021-11-16 19:57:37.000000000
+0100
@@ -29,7 +29,7 @@
copyright = u"2019, Sentry Team and Contributors"
author = u"Sentry Team and Contributors"
-release = "1.4.1"
+release = "1.5.0"
version = ".".join(release.split(".")[:2]) # The short X.Y version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/client.py
new/sentry-python-1.5.0/sentry_sdk/client.py
--- old/sentry-python-1.4.1/sentry_sdk/client.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/client.py 2021-11-16
19:57:37.000000000 +0100
@@ -201,6 +201,10 @@
new_event = before_send(event, hint or {})
if new_event is None:
logger.info("before send dropped event (%s)", event)
+ if self.transport:
+ self.transport.record_lost_event(
+ "before_send", data_category="error"
+ )
event = new_event # type: ignore
return event
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/consts.py
new/sentry-python-1.5.0/sentry_sdk/consts.py
--- old/sentry-python-1.4.1/sentry_sdk/consts.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/consts.py 2021-11-16
19:57:37.000000000 +0100
@@ -52,7 +52,7 @@
release=None, # type: Optional[str]
environment=None, # type: Optional[str]
server_name=None, # type: Optional[str]
- shutdown_timeout=2, # type: int
+ shutdown_timeout=2, # type: float
integrations=[], # type: Sequence[Integration] # noqa: B006
in_app_include=[], # type: List[str] # noqa: B006
in_app_exclude=[], # type: List[str] # noqa: B006
@@ -76,7 +76,7 @@
traces_sampler=None, # type: Optional[TracesSampler]
auto_enabling_integrations=True, # type: bool
auto_session_tracking=True, # type: bool
- send_client_reports=False, # type: bool
+ send_client_reports=True, # type: bool
_experiments={}, # type: Experiments # noqa: B006
):
# type: (...) -> None
@@ -101,7 +101,7 @@
del _get_default_options
-VERSION = "1.4.1"
+VERSION = "1.5.0"
SDK_INFO = {
"name": "sentry.python",
"version": VERSION,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/envelope.py
new/sentry-python-1.5.0/sentry_sdk/envelope.py
--- old/sentry-python-1.4.1/sentry_sdk/envelope.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/envelope.py 2021-11-16
19:57:37.000000000 +0100
@@ -295,13 +295,18 @@
if not line:
return None
headers = parse_json(line)
- length = headers["length"]
- payload = f.read(length)
- if headers.get("type") in ("event", "transaction"):
+ length = headers.get("length")
+ if length is not None:
+ payload = f.read(length)
+ f.readline()
+ else:
+ # if no length was specified we need to read up to the end of line
+ # and remove it (if it is present, i.e. not the very last char in
an eof terminated envelope)
+ payload = f.readline().rstrip(b"\n")
+ if headers.get("type") in ("event", "transaction", "metric_buckets"):
rv = cls(headers=headers,
payload=PayloadRef(json=parse_json(payload)))
else:
rv = cls(headers=headers, payload=payload)
- f.readline()
return rv
@classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/sentry-python-1.4.1/sentry_sdk/integrations/aiohttp.py
new/sentry-python-1.5.0/sentry_sdk/integrations/aiohttp.py
--- old/sentry-python-1.4.1/sentry_sdk/integrations/aiohttp.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/integrations/aiohttp.py 2021-11-16
19:57:37.000000000 +0100
@@ -65,9 +65,7 @@
try:
version = tuple(map(int, AIOHTTP_VERSION.split(".")[:2]))
except (TypeError, ValueError):
- raise DidNotEnable(
- "AIOHTTP version unparseable: {}".format(AIOHTTP_VERSION)
- )
+ raise DidNotEnable("AIOHTTP version unparsable:
{}".format(AIOHTTP_VERSION))
if version < (3, 4):
raise DidNotEnable("AIOHTTP 3.4 or newer required.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/sentry-python-1.4.1/sentry_sdk/integrations/aws_lambda.py
new/sentry-python-1.5.0/sentry_sdk/integrations/aws_lambda.py
--- old/sentry-python-1.4.1/sentry_sdk/integrations/aws_lambda.py
2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/integrations/aws_lambda.py
2021-11-16 19:57:37.000000000 +0100
@@ -284,12 +284,14 @@
# Python 3.7: If the bootstrap module is *already imported*, it is the
# one we actually want to use (no idea what's in __main__)
#
- # On Python 3.8 bootstrap is also importable, but will be the same file
+ # Python 3.8: bootstrap is also importable, but will be the same file
# as __main__ imported under a different name:
#
# sys.modules['__main__'].__file__ == sys.modules['bootstrap'].__file__
# sys.modules['__main__'] is not sys.modules['bootstrap']
#
+ # Python 3.9: bootstrap is in __main__.awslambdaricmain
+ #
# On container builds using the
`aws-lambda-python-runtime-interface-client`
# (awslamdaric) module, bootstrap is located in
sys.modules['__main__'].bootstrap
#
@@ -297,10 +299,18 @@
if "bootstrap" in sys.modules:
return sys.modules["bootstrap"]
elif "__main__" in sys.modules:
- if hasattr(sys.modules["__main__"], "bootstrap"):
+ module = sys.modules["__main__"]
+ # python3.9 runtime
+ if hasattr(module, "awslambdaricmain") and hasattr(
+ module.awslambdaricmain, "bootstrap" # type: ignore
+ ):
+ return module.awslambdaricmain.bootstrap # type: ignore
+ elif hasattr(module, "bootstrap"):
# awslambdaric python module in container builds
- return sys.modules["__main__"].bootstrap # type: ignore
- return sys.modules["__main__"]
+ return module.bootstrap # type: ignore
+
+ # python3.8 runtime
+ return module
else:
return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/integrations/beam.py
new/sentry-python-1.5.0/sentry_sdk/integrations/beam.py
--- old/sentry-python-1.4.1/sentry_sdk/integrations/beam.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/integrations/beam.py 2021-11-16
19:57:37.000000000 +0100
@@ -80,7 +80,6 @@
def _wrap_inspect_call(cls, func_name):
# type: (Any, Any) -> Any
- from apache_beam.typehints.decorators import getfullargspec # type: ignore
if not hasattr(cls, func_name):
return None
@@ -105,6 +104,8 @@
return get_function_args_defaults(process_func)
except ImportError:
+ from apache_beam.typehints.decorators import getfullargspec #
type: ignore
+
return getfullargspec(process_func)
setattr(_inspect, USED_FUNC, True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/integrations/sanic.py
new/sentry-python-1.5.0/sentry_sdk/integrations/sanic.py
--- old/sentry-python-1.4.1/sentry_sdk/integrations/sanic.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/integrations/sanic.py 2021-11-16
19:57:37.000000000 +0100
@@ -27,6 +27,7 @@
from sanic.request import Request, RequestParameters
from sentry_sdk._types import Event, EventProcessor, Hint
+ from sanic.router import Route
try:
from sanic import Sanic, __version__ as SANIC_VERSION
@@ -36,19 +37,31 @@
except ImportError:
raise DidNotEnable("Sanic not installed")
+old_error_handler_lookup = ErrorHandler.lookup
+old_handle_request = Sanic.handle_request
+old_router_get = Router.get
+
+try:
+ # This method was introduced in Sanic v21.9
+ old_startup = Sanic._startup
+except AttributeError:
+ pass
+
class SanicIntegration(Integration):
identifier = "sanic"
+ version = (0, 0) # type: Tuple[int, ...]
@staticmethod
def setup_once():
# type: () -> None
+
try:
- version = tuple(map(int, SANIC_VERSION.split(".")))
+ SanicIntegration.version = tuple(map(int,
SANIC_VERSION.split(".")))
except (TypeError, ValueError):
raise DidNotEnable("Unparsable Sanic version:
{}".format(SANIC_VERSION))
- if version < (0, 8):
+ if SanicIntegration.version < (0, 8):
raise DidNotEnable("Sanic 0.8 or newer required.")
if not HAS_REAL_CONTEXTVARS:
@@ -71,89 +84,194 @@
# https://github.com/huge-success/sanic/issues/1332
ignore_logger("root")
- old_handle_request = Sanic.handle_request
+ if SanicIntegration.version < (21, 9):
+ _setup_legacy_sanic()
+ return
- async def sentry_handle_request(self, request, *args, **kwargs):
- # type: (Any, Request, *Any, **Any) -> Any
- hub = Hub.current
- if hub.get_integration(SanicIntegration) is None:
- return old_handle_request(self, request, *args, **kwargs)
-
- weak_request = weakref.ref(request)
-
- with Hub(hub) as hub:
- with hub.configure_scope() as scope:
- scope.clear_breadcrumbs()
-
scope.add_event_processor(_make_request_processor(weak_request))
-
- response = old_handle_request(self, request, *args, **kwargs)
- if isawaitable(response):
- response = await response
-
- return response
-
- Sanic.handle_request = sentry_handle_request
-
- old_router_get = Router.get
-
- 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:
- 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
-
- old_error_handler_lookup = ErrorHandler.lookup
-
- def sentry_error_handler_lookup(self, exception):
- # type: (Any, Exception) -> Optional[object]
- _capture_exception(exception)
- old_error_handler = old_error_handler_lookup(self, exception)
+ _setup_sanic()
- if old_error_handler is None:
- return None
- if Hub.current.get_integration(SanicIntegration) is None:
- return old_error_handler
+class SanicRequestExtractor(RequestExtractor):
+ def content_length(self):
+ # type: () -> int
+ if self.request.body is None:
+ return 0
+ return len(self.request.body)
+
+ def cookies(self):
+ # type: () -> Dict[str, str]
+ return dict(self.request.cookies)
+
+ def raw_data(self):
+ # type: () -> bytes
+ return self.request.body
+
+ def form(self):
+ # type: () -> RequestParameters
+ return self.request.form
+
+ def is_json(self):
+ # type: () -> bool
+ raise NotImplementedError()
+
+ def json(self):
+ # type: () -> Optional[Any]
+ return self.request.json
+
+ def files(self):
+ # type: () -> RequestParameters
+ return self.request.files
+
+ def size_of_file(self, file):
+ # type: (Any) -> int
+ return len(file.body or ())
+
+
+def _setup_sanic():
+ # type: () -> None
+ Sanic._startup = _startup
+ ErrorHandler.lookup = _sentry_error_handler_lookup
+
+
+def _setup_legacy_sanic():
+ # type: () -> None
+ Sanic.handle_request = _legacy_handle_request
+ Router.get = _legacy_router_get
+ ErrorHandler.lookup = _sentry_error_handler_lookup
+
+
+async def _startup(self):
+ # type: (Sanic) -> None
+ # This happens about as early in the lifecycle as possible, just after the
+ # Request object is created. The body has not yet been consumed.
+ self.signal("http.lifecycle.request")(_hub_enter)
+
+ # This happens after the handler is complete. In v21.9 this signal is not
+ # dispatched when there is an exception. Therefore we need to close out
+ # and call _hub_exit from the custom exception handler as well.
+ # See https://github.com/sanic-org/sanic/issues/2297
+ self.signal("http.lifecycle.response")(_hub_exit)
+
+ # This happens inside of request handling immediately after the route
+ # has been identified by the router.
+ self.signal("http.routing.after")(_set_transaction)
+
+ # The above signals need to be declared before this can be called.
+ await old_startup(self)
+
+
+async def _hub_enter(request):
+ # type: (Request) -> None
+ hub = Hub.current
+ request.ctx._sentry_do_integration = (
+ hub.get_integration(SanicIntegration) is not None
+ )
+
+ if not request.ctx._sentry_do_integration:
+ return
+
+ weak_request = weakref.ref(request)
+ request.ctx._sentry_hub = Hub(hub)
+ request.ctx._sentry_hub.__enter__()
+
+ with request.ctx._sentry_hub.configure_scope() as scope:
+ scope.clear_breadcrumbs()
+ scope.add_event_processor(_make_request_processor(weak_request))
+
- async def sentry_wrapped_error_handler(request, exception):
- # type: (Request, Exception) -> Any
- try:
- response = old_error_handler(request, exception)
- if isawaitable(response):
- response = await response
- return response
- except Exception:
- # Report errors that occur in Sanic error handler. These
- # exceptions will not even show up in Sanic's
- # `sanic.exceptions` logger.
- exc_info = sys.exc_info()
- _capture_exception(exc_info)
- reraise(*exc_info)
+async def _hub_exit(request, **_):
+ # type: (Request, **Any) -> None
+ request.ctx._sentry_hub.__exit__(None, None, None)
- return sentry_wrapped_error_handler
- ErrorHandler.lookup = sentry_error_handler_lookup
+async def _set_transaction(request, route, **kwargs):
+ # type: (Request, Route, **Any) -> None
+ hub = Hub.current
+ if hub.get_integration(SanicIntegration) is not None:
+ with capture_internal_exceptions():
+ with hub.configure_scope() as scope:
+ route_name = route.name.replace(request.app.name,
"").strip(".")
+ scope.transaction = route_name
+
+
+def _sentry_error_handler_lookup(self, exception, *args, **kwargs):
+ # type: (Any, Exception, *Any, **Any) -> Optional[object]
+ _capture_exception(exception)
+ old_error_handler = old_error_handler_lookup(self, exception, *args,
**kwargs)
+
+ if old_error_handler is None:
+ return None
+
+ if Hub.current.get_integration(SanicIntegration) is None:
+ return old_error_handler
+
+ async def sentry_wrapped_error_handler(request, exception):
+ # type: (Request, Exception) -> Any
+ try:
+ response = old_error_handler(request, exception)
+ if isawaitable(response):
+ response = await response
+ return response
+ except Exception:
+ # Report errors that occur in Sanic error handler. These
+ # exceptions will not even show up in Sanic's
+ # `sanic.exceptions` logger.
+ exc_info = sys.exc_info()
+ _capture_exception(exc_info)
+ reraise(*exc_info)
+ finally:
+ # As mentioned in previous comment in _startup, this can be removed
+ # after https://github.com/sanic-org/sanic/issues/2297 is resolved
+ if SanicIntegration.version >= (21, 9):
+ await _hub_exit(request)
+
+ return sentry_wrapped_error_handler
+
+
+async def _legacy_handle_request(self, request, *args, **kwargs):
+ # type: (Any, Request, *Any, **Any) -> Any
+ hub = Hub.current
+ if hub.get_integration(SanicIntegration) is None:
+ return old_handle_request(self, request, *args, **kwargs)
+
+ weak_request = weakref.ref(request)
+
+ with Hub(hub) as hub:
+ with hub.configure_scope() as scope:
+ scope.clear_breadcrumbs()
+ scope.add_event_processor(_make_request_processor(weak_request))
+
+ response = old_handle_request(self, request, *args, **kwargs)
+ if isawaitable(response):
+ response = await response
+
+ return response
+
+
+def _legacy_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:
+ if SanicIntegration.version and SanicIntegration.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
def _capture_exception(exception):
@@ -211,39 +329,3 @@
return event
return sanic_processor
-
-
-class SanicRequestExtractor(RequestExtractor):
- def content_length(self):
- # type: () -> int
- if self.request.body is None:
- return 0
- return len(self.request.body)
-
- def cookies(self):
- # type: () -> Dict[str, str]
- return dict(self.request.cookies)
-
- def raw_data(self):
- # type: () -> bytes
- return self.request.body
-
- def form(self):
- # type: () -> RequestParameters
- return self.request.form
-
- def is_json(self):
- # type: () -> bool
- raise NotImplementedError()
-
- def json(self):
- # type: () -> Optional[Any]
- return self.request.json
-
- def files(self):
- # type: () -> RequestParameters
- return self.request.files
-
- def size_of_file(self, file):
- # type: (Any) -> int
- return len(file.body or ())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/tracing.py
new/sentry-python-1.5.0/sentry_sdk/tracing.py
--- old/sentry-python-1.4.1/sentry_sdk/tracing.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/tracing.py 2021-11-16
19:57:37.000000000 +0100
@@ -617,7 +617,7 @@
1. If a sampling decision is passed to `start_transaction`
(`start_transaction(name: "my transaction", sampled: True)`), that
- decision will be used, regardlesss of anything else
+ decision will be used, regardless of anything else
2. If `traces_sampler` is defined, its decision will be used. It can
choose to keep or ignore any parent sampling decision, or use the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/tracing_utils.py
new/sentry-python-1.5.0/sentry_sdk/tracing_utils.py
--- old/sentry-python-1.4.1/sentry_sdk/tracing_utils.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/tracing_utils.py 2021-11-16
19:57:37.000000000 +0100
@@ -65,7 +65,7 @@
# of the form `sentry=xxxx`
SENTRY_TRACESTATE_ENTRY_REGEX = re.compile(
# either sentry is the first entry or there's stuff immediately before it,
- # ending in a commma (this prevents matching something like
`coolsentry=xxx`)
+ # ending in a comma (this prevents matching something like
`coolsentry=xxx`)
"(?:^|.+,)"
# sentry's part, not including the potential comma
"(sentry=[^,]*)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/sentry_sdk/transport.py
new/sentry-python-1.5.0/sentry_sdk/transport.py
--- old/sentry-python-1.4.1/sentry_sdk/transport.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/sentry_sdk/transport.py 2021-11-16
19:57:37.000000000 +0100
@@ -356,7 +356,10 @@
else:
new_items.append(item)
- envelope.items[:] = new_items
+ # Since we're modifying the envelope here make a copy so that others
+ # that hold references do not see their envelope modified.
+ envelope = Envelope(headers=envelope.headers, items=new_items)
+
if not envelope.items:
return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/setup.py
new/sentry-python-1.5.0/setup.py
--- old/sentry-python-1.4.1/setup.py 2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/setup.py 2021-11-16 19:57:37.000000000 +0100
@@ -21,7 +21,7 @@
setup(
name="sentry-sdk",
- version="1.4.1",
+ version="1.5.0",
author="Sentry Team and Contributors",
author_email="[email protected]",
url="https://github.com/getsentry/sentry-python",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/sentry-python-1.4.1/tests/integrations/aws_lambda/test_aws.py
new/sentry-python-1.5.0/tests/integrations/aws_lambda/test_aws.py
--- old/sentry-python-1.4.1/tests/integrations/aws_lambda/test_aws.py
2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/integrations/aws_lambda/test_aws.py
2021-11-16 19:57:37.000000000 +0100
@@ -105,7 +105,9 @@
return get_boto_client()
[email protected](params=["python3.6", "python3.7", "python3.8", "python2.7"])
[email protected](
+ params=["python3.6", "python3.7", "python3.8", "python3.9", "python2.7"]
+)
def lambda_runtime(request):
return request.param
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/sentry-python-1.4.1/tests/integrations/beam/test_beam.py
new/sentry-python-1.5.0/tests/integrations/beam/test_beam.py
--- old/sentry-python-1.4.1/tests/integrations/beam/test_beam.py
2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/integrations/beam/test_beam.py
2021-11-16 19:57:37.000000000 +0100
@@ -152,7 +152,9 @@
class _OutputProcessor(OutputProcessor):
- def process_outputs(self, windowed_input_element, results):
+ def process_outputs(
+ self, windowed_input_element, results, watermark_estimator=None
+ ):
print(windowed_input_element)
try:
for result in results:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/sentry-python-1.4.1/tests/integrations/sanic/test_sanic.py
new/sentry-python-1.5.0/tests/integrations/sanic/test_sanic.py
--- old/sentry-python-1.4.1/tests/integrations/sanic/test_sanic.py
2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/integrations/sanic/test_sanic.py
2021-11-16 19:57:37.000000000 +0100
@@ -173,11 +173,6 @@
kwargs["app"] = app
if SANIC_VERSION >= (21, 3):
- try:
- app.router.reset()
- app.router.finalize()
- except AttributeError:
- ...
class MockAsyncStreamer:
def __init__(self, request_body):
@@ -203,6 +198,13 @@
patched_request = request.Request(**kwargs)
patched_request.stream = MockAsyncStreamer([b"hello", b"foo"])
+ if SANIC_VERSION >= (21, 9):
+ await app.dispatch(
+ "http.lifecycle.request",
+ context={"request": patched_request},
+ inline=True,
+ )
+
await app.handle_request(
patched_request,
)
@@ -217,6 +219,15 @@
assert r.status == 200
async def runner():
+ if SANIC_VERSION >= (21, 3):
+ if SANIC_VERSION >= (21, 9):
+ await app._startup()
+ else:
+ try:
+ app.router.reset()
+ app.router.finalize()
+ except AttributeError:
+ ...
await asyncio.gather(*(task(i) for i in range(1000)))
if sys.version_info < (3, 7):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/tests/test_basics.py
new/sentry-python-1.5.0/tests/test_basics.py
--- old/sentry-python-1.4.1/tests/test_basics.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/test_basics.py 2021-11-16
19:57:37.000000000 +0100
@@ -77,9 +77,13 @@
assert Hub.current.last_event_id() == event_id
-def test_option_callback(sentry_init, capture_events):
+def test_option_callback(sentry_init, capture_events, monkeypatch):
drop_events = False
drop_breadcrumbs = False
+ reports = []
+
+ def record_lost_event(reason, data_category=None, item=None):
+ reports.append((reason, data_category))
def before_send(event, hint):
assert isinstance(hint["exc_info"][1], ValueError)
@@ -96,6 +100,10 @@
sentry_init(before_send=before_send, before_breadcrumb=before_breadcrumb)
events = capture_events()
+ monkeypatch.setattr(
+ Hub.current.client.transport, "record_lost_event", record_lost_event
+ )
+
def do_this():
add_breadcrumb(message="Hello", hint={"foo": 42})
try:
@@ -106,8 +114,10 @@
do_this()
drop_breadcrumbs = True
do_this()
+ assert not reports
drop_events = True
do_this()
+ assert reports == [("before_send", "error")]
normal, no_crumbs = events
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/tests/test_envelope.py
new/sentry-python-1.5.0/tests/test_envelope.py
--- old/sentry-python-1.4.1/tests/test_envelope.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/test_envelope.py 2021-11-16
19:57:37.000000000 +0100
@@ -132,3 +132,135 @@
"event_id": "15210411201320122115110420122013",
"sent_at": "2012-11-21T12:31:12.415908Z",
}
+
+
+def test_envelope_with_sized_items():
+ """
+ Tests that it successfully parses envelopes with
+ the item size specified in the header
+ """
+ envelope_raw = (
+ b'{"event_id":"9ec79c33ec9942ab8353589fcb2e04dc"}\n'
+ + b'{"type":"type1","length":4 }\n1234\n'
+ + b'{"type":"type2","length":4 }\nabcd\n'
+ + b'{"type":"type3","length":0}\n\n'
+ + b'{"type":"type4","length":4 }\nab12\n'
+ )
+ envelope_raw_eof_terminated = envelope_raw[:-1]
+
+ for envelope_raw in (envelope_raw, envelope_raw_eof_terminated):
+ actual = Envelope.deserialize(envelope_raw)
+
+ items = [item for item in actual]
+
+ assert len(items) == 4
+
+ assert items[0].type == "type1"
+ assert items[0].get_bytes() == b"1234"
+
+ assert items[1].type == "type2"
+ assert items[1].get_bytes() == b"abcd"
+
+ assert items[2].type == "type3"
+ assert items[2].get_bytes() == b""
+
+ assert items[3].type == "type4"
+ assert items[3].get_bytes() == b"ab12"
+
+ assert actual.headers["event_id"] == "9ec79c33ec9942ab8353589fcb2e04dc"
+
+
+def test_envelope_with_implicitly_sized_items():
+ """
+ Tests that it successfully parses envelopes with
+ the item size not specified in the header
+ """
+ envelope_raw = (
+ b'{"event_id":"9ec79c33ec9942ab8353589fcb2e04dc"}\n'
+ + b'{"type":"type1"}\n1234\n'
+ + b'{"type":"type2"}\nabcd\n'
+ + b'{"type":"type3"}\n\n'
+ + b'{"type":"type4"}\nab12\n'
+ )
+ envelope_raw_eof_terminated = envelope_raw[:-1]
+
+ for envelope_raw in (envelope_raw, envelope_raw_eof_terminated):
+ actual = Envelope.deserialize(envelope_raw)
+ assert actual.headers["event_id"] == "9ec79c33ec9942ab8353589fcb2e04dc"
+
+ items = [item for item in actual]
+
+ assert len(items) == 4
+
+ assert items[0].type == "type1"
+ assert items[0].get_bytes() == b"1234"
+
+ assert items[1].type == "type2"
+ assert items[1].get_bytes() == b"abcd"
+
+ assert items[2].type == "type3"
+ assert items[2].get_bytes() == b""
+
+ assert items[3].type == "type4"
+ assert items[3].get_bytes() == b"ab12"
+
+
+def test_envelope_with_two_attachments():
+ """
+ Test that items are correctly parsed in an envelope with to size specified
items
+ """
+ two_attachments = (
+
b'{"event_id":"9ec79c33ec9942ab8353589fcb2e04dc","dsn":"https://e12d836b15bb49d7bbf99e64295d995b:@sentry.io/42"}\n'
+ +
b'{"type":"attachment","length":10,"content_type":"text/plain","filename":"hello.txt"}\n'
+ + b"\xef\xbb\xbfHello\r\n\n"
+ +
b'{"type":"event","length":41,"content_type":"application/json","filename":"application.log"}\n'
+ + b'{"message":"hello world","level":"error"}\n'
+ )
+ two_attachments_eof_terminated = two_attachments[
+ :-1
+ ] # last \n is optional, without it should still be a valid envelope
+
+ for envelope_raw in (two_attachments, two_attachments_eof_terminated):
+ actual = Envelope.deserialize(envelope_raw)
+ items = [item for item in actual]
+
+ assert len(items) == 2
+ assert items[0].get_bytes() == b"\xef\xbb\xbfHello\r\n"
+ assert items[1].payload.json == {"message": "hello world", "level":
"error"}
+
+
+def test_envelope_with_empty_attachments():
+ """
+ Test that items are correctly parsed in an envelope with two 0 length
items (with size specified in the header
+ """
+ two_empty_attachments = (
+ b'{"event_id":"9ec79c33ec9942ab8353589fcb2e04dc"}\n'
+ + b'{"type":"attachment","length":0}\n\n'
+ + b'{"type":"attachment","length":0}\n\n'
+ )
+
+ two_empty_attachments_eof_terminated = two_empty_attachments[
+ :-1
+ ] # last \n is optional, without it should still be a valid envelope
+
+ for envelope_raw in (two_empty_attachments,
two_empty_attachments_eof_terminated):
+ actual = Envelope.deserialize(envelope_raw)
+ items = [item for item in actual]
+
+ assert len(items) == 2
+ assert items[0].get_bytes() == b""
+ assert items[1].get_bytes() == b""
+
+
+def test_envelope_without_headers():
+ """
+ Test that an envelope without headers is parsed successfully
+ """
+ envelope_without_headers = (
+ b"{}\n" + b'{"type":"session"}\n' + b'{"started":
"2020-02-07T14:16:00Z"}'
+ )
+ actual = Envelope.deserialize(envelope_without_headers)
+ items = [item for item in actual]
+
+ assert len(items) == 1
+ assert items[0].payload.get_bytes() == b'{"started":
"2020-02-07T14:16:00Z"}'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/tests/test_transport.py
new/sentry-python-1.5.0/tests/test_transport.py
--- old/sentry-python-1.4.1/tests/test_transport.py 2021-09-22
14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tests/test_transport.py 2021-11-16
19:57:37.000000000 +0100
@@ -279,7 +279,7 @@
client.flush()
# this goes out with an extra envelope because it's flushed after the last
item
- # that is normally in the queue. This is quite funny in a way beacuse it
means
+ # that is normally in the queue. This is quite funny in a way because it
means
# that the envelope that caused its own over quota report (an error with an
# attachment) will include its outcome since it's pending.
assert len(capturing_server.captured) == 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/sentry-python-1.4.1/tox.ini
new/sentry-python-1.5.0/tox.ini
--- old/sentry-python-1.4.1/tox.ini 2021-09-22 14:34:25.000000000 +0200
+++ new/sentry-python-1.5.0/tox.ini 2021-11-16 19:57:37.000000000 +0100
@@ -46,7 +46,7 @@
{pypy,py2.7,py3.5,py3.6,py3.7,py3.8}-celery-{4.3,4.4}
{py3.6,py3.7,py3.8}-celery-5.0
- py3.7-beam-{2.12,2.13}
+ py3.7-beam-{2.12,2.13,2.32,2.33}
# The aws_lambda tests deploy to the real AWS and have their own matrix of
Python versions.
py3.7-aws_lambda
@@ -140,6 +140,8 @@
beam-2.12: apache-beam>=2.12.0, <2.13.0
beam-2.13: apache-beam>=2.13.0, <2.14.0
+ beam-2.32: apache-beam>=2.32.0, <2.33.0
+ beam-2.33: apache-beam>=2.33.0, <2.34.0
beam-master:
git+https://github.com/apache/beam#egg=apache-beam&subdirectory=sdks/python
celery: redis
@@ -300,6 +302,9 @@
{py3.5,py3.6,py3.7,py3.8,py3.9}-flask-{0.10,0.11,0.12}: pip install
pytest<5
{py3.6,py3.7,py3.8,py3.9}-flask-{0.11}: pip install Werkzeug<2
+ ; https://github.com/more-itertools/more-itertools/issues/578
+ py3.5-flask-{0.10,0.11,0.12}: pip install more-itertools<8.11.0
+
py.test {env:TESTPATH} {posargs}
[testenv:linters]