scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.38k stars 514 forks source link

print(shape.auto_shape_type) gives KeyError: 'line' #749

Open joereddington opened 2 years ago

joereddington commented 2 years ago

Hello!

I have the following code:

from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE

prs = Presentation("mcve.pptx")  
for slide in prs.slides: 
    for shape in slide.shapes:
        if shape.shape_type == MSO_SHAPE_TYPE.AUTO_SHAPE:
            print("Is this the problem {}".format(shape.auto_shape_type))

Running on mcve.pptx (1 slide, 2 shapes)

I would expect it to print out a string. However it fails with keyerror:

bash-3.2$ python3 mcve.py
Traceback (most recent call last):
  File "mcve.py", line 9, in <module>
    print("Is this the problem {}".format(shape.auto_shape_type))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pptx/shapes/autoshape.py", line 302, in auto_shape_type
    return self._sp.prst
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pptx/oxml/shapes/autoshape.py", line 303, in prst
    return prstGeom.prst
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pptx/oxml/xmlchemy.py", line 244, in get_attr_value
    return self._simple_type.from_xml(attr_str_value)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pptx/enum/base.py", line 198, in from_xml
    return cls._xml_to_member[xml_val]
KeyError: 'line'
bash-3.2$    

Is this the expected behaviour? It occurs in 0.6.18 and 0.6.21.

MartinPacker commented 2 years ago

Do you mean 0.6.21 rather than 0.6.12? Even 0.6.18 is over two years old. 0.6.21 is the latest.

joereddington commented 2 years ago

Do you mean 0.6.21 rather than 0.6.12? Even 0.6.18 is over two years old. 0.6.21 is the latest.

Thank you. Fixed :)

MartinPacker commented 2 years ago

Ah. I see why the noseless smiley. :-)

But that doesn't mean your problem's gone away. (And I can't solve it.)

scanny commented 2 years ago

@joereddington "line" is not a valid auto-shape type. It is however a valid connector type.

Next step would be to understand the provenance of that particular shape and perhaps have a look at its XML with print(shape._sp.xml).

joereddington commented 2 years ago

So here's what print(shape._sp.xml) gets me:

<p:sp xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:nvSpPr>
    <p:cNvPr id="2" name="Title 1"/>
    <p:cNvSpPr>
      <a:spLocks noGrp="1"/>
    </p:cNvSpPr>
    <p:nvPr>
      <p:ph type="title"/>
    </p:nvPr>
  </p:nvSpPr>
  <p:spPr/>
  <p:txBody>
    <a:bodyPr/>
    <a:lstStyle/>
    <a:p>
      <a:r>
        <a:rPr lang="en-US" dirty="0">
          <a:solidFill>
            <a:srgbClr val="FF0000"/>
          </a:solidFill>
        </a:rPr>
        <a:t>Food chat</a:t>
      </a:r>
    </a:p>
  </p:txBody>
</p:sp>

<p:sp xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:nvSpPr>
    <p:cNvPr id="273" name="Line 47"/>
    <p:cNvSpPr/>
    <p:nvPr/>
  </p:nvSpPr>
  <p:spPr>
    <a:xfrm flipH="1">
      <a:off x="4426936" y="4869891"/>
      <a:ext cx="328680" cy="327600"/>
    </a:xfrm>
    <a:prstGeom prst="line">
      <a:avLst/>
    </a:prstGeom>
    <a:ln w="76320">
      <a:solidFill>
        <a:schemeClr val="bg1">
          <a:lumMod val="75000"/>
        </a:schemeClr>
      </a:solidFill>
      <a:round/>
    </a:ln>
  </p:spPr>
</p:sp>

So one of my questions is: if it's not a valid autoshape - then why is it passing the if shape.shape_type == MSO_SHAPE_TYPE.AUTO_SHAPE: line? the other is - why has it got an auto_shape_type method?

scanny commented 2 years ago

Hmm, interesting. How did the second shape get there? Was it created with PowerPoint for example?

I would expect that shape to be a <p:cxnSp> ("connection-shape") element.

joereddington commented 2 years ago

I believe it was created in powerpoint, but it might have been created in ppt rather than pptx.

Interestingly - if I drag either end of the line around a bit, the error remains, but if I 'edit points', and so something like this: Screenshot 2021-10-07 at 16 17 00

then the errror goes away...

I'll ask the file owner how the shapes were created

scanny commented 2 years ago

Another thing that might be interesting is to use VBA or other win32com interface to see what the Microsoft API reports for these things, something like:

Debug.Print shape.Type
Debug.Print shape.AutoShapeType

It's possible that PowerPoint makes allowances for a connector shape to have two forms. If it does we can consider accommodating the same in python-pptx on a defacto-spec basis :)

Shape.Type and allowable values

Shape.AutoShapeType and allowable values