Deep python bug. Changing an object via propertyLink may touch unnecessary stuff [fix proposed]

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

Fixing this caused ScrewMaker to not work properly. See https://forum.freecadweb.org/viewtopic.php?f=10&t=21039
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

I think I'm experiencing this bug again. I'm trying to recover one old project. And recomputing it with Part-o-magic observer running causes dependency graph to change (a loop is created). I need to investigate it more, this may take me forever to come up with a decent steps-to-reproduce sequence.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

Currently, steps to reproduce are:
1 install Part-o-magic and Lattice2 (make sure to have the latest Lattice2, otherwise recompute fails now I patched Lattice to work around this bug)
2 open this file
grinder v02.FCStd
(438.34 KiB) Downloaded 27 times
It's a bit broken, because it has some old experimental containers. You can ignore that, as the dependencies look like all right.
3 right-click "Sketch - master section", Mark To Recompute
4 Recompute. The project recomputes fine.
But! the project just got a dependency loop, which can be seen in dependency graph. Any further recomputes are impossible.

Observations.
* pausing part-o-magic's observer before step 4 removes the problem.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

Progress...
Uninstalled part-o-magic, but problem is still there!
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

In debugger, I get lots of writes to link properties.
For example. (this write doesn't cause problems by itself, but it shouldn't happen!)

Code: Select all

