0

I'm trying to concatenate string and bytes in Python. This isn't working, but I think it could work if we could get rid of the b'' and treat the bytes object as a string:

import binascii

s = 'hello world'

hex_code = binascii.hexlify(bytes(s, 'utf-8'))
print(hex_code) # b'68656c6c6f20776f726c64'

# this would work
print('68656c6c6f20776f726c64' + ' some other string')

# this fails
print(hex_code + ' some other string')

My ultimate use case is for something totally unrelated. SQL Server supports setting metadata by issuing a `SET CONTEXT_INFO' command which requires the metadata be encoded. Ideally I want to construct this metadata from my application. My command might look something like:

import bin2ascii

def set_context(conn, context_info: str):
    hex_string = binascii.hexlify(bytes(context_info, 'utf-8'))
    conn.execute('SET CONTEXT_INFO 0x' + hex_string)

This of course isn't working because I can't figure a way to concatenate string and bytes.

rookie
  • 2,783
  • 5
  • 29
  • 43
  • You cannot concatenate strings and bytes. Convert one to the other and then concatenate. As you already thought of: " treat the bytes object as a string" So, your question amounts to "how to convert a bytes object into a string object", So here you can just use `hex_code.decode()` to get back a string... note, you should have used `s.encode('utf-8')` instead of the bytes constructor, just to do it more idiomatically – juanpa.arrivillaga Mar 21 '20 at 00:17
  • Thanks @juanpa.arrivillaga -- ultimately my use case requires a bytes string. How can I get this? – rookie Mar 21 '20 at 00:18
  • do you mean to pass to `conn.execute`? Then the simplest way would just be to use a bytes literal there: `conn.execute(b'SET CONTEXT_INFO 0x' + hex_string)` of course, `hex_string` in this case is not a string... it's a bytes object, so that's a misleading name. I would just do `hexlified = binascii.hexlify(context_info.encode('utf-8')); conn.execute(b'SET CONTEXT_INFO 0x' + hexlified)` – juanpa.arrivillaga Mar 21 '20 at 00:20
  • As an aside, it is generally considered a security risk to use naive string concatenation in this case, because it makes you vulnerable to SQL injection. That may or may not be an issue – juanpa.arrivillaga Mar 21 '20 at 00:25
  • SQLI isn't a concern here because the metadata is constructed internally and not from user data. Unfortunately `conn.execute(b'...')` doesn't work with the library I'm using (sqlalchemy). – rookie Mar 21 '20 at 00:27
  • OK. What do you mean `conn.execute(b'...')` **doesn't work**. What, **exactly** doesn't work? You said it requires `bytes`, so either it *doesn't* require `bytes` or it's not working for an unrelated reason. – juanpa.arrivillaga Mar 21 '20 at 00:28
  • If it's sqlalchemy, then `conn.execute` **doesn't accept bytes** as you said. Instead, it requires a `str` object, or the specialized sqlalchemy objects... in any case, I've given to you the solution already – juanpa.arrivillaga Mar 21 '20 at 00:30
  • @juanpa.arrivillaga what's the solution? The function doesn't accept bytes. How do we turn bytes into a string that the function can accept? – rookie Mar 21 '20 at 00:31
  • I already explained that to you. You would use `hex_string.decode()`. So `conn.execute('SET CONTEXT_INFO 0x' + hex_string.decode())`. Note, you implied the exact opposite, btw, when you stated "ultimately my use case requires a bytes string". It requires **a string**. Not bytes. – juanpa.arrivillaga Mar 21 '20 at 00:32
  • @juanpa.arrivillaga thanks - I can give you credit if you want to add it as an official answer. – rookie Mar 21 '20 at 00:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210040/discussion-between-rookie-and-juanpa-arrivillaga). – rookie Mar 21 '20 at 00:45

0 Answers0