Opened 7 years ago
Closed 6 years ago
#29412 closed Bug (fixed)
django.utils.text.slugify() shouldn't return a SafeString
Reported by: | Andreas Pelme | Owned by: | |
---|---|---|---|
Component: | Utilities | Version: | 2.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
https://github.com/django/django/commit/ccfd1295f986cdf628d774937d0b38a14584721f changed SafeString.__str__
to return itself rather than a native string.
This works fine in most places. However, interning (sys.intern
) a SafeString
does not work, it needs to be converted to a regular string first.
I use slugify to generate file names and passing it on to pathlib.Path. Path interns strings and this breaks:
>>> from django.utils.text import slugify >>> import pathlib >>> pathlib.Path(slugify('foo')) Traceback (most recent call last): File "<input>", line 1, in <module> File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 999, in __new__ self = cls._from_parts(args, init=False) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 656, in _from_parts drv, root, parts = self._parse_args(args) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 649, in _parse_args return cls._flavour.parse_parts(parts) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 69, in parse_parts parsed.append(sys.intern(rel)) TypeError: can't intern SafeText >>> pathlib.Path(str(slugify('foo'))) Traceback (most recent call last): File "<input>", line 1, in <module> File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 999, in __new__ self = cls._from_parts(args, init=False) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 656, in _from_parts drv, root, parts = self._parse_args(args) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 649, in _parse_args return cls._flavour.parse_parts(parts) File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 69, in parse_parts parsed.append(sys.intern(rel)) TypeError: can't intern SafeText >>> pathlib.Path(slugify('foo') + '') # workaround PosixPath('foo')
The only way to work around this is to use some kind of string operation that will turn it into a native string but that feels like a workaround.
Maybe the problem is not SafeString but rather that django.utils.text.slugify
that does return a SafeString instead of a regular string? The builtin slugify filter could still return a safe string?
Change History (5)
comment:1 by , 7 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 6 years ago
Type: | Uncategorized → Bug |
---|
comment:5 by , 6 years ago
Summary: | django.utils.text.slugify / SafeString → django.utils.text.slugify() shouldn't return a SafeString |
---|---|
Triage Stage: | Accepted → Ready for checkin |
I would also question the usage of
mark_safe
inslugify
. I think the only backwards incompatibility would be that the result of adding aSafeString
to aslugify()
value would not be safe. I don't think it's much of an issue, if it's documented in release notes.