0	App::Property::aboutToSetValue	Property.cpp	132	0x7fff4db490da	
1	App::PropertyLink::setValue	PropertyLinks.cpp	83	0x7fff4db6526d	
2	App::PropertyLink::setPyObject	PropertyLinks.cpp	109	0x7fff4db6555d	
3	App::DocumentObjectPy::setCustomAttributes	DocumentObjectPyImp.cpp	326	0x7fff4da72437	
4	App::DocumentObjectPy::_setattr	DocumentObjectPy.cpp	1112	0x7fff4da72809	
5	Part::PartFeaturePy::_setattr	PartFeaturePy.cpp	344	0x7fff48376e7a	
6	App::FeaturePythonPyT<Part::PartFeaturePy>::_setattr	FeaturePythonPyImp.inl	124	0x7fff4828f02c	
7	Base::PyObjectBase::__setattr	PyObjectBase.cpp	206	0x7fff4d647b47	
8	Base::PyObjectBase::startNotify	PyObjectBase.cpp	342	0x7fff4d647e84	
9	App::PropertyContainerPy::staticCallback_setEditorMode	PropertyContainerPy.cpp	398	0x7fff4db510da	
10	PyCFunction_Call	methodobject.c	81	0x1e17dd18	
11	call_function	ceval.c	4033	0x1e21c934	
12	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
13	PyEval_EvalCodeEx	ceval.c	3265	0x1e214dff	
14	fast_function	ceval.c	4133	0x1e21deea	
15	call_function	ceval.c	4055	0x1e21ca19	
16	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
17	fast_function	ceval.c	4120	0x1e21de4f	
18	call_function	ceval.c	4055	0x1e21ca19	
19	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
20	fast_function	ceval.c	4120	0x1e21de4f	
21	call_function	ceval.c	4055	0x1e21ca19	
22	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
23	PyEval_EvalCodeEx	ceval.c	3265	0x1e214dff	
24	function_call	funcobject.c	531	0x1e15cb1d	
25	PyObject_Call	abstract.c	2529	0x1e10bddb	
26	instancemethod_call	classobject.c	2602	0x1e12b749	
27	PyObject_Call	abstract.c	2529	0x1e10bddb	
28	PyEval_CallObjectWithKeywords	ceval.c	3903	0x1e214426	
29	PyObject_CallObject	abstract.c	2518	0x1e10c360	
30	Py::Callable::apply	Objects.hxx	3227	0x7fff4d54dcba	
31	App::FeaturePythonImp::execute	FeaturePython.cpp	79	0x7fff4dae32ac	
32	App::FeaturePythonT<Part::Feature>::execute	FeaturePython.h	89	0x7fff4828fb12	
33	App::DocumentObject::recompute	DocumentObject.cpp	78	0x7fff4da4385f	
34	Part::Feature::recompute	PartFeature.cpp	83	0x7fff48283b0b	
35	App::Document::_recomputeFeature	Document.cpp	2078	0x7fff4d917497	
36	App::Document::recompute	Document.cpp	1945	0x7fff4d90fc19	
37	App::DocumentPy::recompute	DocumentPyImp.cpp	387	0x7fff4da8b158	
38	App::DocumentPy::staticCallback_recompute	DocumentPy.cpp	1695	0x7fff4da8b032	
39	PyCFunction_Call	methodobject.c	81	0x1e17dd18	
40	call_function	ceval.c	4033	0x1e21c934	
41	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
42	PyEval_EvalCodeEx	ceval.c	3265	0x1e214dff	
43	PyEval_EvalCode	ceval.c	679	0x1e2144a9	
44	run_mod	pythonrun.c	1377	0x1e278ed9	
45	PyRun_StringFlags	pythonrun.c	1340	0x1e27655d	
46	Base::InterpreterSingleton::runString	Interpreter.cpp	196	0x7fff4d5c1325	
47	Gui::Command::doCommand	Command.cpp	475	0x7fff4c138990	
48	StdCmdRefresh::activated	CommandDoc.cpp	1202	0x7fff4c15e479	
49	Gui::Command::invoke	Command.cpp	300	0x7fff4c137ebe	
50	Gui::Action::onActivated	Action.cpp	95	0x7fff4c1233de	
51	Gui::Action::qt_static_metacall	moc_Action.cpp	49	0x7fff4c1228e1	
52	QBuffer::qt_static_metacall	QtCored4		0x5eaab109	
53	QAbstractItemView::qt_metacast	QtGuid4		0x5ee0a5dd	
54	QAbstractItemView::qt_metacast	QtGuid4		0x5ee09a0d	
55	QAbstractItemView::qt_metacast	QtGuid4		0x5ee2f595	
56	QAbstractItemView::qt_metacast	QtGuid4		0x5f62ad84	
57	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d2c67	
58	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d1d46	
59	QAbstractItemView::qt_metacast	QtGuid4		0x5f62a89c	
60	QAbstractItemView::qt_metacast	QtGuid4		0x5eedd556	
61	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d1879	
62	QAbstractItemView::qt_metacast	QtGuid4		0x5f62a6da	
63	QAbstractItemView::qt_metacast	QtGuid4		0x5ee3bbf6	
64	QAbstractItemView::qt_metacast	QtGuid4		0x5ee36f26	
65	Gui::GUIApplication::notify	GuiApplication.cpp	91	0x7fff4c0e0fb2	
66	QBuffer::qt_static_metacall	QtCored4		0x5ea8a1ca	
67	QBuffer::qt_static_metacall	QtCored4		0x5eb53a6c	
68	QAbstractItemView::qt_metacast	QtGuid4		0x5ee3dac6	
69	QAbstractItemView::qt_metacast	QtGuid4		0x5ef2877f	
70	QAbstractItemView::qt_metacast	QtGuid4		0x5ef23991	
71	CallWindowProcW	USER32		0x7fff81641c24	
72	DispatchMessageW	USER32		0x7fff8164156c	
73	QBuffer::qt_static_metacall	QtCored4		0x5eadeef8	
74	QAbstractItemView::qt_metacast	QtGuid4		0x5ef2c875	
75	QBuffer::qt_static_metacall	QtCored4		0x5ea85f24	
76	QBuffer::qt_static_metacall	QtCored4		0x5ea86207	
77	QBuffer::qt_static_metacall	QtCored4		0x5ea8824c	
78	QAbstractItemView::qt_metacast	QtGuid4		0x5ee361c8	
79	Gui::Application::runApplication	Application.cpp	1778	0x7fff4bf9e767	
80	main	MainGui.cpp	239	0x7ff7458935c5	
81	WinMain	FreeCAD_d		0x7ff7458a32d1	
82	__tmainCRTStartup	crtexe.c	618	0x7ff7458a1391	
83	WinMainCRTStartup	crtexe.c	466	0x7ff7458a110e	
84	BaseThreadInitThunk	KERNEL32		0x7fff81d48364	
85	RtlUserThreadStart	ntdll		0x7fff81e570d1	
This goes like that: LinearArray recomputes. It intensely updates read-onlyness of its own properties (calls setEditorMode()). Populate004 has a link property pointing to the LinearArray. And when LinearArray updates, it is modified, which for some reason triggers reassignment of Populate004's link to it.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff

