KeyError on importing dxf with unicode layer names

Bug #1472429 reported by Peter Dat on 2015-07-07
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Inkscape
Undecided
Alvin Penner

Bug Description

This is the exception:

Traceback (most recent call last):
  File "dxf_input.py", line 477, in <module>
    layer = layer_nodes[vals[groups['8']][0]]
KeyError: u'\u9884\u8bbe\u56fe\u5c42'

This is the importer:

(35794) % md5sum /usr/share/inkscape/extensions/dxf_input.py
3f2618d8bbefb24d7151b849d9fb8001 /usr/share/inkscape/extensions/dxf_input.py

from:
inkscape 0.91-9

Here's the python version:
(35799) % python2 --version
Python 2.7.10

Last, this is a snippet from the dxf
...
AcDbLayerTableRecord
  2
\U+9884\U+8BBE\U+56FE\U+5C42
 70
     0
 62
     7
  6
...

renaming the layer to an ascii string in editor heals the problem.

su_v (suv-lp) wrote :

Please attach a small test case (DXF file) to ease testing on other systems, thank you.

tags: added: encoding importing
removed: importer unicode
Changed in inkscape:
status: New → Incomplete
su_v (suv-lp) wrote :

Closing due to lack of test case (no further feedback by the reporter).

Feel free to reopen and attach a DXF file which can serve as test case to fix the reported issue.

Changed in inkscape:
status: Incomplete → Invalid
Michael Thomson (ubuntu-net) wrote :

Hi folks

I hit a similar problem as well, from DXF generated by SolveSpace version 2.1 running on MacOS X 10.11.5

When the attached file (Rectangle.dxf) is opened in Inkscape 0.91 on the same platform I get this error:

Traceback (most recent call last):
  File "dxf_input.py", line 477, in <module>
    layer = layer_nodes[vals[groups['8']][0]]
KeyError: u's001-#def-active-grp'

Editing the file (see Rectangle_fixed.dxf) to change this value (at line 1966) resolves the problem, but the only working value I found was 0 (zero), unquoted.

Any other numeric or string constant generated a similar error.

su_v (suv-lp) on 2016-05-20
Changed in inkscape:
status: Invalid → New
Michael Thomson (ubuntu-net) wrote :

The same Rectangle.dxf does import correctly into FreeCAD 0.16, whose DXF import is also written in Python and maintained by Yorik here: https://github.com/yorikvanhavre/Draft-dxf-importer
While I'm sure its internal implementation will be different it might offer some inspiration for how it handles labelled elements?

Alvin Penner (apenner) wrote :

 Attached is a modified version of a dxf file which contains the desired layer name and loads correctly into Inkscape. The original file contained a layer name called 'text' which had been declared but not used, so I renamed it to be 's001-#def-active-grp', which fixes the problem temporarily.
 The 'normal' usage for a layer name is that it will be declared once in the 'TABLE' section of the dxf file. In this declaration it will be associated with other attributes like default color for example. Then the same layer name may be used multiple times in the 'ENTITIES' section where it will be associated with specific objects. The Inkscape dxf import code, unfortunately, was written in such a way that the original declaration in the TABLE section is mandatory and the program will crash if it does not exist. The file 'Rectangle.dxf' does not follow this convention, therefore it crashes.
 I'll take a look at the code to see if this condition can be relaxed. or at the very least, perhaps a more user-friendly warning can be issued. It has been some years since I looked at this, so it may take a week or so to come up with a proposal.

Changed in inkscape:
status: New → Confirmed
Michael Thomson (ubuntu-net) wrote :

Fast work, thanks. So the SolveSpace DXF export is failing to initially declare the layer name 's001-#def-active-grp' but subsequently has objects that use it. I can see how that would cause SNAFUs.

Does this mean I should [alternatively|in parallel] raise a bug with the SolveSpace project instead?

Michael Thomson (ubuntu-net) wrote :

Hmmm - would it be reasonable to look for the layer name in the table, but if not found, default to layer '0' (which, presumably, can be guaranteed to exist, after your code at line 420?)

e.g. something like

if layer_nodes.has_key(vals[groups['8']][0]):
    layer = layer_nodes[vals[groups['8']][0]]
else:
    layer = layer_nodes['0']

Alvin Penner (apenner) wrote :

attached is a proposed modification of the file dxf_input.py. This version will create a new layer automatically if the layer had not been previously declared in the TABLE section.

If testing this code under Inkscape 0.91, it will be necessary to also obtain an uptodate version of the file dxf_input.inx from:
http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/files/head:/share/extensions/

Michael Thomson (ubuntu-net) wrote :

Hooray! I can confirm that this works, with an unmodified file from the SolveSpace application that doesn't have TABLE entries for its layers.

Thanks for the super-fast response Alvin. Hope to see this in the next Inkscape release.

Alvin Penner (apenner) wrote :

good to hear, fix committed to rev 14910

Changed in inkscape:
status: Confirmed → Fix Committed
assignee: nobody → Alvin Penner (apenner)
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers