Skip to content

Commit 10f7e8d

Browse files
committed
Release v4.7.1
2 parents 2d4e88e + 8ad3c40 commit 10f7e8d

File tree

20 files changed

+332
-250
lines changed

20 files changed

+332
-250
lines changed

.github/workflows/license-audit.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ on: [push, pull_request]
44

55
jobs:
66
license-audit:
7-
# TODO: a GH action update broke the 'ubuntu-latest' image
8-
# when it's fixed, we should switch back
9-
runs-on: ubuntu-20.04
7+
runs-on: 'ubuntu-latest'
108

119
steps:
1210
- uses: actions/checkout@v2
1311

1412
- name: Set up Python
1513
uses: actions/setup-python@v2
1614
with:
17-
# License Finder's Docker image uses Python 3.5
18-
python-version: 3.5
15+
# License Finder's Docker image uses Python 3.10
16+
python-version: '3.10'
1917

2018
- name: Fetch decisions.yml
2119
run: curl https://raw.githubusercontent.com/bugsnag/license-audit/master/config/decision_files/global.yml -o decisions.yml
@@ -32,6 +30,10 @@ jobs:
3230
run: >
3331
docker run -v $PWD:/scan licensefinder/license_finder /bin/bash -lc "
3432
cd /scan &&
35-
pip3 install -r requirements.txt --quiet &&
33+
apt-get update &&
34+
apt-get install -y python3-venv &&
35+
python3 -m venv .venv &&
36+
source .venv/bin/activate &&
37+
pip3 install -r requirements.txt &&
3638
license_finder --decisions-file decisions.yml --python-version 3 --enabled-package-managers=pip
3739
"

.github/workflows/python-package.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ jobs:
1414
include:
1515
- python-version: '3.5'
1616
os: 'ubuntu-20.04'
17+
pip-trusted-host: 'pypi.python.org pypi.org files.pythonhosted.org'
1718
- python-version: '3.6'
1819
os: 'ubuntu-20.04'
1920

2021
steps:
21-
- uses: actions/checkout@v3
22+
- uses: actions/checkout@v4
2223

2324
- name: Set up Python ${{ matrix.python-version }}
24-
uses: actions/setup-python@v4
25+
uses: actions/setup-python@v5
2526
with:
2627
python-version: ${{ matrix.python-version }}
28+
env:
29+
PIP_TRUSTED_HOST: ${{ matrix.pip-trusted-host }}
2730

2831
- name: Install dependencies
2932
run: |

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
=========
33

