pythonpython-3.xopenpyxlfuture-warning

openpyxl - FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead


I'm getting a warning when loading an xlsm file using openpyxl for python, then saving/closing it after I add some data to specific 7 cells in a specific sheet. The issue is that I'm getting a "FutureWarning" that I have no idea what it is about. I've searched for this for some time now and have not been able to decipher.

I'm suspecting that the wb.save() method is what's triggering this warning as it doesn't show up when I comment this specific line up.

Does anyone know what this is?

CODE

wb = openpyxl.load_workbook(filename=directory_path.xlsm, keep_vba=True)
ws = wb['sheetname']
ws.cell(row1, col1).value = ### (some number)
ws.cell(row2, col2).value = ### (some number)
ws.cell(row3, col3).value = ### (some number)
ws.cell(row4, col4).value = ### (some number)
ws.cell(row5, col5).value = ### (some number)
ws.cell(row6, col6).value = ### (some number)
ws.cell(row7, col7).value = ### (some number)
wb.save(directory_path.xlsm)
wb.close()

WARNING MESSAGE

C:\Users\...\Anaconda3\lib\site-packages\openpyxl\comments\shape_writer.py:75: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead.
  if not shape_types:

Solution

  • Openpyxl seems to be using an older version of lxml. It is a warning in your version of lxml.

    Line 73-76 of the shape_writer source code are:

    # check whether comments shape type already exists
    shape_types = root.find("{%s}shapetype[@id='_x0000_t202']" % vmlns)
    if not shape_types:
        self.add_comment_shapetype(root)
    

    The issue is the if not shape_types:. root.find() is a call to lxml. The documentation for lxml says:

    Prior to ElementTree 1.3 and lxml 2.0, you could also check the truth value of an Element to see if it has children, i.e. if the list of children is empty:

    if root:   # this no longer works!
        print("The root element has children")
    

    This is no longer supported as people tend to expect that a "something" evaluates to True and expect Elements to be "something", may they have children or not. So, many users find it surprising that any Element would evaluate to False in an if-statement like the above. Instead, use len(element), which is both more explicit and less error prone.