Skip to content

Commit 9d165e1

Browse files
DYN-8274 PythonScript With Dispose when Exception (#16312)
1 parent e806d54 commit 9d165e1

3 files changed

Lines changed: 230 additions & 0 deletions

File tree

extern/Python/Python.Runtime.dll

512 Bytes
Binary file not shown.

test/Libraries/DynamoPythonTests/PythonEditTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,50 @@ public void Test_With_Exception_Python()
690690
Assert.IsTrue(pythonNode.NodeInfos.FirstOrDefault().Message.Contains(warningMessageExpected));
691691
}
692692

693+
[Test]
694+
public void Test_With_Exception_IDisposeCheck_Python()
695+
{
696+
//This piece of code will generate an exception in PythonScript node
697+
var line_update = "Point.ByCoordinate(10,20)";
698+
var warningMessageExpected = "type object 'Point' has no attribute 'ByCoordinate'";
699+
700+
// open test graph
701+
var examplePath = Path.Combine(TestDirectory, @"core\python", @"withDisposeFFITarget.dyn");
702+
ViewModel.OpenCommand.Execute(examplePath);
703+
ViewModel.HomeSpace.Run();
704+
705+
var watchNode = ViewModel.Model.CurrentWorkspace.Nodes.OfType<Watch>().First();
706+
var pythonNode = ViewModel.Model.CurrentWorkspace.Nodes.OfType<PythonNode>().First();
707+
708+
//Verify that has the value 1 meaning that was disposed the first time
709+
Assert.That(watchNode.OutputData.InitialValue, Is.EqualTo("1"));
710+
711+
712+
var script = pythonNode.Script;
713+
//Replacing this text in the code will generate an exception in the PythonScript node
714+
script = script.Replace("Point.ByCoordinates(10,20)", line_update);
715+
716+
UpdatePythonNodeContent(pythonNode, script);
717+
pythonNode.OnNodeModified();
718+
ViewModel.HomeSpace.Run();
719+
720+
//Verity that we have 1 warning in the python node
721+
Assert.AreEqual(pythonNode.NodeInfos.Count, 1);
722+
//Check that the warning message expected is correct
723+
Assert.IsTrue(pythonNode.NodeInfos.FirstOrDefault().Message.Contains(warningMessageExpected));
724+
725+
//Restore the string in the script for avoiding the exception when running the graph
726+
script = script.Replace(line_update, "Point.ByCoordinates(10,20)");
727+
UpdatePythonNodeContent(pythonNode, script);
728+
pythonNode.OnNodeModified();
729+
ViewModel.HomeSpace.Run();
730+
731+
//Verity that we don't have warnings in the python node
732+
Assert.AreEqual(pythonNode.NodeInfos.Count, 0);
733+
//Verify Watch node has the value 3 meaning that the object was disposed 3 times (even when there was an exception in the second run)
734+
Assert.That(watchNode.OutputData.InitialValue, Is.EqualTo("3"));
735+
}
736+
693737
[Test]
694738
public void CpythonRestart_ReloadsModules()
695739
{
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
{
2+
"Uuid": "ec1123a0-186a-4571-91f7-217331576507",
3+
"IsCustomNode": false,
4+
"Description": "",
5+
"Name": "withDisposeFFITarget",
6+
"ElementResolver": {
7+
"ResolutionMap": {}
8+
},
9+
"Inputs": [],
10+
"Outputs": [],
11+
"Nodes": [
12+
{
13+
"ConcreteType": "PythonNodeModels.PythonNode, PythonNodeModels",
14+
"Code": "import clr\r\nclr.AddReference('FFITarget')\r\nfrom FFITarget import AbstractDerivedDisposeTracer2, AbstractDisposeTracert\r\nclr.AddReference('ProtoGeometry')\r\nfrom Autodesk.DesignScript.Geometry import *\r\n\r\n\r\n\r\nwith AbstractDerivedDisposeTracer2() as test:\r\n test.StupidPlaceHolderMethod()\r\n Point.ByCoordinates(10,20)\r\n \r\nOUT = AbstractDisposeTracert.DisposeCount",
15+
"Engine": "CPython3",
16+
"VariableInputPorts": true,
17+
"Height": 117.0,
18+
"Width": 176.0,
19+
"WidthBorder": 176.0,
20+
"HeightBorder": 117.0,
21+
"Id": "ffb5025ebbbe40fd9b077d07f4558d9b",
22+
"NodeType": "PythonScriptNode",
23+
"Inputs": [
24+
{
25+
"Id": "c274c465a1e149d6960d1783b8361f89",
26+
"Name": "IN[0]",
27+
"Description": "Input #0",
28+
"UsingDefaultValue": false,
29+
"Level": 2,
30+
"UseLevels": false,
31+
"KeepListStructure": false,
32+
"Height": 34.0,
33+
"Width": 100.0,
34+
"WidthBorder": 100.0,
35+
"HeightBorder": 100.0
36+
}
37+
],
38+
"Outputs": [
39+
{
40+
"Id": "c3426226dadb4822953d066cc1c9fbb0",
41+
"Name": "OUT",
42+
"Description": "Result of the python script",
43+
"UsingDefaultValue": false,
44+
"Level": 2,
45+
"UseLevels": false,
46+
"KeepListStructure": false,
47+
"Height": 34.0,
48+
"Width": 100.0,
49+
"WidthBorder": 100.0,
50+
"HeightBorder": 100.0
51+
}
52+
],
53+
"Replication": "Disabled",
54+
"Description": "Runs an embedded Python script."
55+
},
56+
{
57+
"ConcreteType": "CoreNodeModels.Watch, CoreNodeModels",
58+
"WatchWidth": 28.0,
59+
"WatchHeight": 40.0,
60+
"Height": 117.0,
61+
"Width": 129.0,
62+
"WidthBorder": 129.0,
63+
"HeightBorder": 117.0,
64+
"Id": "fa61800d5cbf4ac18ed508029f5e9950",
65+
"NodeType": "ExtensionNode",
66+
"Inputs": [
67+
{
68+
"Id": "81b77fa9854b4756a77baadb954eed72",
69+
"Name": "",
70+
"Description": "Node to show output from",
71+
"UsingDefaultValue": false,
72+
"Level": 2,
73+
"UseLevels": false,
74+
"KeepListStructure": false,
75+
"Height": 34.0,
76+
"Width": 100.0,
77+
"WidthBorder": 100.0,
78+
"HeightBorder": 100.0
79+
}
80+
],
81+
"Outputs": [
82+
{
83+
"Id": "b60b5c4b04ae4ddcb5f2cc729a84d5e6",
84+
"Name": "",
85+
"Description": "Node output",
86+
"UsingDefaultValue": false,
87+
"Level": 2,
88+
"UseLevels": false,
89+
"KeepListStructure": false,
90+
"Height": 34.0,
91+
"Width": 100.0,
92+
"WidthBorder": 100.0,
93+
"HeightBorder": 100.0
94+
}
95+
],
96+
"Replication": "Disabled",
97+
"Description": "Visualizes a node's output"
98+
}
99+
],
100+
"Connectors": [
101+
{
102+
"Start": "c3426226dadb4822953d066cc1c9fbb0",
103+
"End": "81b77fa9854b4756a77baadb954eed72",
104+
"Id": "b4abe77dd1574a35a92bd1e6f9fd00e9",
105+
"IsHidden": "False"
106+
}
107+
],
108+
"Dependencies": [],
109+
"NodeLibraryDependencies": [],
110+
"EnableLegacyPolyCurveBehavior": true,
111+
"Thumbnail": "",
112+
"GraphDocumentationURL": null,
113+
"ExtensionWorkspaceData": [
114+
{
115+
"ExtensionGuid": "28992e1d-abb9-417f-8b1b-05e053bee670",
116+
"Name": "Properties",
117+
"Version": "3.6",
118+
"Data": {}
119+
}
120+
],
121+
"Author": "",
122+
"Linting": {
123+
"activeLinter": "None",
124+
"activeLinterId": "7b75fb44-43fd-4631-a878-29f4d5d8399a",
125+
"warningCount": 0,
126+
"errorCount": 0
127+
},
128+
"Bindings": [],
129+
"View": {
130+
"Dynamo": {
131+
"ScaleFactor": 1.0,
132+
"HasRunWithoutCrash": true,
133+
"IsVisibleInDynamoLibrary": true,
134+
"Version": "3.6.0.6885",
135+
"RunType": "Manual",
136+
"RunPeriod": "1000"
137+
},
138+
"Camera": {
139+
"Name": "_Background Preview",
140+
"EyeX": -17.0,
141+
"EyeY": 24.0,
142+
"EyeZ": 50.0,
143+
"LookX": 12.0,
144+
"LookY": -13.0,
145+
"LookZ": -58.0,
146+
"UpX": 0.0,
147+
"UpY": 1.0,
148+
"UpZ": 0.0
149+
},
150+
"ConnectorPins": [],
151+
"NodeViews": [
152+
{
153+
"Id": "ffb5025ebbbe40fd9b077d07f4558d9b",
154+
"Name": "Python Script",
155+
"IsSetAsInput": false,
156+
"IsSetAsOutput": false,
157+
"Excluded": false,
158+
"ShowGeometry": true,
159+
"X": 122.0,
160+
"Y": 194.0,
161+
"Width": 176.0,
162+
"Height": 117.0,
163+
"WidthBorder": 176.0,
164+
"HeightBorder": 117.0
165+
},
166+
{
167+
"Id": "fa61800d5cbf4ac18ed508029f5e9950",
168+
"Name": "Watch",
169+
"IsSetAsInput": false,
170+
"IsSetAsOutput": false,
171+
"Excluded": false,
172+
"ShowGeometry": true,
173+
"X": 414.0,
174+
"Y": 165.5,
175+
"Width": 129.0,
176+
"Height": 117.0,
177+
"WidthBorder": 129.0,
178+
"HeightBorder": 117.0
179+
}
180+
],
181+
"Annotations": [],
182+
"X": 0.0,
183+
"Y": 0.0,
184+
"Zoom": 1.0
185+
}
186+
}

0 commit comments

Comments
 (0)