Post by DeepSOIC »

Now this trace seems to be the actual culprit, but I struggle to understand where it comes from.

Code: Select all

0	App::Property::aboutToSetValue	Property.cpp	132	0x7fff4db490da	
1	App::PropertyLink::setValue	PropertyLinks.cpp	83	0x7fff4db6526d	
2	App::PropertyLink::setPyObject	PropertyLinks.cpp	109	0x7fff4db6555d	
3	App::DocumentObjectPy::setCustomAttributes	DocumentObjectPyImp.cpp	357	0x7fff4da725f9	
4	App::DocumentObjectPy::_setattr	DocumentObjectPy.cpp	1112	0x7fff4da72809	
5	Part::PartFeaturePy::_setattr	PartFeaturePy.cpp	344	0x7fff48376e7a	
6	Base::PyObjectBase::__setattr	PyObjectBase.cpp	206	0x7fff4d647b47	
7	Base::PyObjectBase::startNotify	PyObjectBase.cpp	342	0x7fff4d647e84	
8	Base::PyObjectBase::__setattr	PyObjectBase.cpp	212	0x7fff4d647b83	
9	Base::PyObjectBase::startNotify	PyObjectBase.cpp	342	0x7fff4d647e84	
10	Base::PyObjectBase::__setattr	PyObjectBase.cpp	212	0x7fff4d647b83	
11	Base::PyObjectBase::startNotify	PyObjectBase.cpp	342	0x7fff4d647e84	
12	Base::PyObjectBase::__setattr	PyObjectBase.cpp	212	0x7fff4d647b83	
13	PyObject_SetAttr	object.c	1252	0x1e180ac8	
14	PyEval_EvalFrameEx	ceval.c	2018	0x1e2188ec	
15	PyEval_EvalCodeEx	ceval.c	3265	0x1e214dff	
16	PyEval_EvalCode	ceval.c	679	0x1e2144a9	
17	run_mod	pythonrun.c	1377	0x1e278ed9	
18	PyRun_StringFlags	pythonrun.c	1340	0x1e27655d	
19	Base::InterpreterSingleton::runString	Interpreter.cpp	196	0x7fff4d5c1325	
20	App::ObjectIdentifier::setValue	ObjectIdentifier.cpp	1103	0x7fff4db4109f	
21	App::Property::setPathValue	Property.cpp	90	0x7fff4db48a57	
22	App::PropertyExpressionEngine::execute	PropertyExpressionEngine.cpp	604	0x7fff4dbb1510	
23	App::Document::_recomputeFeature	Document.cpp	2067	0x7fff4d9173bd	
24	App::Document::recompute	Document.cpp	1945	0x7fff4d90fc19	
25	App::DocumentPy::recompute	DocumentPyImp.cpp	387	0x7fff4da8b158	
26	App::DocumentPy::staticCallback_recompute	DocumentPy.cpp	1695	0x7fff4da8b032	
27	PyCFunction_Call	methodobject.c	81	0x1e17dd18	
28	call_function	ceval.c	4033	0x1e21c934	
29	PyEval_EvalFrameEx	ceval.c	2681	0x1e21a2ca	
30	PyEval_EvalCodeEx	ceval.c	3265	0x1e214dff	
31	PyEval_EvalCode	ceval.c	679	0x1e2144a9	
32	run_mod	pythonrun.c	1377	0x1e278ed9	
33	PyRun_StringFlags	pythonrun.c	1340	0x1e27655d	
34	Base::InterpreterSingleton::runString	Interpreter.cpp	196	0x7fff4d5c1325	
35	Gui::Command::doCommand	Command.cpp	475	0x7fff4c138990	
36	StdCmdRefresh::activated	CommandDoc.cpp	1202	0x7fff4c15e479	
37	Gui::Command::invoke	Command.cpp	300	0x7fff4c137ebe	
38	Gui::Action::onActivated	Action.cpp	95	0x7fff4c1233de	
39	Gui::Action::qt_static_metacall	moc_Action.cpp	49	0x7fff4c1228e1	
40	QBuffer::qt_static_metacall	QtCored4		0x5eaab109	
41	QAbstractItemView::qt_metacast	QtGuid4		0x5ee0a5dd	
42	QAbstractItemView::qt_metacast	QtGuid4		0x5ee09a0d	
43	QAbstractItemView::qt_metacast	QtGuid4		0x5ee2f595	
44	QAbstractItemView::qt_metacast	QtGuid4		0x5f62ad84	
45	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d2c67	
46	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d1d46	
47	QAbstractItemView::qt_metacast	QtGuid4		0x5f62a89c	
48	QAbstractItemView::qt_metacast	QtGuid4		0x5eedd556	
49	QAbstractItemView::qt_metacast	QtGuid4		0x5f4d1879	
50	QAbstractItemView::qt_metacast	QtGuid4		0x5f62a6da	
51	QAbstractItemView::qt_metacast	QtGuid4		0x5ee3bbf6	
52	QAbstractItemView::qt_metacast	QtGuid4		0x5ee36f26	
53	Gui::GUIApplication::notify	GuiApplication.cpp	91	0x7fff4c0e0fb2	
54	QBuffer::qt_static_metacall	QtCored4		0x5ea8a1ca	
55	QBuffer::qt_static_metacall	QtCored4		0x5eb53a6c	
56	QAbstractItemView::qt_metacast	QtGuid4		0x5ee3dac6	
57	QAbstractItemView::qt_metacast	QtGuid4		0x5ef2877f	
58	QAbstractItemView::qt_metacast	QtGuid4		0x5ef23991	
59	CallWindowProcW	USER32		0x7fff81641c24	
60	DispatchMessageW	USER32		0x7fff8164156c	
61	QBuffer::qt_static_metacall	QtCored4		0x5eadeef8	
62	QAbstractItemView::qt_metacast	QtGuid4		0x5ef2c875	
63	QBuffer::qt_static_metacall	QtCored4		0x5ea85f24	
64	QBuffer::qt_static_metacall	QtCored4		0x5ea86207	
65	QBuffer::qt_static_metacall	QtCored4		0x5ea8824c	
66	QAbstractItemView::qt_metacast	QtGuid4		0x5ee361c8	
67	Gui::Application::runApplication	Application.cpp	1778	0x7fff4bf9e767	
68	main	MainGui.cpp	239	0x7ff7458935c5	
69	WinMain	FreeCAD_d		0x7ff7458a32d1	
70	__tmainCRTStartup	crtexe.c	618	0x7ff7458a1391	
71	WinMainCRTStartup	crtexe.c	466	0x7ff7458a110e	
72	BaseThreadInitThunk	KERNEL32		0x7fff81d48364	
73	RtlUserThreadStart	ntdll		0x7fff81e570d1	
Somehow, Extrude's link property is modified as a result of expression engine executing this python string:
"App.getDocument('grinder_v02').getObject('Extrude').Dir.z = 0.25"
I still don't quite get, how it ends up modifying Extrude's link property...
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff [reopened]

