# \[PyCall\] append!() returns PyError (:PyList\_Append) bad argument to internal function error

**URL:** <https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263>\
**Category:** General Usage\
**Tags:** pycall\
**Created:** [April 18, 2017, 8:09am UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263 "2017-04-18T08:09:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [April 18, 2017, 8:09am UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/1 "2017-04-18T08:09:59Z")

</div>

I am trying to port in Julia the above python code:

```python
from ezodf import newdoc, Sheet

ods = newdoc(doctype='ods', filename='spreadsheet.ods')
sheet = Sheet('SHEET', size=(10, 10))
ods.sheets += sheet
sheet['A1'].set_value("1.5")
ods.save()

```

The problem is with the += (python extend) part:

```julia
using PyCall
@pyimport ezodf
filename="testspreadsheet.ods"
destDoc = ezodf.newdoc(doctype="ods", filename=filename)
sheet = ezodf.Sheet("SHEET", size=(10, 10))
append!(destDoc[:sheets],sheet)
# a = PyVector(destDoc[:sheets])
# append!(a,sheet) # same error

```

```julia
PyError (:PyList_Append) <type 'exceptions.SystemError'>
SystemError('../Objects/listobject.c:290: bad argument to internal function',)

 in pyerr_check at exception.jl:56 [inlined]
 in pyerr_check at exception.jl:61 [inlined]
 in macro expansion at exception.jl:81 [inlined]
 in push!(::PyCall.PyObject, ::PyCall.PyObject) at PyCall.jl:657
 in append!(::PyCall.PyObject, ::PyCall.PyObject) at PyCall.jl:679
 in include_string(::String, ::String) at loading.jl:441
 in include_string(::String, ::String, ::Int64) at eval.jl:28
 in include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N}) at eval.jl:32
 in (::Atom.##53#56{String,Int64,String})() at eval.jl:50
 in withpath(::Atom.##53#56{String,Int64,String}, ::String) at utils.jl:30
 in withpath(::Function, ::String) at eval.jl:38
 in macro expansion at eval.jl:49 [inlined]
 in (::Atom.##52#55{Dict{String,Any}})() at task.jl:60

```

Any hint ? Thank you…  
(I di try with push!) and converting all to PyVector() but the error remains the same)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 18, 2017, 7:09pm UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/2 "2017-04-18T19:09:11Z")

</div>

This looks like a bug in `append!(a::PyObject, b::PyObject)`. I’ll try to push a fix soon.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 18, 2017, 7:34pm UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/3 "2017-04-18T19:34:32Z")

</div>

The issue is that the PyCall `append!` function only works for Python `list` objects, which is not what you have here. As a fallback, I guess it should call the ` __iadd__ ` method, since that is what `+=` really does in Python.

As a workaround, you can call `destDoc[:sheets][: __iadd__](sheet)`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 18, 2017, 7:37pm UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/4 "2017-04-18T19:37:45Z")

</div>

I’m not sure it is safe for me to define `append!` to call ` __iadd__ ` in general, since `+=` in Python is not necessarily appending to a list.

However, I could define the `a .+= b` operator on a PyObject to call ` __iadd__ ` in Julia 0.6, which would have the added benefit of closely resembling the Python syntax.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 18, 2017, 7:56pm UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/5 "2017-04-18T19:56:45Z")

</div>

Ah, there is a PySequence\_InPlaceConcat API function that I should be using here, instead of the PyList API, which should work for any object implementing the sequence protocol.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [April 19, 2017, 5:13am UTC](https://discourse.julialang.org/t/pycall-append-returns-pyerror-pylist-append-bad-argument-to-internal-function-error/3263/6 "2017-04-19T05:13:17Z")

</div>

Thank you… I confirm that calling directly **iadd** works:

```julia
using PyCall
@pyimport ezodf
filename="testspreadsheet.ods"
destDoc = ezodf.newdoc(doctype="ods", filename=filename)
sheet = ezodf.Sheet("SHEET", size=(10, 10))
destDoc[:sheets][: __iadd__](sheet)
sheet[1,1][:set_value](1.5)
destDoc[:save]()

```
