Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruff Linting (Bugbear & Bandit) #1319

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fdcbc77
Fixes for flake8-bandit
TimPansino Mar 3, 2025
8bac419
Remove unnecessary nosec comments
TimPansino Mar 3, 2025
d98e5d0
Enable flake8-bugbear
TimPansino Mar 3, 2025
fb29439
Fix B009 get-attr-with-constant
TimPansino Mar 3, 2025
61ec1c4
Fix B015 useless-comparison
TimPansino Mar 3, 2025
2b96107
Fix B011 assert-false
TimPansino Mar 3, 2025
396ad40
Fix B018 useless-expression
TimPansino Mar 3, 2025
0a1c07b
Fix B028 no-explicit-stacklevel
TimPansino Mar 3, 2025
e1ec4de
Fix B010 set-attr-with-constant
TimPansino Mar 3, 2025
53916ea
Fix B006 mutable-argument-default
TimPansino Mar 3, 2025
aff246e
Fix B904 raise-without-from-inside-except
TimPansino Mar 3, 2025
9f41375
Fix B004 unreliable-callable-check
TimPansino Mar 3, 2025
fe8539c
Fix B023 function-uses-loop-variable
TimPansino Mar 3, 2025
3ae2e75
Fix B012 jump-statement-in-finally
TimPansino Mar 3, 2025
0ba8916
Fix B026 star-arg-unpacking-after-keyword-arg
TimPansino Mar 3, 2025
af9e742
Fix B003 assignment-to-os-environ
TimPansino Mar 3, 2025
3f8c465
Fix B007 unused-loop-control-variable
TimPansino Mar 3, 2025
978f7fc
Fix B007 unused-loop-control-variable
TimPansino Mar 4, 2025
7ef8278
Fix PERF401 manual-list-comprehension
TimPansino Mar 4, 2025
0968284
Enable megalinter status reporting
TimPansino Mar 4, 2025
b31af89
Fix ruff exclusions without losing file count
TimPansino Mar 4, 2025
aeeba0c
Ruff Format
TimPansino Mar 4, 2025
984da7d
Sort imports
TimPansino Mar 14, 2025
729f738
Fix G002 logging-percent-format
TimPansino Mar 14, 2025
ae84064
Fix A001 builtin-variable-shadowing
TimPansino Mar 14, 2025
337f775
Consolidate and fix Environ fixtures
TimPansino Mar 14, 2025
a1c3402
Fix broken span intrinsic assertion
TimPansino Mar 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/get-envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def main(f):
filtered_envs = environments[GROUP_NUMBER::TOTAL_GROUPS]
joined_envs = ",".join(filtered_envs)

