-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
9438 py2 bytes directory listing #1008
Conversation
This prevents the template from being promoted to unicode via interpolation of unicode paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new test looks good, and the proposed change fixes it in a way which seems reasonably compatible.
If you want to address any of the minor feedback inline, feel free to do so either as a tweak before landing or as a follow-up.
src/twisted/web/static.py
Outdated
Return a resource that generates an HTML listing of the | ||
directory this path represents. | ||
|
||
@return: A L{resource.Resource} that renders the directory to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that DirectoryLister
is public, this could refer directly to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it public though. 😭
path = self.path | ||
names = self.listNames() | ||
else: | ||
# DirectoryLister works in terms of native strings, so on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we not need to do the inverse (.asTextMode()
) on PY3 then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, but for a bad reason: File
and DirectoryLister
are tricky.
getChild
now decodes all descendant paths to text, so that by the time the empty path is reached and directoryListing
called, the path given to DirectoryLister
is guaranteed to be text, unless of course the path being listed is the File
's own path.
Given:
from twisted.web import server, static
from twisted.internet import defer, endpoints, task
@task.react
def main(reactor):
site = server.Site(static.File(b"/path/to/some/directory/"))
listener = endpoints.serverFromString(reactor, "tcp:8080")
d = listener.listen(site)
@d.addCallback
def _(_):
return defer.Deferred()
return d
Assuming that /path/to/some/directory/child
exists, accessing http://localhost:8080/child/
or any other descendant creates a DirectoryLister
with a text path. Accessing http://localhost:8080/
, however, creates one with a bytes path.
Surprise! On Python 3, this is fine. That's DirectoryLister
itself decodes bytes descendants to text on Python 3.
So the actual admitted by DirectoryLister
is:
DirectoryLister parameter |
Python 3 | Python 2 |
---|---|---|
pathname | str or bytes |
str |
dirs | str or bytes |
str |
contentTypes | dict of str |
dict of str |
contentEncodings | dict of str |
dict of str |
defaultType | str |
str |
Which is not exactly what I said in the commit message, but does mean this part of the PR is correct (I think.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every day I'm a little more sympathetic towards web2's abandonment of this API :).
src/twisted/web/test/test_static.py
Outdated
self.assertIsInstance(response, bytes) | ||
if sys.getfilesystemencoding().lower() not in ('utf-8', 'mcbs'): | ||
test_emptyChildUnicodeParent.skip = ( | ||
"Cannot write unicode filenames with file system encoding of" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ITYM "non-ASCII"? Given that the u''
child is the one we care about, I'm pretty sure that will survive most boneheaded filesystem encodings, and this skip could be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a safeguard I carried over from another test, because who knows what sys.getfilesystemencoding, which FilePath
uses, is going to return. But as you point out, it should be impossible that SynchronousTestCase.mkstemp().decode(sys.getfilesystemencoding()) + u''
could return an unencodable path, so this skip is unnecessary.
It should be impossible for SynchronousTestCase.mkstemp().decode(sys.getfilesystemencoding()) + u'' to return an unencodable path, so the skip is unnecessary.
Is there a plan to release new twisted version with this fix? |
Contributor Checklist: