Correct non-gui DXF C++ importer to not generate pending python exceptions (#20328)

* Add a test case for DXF import

* Test gui flag rather than look for import error to make gui decision

The new code is cleaner and faster and avoids any exception stuff

* Properly avoid trying to use Layer's View object in non-GUI

The code was trying to avoid this but had a Python None object rather than a null C++ pointer and so tried setting a property on None. This left an unhandled exception state which acted as a booby trap that caused the later failure of some unrelated code.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* De-lint, remove wong "unsupported" message
Hidden layers have been supported for a while but still generated an import note about this being unsupported.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Kevin Martin
2025-03-31 12:20:37 -04:00
committed by GitHub
parent 9153926cbf
commit 0986dadb2f
7 changed files with 2373 additions and 23 deletions

View File

@@ -25,6 +25,7 @@ SET(TestData_SRCS
TestData/bad_xml.xml
TestData/bad_version.xml
TestData/content_items.xml
TestData/DXFSample.dxf
)
SOURCE_GROUP("" FILES ${Test_SRCS} ${TestData_SRCS})

View File

@@ -21,6 +21,7 @@
# * *
# ***************************************************************************/
from plistlib import UID
import FreeCAD, os, unittest, tempfile
from FreeCAD import Base
import math
@@ -671,6 +672,49 @@ class DocumentBasicCases(unittest.TestCase):
FreeCAD.closeDocument("CreateTest")
class DocumentImportCases(unittest.TestCase):
def testDXFImportCPPIssue20195(self):
import importDXF
from draftutils import params
# Set options, doing our best to restore them:
wasShowDialog = params.get_param("dxfShowDialog")
wasUseLayers = params.get_param("dxfUseDraftVisGroups")
wasUseLegacyImporter = params.get_param("dxfUseLegacyImporter")
wasCreatePart = params.get_param("dxfCreatePart")
wasCreateDraft = params.get_param("dxfCreateDraft")
wasCreateSketch = params.get_param("dxfCreateSketch")
try:
# disable Preferences dialog in gui mode (avoids popup prompt to user)
params.set_param("dxfShowDialog", False)
# Preserve the DXF layers (makes the checking of document contents easier)
params.set_param("dxfUseDraftVisGroups", True)
# Use the new C++ importer -- that's where the bug was
params.set_param("dxfUseLegacyImporter", False)
# create simple part shapes (3 params)
# This is required to display the bug because creation of Draft objects clears out the
# pending exception this test is looking for, whereas creation of the simple shape object
# actually throws on the pending exception so the entity is absent from the document.
params.set_param("dxfCreatePart", True)
params.set_param("dxfCreateDraft", False)
params.set_param("dxfCreateSketch", False)
importDXF.insert(
FreeCAD.getHomePath() + "Mod/Test/TestData/DXFSample.dxf", "ImportedDocName"
)
finally:
params.set_param("dxfShowDialog", wasShowDialog)
params.set_param("dxfUseDraftVisGroups", wasUseLayers)
params.set_param("dxfUseLegacyImporter", wasUseLegacyImporter)
params.set_param("dxfCreatePart", wasCreatePart)
params.set_param("dxfCreateDraft", wasCreateDraft)
params.set_param("dxfCreateSketch", wasCreateSketch)
doc = FreeCAD.getDocument("ImportedDocName")
# This doc should ahve 3 objects: The Layers containter, the DXF layer called 0, and one Line
self.assertEqual(len(doc.Objects), 3)
FreeCAD.closeDocument("ImportedDocName")
# class must be defined in global scope to allow it to be reloaded on document open
class SaveRestoreSpecialGroup:
def __init__(self, obj):

File diff suppressed because it is too large Load Diff