Skip to content

Commit 95bc31a

Browse files
bdeeneyTimPansino
andauthored
Fix handling of cherrypy HTTPRedirects (#324)
* Fix handling of cherrypy HTTPRedirects * Format and linting * Add more linting ignored rules * Further linter tuning Co-authored-by: Tim Pansino <[email protected]>
1 parent 86c7837 commit 95bc31a

File tree

4 files changed

+43
-30
lines changed

4 files changed

+43
-30
lines changed

.mega-linter.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ ENABLE_LINTERS: # If you use ENABLE_LINTERS variable, all other linters will be
2121
- YAML_PRETTIER
2222
- YAML_V8R
2323
- YAML_YAMLLINT
24+
25+
PYTHON_FLAKE8_CONFIG_FILE: setup.cfg
26+
PYTHON_BLACK_CONFIG_FILE: pyproject.toml
27+
PYTHON_PYLINT_CONFIG_FILE: pyproject.toml
28+
PYTHON_ISORT_CONFIG_FILE: pyproject.toml
29+
30+
PYTHON_PYLINT_ARGUMENTS: "--fail-under=0 --fail-on=E"
31+
2432
# IGNORE_GITIGNORED_FILES: true # Currently broken
2533
EXCLUDED_DIRECTORIES:
2634
- "__pycache__"

newrelic/hooks/framework_cherrypy.py

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,23 @@
3737
# * We don't handle any sub dispatching that may be occurring due to the
3838
# use of XMLRPCDispatcher.
3939

40+
from newrelic.api.error_trace import wrap_error_trace
4041
from newrelic.api.function_trace import FunctionTrace, wrap_function_trace
41-
from newrelic.api.transaction import current_transaction
4242
from newrelic.api.time_trace import notice_error
43+
from newrelic.api.transaction import current_transaction
4344
from newrelic.api.wsgi_application import wrap_wsgi_application
4445
from newrelic.common.object_names import callable_name
45-
from newrelic.common.object_wrapper import (ObjectProxy, function_wrapper,
46-
wrap_function_wrapper)
47-
from newrelic.api.error_trace import wrap_error_trace
46+
from newrelic.common.object_wrapper import (
47+
ObjectProxy,
48+
function_wrapper,
49+
wrap_function_wrapper,
50+
)
4851

4952

5053
def framework_details():
5154
import cherrypy
52-
return ('CherryPy', getattr(cherrypy, '__version__', None))
55+
56+
return ("CherryPy", getattr(cherrypy, "__version__", None))
5357

5458

5559
def status_code(exc, value, tb):
@@ -62,9 +66,11 @@ def status_code(exc, value, tb):
6266
# In the case of an HTTPError that is malformed (e.g.
6367
# HTTPError("10 Bad error")), value will not have a code attr.
6468
# In both of those cases, we fall back to value.status
65-
code = getattr(value, 'code', value.status)
69+
code = getattr(value, "code", value.status)
6670
return code
6771

72+
return None
73+
6874

6975
@function_wrapper
7076
def handler_wrapper(wrapped, instance, args, kwargs):
@@ -84,14 +90,13 @@ def handler_wrapper(wrapped, instance, args, kwargs):
8490

8591

8692
class ResourceProxy(ObjectProxy):
87-
8893
def __getattr__(self, name):
8994
# Methods on the wrapped object corresponding to the HTTP
9095
# method will always be upper case. Wrap the method when
9196
# returned with the handler wrapper.
9297

9398
attr = super(ResourceProxy, self).__getattr__(name)
94-
return name.isupper() and handler_wrapper(attr) or attr
99+
return handler_wrapper(attr) if name.isupper() else attr
95100

96101

97102
def wrapper_Dispatcher_find_handler(wrapped, instance, args, kwargs):
@@ -108,19 +113,19 @@ def wrapper_Dispatcher_find_handler(wrapped, instance, args, kwargs):
108113
except: # Catch all
109114
# Can end up here when a custom _cp_dispatch() method is
110115
# used and that raises an exception.
111-
notice_error()
116+
notice_error(status_code=status_code)
112117
raise
113118

114119
if obj:
115-
if instance.__class__.__name__ == 'MethodDispatcher':
120+
if instance.__class__.__name__ == "MethodDispatcher":
116121
# We initially name the web transaction as if the
117122
# corresponding method for the HTTP method will not
118123
# be found and the request will not be allowed. This
119124
# will be overridden with the actual handler name
120125
# when the subsequent wrapper around the handler is
121126
# executed.
122127

123-
transaction.set_transaction_name('405', group='StatusCode')
128+
transaction.set_transaction_name("405", group="StatusCode")
124129

125130
# We have to use a custom object proxy here in order
126131
# to intercept accesses made by the dispatcher on the
@@ -141,7 +146,7 @@ def wrapper_Dispatcher_find_handler(wrapped, instance, args, kwargs):
141146
# No handler could be found so name the web transaction
142147
# after the 404 status code.
143148

144-
transaction.set_transaction_name('404', group='StatusCode')
149+
transaction.set_transaction_name("404", group="StatusCode")
145150

146151
return obj, vpath
147152

@@ -159,7 +164,7 @@ def wrapper_RoutesDispatcher_find_handler(wrapped, instance, args, kwargs):
159164

160165
except: # Catch all
161166
# Can end up here when the URL was invalid in some way.
162-
notice_error()
167+
notice_error(status_code=status_code)
163168
raise
164169

165170
if handler:
@@ -172,34 +177,31 @@ def wrapper_RoutesDispatcher_find_handler(wrapped, instance, args, kwargs):
172177
# No handler could be found so name the web transaction
173178
# after the 404 status code.
174179

175-
transaction.set_transaction_name('404', group='StatusCode')
180+
transaction.set_transaction_name("404", group="StatusCode")
176181

177182
return handler
178183

179184

180185
def instrument_cherrypy__cpreqbody(module):
181-
wrap_function_trace(module, 'process_multipart')
182-
wrap_function_trace(module, 'process_multipart_form_data')
186+
wrap_function_trace(module, "process_multipart")
187+
wrap_function_trace(module, "process_multipart_form_data")
183188

184189

185190
def instrument_cherrypy__cprequest(module):
186-
wrap_function_trace(module, 'Request.handle_error')
191+
wrap_function_trace(module, "Request.handle_error")
187192

188193

189194
def instrument_cherrypy__cpdispatch(module):
190-
wrap_function_wrapper(module, 'Dispatcher.find_handler',
191-
wrapper_Dispatcher_find_handler)
192-
wrap_function_wrapper(module, 'RoutesDispatcher.find_handler',
193-
wrapper_RoutesDispatcher_find_handler)
194-
wrap_error_trace(module, 'PageHandler.__call__',
195-
ignore=['cherrypy._cperror:InternalRedirect'], status_code=status_code)
195+
wrap_function_wrapper(module, "Dispatcher.find_handler", wrapper_Dispatcher_find_handler)
196+
wrap_function_wrapper(module, "RoutesDispatcher.find_handler", wrapper_RoutesDispatcher_find_handler)
197+
wrap_error_trace(
198+
module, "PageHandler.__call__", ignore=["cherrypy._cperror:InternalRedirect"], status_code=status_code
199+
)
196200

197201

198202
def instrument_cherrypy__cpwsgi(module):
199-
wrap_wsgi_application(module, 'CPWSGIApp.__call__',
200-
framework=framework_details())
203+
wrap_wsgi_application(module, "CPWSGIApp.__call__", framework=framework_details())
201204

202205

203206
def instrument_cherrypy__cptree(module):
204-
wrap_wsgi_application(module, 'Application.__call__',
205-
framework=framework_details())
207+
wrap_wsgi_application(module, "Application.__call__", framework=framework_details())

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ include = '\.pyi?$'
66
profile = "black"
77

88
[tool.pylint.messages_control]
9-
disable = "C0330, C0326"
9+
disable = "C0103,C0115,C0116,C0415,E0401,E1120,E122,E126,E127,E128,E203,E501,E722,R1725,W0613,W0613,W504"
1010

1111
[tool.pylint.format]
12-
max-line-length = "88"
12+
max-line-length = "120"
13+
14+
[tool.pylint.basic]
15+
good-names = "exc,val,tb"

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ license_files =
55

66
[flake8]
77
max-line-length = 120
8-
extend-ignore = E203,E501
8+
extend-ignore = C0103,C0115,C0116,C0415,E0401,E1120,E122,E126,E127,E128,E203,E501,E722,R1725,W0613,W0613,W504

0 commit comments

Comments
 (0)