# Avoiding conversion of (an invalid) string returned from PyCall when passing back to Python

**URL:** <https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 15, 2016, 6:01pm UTC](https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974 "2016-12-15T18:01:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [December 15, 2016, 6:01pm UTC](https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974/1 "2016-12-15T18:01:12Z")

</div>

In Python

```julia
>>> import base64
>>> base64.urlsafe_b64decode('08lZBOeQrbLPrIK8d029jtuj3rl3oC6DD_4MUEKu_8TAlZIOSub4a-RJ2Me8z5Dv')

```

produces the following string:  
`'\xd3\xc9Y\x04\xe7\x90\xad\xb2\xcf\xac\x82\xbcwM\xbd\x8e\xdb\xa3\xde\xb9w\xa0.\x83\x0f\xfe\x0cPB\xae\xff\xc4\xc0\x95\x92\x0eJ\xe6\xf8k\xe4I\xd8\xc7\xbc\xcf\x90\xef'`  
This is not really a valid string so Julia will understandably complain about printing it…

```julia
@pyimport base64
base64.urlsafe_b64decode(input)
"ԉY\x04琭Error showing value of type String:
ERROR: UnicodeError: invalid character index
...

```

but the real problem is that I can’t pass it back to Python through PyCall

```julia
@pyimport base64
str = base64.urlsafe_b64decode(input)
base64.encode(str)
ERROR: PyError (PyUnicode_DecodeUTF8) <type 'exceptions.UnicodeDecodeError'>
UnicodeDecodeError('utf8', '\xd3\xc9Y\x04\xe7\x90\xad\xb2\xcf\xac\x82\xbcwM\xbd\x8e\xdb\xa3\xde\xb9w\xa0.\x83\x0f\xfe\x0cPB\xae\xff\xc4\xc0\x95\x92\x0eJ\xe6\xf8k\xe4I\xd8\xc7\xbc\xcf\x90\xef', 0, 1, 'invalid continuation byte')

```

as I assume Julia is trying to convert it to a UTF-8 encoding before passing it to Python.

I could wrap the python functionality in a `@pydef`ed class to avoid these conversions, but I wonder if there is an alternative approach which avoids this problem?

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [December 15, 2016, 6:36pm UTC](https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974/2 "2016-12-15T18:36:05Z")

</div>

One option is to use `pycall` to retain the underlying Python object:

```julia
strobj = pycall(base64.urlsafe_b64decode, PyObject, "08lZBOeQrbLPrIK8d029jtuj3rl3oC6DD_4MUEKu_8TAlZIOSub4a-RJ2Me8z5Dv")

```

which one can then use in the following call to Python.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [May 28, 2017, 12:27am UTC](https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974/3 "2017-05-28T00:27:31Z")

</div>

Julia doesn’t really have a binary string type (if you use the string macro `b"..."` it returns a `Vector{UInt8}`).  
What happens if you convert the return immediately: `binstr = convert(Vector{UInt8}, base64.urlsafe_b64decode(input))`?  
Does `base64.encode(binstr)` then work correctly?

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [May 28, 2017, 10:13am UTC](https://discourse.julialang.org/t/avoiding-conversion-of-an-invalid-string-returned-from-pycall-when-passing-back-to-python/974/4 "2017-05-28T10:13:49Z")

</div>

Thanks Scott, your solution also works well.

```julia
julia> using PyCall
julia> @pyimport base64
julia> input = "08lZBOeQrbLPrIK8d029jtuj3rl3oC6DD_4MUEKu_8TAlZIOSub4a-RJ2Me8z5Dv";
julia> base64.urlsafe_b64encode(convert(Vector{UInt8},base64.urlsafe_b64decode(input)))
"08lZBOeQrbLPrIK8d029jtuj3rl3oC6DD_4MUEKu_8TAlZIOSub4a-RJ2Me8z5Dv"

```
