PyCall deprecation warning - getindex o.x vs o[x] where x is a julia variable

All

I get the following deprecation warning

 Warning: `getindex(o::PyObject, s::AbstractString)` is deprecated in favor of dot overloading (`getproperty`) so elements should now be accessed as e.g. `o."s"` instead of `o["s"]`.
│   caller = addChartToWorkbook!(workbook::PyCall.PyObject, worksheet::PyCall.PyObject, chartDict::Dict{AbstractString, Dict{AbstractString, Any}}, location::String) at charts.jl:61

it relates to the second last line of this code snippet.
I don’t know how to fix this as in my case the key s is a variable in my julia code.

Any ideas?


function addChartToWorkbook!(workbook::PyCall.PyObject, worksheet::PyCall.PyObject, chartDict::Dict{AbstractString,Dict{AbstractString,Any}}, location::AbstractString) # ;properties=["set_x_axis", "set_y_axis","set_legend"])
	chart = PyCall.pycall(workbook."add_chart", PyCall.PyAny, chartDict["add_chart"])
	stopboolean = true
	i = 1
	local thiskey
	while stopboolean
		thiskey = string("series", i)
		if haskey(chartDict, thiskey)
			PyCall.pycall(chart."add_series", PyCall.PyAny, chartDict[thiskey])
		else
			stopboolean = false
			break # if there is no series2 then we assume there is no series 3 to n either
		end
		i += 1
	end
	# check if this is a combined chart
	thiskey = "combChart"
	i2 = 1
	stopboolean = true
	if haskey(chartDict, thiskey)
		second_chart = PyCall.pycall(workbook."add_chart", PyCall.PyAny, chartDict[thiskey])
		while stopboolean
			thiskey = string("series_comb", i2)
			if haskey(chartDict, thiskey)
				PyCall.pycall(second_chart."add_series", PyCall.PyAny, chartDict[thiskey])
			else
				stopboolean = false
				break # if there is no series2 then we assume there is no series 3 to n either
			end
			i2 += 1
		end
		# combine the charts
		PyCall.pycall(chart."combine", PyCall.PyAny, second_chart)		
	end
	# set other properties
	for x in keys(chartDict)
		fieldsWhichAreAlreadySet = [convert(String, string("series", zz)) for zz in 1:i]
		resevedKeywords = ["combChart","series_comb1","series_comb2","series_comb3", "series_comb4"] # currently limited to 1+4 series for combined charts
		append!(fieldsWhichAreAlreadySet, ["add_series","add_chart"])
		append!(fieldsWhichAreAlreadySet, resevedKeywords)		
		if !in(x, fieldsWhichAreAlreadySet)
            PyCall.pycall(chart[x], PyCall.PyAny, chartDict[x])	# TBD: unclear how to fix this line... (deprecated syntax...)
		end			
	end
	PyCall.pycall(worksheet."insert_chart", PyCall.PyAny, location, chart)
end
 

If it’s a field of the object, i.e. you want it to correspond to chart.x in Python, do getproperty(chart, x).

If it’s an index of a container, i.e. you want it to correspond to chart[x] in Python, do get(chart, x).

Thank you @stevengj

Unfortunately neither seems to work.
As I have two calls to chart[x] in the same line, I even tried the two combinations (once get and once getproperty).

Maybe it is an issue with the underlying pandas function.
I think I am using pandas.ExcelWriter — pandas 2.2.3 documentation (I have not used my code snippet for a while)

If you have time to look at my example code.
Here is an ‘MWE’ (you can run the first 150 rows of the file “1.frenchMTPLdata_single_tree.jl”)

resultingFiles, resM = dtm(dtmtable, sett)

the error I am getting is

 C:\Users\BERNHA~1.KOE\AppData\Local\Temp\jl_E6216n\dtmresult.xlsx
