Opened 5 weeks ago

Closed 4 weeks ago

#35927 closed Cleanup/optimization (invalid)

utils/encoding.py force_string, smart_string, force_bytes, and smart_bytes should verify encoding parameter is not None

Reported by: Derek M. Knowlton Owned by: Derek Knowlton
Component: Utilities Version: 5.1
Severity: Normal Keywords: encoding, none, smart_str, force_str, smart_bytes, force_bytes, utils
Cc: Derek M. Knowlton Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Overview

The force_str(), force_bytes(), smart_str(), smart_bytes() functions in django/utils/encoding.py currently doesn't verify that the encoding parameter is not None. When None is passed as the encoding parameter and the input is bytes, it results in a TypeError from Python's built-in str() function rather than providing a clear validation error.

Reproduction

from django.utils.encoding import force_str

# This raises TypeError: str() argument 'encoding' must be str, not None
result = force_str(b'test', encoding=None)

Behaviors

Current Behavior:

  • When encoding=None is passed by input, a TypeError is raised by Python's built-in str() function
  • The error message from this specific error does not indicate that the error originated from utils/encoding.py, or that the error comes from an incorrect value passed to the functions inside utils/encoding.py
  • No upfront validation is performed on the encoding parameter

Expected Behavior:

  • Early detection of invalid encoding parameter
  • Custom TypeError with a descriptive message if None is passed
  • Follows explicit parameter validation principles

Suggested Fix

if encoding is None:
    raise TypeError("{{function name}}: encoding parameter cannot be None")

Summary

Though this change is small, it would improve developer experience by increasing the accuracy of error handling. This change is backwards compatible as it does not change the functionality of the code as passing None was never valid.

Change History (1)

comment:1 by Natalia Bidart, 4 weeks ago

Resolution: invalid
Status: assignedclosed

Hello Derek, thank you for taking the time to create this report. I appreciate your concern, but I believe we can't accept this ticket for two main reasons:

  1. There is nothing in the docs for these functions that would suggest that None is a valid value for the encoding param. Passing None would be considered user error, just as passing other invalid types like a list or dict would be.
  2. Django relies on Python's dynamic typing, and it doesn't validate every function argument exhaustively. Expecting validation in every case would go against Python's design principles and introduce unnecessary overhead.

Thanks again for your feedback!

Note: See TracTickets for help on using tickets.
Back to Top