Post by DeepSOIC »

Now narrowed down so no external workbench is required.
1. Load:
grinder_v02_strpped3.FCStd
(89.85 KiB) Downloaded 32 times
2. right-click Spreadsheet, Mark to recompute.
3. Recompute.
-> recomputes fine, but dependency loop Extrude<=>Slice is created.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff [reopened]

Post by DeepSOIC »

User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff [reopened]

Post by DeepSOIC »

Shorter.
1. Open file.
2. run:

Code: Select all

App.ActiveDocument.getObject("Extrude").Dir.z = 0
-> graph changes.

EDIT: this does it too: App.ActiveDocument.getObject("Extrude").Label = "test"
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Deep python bug. Changing an object via propertyLink may touch unnecessary stuff [reopened]

Post by DeepSOIC »

I think this one is a more controlled way of reproducing the bug.
1. Load file.
2. run code:

Code: Select all

#reset all notification chains
App.ActiveDocument.Fusion
App.ActiveDocument.Sketch010
App.ActiveDocument.Extrude
App.ActiveDocument.Slice
App.ActiveDocument.CompoundFilter

#controlled sequence to recreate bug
extrude = App.ActiveDocument.Extrude
slice = App.ActiveDocument.Slice
filt = App.ActiveDocument.CompoundFilter
slice.Base
filt.Base
extrude.Label = "test"
-> graph changes.
Attachments
grinder_v02_strpped3.FCStd
(same file as before, just attached again for convenience)
(89.85 KiB) Downloaded 24 times
Post Reply