Scientific-Inkscape icon indicating copy to clipboard operation
Scientific-Inkscape copied to clipboard

AttributeError: 'NoneType' object has no attribute 'iddict'

Open turing opened this issue 3 months ago • 4 comments

Describe the bug

In an extension, this code runs:

84:        svg_path = ClipPath._rect_circle_cut(
85:            radius,
86:            config.SVG.get_page_bbox().width,
87:            config.SVG.get_page_bbox().height,
88:            origin
89:        ) # just returns svg path data
90:        
91:        path = inkex.elements.PathElement()
92:        path.set('d', svg_path)
93:        path_id = config.SVG.get_unique_id(f"{eid}_path_")
94:        path.set_id(path_id)
95:        
96:        path_data = svg_path

Path id returned is a string, something like ext_outside_circle_clip_path_0

Results in:

  File ".../clippath.py", line 94, in outside_circle
    path.set_id(path_id)
  File ".../lib/text/cache.py", line 636, in set_id_mod
    self.croot.iddict[new_id] = self
AttributeError: 'NoneType' object has no attribute 'iddict'

This is happening only after a version upgrade.

To Reproduce Run my code :)

** SVG attachments ** Happy to provide privately.

** Error messages ** See above

** Inkscape version:** Inkscape 1.3 (0e150ed, 2023-07-21)

turing avatar Apr 11 '24 08:04 turing

#inkex.BaseElement.set_id = set_id_mod # type:ignore

Commenting out line 644 fixes my problem (at least temporarily!)

turing avatar Apr 11 '24 16:04 turing

It's failing because the caching added by the text submodule assumes that IDs are set after they are added to documents. Your workaround will probably break a lot of the caching.

For a more robust temporary solution, add the element to the SVG (i.e., insert or append it somewhere) before setting the ID.

burghoff avatar Apr 11 '24 16:04 burghoff

AttributeError: 'NoneType' object has no attribute 'iddict'

is the result of this:

   def outside_circle(origin, radius, eid, label):

        svg_path = ClipPath._rect_circle_cut(
            radius,
            config.SVG.get_page_bbox().width,
            config.SVG.get_page_bbox().height,
            origin
        )
        
        path = inkex.elements.PathElement()
        path.set('d', svg_path)
        path_id = config.SVG.get_unique_id(f"{eid}_path_")
        path_data = svg_path

        clip = inkex.elements.ClipPath()
        clip_id = config.SVG.get_unique_id(f"{eid}_")
        clip.append(path)

        # THIS IS CRITICAL. NOTE THE APPENDING TO DEFS
        config.SVG.defs.append(clip)

        path.set_id(path_id)
        clip.set_id(clip_id)

        path_element = elements.add(path, label) #elements is a structure in my extension, it's being added to the DOM above.
        clip_element = elements.add(clip, label)

The IDs are now set after the elements are added to the SVG, but I get the same result.

turing avatar Apr 11 '24 19:04 turing

The dev version should work now. Let me know if it's fine and I'll close the issue.

burghoff avatar Apr 11 '24 23:04 burghoff

Checked out dev, pulled the lib, getting:

  File "/items.py", line 1036, in create_concentric_clip_group
    clip_subgroup.append(item.inkex_item)
  File "/lib/text/cache.py", line 1384, in append_func
    oldroot = el.croot
AttributeError: 'NoneType' object has no attribute 'croot'

My source:

        svg_path = ClipPath._rect_circle_cut(
            radius,
            config.SVG.get_page_bbox().width,
            config.SVG.get_page_bbox().height,
            origin
        )
        
        path = inkex.elements.PathElement()
        path.set('d', svg_path)
        path_id = config.SVG.get_unique_id(f"{eid}_path_")
        path_data = svg_path

        clip = inkex.elements.ClipPath()
        clip_id = config.SVG.get_unique_id(f"{eid}_")
        clip.append(path)

        # THIS IS CRITICAL. NOTE THE APPENDING TO DEFS
        config.SVG.defs.append(clip)

        path.set_id(path_id)
        clip.set_id(clip_id)

turing avatar Apr 18 '24 18:04 turing

Not replicated—similar code is fine for me (I took out _rect_circle_cut since I don't have that).

It looks like a problem in items.py, as it's trying to append a None to the document somewhere. I don't know what that is, though.

burghoff avatar Apr 18 '24 18:04 burghoff

Note that appending None to a document fails even without the text submodule:

File "sandbox.py", line 115, in effect
    self.svg.append(None)
TypeError: Argument 'element' has incorrect type (expected lxml.etree._Element, got NoneType)

burghoff avatar Apr 18 '24 18:04 burghoff

Nevermind! The second error was my fault! :) Your changes solve the issue.

turing avatar Apr 18 '24 19:04 turing