Skip to content

Commit

Permalink
relax speedups str check
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Oct 17, 2024
1 parent 4dafb7c commit 8cb1691
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Version 3.1.0

Unreleased

- Fix compatibility when ``__str__`` returns a ``str`` subclass. :issue:`472`


Version 3.0.1
-------------
Expand Down
2 changes: 1 addition & 1 deletion src/markupsafe/_speedups.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ escape_unicode_kind4(PyUnicodeObject *in)
static PyObject*
escape_unicode(PyObject *self, PyObject *s)
{
if (!PyUnicode_CheckExact(s))
if (!PyUnicode_Check(s))
return NULL;

// This check is no longer needed in Python 3.12.
Expand Down
36 changes: 36 additions & 0 deletions tests/test_escape.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import typing as t

import pytest

from markupsafe import escape
Expand Down Expand Up @@ -30,3 +32,37 @@
)
def test_escape(value: str, expect: str) -> None:
assert escape(value) == Markup(expect)


class Proxy:
def __init__(self, value: t.Any) -> None:
self.__value = value

@property # type: ignore[misc]
def __class__(self) -> type[t.Any]:
# Make o.__class__ and isinstance(o, str) see the proxied object.
return self.__value.__class__ # type: ignore[no-any-return]

def __str__(self) -> str:
return str(self.__value)


def test_proxy() -> None:
"""Handle a proxy object that pretends its __class__ is str."""
p = Proxy("test")
assert p.__class__ is str
assert isinstance(p, str)
assert escape(p) == Markup("test")


class ReferenceStr(str):
def __str__(self) -> str:
# This should return a str, but it returns the subclass instead.
return self


def test_subclass() -> None:
"""Handle if str(o) does not return a plain str."""
s = ReferenceStr("test")
assert isinstance(s, str)
assert escape(s) == Markup("test")

0 comments on commit 8cb1691

Please sign in to comment.