assert joined_envs, (
assert joined_envs, ( # noqa: S101
f"No environments found.\nenvironments = {str(environments)}\nGROUP_NUMBER = {GROUP_NUMBER + 1}\nTOTAL_GROUPS = {TOTAL_GROUPS}"
)
print(joined_envs)
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
contents: write
issues: write
pull-requests: write
statuses: write
steps:
# Git Checkout
- name: Checkout Code
Expand All @@ -47,6 +48,8 @@ jobs:
VALIDATE_ALL_CODEBASE: "true"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY
GITHUB_STATUS_REPORTER: "true"
GITHUB_COMMENT_REPORTER: "true"
PYTHON_RUFF_ARGUMENTS: --config pyproject.toml --config 'output-format="github"'
PYTHON_RUFF_FORMAT_ARGUMENTS: --config pyproject.toml --config 'output-format="github"'

Expand Down
2 changes: 0 additions & 2 deletions .mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@ ENABLE_LINTERS: # If you use ENABLE_LINTERS variable, all other linters will be
- YAML_YAMLLINT

PYTHON_RUFF_CONFIG_FILE: pyproject.toml
PYTHON_RUFF_CLI_LINT_MODE: project
PYTHON_RUFF_FORMAT_CONFIG_FILE: pyproject.toml
PYTHON_RUFF_FORMAT_CLI_LINT_MODE: project
2 changes: 1 addition & 1 deletion newrelic/admin/run_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@ def log_message(text, *args):
log_message("program_exe_path = %r", program_exe_path)
log_message("execl_arguments = %r", [program_exe_path] + args)

os.execl(program_exe_path, *args)
os.execl(program_exe_path, *args) # noqa: S606
2 changes: 1 addition & 1 deletion newrelic/admin/run_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,4 @@ def log_message(text, *args):
log_message("python_exe_path = %r", python_exe_path)
log_message("execl_arguments = %r", [python_exe_path, python_exe_path] + args)

os.execl(python_exe_path, python_exe_path, *args)
os.execl(python_exe_path, python_exe_path, *args) # noqa: S606
8 changes: 4 additions & 4 deletions newrelic/admin/validate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _function1():

@function_trace()
def _function2():
for i in range(10):
for _ in range(10):
_function1()

@error_trace()
Expand Down Expand Up @@ -68,7 +68,7 @@ def _wsgi_application(environ, start_response):
response_headers = [("Content-type", "text/plain"), ("Content-Length", str(len(output)))]
start_response(status, response_headers)

for i in range(10):
for _ in range(10):
_function1()

_function2()
Expand All @@ -84,7 +84,7 @@ def _wsgi_application(environ, start_response):

@background_task()
def _background_task():
for i in range(10):
for _ in range(10):
_function1()

_function2()
Expand Down Expand Up @@ -154,7 +154,7 @@ def validate_config(args):
if len(args) >= 2:
log_file = args[1]
else:
log_file = "/tmp/python-agent-test.log" # nosec
log_file = "/tmp/python-agent-test.log"

log_level = logging.DEBUG

Expand Down
1 change: 1 addition & 0 deletions newrelic/api/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def record_exception(self, exc=None, value=None, tb=None, params=None, ignore_er
warnings.warn(
("The record_exception function is deprecated. Please use the new api named notice_error instead."),
DeprecationWarning,
stacklevel=2,
)

self.notice_error(error=(exc, value, tb), attributes=params, ignore=ignore_errors)
Expand Down
2 changes: 1 addition & 1 deletion newrelic/api/asgi_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ async def send_inject_browser_agent(self, message):
# check to see if we have to modify the content-length
# header
headers = self.initial_message["headers"]
for header_index, header_data in enumerate(headers):
for header_index, header_data in enumerate(headers): # noqa: B007
header_name, header_value = header_data
if header_name.lower() == b"content-length":
break
Expand Down
5 changes: 4 additions & 1 deletion newrelic/api/database_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@


def register_database_client(
dbapi2_module, database_product, quoting_style="single", explain_query=None, explain_stmts=[], instance_info=None
dbapi2_module, database_product, quoting_style="single", explain_query=None, explain_stmts=None, instance_info=None
):
if explain_stmts is None:
explain_stmts = []

_logger.debug(
"Registering database client module %r where database "
"is %r, quoting style is %r, explain query statement is %r and "
Expand Down
20 changes: 16 additions & 4 deletions newrelic/api/error_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@


class ErrorTrace:
def __init__(self, ignore_errors=[], ignore=None, expected=None, status_code=None, parent=None):
def __init__(self, ignore_errors=None, ignore=None, expected=None, status_code=None, parent=None):
if ignore_errors is None:
ignore_errors = []
if parent is None:
parent = current_trace()

Expand All @@ -33,6 +35,7 @@ def __init__(self, ignore_errors=[], ignore=None, expected=None, status_code=Non
warnings.warn(
("The ignore_errors argument is deprecated. Please use the new ignore argument instead."),
DeprecationWarning,
stacklevel=2,
)

def __enter__(self):
Expand All @@ -50,7 +53,10 @@ def __exit__(self, exc, value, tb):
)


def ErrorTraceWrapper(wrapped, ignore_errors=[], ignore=None, expected=None, status_code=None):
def ErrorTraceWrapper(wrapped, ignore_errors=None, ignore=None, expected=None, status_code=None):
if ignore_errors is None:
ignore_errors = []

def wrapper(wrapped, instance, args, kwargs):
parent = current_trace()

Expand All @@ -63,11 +69,17 @@ def wrapper(wrapped, instance, args, kwargs):
return FunctionWrapper(wrapped, wrapper)


def error_trace(ignore_errors=[], ignore=None, expected=None, status_code=None):
def error_trace(ignore_errors=None, ignore=None, expected=None, status_code=None):
if ignore_errors is None:
ignore_errors = []

return functools.partial(
ErrorTraceWrapper, ignore_errors=ignore_errors, ignore=ignore, expected=expected, status_code=status_code
)


def wrap_error_trace(module, object_path, ignore_errors=[], ignore=None, expected=None, status_code=None):
def wrap_error_trace(module, object_path, ignore_errors=None, ignore=None, expected=None, status_code=None):
if ignore_errors is None:
ignore_errors = []

wrap_object(module, object_path, ErrorTraceWrapper, (ignore_errors, ignore, expected, status_code))
2 changes: 2 additions & 0 deletions newrelic/api/lambda_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def LambdaHandlerWrapper(*args, **kwargs):
"APIs provided in the newrelic-lambda package."
),
DeprecationWarning,
stacklevel=2,
)

return _LambdaHandlerWrapper(*args, **kwargs)
Expand All @@ -164,6 +165,7 @@ def lambda_handler(application=None, name=None, group=None):
warnings.warn(
("The lambda_handler API has been deprecated. Please use the APIs provided in the newrelic-lambda package."),
DeprecationWarning,
stacklevel=2,
)

return functools.partial(_LambdaHandlerWrapper, application=application, name=name, group=group)
1 change: 1 addition & 0 deletions newrelic/api/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def __init__(
"please use newrelic.api.log.NewRelicLogForwardingHandler to take advantage of all the "
"features included in application log forwarding such as proper batching.",
DeprecationWarning,
stacklevel=2,
)
super(NewRelicLogHandler, self).__init__(level=level)
self.license_key = license_key or self.settings.license_key
Expand Down
17 changes: 14 additions & 3 deletions newrelic/api/message_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ def create_node(self):


def MessageTraceWrapper(
wrapped, library, operation, destination_type, destination_name, params={}, terminal=True, async_wrapper=None
wrapped, library, operation, destination_type, destination_name, params=None, terminal=True, async_wrapper=None
):
if params is None:
params = {}

def _nr_message_trace_wrapper_(wrapped, instance, args, kwargs):
wrapper = async_wrapper if async_wrapper is not None else get_async_wrapper(wrapped)
if not wrapper:
Expand Down Expand Up @@ -151,7 +154,12 @@ def _nr_message_trace_wrapper_(wrapped, instance, args, kwargs):
return FunctionWrapper(wrapped, _nr_message_trace_wrapper_)


def message_trace(library, operation, destination_type, destination_name, params={}, terminal=True, async_wrapper=None):
def message_trace(
library, operation, destination_type, destination_name, params=None, terminal=True, async_wrapper=None
):
if params is None:
params = {}

return functools.partial(
MessageTraceWrapper,
library=library,
Expand All @@ -171,10 +179,13 @@ def wrap_message_trace(
operation,
destination_type,
destination_name,
params={},
params=None,
terminal=True,
async_wrapper=None,
):
if params is None:
params = {}

wrap_object(
module,
object_path,
Expand Down
3 changes: 2 additions & 1 deletion newrelic/api/ml_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def record_llm_feedback_event(trace_id, rating, category=None, message=None, met
if not transaction:
warnings.warn(
"No message feedback events will be recorded. record_llm_feedback_event must be called within the "
"scope of a transaction."
"scope of a transaction.",
stacklevel=2,
)
return

Expand Down
2 changes: 2 additions & 0 deletions newrelic/api/time_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ def record_exception(self, exc_info=None, params=None, ignore_errors=None):
warnings.warn(
("The record_exception function is deprecated. Please use the new api named notice_error instead."),
DeprecationWarning,
stacklevel=2,
)

self.notice_error(error=exc_info, attributes=params, ignore=ignore_errors)
Expand Down Expand Up @@ -700,6 +701,7 @@ def record_exception(exc=None, value=None, tb=None, params=None, ignore_errors=N
warnings.warn(
("The record_exception function is deprecated. Please use the new api named notice_error instead."),
DeprecationWarning,
stacklevel=2,
)

notice_error(error=(exc, value, tb), attributes=params, ignore=ignore_errors, application=application)
Expand Down
13 changes: 11 additions & 2 deletions newrelic/api/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ def __del__(self):
self.__exit__(None, None, None)

def __enter__(self):
assert self._state == self.STATE_PENDING
if self._state != self.STATE_PENDING:
raise RuntimeError("Attempting to start Transaction that's in an invalid state.")

# Bail out if the transaction is not enabled.

Expand Down Expand Up @@ -994,7 +995,7 @@ def user_attributes(self):
def _compute_sampled_and_priority(self):
if self._priority is None:
# truncate priority field to 6 digits past the decimal
self._priority = float(f"{random.random():.6f}") # nosec
self._priority = float(f"{random.random():.6f}") # noqa: S311

if self._sampled is None:
self._sampled = self._application.compute_sampled()
Expand Down Expand Up @@ -1110,6 +1111,7 @@ def create_distributed_trace_payload(self):
"Please use the insert_distributed_trace_headers API."
),
DeprecationWarning,
stacklevel=2,
)
return self._create_distributed_trace_payload()

Expand Down Expand Up @@ -1235,6 +1237,7 @@ def accept_distributed_trace_payload(self, *args, **kwargs):
"Please use the accept_distributed_trace_headers API."
),
DeprecationWarning,
stacklevel=2,
)
if not self._can_accept_distributed_trace_headers():
return False
Expand Down Expand Up @@ -1591,6 +1594,7 @@ def record_exception(self, exc=None, value=None, tb=None, params=None, ignore_er
warnings.warn(
("The record_exception function is deprecated. Please use the new api named notice_error instead."),
DeprecationWarning,
stacklevel=2,
)

self.notice_error(error=(exc, value, tb), attributes=params, ignore=ignore_errors)
Expand Down Expand Up @@ -1779,6 +1783,7 @@ def add_custom_parameter(self, name, value): # pragma: no cover
warnings.warn(
("The add_custom_parameter API has been deprecated. Please use the add_custom_attribute API."),
DeprecationWarning,
stacklevel=2,
)
return self.add_custom_attribute(name, value)

Expand All @@ -1789,6 +1794,7 @@ def add_custom_parameters(self, items): # pragma: no cover
warnings.warn(
("The add_custom_parameters API has been deprecated. Please use the add_custom_attributes API."),
DeprecationWarning,
stacklevel=2,
)
return self.add_custom_attributes(items)

Expand Down Expand Up @@ -1899,6 +1905,7 @@ def add_custom_parameter(key, value): # pragma: no cover
warnings.warn(
("The add_custom_parameter API has been deprecated. Please use the add_custom_attribute API."),
DeprecationWarning,
stacklevel=2,
)
return add_custom_attribute(key, value)

Expand All @@ -1910,6 +1917,7 @@ def add_custom_parameters(items): # pragma: no cover
warnings.warn(
("The add_custom_parameters API has been deprecated. Please use the add_custom_attributes API."),
DeprecationWarning,
stacklevel=2,
)
return add_custom_attributes(items)

Expand Down Expand Up @@ -1946,6 +1954,7 @@ def get_browser_timing_footer(nonce=None):
warnings.warn(
"The get_browser_timing_footer function is deprecated. Please migrate to only using the get_browser_timing_header API instead.",
DeprecationWarning,
stacklevel=2,
)
return ""

Expand Down
1 change: 1 addition & 0 deletions newrelic/api/web_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ def browser_timing_footer(self, nonce=None):
warnings.warn(
"The browser_timing_footer function is deprecated. Please migrate to only using the browser_timing_header api instead.",
DeprecationWarning,
stacklevel=2,
)
return ""

Expand Down
4 changes: 2 additions & 2 deletions newrelic/common/agent_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,11 @@ def send_request(
response = self._connection.request_encode_url(
method, path, fields=params, body=body, headers=merged_headers, **self._urlopen_kwargs
)
except urllib3.exceptions.HTTPError as e:
except urllib3.exceptions.HTTPError as exc:
self.log_response(self._audit_log_fp, request_id, 0, None, None, connection)
# All urllib3 HTTP errors should be treated as a network
# interface exception.
raise NetworkInterfaceException(e)
raise NetworkInterfaceException(exc) from exc

self.log_response(self._audit_log_fp, request_id, response.status, response.headers, response.data, connection)

Expand Down
2 changes: 1 addition & 1 deletion newrelic/common/coroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def _iscoroutinefunction_tornado(fn):


def is_coroutine_callable(wrapped):
return is_coroutine_function(wrapped) or is_coroutine_function(getattr(wrapped, "__call__", None))
return is_coroutine_function(wrapped) or is_coroutine_function(getattr(wrapped, "__call__", None)) # noqa: B004


if hasattr(inspect, "isasyncgenfunction"):
Expand Down
2 changes: 1 addition & 1 deletion newrelic/common/encoding_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def generate_path_hash(name, seed):
if not isinstance(name, bytes):
name = name.encode("UTF-8")

path_hash = rotated ^ int(hashlib.md5(name).hexdigest()[-8:], base=16) # nosec
path_hash = rotated ^ int(hashlib.md5(name).hexdigest()[-8:], base=16) # noqa: S324
return f"{path_hash:08x}"


Expand Down
4 changes: 2 additions & 2 deletions newrelic/common/object_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def _object_context(object): # noqa: A002
# If it's not a class method, it must be an instance method.

if cname is None:
cname = getattr(object.__self__.__class__, "__qualname__")
cname = object.__self__.__class__.__qualname__

path = f"{cname}.{object.__name__}"

Expand All @@ -140,7 +140,7 @@ def _object_context(object): # noqa: A002
# qualified name.

if path is None and hasattr(object, "__class__"):
path = getattr(object.__class__, "__qualname__")
path = object.__class__.__qualname__

# Now calculate the name of the module object is defined in.

Expand Down
Loading
Loading