Patchwork [STABLE] hgweb: cast bytearray to bytes

login
register
mail settings
Submitter Gregory Szorc
Date Nov. 10, 2018, midnight
Message ID <bd88e17266d4e5cf10d3.1541808059@gps-ubuntu-vm-2>
Download mbox | patch
Permalink /patch/36496/
State Accepted
Headers show

Comments

Gregory Szorc - Nov. 10, 2018, midnight
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1541807379 0
#      Fri Nov 09 23:49:39 2018 +0000
# Branch stable
# Node ID bd88e17266d4e5cf10d3b2f4d4868b51ae35133d
# Parent  5b530d767e6726374382a7bde932bcc528568b85
hgweb: cast bytearray to bytes

PEP-3333 seems to indicate that bytes is the only allowed type that can
be used to express the output of a WSGI application. And some WSGI
environments seem to enforce this (mod_wsgi does).

This commit universally casts bytearray instances to bytes to appease
the WSGI specification.

I found this because wireprotov2 is emitting bytearray instances. I'd
like to keep things that way because the way it builds a data
structure, bytearray is more efficient. I'd rather keep the low-level
code efficient (and using bytearray) and cast at the edges than impose
a performance penalty on code that may run outside WSGI contexts.
Yuya Nishihara - Nov. 10, 2018, 3:07 a.m.
On Sat, 10 Nov 2018 00:00:59 +0000, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1541807379 0
> #      Fri Nov 09 23:49:39 2018 +0000
> # Branch stable
> # Node ID bd88e17266d4e5cf10d3b2f4d4868b51ae35133d
> # Parent  5b530d767e6726374382a7bde932bcc528568b85
> hgweb: cast bytearray to bytes

Queued for stable, thanks.

Patch

diff --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py
--- a/mercurial/hgweb/request.py
+++ b/mercurial/hgweb/request.py
@@ -540,6 +540,12 @@  class wsgiresponse(object):
             yield self._bodybytes
         elif self._bodygen:
             for chunk in self._bodygen:
+                # PEP-3333 says that output must be bytes. And some WSGI
+                # implementations enforce this. We cast bytes-like types here
+                # for convenience.
+                if isinstance(chunk, bytearray):
+                    chunk = bytes(chunk)
+
                 yield chunk
         elif self._bodywillwrite:
             self._bodywritefn = write