So what's the use case for Python 2/3 compatible code? IMO the main use case for the PEP is simply to be able to construct bytes from a combination of a template and some input that may include further bytes and numbers. E.g. in asyncio when you write an HTTP client or server you have to construct bytes to write to the socket, and I'd be happy if I could write b'HTTP/1.0 %d %b\r\n' % (status, message) rather than having to use str(status).encode('ascii') and concatenation or join().


On Thu, Mar 27, 2014 at 11:47 AM, Brett Cannon <bcannon@gmail.com> wrote:


On Thu Mar 27 2014 at 2:42:40 PM, Guido van Rossum <guido@python.org> wrote:
Much better, but I'm still not happy with including %s at all. Otherwise it's accept-worthy. (How's that for pressure. :-)

But if we only add %b and leave out %s then how is this going to lead to Python 2/3 compatible code since %b is not in Python 2? Or am I misunderstanding you?

-Brett
 


On Thu, Mar 27, 2014 at 11:04 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
On 03/27/2014 10:55 AM, Ethan Furman wrote:
On 03/27/2014 10:29 AM, Guido van Rossum wrote:

I also don't understand why we can't use %b instead of %s. AFAIK %b currently doesn't mean anything and I somehow don't
expect we're likely to add it for other reasons (unless there's a proposal I'm missing?). Just like we use %a instead of
%r to remind people that it's not quite the same (since it applies .encode('ascii', 'backslashreplace')), shouldn't we
use anything *but* %s to remind people that that is also not the same (not at all, in fact)? The PEP's argument against
%b ("rejected as not adding any value either in clarity or simplicity") is hardly a good reason.

The biggest reason to use %s is to support a common code base for 2/3 endeavors.  The biggest reason to not include %b
is that it means binary number in format(); given that each type can invent it's own mini-language, this probably isn't
a very strong argument against it.

I have moderate feelings for keeping %s as a synonym for %b for backwards compatibility with Py2 code (when it's
appropriate).

Changed to:
----------------------------------------------------------------------------------
``%b`` will insert a series of bytes.  These bytes are collected in one of two
ways:

  - input type supports ``Py_buffer`` [4]_?

    use it to collect the necessary bytes

  - input type is something else?
    use its ``__bytes__`` method [5]_ ; if there isn't one, raise a ``TypeError``

In particular, ``%b`` will not accept numbers nor ``str``.  ``str`` is rejected
as the string to bytes conversion requires an encoding, and we are refusing to
guess; numbers are rejected because:

  - what makes a number is fuzzy (float? Decimal? Fraction? some user type?)

  - allowing numbers would lead to ambiguity between numbers and textual
    representations of numbers (3.14 vs '3.14')

  - given the nature of wire formats, explicit is definitely better than implicit

``%s`` is included as a synonym for ``%b`` for the sole purpose of making 2/3 code
bases easier to maintain.  Python 3 only code should use ``%b``.

Examples::

    >>> b'%b' % b'abc'
    b'abc'

    >>> b'%b' % 'some string'.encode('utf8')
    b'some string'

    >>> b'%b' % 3.14

    Traceback (most recent call last):
    ...
    TypeError: b'%b' does not accept 'float'

    >>> b'%b' % 'hello world!'

    Traceback (most recent call last):
    ...
    TypeError: b'%b' does not accept 'str'
----------------------------------------------------------------------------------


--
~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev



--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/brett%40python.org



--
--Guido van Rossum (python.org/~guido)