4+
## v4.7.1 (2024-05-22)
5+
6+
### Bug fixes
7+
8+
* Avoid reading `__code__` when setting a custom delivery unless it exists
9+
[#387](https://github.com/bugsnag/bugsnag-python/pull/387)
10+
411
## v4.7.0 (2024-04-24)
512

613
### Enhancements

bugsnag/configuration.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,11 @@ def delivery(self, value):
279279
# this should be made mandatory in the next major release
280280
if (
281281
hasattr(value, 'deliver_sessions') and
282-
callable(value.deliver_sessions)
282+
callable(value.deliver_sessions) and
283+
# Mock objects don't allow accessing or mocking '__code__' so
284+
# ensure it exists before attempting to read it
285+
# __code__ should always be present in a real delivery object
286+
hasattr(value.deliver_sessions, '__code__')
283287
):
284288
parameter_names = value.deliver_sessions.__code__.co_varnames
285289

bugsnag/delivery.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ def deliver_sessions(self, config, payload: Any, options=None):
9393
options = {}
9494

9595
options['endpoint'] = config.session_endpoint
96-
options['success'] = 202
9796

9897
self.deliver(config, payload, options)
9998

@@ -151,10 +150,14 @@ def request():
151150
status = resp.getcode()
152151

153152
if 'success' in options:
154-
success = options['success']
153+
# if an expected status code has been given then it must match
154+
# exactly with the actual status code
155+
success = status == options['success']
155156
else:
156-
success = 200
157-
if status != success:
157+
# warn if we don't get a 2xx status code by default
158+
success = status >= 200 and status < 300
159+
160+
if not success:
158161
config.logger.warning(
159162
'Delivery to %s failed, status %d' % (uri, status)
160163
)
@@ -184,12 +187,16 @@ def request():
184187

185188
response = requests.post(uri, **req_options)
186189
status = response.status_code
190+
187191
if 'success' in options:
188-
success = options['success']
192+
# if an expected status code has been given then it must match
193+
# exactly with the actual status code
194+
success = status == options['success']
189195
else:
190-
success = requests.codes.ok
196+
# warn if we don't get a 2xx status code by default
197+
success = status >= 200 and status < 300
191198

192-
if status != success:
199+
if not success:
193200
config.logger.warning(
194201
'Delivery to %s failed, status %d' % (uri, status)
195202
)

bugsnag/notifier.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
_NOTIFIER_INFORMATION = {
22
'name': 'Python Bugsnag Notifier',
33
'url': 'https://github.com/bugsnag/bugsnag-python',
4-
'version': '4.7.0'
4+
'version': '4.7.1'
55
}

bugsnag/sessiontracker.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ def __deliver(self, sessions: List[Dict], asynchronous=True):
139139

140140
deliver = self.config.delivery.deliver_sessions
141141

142-
if 'options' in deliver.__code__.co_varnames:
142+
if (
143+
hasattr(deliver, '__code__') and
144+
'options' in deliver.__code__.co_varnames
145+
):
143146
try:
144147
post_delivery_callback = self._request_tracker.new_request()
145148

features/celery.feature

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
Feature: Celery
2+
3+
Scenario Outline: Handled exceptions are delivered in Celery <celery-version>
4+
Given I start the service "celery-<celery-version>"
5+
When I execute the command "python bugsnag_celery_test_app/queue_task.py handled" in the service "celery-<celery-version>"
6+
And I wait to receive an error
7+
Then the error is valid for the error reporting API version "4.0" for the "Python Bugsnag Notifier" notifier
8+
And the exception "errorClass" equals "Exception"
9+
And the exception "message" equals "oooh nooo"
10+
And the event "unhandled" is false
11+
And the event "severity" equals "warning"
12+
And the event "severityReason.type" equals "handledException"
13+
And the event "device.runtimeVersions.celery" matches "<celery-version>\.\d+\.\d+"
14+
15+
@not-python-3.11 @not-python-3.12
16+
Examples:
17+
| celery-version |
18+
| 4 |
19+
20+
@not-python-3.5
21+
Examples:
22+
| celery-version |
23+
| 5 |
24+
25+
Scenario Outline: Unhandled exceptions are delivered in Celery <celery-version>
26+
Given I start the service "celery-<celery-version>"
27+
When I execute the command "python bugsnag_celery_test_app/queue_task.py unhandled" in the service "celery-<celery-version>"
28+
And I wait to receive an error
29+
Then the error is valid for the error reporting API version "4.0" for the "Python Bugsnag Notifier" notifier
30+
And the exception "errorClass" equals "KeyError"
31+
And the exception "message" equals "'b'"
32+
And the event "unhandled" is true
33+
And the event "severity" equals "error"
34+
And the event "severityReason.type" equals "unhandledExceptionMiddleware"
35+
And the event "severityReason.attributes.framework" equals "Celery"
36+
And the event "device.runtimeVersions.celery" matches "<celery-version>\.\d+\.\d+"
37+
And the event "context" equals "bugsnag_celery_test_app.tasks.unhandled"
38+
And the event "metaData.extra_data.task_id" is not null
39+
# these aren't strings but the maze runner step works on arrays and hashes
40+
And the event "metaData.extra_data.args" string is empty
41+
And the event "metaData.extra_data.kwargs" string is empty
42+
43+
@not-python-3.11 @not-python-3.12
44+
Examples:
45+
| celery-version |
46+
| 4 |
47+
48+
@not-python-3.5
49+
Examples:
50+
| celery-version |
51+
| 5 |
52+
53+
Scenario Outline: Task arguments are added to metadata in Celery <celery-version>
54+
Given I start the service "celery-<celery-version>"
55+
When I execute the command "python bugsnag_celery_test_app/queue_task.py add 1 2 3 '4' a=100 b=200" in the service "celery-<celery-version>"
56+
And I wait to receive an error
57+
Then the error is valid for the error reporting API version "4.0" for the "Python Bugsnag Notifier" notifier
58+
And the exception "errorClass" equals "AssertionError"
59+
And the exception "message" equals ""
60+
And the event "unhandled" is true
61+
And the event "severity" equals "error"
62+
And the event "severityReason.type" equals "unhandledExceptionMiddleware"
63+
And the event "severityReason.attributes.framework" equals "Celery"
64+
And the event "device.runtimeVersions.celery" matches "<celery-version>\.\d+\.\d+"
65+
And the event "context" equals "bugsnag_celery_test_app.tasks.add"
66+
And the event "metaData.extra_data.task_id" is not null
67+
And the error payload field "events.0.metaData.extra_data.args" is an array with 4 elements
68+
And the event "metaData.extra_data.args.0" equals "1"
69+
And the event "metaData.extra_data.args.1" equals "2"
70+
And the event "metaData.extra_data.args.2" equals "3"
71+
And the event "metaData.extra_data.args.3" equals "4"
72+
And the event "metaData.extra_data.kwargs.a" equals "100"
73+
And the event "metaData.extra_data.kwargs.b" equals "200"
74+
75+
@not-python-3.11 @not-python-3.12
76+
Examples:
77+
| celery-version |
78+
| 4 |
79+
80+
@not-python-3.5
81+
Examples:
82+
| celery-version |
83+
| 5 |
84+
85+
Scenario Outline: Errors in shared tasks are reported in Celery <celery-version>
86+
Given I start the service "celery-<celery-version>"
87+
When I execute the command "python bugsnag_celery_test_app/queue_task.py divide 10 0" in the service "celery-<celery-version>"
88+
And I wait to receive an error
89+
Then the error is valid for the error reporting API version "4.0" for the "Python Bugsnag Notifier" notifier
90+
And the exception "errorClass" equals "ZeroDivisionError"
91+
And the exception "message" equals "division by zero"
92+
And the event "unhandled" is true
93+
And the event "severity" equals "error"
94+
And the event "severityReason.type" equals "unhandledExceptionMiddleware"
95+
And the event "severityReason.attributes.framework" equals "Celery"
96+
And the event "device.runtimeVersions.celery" matches "<celery-version>\.\d+\.\d+"
97+
And the event "context" equals "bugsnag_celery_test_app.tasks.divide"
98+
And the event "metaData.extra_data.task_id" is not null
99+
And the error payload field "events.0.metaData.extra_data.args" is an array with 2 elements
100+
And the event "metaData.extra_data.args.0" equals "10"
101+
And the event "metaData.extra_data.args.1" equals "0"
102+
And the event "metaData.extra_data.kwargs" string is empty
103+
104+
@not-python-3.11 @not-python-3.12
105+
Examples:
106+
| celery-version |
107+
| 4 |
108+
109+
@not-python-3.5
110+
Examples:
111+
| celery-version |
112+
| 5 |
113+
114+
Scenario Outline: Successful tasks do not report errors in Celery <celery-version>
115+
Given I start the service "celery-<celery-version>"
116+
When I execute the command "python bugsnag_celery_test_app/queue_task.py add 1 2 3 4 5 6 7 a=8 b=9" in the service "celery-<celery-version>"
117+
Then I should receive no errors
118+
119+
@not-python-3.11 @not-python-3.12
120+
Examples:
121+
| celery-version |
122+
| 4 |
123+
124+
@not-python-3.5
125+
Examples:
126+
| celery-version |
127+
| 5 |
128+
129+
Scenario Outline: Successful shared tasks do not report errors in Celery <celery-version>
130+
Given I start the service "celery-<celery-version>"
131+
When I execute the command "python bugsnag_celery_test_app/queue_task.py divide 10 2" in the service "celery-<celery-version>"
132+
Then I should receive no errors
133+
134+
@not-python-3.11 @not-python-3.12
135+
Examples:
136+
| celery-version |
137+
| 4 |
138+
139+
@not-python-3.5
140+
Examples:
141+
| celery-version |
142+
| 5 |

features/fixtures/celery/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ARG PYTHON_TEST_VERSION
2+
FROM python:$PYTHON_TEST_VERSION
3+
4+
COPY app/ /usr/src/app
5+
COPY temp-bugsnag-python/ /usr/src/bugsnag
6+
7+
WORKDIR /usr/src/app
8+
9+
ARG CELERY_TEST_VERSION
10+
RUN CELERY_TEST_VERSION=$CELERY_TEST_VERSION pip install --no-cache-dir -r requirements.txt
11+
12+
CMD celery --app bugsnag_celery_test_app.main worker -l INFO

features/fixtures/celery/app/bugsnag_celery_test_app/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)