ePyCallWriteExcel = PyError ($(Expr(:escape, :(ccall(#= C:\Users\bernhard.koenig\.julia\packages\PyCall\1gn3u\src\PyCall.jl:783 =# @pysym(:PyObject_GetItem), PyPtr, (PyPtr, PyPtr), o, PyObject(k)))))) <class 'TypeError'>
TypeError("'ChartColumn' object is not subscriptable")

PyCall.PyError
  msg: String "\$(Expr(:escape, :(ccall(#= C:\\Users\\bernhard.koenig\\.julia\\packages\\PyCall\\1gn3u\\src\\PyCall.jl:783 =# @pysym(:PyObject_GetItem), PyPtr, (PyPtr, PyPtr), o, PyObject(k)))))"
  T: PyCall.PyObject
    o: Ptr{PyCall.PyObject_struct} @0x00007ffd23e85ea0
  val: PyCall.PyObject
    o: Ptr{PyCall.PyObject_struct} @0x0000020038718640
  traceback: PyCall.PyObject
    o: Ptr{PyCall.PyObject_struct} @0x0000000000000000

Can you give a working example in Python? Once you know how to write it in Python, it’s easier to translate to Julia.

PS. Give a minimal example. Load one object and do the indexing/subscript operation you want. Get rid of all the other chart stuff.

PPS. Don’t post screenshots of code, please. They are not searchable, not copy-pasteable, and are counter-productive overall.

2 Likes

thank you.

I have a Julia MWE now (as my Python skills are limited)
But the depreciation warning is not thrown anymore (why?)
So I guess my original question is somewhat moot now.

as you can see below chart[x] is used

#using DecisionTrees 
using PyCall
using DataFrames

statsfile = joinpath(mktempdir(),"abc.xlsx")
#statsfile = raw"C:\temp\8.xlsx"

function me(statsfile) 
data = DataFrame(x=collect(1:13), y=collect(1:13).*2)

@assert isdir(splitdir(statsfile)[1])
isfile(statsfile) && rm(statsfile)

pyModPandas = PyCall.pyimport_conda("pandas", "pandas")

writer = pyModPandas.ExcelWriter(statsfile, engine="xlsxwriter")
sheet = "sheet1"
# create python dataframe	
dataDict = Dict("x" => data.x,"y"=>data.y)
pyDF = PyCall.pycall(pyModPandas.DataFrame, PyCall.PyObject, dataDict, columns=propertynames(data))
PyCall.pycall(pyDF."to_excel", PyCall.PyAny, writer, header=false, index=false, sheet_name=sheet, startrow=1, startcol=1)
#writer.close()

chartDict = Dict(
"set_y_axis" => Dict("name"=>"Observed Ratio", "major_gridlines"=>Dict{Any, Any}("visible"=>true)),
"set_legend" => Dict("position"=>"right"),
"set_size"   => Dict("y_scale"=>1.5, "x_scale"=>2.4),
"series1"    => Dict("name"=>"=sheet1!\$B\$2", "values"=>"=sheet1!\$B\$3:\$B\$10", "categories"=>"=sheet1!\$C\$3:\$C\$10"),
"add_chart"  => Dict("type"=>"column"),
"set_title"  => Dict("name"=>"Observed Ratio per Segment")
)

workbook = writer.book
	
#crt = Chart("sheet1",chartDict,"D1")

#writer.close()

chart = PyCall.pycall(workbook."add_chart", PyCall.PyAny, chartDict["add_chart"])

PyCall.pycall(chart."add_series", PyCall.PyAny, chartDict["series1"])

# set other properties
for x in ["set_y_axis","set_legend","set_size","set_title"]
    PyCall.pycall(chart[x], PyCall.PyAny, chartDict[x])	# TBD: unclear how to fix this line... (deprecated syntax...)
end
worksheet = writer.sheets["sheet1"]
PyCall.pycall(worksheet."insert_chart", PyCall.PyAny, "D1", chart)

writer.close()
@show statsfile
return nothing 
end

me(statsfile)