diff --git a/src/IronPythonExtension/IronPythonExtension.cs b/src/IronPythonExtension/IronPythonExtension.cs deleted file mode 100644 index 38babc3b8ef..00000000000 --- a/src/IronPythonExtension/IronPythonExtension.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using Dynamo.Extensions; -using Dynamo.Logging; -using Dynamo.PythonServices; - -namespace IronPythonExtension -{ - /// - /// This extension does nothing but loading DSIronPython to make IronPython engine - /// available as one alternative Python evaluation option - /// - public class IronPythonExtension : IExtension, ILogSource - { - private const string PythonEvaluatorAssembly = "DSIronPython"; - - /// - /// Dispose function - /// - public void Dispose() - { - // Do nothing for now - } - - /// - /// Extension unique GUID - /// - public string UniqueId => "D7B449D7-4D54-47EF-B742-30C7BEDFBE92"; - - /// - /// Extension name - /// - public string Name => "IronPythonExtension"; - - #region ILogSource - - public event Action MessageLogged; - internal void OnMessageLogged(ILogMessage msg) - { - if (this.MessageLogged != null) - { - MessageLogged?.Invoke(msg); - } - } - #endregion - - /// - /// Action to be invoked when Dynamo begins to start up. - /// - /// - public void Startup(StartupParams sp) - { - // Do nothing for now - } - - /// - /// Action to be invoked when the Dynamo has started up and is ready - /// for user interaction. - /// - /// - public void Ready(ReadyParams sp) - { - // Searches for DSIronPython engine binary in same folder with extension itself - var targetDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(IronPythonExtension)).Location); - var libraryLoader = sp.StartupParams.LibraryLoader; - Assembly pythonEvaluatorLib = null; - try - { - pythonEvaluatorLib = Assembly.LoadFrom(Path.Combine(targetDir, PythonEvaluatorAssembly + ".dll")); - } - catch (Exception ex) - { - // Most likely the IronPython engine is excluded in this case - // but logging the exception message in case for diagnose - OnMessageLogged(LogMessage.Info(ex.Message)); - return; - } - // Import IronPython Engine into VM, so Python node using IronPython engine could evaluate correctly - if (pythonEvaluatorLib != null) - { - libraryLoader.LoadNodeLibrary(pythonEvaluatorLib); - } - } - - /// - /// Action to be invoked when shutdown has begun. - /// - public void Shutdown() - { - // Do nothing for now - } - } -} diff --git a/src/IronPythonExtension/IronPythonExtension.csproj b/src/IronPythonExtension/IronPythonExtension.csproj deleted file mode 100644 index 6eaba61943e..00000000000 --- a/src/IronPythonExtension/IronPythonExtension.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - {182FCA4E-B6EF-451F-9EC4-7BF2C622F4F7} - Library - Properties - IronPythonExtension - IronPythonExtension - - - - {7858fa8c-475f-4b8e-b468-1f8200778cf8} - DynamoCore - False - - - {8872ca17-c10d-43b9-8393-5c5a57065eb0} - PythonNodeModels - False - - - {ef879a10-041d-4c68-83e7-3192685f1bae} - DynamoServices - False - - - - - - - - - - - - \ No newline at end of file diff --git a/src/IronPythonExtension/IronPythonExtension_ExtensionDefinition.xml b/src/IronPythonExtension/IronPythonExtension_ExtensionDefinition.xml deleted file mode 100644 index e2eb061ebad..00000000000 --- a/src/IronPythonExtension/IronPythonExtension_ExtensionDefinition.xml +++ /dev/null @@ -1,4 +0,0 @@ - - ..\IronPythonExtension.dll - IronPythonExtension.IronPythonExtension - \ No newline at end of file diff --git a/src/IronPythonExtension/Properties/AssemblyInfo.cs b/src/IronPythonExtension/Properties/AssemblyInfo.cs deleted file mode 100644 index 20b6fa9f71a..00000000000 --- a/src/IronPythonExtension/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("IronPythonExtension")] -[assembly: AssemblyCulture("")] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("182fca4e-b6ef-451f-9ec4-7bf2c622f4f7")] diff --git a/src/Libraries/DSCPython/CPythonEvaluator.cs b/src/Libraries/DSCPython/CPythonEvaluator.cs index 5565f11aff0..4b792f15e03 100644 --- a/src/Libraries/DSCPython/CPythonEvaluator.cs +++ b/src/Libraries/DSCPython/CPythonEvaluator.cs @@ -131,13 +131,6 @@ public void Dispose() } } - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use Dynamo.PythonServices.EvaluationState instead.")] - public enum EvaluationState { Begin, Success, Failed } - - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use evaluation handlers from Dynamo.PythonServices instead.")] - public delegate void EvaluationEventHandler(EvaluationState state, PyScope scope, string code, IList bindingValues); /// /// Evaluates a Python script in the Dynamo context. @@ -624,12 +617,7 @@ private static bool IsMarkedToSkipConversion(PyObject pyObj) #region Evaluation events - /// - /// Emitted immediately before execution begins - /// - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use EvaluationStarted instead")] - public static event EvaluationEventHandler EvaluationBegin; + /// @@ -638,13 +626,6 @@ private static bool IsMarkedToSkipConversion(PyObject pyObj) [SupressImportIntoVM] public override event EvaluationStartedEventHandler EvaluationStarted; - /// - /// Emitted immediately after execution ends or fails - /// - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use EvaluationFinished instead.")] - public static event EvaluationEventHandler EvaluationEnd; - /// /// Emitted immediately after execution ends or fails /// @@ -661,8 +642,6 @@ private void OnEvaluationBegin(PyScope scope, string code, IList bindingValues) { - // Call deprecated events until they are completely removed. - EvaluationBegin?.Invoke(EvaluationState.Begin, scope, code, bindingValues); if (EvaluationStarted != null) { @@ -686,11 +665,7 @@ private void OnEvaluationEnd(bool isSuccessful, string code, IList bindingValues) { - // Call deprecated events until they are completely removed. - EvaluationEnd?.Invoke(isSuccessful ? - EvaluationState.Success : - EvaluationState.Failed, scope, code, bindingValues); - + if (EvaluationFinished != null) { EvaluationFinished(isSuccessful ? Dynamo.PythonServices.EvaluationState.Success : Dynamo.PythonServices.EvaluationState.Failed, diff --git a/src/Libraries/DSIronPython/DSIronPython.csproj b/src/Libraries/DSIronPython/DSIronPython.csproj deleted file mode 100644 index 72c374e4b49..00000000000 --- a/src/Libraries/DSIronPython/DSIronPython.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - {9EEF4F42-6B3B-4358-9A8A-C2701539A822} - Library - Properties - DSIronPython - DSIronPython - - - - - - - - - - - - - - - - - - {7858FA8C-475F-4B8E-B468-1F8200778CF8} - DynamoCore - False - - - {b5f435cb-0d8a-40b1-a4f7-5ecb3ce792a9} - DynamoUtilities - False - - - {ef879a10-041d-4c68-83e7-3192685f1bae} - DynamoServices - False - - - {c0d6dee5-5532-4345-9c66-4c00d7fdb8be} - DesignScriptBuiltin - False - - - - - - - - - \ No newline at end of file diff --git a/src/Libraries/DSIronPython/IronPythonCodeCompletionDataCore.cs b/src/Libraries/DSIronPython/IronPythonCodeCompletionDataCore.cs deleted file mode 100644 index 95da5ed0b72..00000000000 --- a/src/Libraries/DSIronPython/IronPythonCodeCompletionDataCore.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Autodesk.DesignScript.Interfaces; -using Dynamo.PythonServices; - -namespace DSIronPython -{ - /// - /// Concrete type that gets returned and converted to an Avalonedit type implementing - /// ICompletionData when used from WPF ScriptEditorContorl. - /// - internal class IronPythonCodeCompletionDataCore : PythonCodeCompletionDataCore - { - public IronPythonCodeCompletionDataCore(string text, string stub, bool isInstance, - ExternalCodeCompletionType completionType, IExternalCodeCompletionProviderCore providerCore) : - base(text, stub, isInstance, completionType, providerCore) - { - } - } -} diff --git a/src/Libraries/DSIronPython/IronPythonCodeCompletionProviderCore.cs b/src/Libraries/DSIronPython/IronPythonCodeCompletionProviderCore.cs deleted file mode 100644 index 7d8cccc1cd7..00000000000 --- a/src/Libraries/DSIronPython/IronPythonCodeCompletionProviderCore.cs +++ /dev/null @@ -1,488 +0,0 @@ -using Autodesk.DesignScript.Interfaces; -using Dynamo.Logging; -using Dynamo.PythonServices; -using IronPython.Runtime; -using IronPython.Runtime.Types; -using Microsoft.Scripting; -using Microsoft.Scripting.Actions; -using Microsoft.Scripting.Hosting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; - -namespace DSIronPython -{ - internal class IronPythonCodeCompletionProviderCore : PythonCodeCompletionProviderCommon, ILegacyPythonCompletionCore, ILogSource, IDisposable - { - #region Private Members - internal static readonly string clrTypeLookup = "clr.GetClrType({0}) if (\"{0}\" in locals() or \"{0}\" in __builtins__) and isinstance({0}, type) else None"; - - private ScriptEngine engine; - /// - /// The engine used for autocompletion. This essentially keeps - /// track of the state of the editor, allowing access to variable types and - /// imported symbols. - /// - private ScriptScope scope; - #endregion - - #region BACKING LEGACY CLASS DO NOT MODIFY UNTIL 3 - //ILegacyPythonCompletionCore implementations - //!!!- do not modify these signatures until that class is removed. - //We do not know if anyone was using that class, but we needed to remove the compile - //time references between PythonNodeModels and DSIronPython to support dynamically loading - //python versions. - - //note that the public members below are not really public (this is an internal class) - //but must be marked that way to satisfy the legacy interface - - /// - /// The engine used for autocompletion. This essentially keeps - /// track of the state of the editor, allowing access to variable types and - /// imported symbols. - /// - public object Engine - { - get { return engine; } - set { engine = (ScriptEngine)value; } - } - /// - /// The scope used by the engine. This is where all the loaded symbols - /// are stored. It's essentially an environment dictionary. - /// - public object Scope - { - get { return scope; } - set { scope = (ScriptScope)value; } - } - /// - /// List all of the members in a CLR Namespace - /// - /// A reference to the module - /// The name of the module - /// A list of completion data for the namespace - public IEnumerable> EnumerateMembersFromTracker(object nameSpaceTracker, string name) - { - var items = new List>(); - var ns = nameSpaceTracker as NamespaceTracker; - foreach (var member in ns) - { - if (member.Value is NamespaceTracker) - { - items.Add(Tuple.Create(member.Key, name, false, ExternalCodeCompletionType.Namespace)); - } - else if (member.Value is FieldTracker) - { - items.Add(Tuple.Create(member.Key, name, false, ExternalCodeCompletionType.Field)); - } - else if (member.Value is PropertyTracker) - { - items.Add(Tuple.Create(member.Key, name, false, ExternalCodeCompletionType.Property)); - } - else if (member.Value is TypeTracker) - { - items.Add(Tuple.Create(member.Key, name, false, ExternalCodeCompletionType.Class)); - } - } - - return items; - } - public new IEnumerable> EnumerateMembers(Type type, string name) - { - return base.EnumerateMembers(type, name); - } - /// - /// List all of the members in a PythonModule - /// - /// A reference to the module - /// The name of the module - /// A list of completion data for the module - public IEnumerable> EnumerateMembers(object module, string name) - { - var items = new List>(); - var d = (module as PythonModule).Get__dict__(); - - foreach (var member in d) - { - var completionType = member.Value is BuiltinFunction ? ExternalCodeCompletionType.Method : ExternalCodeCompletionType.Field; - items.Add(Tuple.Create((string)member.Key, name, false, completionType)); - } - - return items; - } - /// - /// Recursively lookup a member in a given namespace. - /// - /// A name for a type, possibly delimited by periods. - /// The namespace - /// The type as an object - public object LookupMember(string name, object nameSpaceTracker) - { - if (!(nameSpaceTracker is NamespaceTracker)) - { - throw new ArgumentException("parameter n must be of type NameSpaceTracker"); - } - var nst = nameSpaceTracker as NamespaceTracker; - object varOutput; - - var periodIndex = name.IndexOf('.'); - if (periodIndex == -1) - { - if (nst.TryGetValue(name, out varOutput)) - { - return varOutput; - } - return null; - } - - var currentName = name.Substring(0, periodIndex); - var theRest = name.Substring(periodIndex + 1); - - if (nst.TryGetValue(currentName, out varOutput)) - { - if (varOutput is NamespaceTracker) - { - return LookupMember(theRest, varOutput as NamespaceTracker); - } - } - return null; - } - /// - /// Recursively lookup a variable in the _scope - /// - /// A name for a type, possibly delimited by periods. - /// The type as an object - public object LookupMember(string name) - { - object varOutput; - - var periodIndex = name.IndexOf('.'); - if (periodIndex == -1) - { - if (scope.TryGetVariable(name, out varOutput)) - { - return varOutput; - } - return null; - } - var currentName = name.Substring(0, periodIndex); - var theRest = name.Substring(periodIndex + 1); - - if (scope.TryGetVariable(currentName, out varOutput)) - { - if (varOutput is NamespaceTracker) - { - return LookupMember(theRest, varOutput as NamespaceTracker); - } - } - return null; - - } - public new void UpdateImportedTypes(string code) - { - base.UpdateImportedTypes(code); - } - public new void UpdateVariableTypes(string code) - { - base.UpdateVariableTypes(code); - } - public new Dictionary FindAllVariableAssignments(string code) - { - return base.FindAllVariableAssignments(code); - } - public new Dictionary> FindAllVariables(string code) - { - return base.FindAllVariables(code); - } - public new Type TryGetType(string name) - { - return base.TryGetType(name); - } - #endregion - - #region PythonCodeCompletionProviderCommon implementations - /// - /// Generate completion data for the specified text, while import the given types into the - /// scope and discovering variable assignments. - /// - /// The code to parse - /// Determines if the entire namespace should be used - /// Return a list of IExternalCodeCompletionData - public override IExternalCodeCompletionData[] GetCompletionData(string code, bool expand = false) - { - IEnumerable items = new List(); - - if (code.Contains("\"\"\"")) - { - code = StripDocStrings(code); - } - - UpdateImportedTypes(code); - UpdateVariableTypes(code); // Possibly use hindley-milner in the future - - // If expand param is true use the entire namespace from the line of code - // Else just return the last name of the namespace - string name = expand ? GetLastNameSpace(code) : - GetLastName(code); - if (!String.IsNullOrEmpty(name)) - { - try - { - // Attempt to get type using naming - Type type = expand ? TryGetTypeFromFullName(name) : TryGetType(name); - - // CLR type - if (type != null) - { - items = EnumerateMembers(type, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); - } - // Variable type - else if (VariableTypes.TryGetValue(name, out type)) - { - items = EnumerateMembers(type, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); - } - else - { - var mem = LookupMember(name); - var namespaceTracker = mem as NamespaceTracker; - - // Namespace type - if (namespaceTracker != null) - { - items = EnumerateMembersFromTracker(namespaceTracker, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); - } - else - { - var pythonModule = mem as PythonModule; - - // Python Module type - if (pythonModule != null) - { - items = EnumerateMembers(pythonModule, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); - } - // Python type - else if (mem is PythonType) - { - // Shows static and instance methods in the same way :( - var value = ClrModule.GetClrType(mem as PythonType); - - if (value != null) - { - items = EnumerateMembers(value, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); - } - } - } - } - } - catch (Exception ex) - { - Log(ex.ToString()); - } - } - - // If unable to find matching results and expand was set to false, - // try again using the full namespace (set expand to true) - if (!items.Any() && !expand) - { - return GetCompletionData(code, true); - } - - return items.ToArray(); - } - - /// - /// Used to determine if this IExternalCodeCompletionProviderCore can provide completions for the given engine. - /// - /// - /// - public override bool IsSupportedEngine(string engineName) - { - // Do not reference 'PythonEngineManager.IronPython2EngineName' here - // because it will break compatibility with Dynamo2.13.X - // - //if (engineName == PythonEngineManager.IronPython2EngineName) - if (engineName == "IronPython2") - { - return true; - } - return false; - } - - /// - /// Used to load initialize libraries and types that should be available by default. - /// - /// - public override void Initialize(string dynamoCorePath) - { - var pythonLibDir = string.Empty; - var executionPath = Assembly.GetExecutingAssembly().Location; - // Determine if the Python Standard Library is available in the DynamoCore path - if (!String.IsNullOrEmpty(dynamoCorePath)) - { - pythonLibDir = Path.Combine(dynamoCorePath, IronPythonEvaluator.PythonLibName); - } - - // If IronPython.Std folder is excluded from DynamoCore (which could be user mistake or integrator exclusion) - if (!Directory.Exists(pythonLibDir)) - { - // Try to load IronPython from extension package - pythonLibDir = Path.Combine((new DirectoryInfo(Path.GetDirectoryName(executionPath))).Parent.FullName, IronPythonEvaluator.packageExtraFolderName, IronPythonEvaluator.PythonLibName); - } - - if (!String.IsNullOrEmpty(pythonLibDir)) - { - // Try to load Python Standard Library Type for autocomplete - try - { - var pyLibImports = String.Format("import sys\nsys.path.append(r'{0}')\n", pythonLibDir); - engine.CreateScriptSourceFromString(pyLibImports, SourceCodeKind.Statements).Execute(scope); - } - catch (Exception e) - { - Log(e.ToString()); - Log("Failed to register IronPython's native library. Python autocomplete will not see standard modules."); - } - } - else - { - Log("Valid IronPython Standard Library not found. Python autocomplete will not see native modules."); - } - } - - protected override object GetDescriptionObject(string docCommand) - { - try - { - - return engine.CreateScriptSourceFromString(docCommand, SourceCodeKind.Expression).Execute(scope); - } - catch - { - //This empty catch block is intentional- - //because we are using a python engine to evaluate the completions - //but this engine has not actually loaded the types, it will throw lots of exceptions - //we wish to suppress. - } - - return null; - } - protected override object EvaluateScript(string script, PythonScriptType evalType) - { - switch (evalType) - { - case PythonScriptType.Expression: - return engine.CreateScriptSourceFromString(script, SourceCodeKind.Expression).Execute(scope); - case PythonScriptType.SingleStatement: - return engine.CreateScriptSourceFromString(script, SourceCodeKind.SingleStatement).Execute(scope); - case PythonScriptType.Statements: - return engine.CreateScriptSourceFromString(script, SourceCodeKind.Statements).Execute(scope); - } - return null; - } - - protected override void LogError(string msg) - { - Log(msg); - } - - protected internal override bool ScopeHasVariable(string name) - { - return scope.ContainsVariable(name); - } - - protected override Type GetCLRType(string name) - { - return EvaluateScript(String.Format(clrTypeLookup, name), PythonScriptType.Expression) as Type; - } - #endregion - - #region constructor - - public IronPythonCodeCompletionProviderCore() - { - engine = IronPython.Hosting.Python.CreateEngine(); - scope = engine.CreateScope(); - - VariableTypes = new Dictionary(); - ImportedTypes = new Dictionary(); - ClrModules = new HashSet(); - BadStatements = new Dictionary(); - - // Special case for python variables defined as null - ImportedTypes["None"] = null; - - BasicVariableTypes = new List>(); - - BasicVariableTypes.Add(Tuple.Create(STRING_VARIABLE, typeof(string))); - BasicVariableTypes.Add(Tuple.Create(DOUBLE_VARIABLE, typeof(double))); - BasicVariableTypes.Add(Tuple.Create(INT_VARIABLE, typeof(int))); - BasicVariableTypes.Add(Tuple.Create(LIST_VARIABLE, typeof(IronPython.Runtime.List))); - BasicVariableTypes.Add(Tuple.Create(DICT_VARIABLE, typeof(PythonDictionary))); - - // Main CLR module - engine.CreateScriptSourceFromString("import clr\n", SourceCodeKind.SingleStatement).Execute(scope); - - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - // Determine if the Revit API is available in the given context - if (assemblies.Any(x => x.GetName().Name == "RevitAPI")) - { - // Try to load Revit Type for autocomplete - try - { - var revitImports = - "clr.AddReference('RevitAPI')\nclr.AddReference('RevitAPIUI')\nfrom Autodesk.Revit.DB import *\nimport Autodesk\n"; - - engine.CreateScriptSourceFromString(revitImports, SourceCodeKind.Statements).Execute(scope); - ClrModules.Add("RevitAPI"); - ClrModules.Add("RevitAPIUI"); - } - catch - { - Log("Failed to load Revit types for autocomplete. Python autocomplete will not see Autodesk namespace types."); - } - } - - // Determine if the ProtoGeometry is available in the given context - if (assemblies.Any(x => x.GetName().Name == "ProtoGeometry")) - { - // Try to load ProtoGeometry Type for autocomplete - try - { - var libGImports = - "clr.AddReference('ProtoGeometry')\nfrom Autodesk.DesignScript.Geometry import *\n"; - - engine.CreateScriptSourceFromString(libGImports, SourceCodeKind.Statements).Execute(scope); - ClrModules.Add("ProtoGeometry"); - } - catch (Exception e) - { - Log(e.ToString()); - Log("Failed to load ProtoGeometry types for autocomplete. Python autocomplete will not see Autodesk namespace types."); - } - } - - - } - - #endregion - - #region ILogSource Implementation - /// - /// Raise this event to request loggers log this message. - /// - public event Action MessageLogged; - - private void Log( string message) - { - MessageLogged?.Invoke(LogMessage.Info(message)); - } - #endregion - - public void Dispose() - {} - } -} diff --git a/src/Libraries/DSIronPython/IronPythonEvaluator.cs b/src/Libraries/DSIronPython/IronPythonEvaluator.cs deleted file mode 100644 index ce1cd40505e..00000000000 --- a/src/Libraries/DSIronPython/IronPythonEvaluator.cs +++ /dev/null @@ -1,398 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using Autodesk.DesignScript.Runtime; -using Dynamo.Events; -using Dynamo.Logging; -using Dynamo.PythonServices; -using Dynamo.PythonServices.EventHandlers; -using Dynamo.Session; -using Dynamo.Utilities; -using IronPython.Hosting; - -using Microsoft.Scripting.Hosting; -using Microsoft.Scripting.Utils; - -namespace DSIronPython -{ - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use Dynamo.PythonServices.EvaluationState instead.")] - public enum EvaluationState { Begin, Success, Failed } - - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use evaluation handlers from Dynamo.PythonServices instead.")] - public delegate void EvaluationEventHandler(EvaluationState state, - ScriptEngine engine, - ScriptScope scope, - string code, - IList bindingValues); - - /// - /// Evaluates a Python script in the Dynamo context. - /// - [IsVisibleInDynamoLibrary(false)] - public class IronPythonEvaluator : Dynamo.PythonServices.PythonEngine - { - private const string DynamoPrintFuncName = "__dynamoprint__"; - /// stores a copy of the previously executed code - private static string prev_code { get; set; } - /// stores a copy of the previously compiled engine - private static ScriptSource prev_script { get; set; } - - /// stores a reference to path of IronPython std lib - private static string pythonLibDir { get; set; } - - /// - /// Name of IronPython Std lib - /// - public const string PythonLibName = @"IronPython.StdLib.2.7.9"; - - /// - /// extra folder name in package folder - /// - public const string packageExtraFolderName = @"extra"; - - // Do not reference 'PythonEngineManager.IronPython2EngineName' here - // because it will break compatibility with Dynamo2.13.X - // - //public override string Name => PythonEngineManager.IronPython2EngineName; - - /// - /// Returns the name of this Python engine implementation. - /// This name will appear in the Dynamo's UI. - /// - public override string Name => "IronPython2"; - - /// - /// Use Lazy<PythonEngineManager> to make sure the Singleton class is only initialized once - /// - private static readonly Lazy - lazy = - new Lazy - (() => new IronPythonEvaluator()); - - /// - /// The actual instance stored in the Singleton class - /// - internal static IronPythonEvaluator Instance { get { return lazy.Value; } } - - /// - /// Attempts to build a path referencing the Python Standard Library, - /// returns null if unable to retrieve a valid path. - /// - /// path to the Python Standard Library in Dynamo Core - private static string PythonStandardLibPath() - { - // Attempt to get and cache the Dynamo Core directory path - if (string.IsNullOrEmpty(pythonLibDir)) - { - // Gather executing location, this could be DynamoCore folder or extension bin folder - var executionPath = Assembly.GetExecutingAssembly().Location; - - // Assume the Python Standard Library is available in the DynamoCore path - pythonLibDir = Path.Combine(Path.GetDirectoryName(executionPath), PythonLibName); - - // If IronPython.Std folder is excluded from DynamoCore (which could be user mistake or integrator exclusion) - if (!Directory.Exists(pythonLibDir)) - { - // Try to load IronPython from extension package - pythonLibDir = Path.Combine((new DirectoryInfo(Path.GetDirectoryName(executionPath))).Parent.FullName, packageExtraFolderName, PythonLibName); - } - } - return pythonLibDir; - } - - /// - /// Executes a Python script with custom variable names. Script may be a string - /// read from a file, for example. Pass a list of names (matching the variable - /// names in the script) to bindingNames and pass a corresponding list of values - /// to bindingValues. - /// - /// Python script as a string. - /// Names of values referenced in Python script. - /// Values referenced in Python script. - public override object Evaluate( - string code, - IList bindingNames, - [ArbitraryDimensionArrayImport] IList bindingValues) - { - // TODO - it would be nice if users could modify a preference - // setting enabling the ability to load additional paths - - // Container for paths that will be imported in the PythonEngine - List paths = new List(); - - // Attempt to get the Standard Python Library - string stdLib = PythonStandardLibPath(); - - if (code != prev_code) - { - ScriptEngine PythonEngine = Python.CreateEngine(); - if (!string.IsNullOrEmpty(stdLib)) - { - paths = PythonEngine.GetSearchPaths().ToList(); - paths.Add(stdLib); - } - - // If any paths were successfully retrieved, append them - if (paths.Count > 0) - { - PythonEngine.SetSearchPaths(paths); - } - - ScriptSource script = PythonEngine.CreateScriptSourceFromString(code); - script.Compile(); - prev_script = script; - prev_code = code; - } - - ScriptEngine engine = prev_script.Engine; - ScriptScope scope = engine.CreateScope(); - // For backwards compatibility: "sys" was imported by default due to a bug so we keep it that way - scope.ImportModule("sys"); - - ProcessAdditionalBindings(scope, bindingNames, bindingValues, engine); - - int amt = Math.Min(bindingNames.Count, bindingValues.Count); - - for (int i = 0; i < amt; i++) - { - scope.SetVariable((string)bindingNames[i], InputMarshaler.Marshal(bindingValues[i])); - } - - try - { - OnEvaluationBegin(engine, scope, code, bindingValues); - prev_script.Execute(scope); - } - catch (Exception e) - { - OnEvaluationEnd(false, engine, scope, code, bindingValues); - var eo = engine.GetService(); - string error = eo.FormatException(e); - throw new Exception(error); - } - - OnEvaluationEnd(true, engine, scope, code, bindingValues); - - var result = scope.ContainsVariable("OUT") ? scope.GetVariable("OUT") : null; - - return OutputMarshaler.Marshal(result); - } - - public static object EvaluateIronPythonScript( - string code, - IList bindingNames, - [ArbitraryDimensionArrayImport] IList bindingValues) - { - return Instance.Evaluate(code, bindingNames, bindingValues); - } - - /// - /// Processes additional bindings that are not actual inputs. - /// Currently, only the node name is received in this way. - /// - /// Python scope where execution will occur - /// List of binding names received for evaluation - /// List of binding values received for evaluation - private static void ProcessAdditionalBindings(ScriptScope scope, IList bindingNames, IList bindingValues, ScriptEngine engine) - { - const string NodeNameInput = "Name"; - string nodeName; - if (bindingNames.Count == 0 || !bindingNames[0].Equals(NodeNameInput)) - { - // Defensive code to fallback in case the additional binding is not there, like - // when the evaluator is called directly in tests, passing bindings manually. - nodeName = "USER"; - } - else - { - bindingNames.RemoveAt(0); - nodeName = (string)bindingValues[0]; - bindingValues.RemoveAt(0); - } - - // Session is null when running unit tests. - if (ExecutionEvents.ActiveSession != null) - { - dynamic logger = ExecutionEvents.ActiveSession.GetParameterValue(ParameterKeys.Logger); - Action logFunction = msg => logger.Log($"{nodeName}: {msg}", LogLevel.ConsoleOnly); - scope.SetVariable(DynamoPrintFuncName, logFunction); - ScriptSource source = engine.CreateScriptSourceFromString(RedirectPrint()); - source.Execute(scope); - } - } - - private static string RedirectPrint() - { - return String.Format(@" -import sys - -class DynamoStdOut: - def __init__(self, log_func): - self.text = '' - self.log_func = log_func - def write(self, text): - if text == '\n': - self.log_func(self.text) - self.text = '' - else: - self.text += text -sys.stdout = DynamoStdOut({0}) -", DynamoPrintFuncName); - } - - #region Marshalling - - /// - /// Data Marshaler for all data coming into a Python node. - /// - [SupressImportIntoVM] - public override object InputDataMarshaler - { - get - { - if (inputMarshaler == null) - { - inputMarshaler = new DataMarshaler(); - inputMarshaler.RegisterMarshaler( - delegate(IList lst) - { - var pyList = new IronPython.Runtime.List(); - foreach (var item in lst.Cast().Select(inputMarshaler.Marshal)) - { - pyList.Add(item); - } - return pyList; - }); - inputMarshaler.RegisterMarshaler( - delegate (DesignScript.Builtin.Dictionary dict) - { - var pyDict = new IronPython.Runtime.PythonDictionary(); - foreach (var key in dict.Keys) - { - pyDict.Add(inputMarshaler.Marshal(key), inputMarshaler.Marshal(dict.ValueAtKey(key))); - } - return pyDict; - }); - } - return inputMarshaler; - } - } - - /// - /// Data Marshaler for all data coming into a Python node. - /// - [SupressImportIntoVM] - public static DataMarshaler InputMarshaler => Instance.InputDataMarshaler as DataMarshaler; - - /// - /// Data Marshaler for all data coming out of a Python node. - /// - [SupressImportIntoVM] - public override object OutputDataMarshaler - { - get { return outputMarshaler ?? (outputMarshaler = new DataMarshaler()); } - } - - /// - /// Data Marshaler for all data coming out of a Python node. - /// - [SupressImportIntoVM] - public static DataMarshaler OutputMarshaler => Instance.OutputDataMarshaler as DataMarshaler; - - private static DataMarshaler inputMarshaler; - private static DataMarshaler outputMarshaler; - - #endregion - - #region Evaluation events - - /// - /// Emitted immediately before execution begins - /// - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use EvaluationStarted instead.")] - public static event EvaluationEventHandler EvaluationBegin; - - /// - /// Emitted immediately before execution begins - /// - [SupressImportIntoVM] - public override event EvaluationStartedEventHandler EvaluationStarted; - - /// - /// Emitted immediately after execution ends or fails - /// - [SupressImportIntoVM] - [Obsolete("Deprecated. Please use EvaluationFinished instead.")] - public static event EvaluationEventHandler EvaluationEnd; - - /// - /// Emitted immediately after execution ends or fails - /// - [SupressImportIntoVM] - public override event EvaluationFinishedEventHandler EvaluationFinished; - - /// - /// Called immediately before evaluation starts - /// - /// The engine used to do the evaluation - /// The scope in which the code is executed - /// The code to be evaluated - /// The binding values - these are already added to the scope when called - private void OnEvaluationBegin( ScriptEngine engine, - ScriptScope scope, - string code, - IList bindingValues ) - { - // Call deprecated events until they are completely removed. - EvaluationBegin?.Invoke(EvaluationState.Begin, engine, scope, code, bindingValues); - - if (EvaluationStarted != null) - { - EvaluationStarted(code, bindingValues, (n, v) => { scope.SetVariable(n, InputMarshaler.Marshal(v)); }); - Analytics.TrackEvent( - Dynamo.Logging.Actions.End, - Dynamo.Logging.Categories.PythonOperations, - "IronPythonEvaluation"); - } - } - - /// - /// Called when the evaluation has completed successfully or failed - /// - /// Whether the evaluation succeeded or not - /// The engine used to do the evaluation - /// The scope in which the code is executed - /// The code to that was evaluated - /// The binding values - these are already added to the scope when called - private void OnEvaluationEnd( bool isSuccessful, - ScriptEngine engine, - ScriptScope scope, - string code, - IList bindingValues) - { - // Call deprecated events until they are completely removed. - EvaluationEnd?.Invoke(isSuccessful ? EvaluationState.Success : EvaluationState.Failed, - engine, scope, code, bindingValues); - - if (EvaluationFinished != null) - { - EvaluationFinished( isSuccessful ? Dynamo.PythonServices.EvaluationState.Success : Dynamo.PythonServices.EvaluationState.Failed, - code, bindingValues, (n) => { return OutputMarshaler.Marshal(scope.GetVariable(n)); }); - - Analytics.TrackEvent( - Dynamo.Logging.Actions.End, - Dynamo.Logging.Categories.PythonOperations, - "IronPythonEvaluation"); - } - } - - #endregion - - } -} diff --git a/src/Libraries/DSIronPython/Properties/AssemblyInfo.cs b/src/Libraries/DSIronPython/Properties/AssemblyInfo.cs deleted file mode 100644 index 61af0fb5d8a..00000000000 --- a/src/Libraries/DSIronPython/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DSIronPython")] -[assembly: AssemblyCulture("")] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2cbb6e0f-dfca-49dc-8cff-bc65d82951a1")] diff --git a/src/Libraries/DSIronPython/pkg.json b/src/Libraries/DSIronPython/pkg.json deleted file mode 100644 index 3afee3127d9..00000000000 --- a/src/Libraries/DSIronPython/pkg.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "license": "", - "file_hash": null, - "name": "DynamoIronPython2.7", - "version": "2.5.0", - "description": "*** This is the official version of the IronPython Extension which will load the IronPython2 evaluation engine for Dynamo. *** \r\n\r\nIf you see the following warning 'The configured Python engine could not be found' when you try to run a Python Script node which is set to use IronPython2, the host application for Dynamo (Such as Revit or Civil 3d) will have chosen to exclude IronPython2 as default installed content and you will need to download this extension in order to enable IronPython2 again.\r\n\r\nYou have the ability to either download this IronPython2 Extension or use the alternative out-of-the-box CPython3 engine and migrate your legacy IronPython2 code to CPython3. While there are differences in language the Python basis is the same and we have provided a Migration Assistant to help you migrate your code to Python3.", - "group": "", - "keywords": [ "python", "ironpython" ], - "dependencies": [], - "host_dependencies": [ "Revit", "Civil 3D", "Alias", "Advance Steel", "FormIt" ], - "contents": "", - "engine_version": "2.13.0", - "engine": "dynamo", - "engine_metadata": "This pacakge is compatible with Dynamo2.13.0 release or newer", - "site_url": "https://dynamobim.org/", - "repository_url": "https://github.com/DynamoDS/Dynamo", - "contains_binaries": true, - "node_libraries": [] -} \ No newline at end of file diff --git a/src/Libraries/PythonNodeModels/Properties/AssemblyInfo.cs b/src/Libraries/PythonNodeModels/Properties/AssemblyInfo.cs index 2c94f246e62..b2b4b85c4ef 100644 --- a/src/Libraries/PythonNodeModels/Properties/AssemblyInfo.cs +++ b/src/Libraries/PythonNodeModels/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -21,5 +21,4 @@ [assembly: InternalsVisibleTo("PythonNodeModelsWpf")] [assembly: InternalsVisibleTo("PythonMigrationViewExtension")] [assembly: InternalsVisibleTo("DynamoCoreWpf")] -[assembly: TypeForwardedTo(typeof(PythonNodeModels.PythonEngineVersion))] diff --git a/src/Libraries/PythonNodeModels/PythonNode.cs b/src/Libraries/PythonNodeModels/PythonNode.cs index c16d5769c29..4089c40cd9b 100644 --- a/src/Libraries/PythonNodeModels/PythonNode.cs +++ b/src/Libraries/PythonNodeModels/PythonNode.cs @@ -36,44 +36,9 @@ public abstract class PythonNodeBase : VariableInputNode { private string engine = string.Empty; - [JsonConverter(typeof(StringEnumConverter))] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - // Set the default EngineName value to IronPython2 so that older graphs can show the migration warnings. - [DefaultValue("IronPython2")] - - // When removing this property also replace the serialized property in EngineName - // (i.e remove XmlIgnore and add [JsonProperty("Engine", DefaultValueHandling = DefaultValueHandling.Populate)] - /// - /// Return the user selected python engine enum. - /// - [Obsolete("This property will be deprecated in Dynamo 3.0. Please use EngineName instead")] - public PythonEngineVersion Engine - { - get - { - if (!Enum.TryParse(engine, out PythonEngineVersion engineVersion) || - engineVersion == PythonEngineVersion.Unspecified) - { - //if this is a valid dynamically loaded engine, return unknown, and serialize the name. - if (PythonEngineManager.Instance.AvailableEngines.Any(x=>x.Name == engine)) - { - return PythonEngineVersion.Unknown; - } - // This is a first-time case for newly created nodes only - SetEngineByDefault(); - } - return engineVersion; - } - set - { - engine = value.ToString(); - RaisePropertyChanged(nameof(EngineName)); - } - } - - [XmlIgnore] // Set the default EngineName value to IronPython2 so that older graphs can show the migration warnings. [DefaultValue("IronPython2")] + [JsonProperty("Engine", DefaultValueHandling = DefaultValueHandling.Populate)] /// /// Return the user selected python engine enum. /// @@ -98,20 +63,6 @@ public string EngineName } } - /// - /// Available Python engines. - /// - [Obsolete(@"This method will be removed in future versions of Dynamo. - Please use PythonEngineManager.Instance.AvailableEngines instead")] - public static ObservableCollection AvailableEngines - { - get - { - return new ObservableCollection(PythonEngineManager.Instance.AvailableEngines. - Select(x => Enum.TryParse(x.Name, out PythonEngineVersion version) ? version : PythonEngineVersion.Unspecified)); - } - } - /// /// Set the engine to be used by default for this node, based on user and system settings. /// diff --git a/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionData.cs b/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionData.cs index 4e035e4cb69..3e1cc61d3b1 100644 --- a/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionData.cs +++ b/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Windows.Media.Imaging; @@ -15,7 +15,6 @@ public class IronPythonCompletionData : ICompletionData { private static Dictionary TypeToIcon; - private readonly IronPythonCompletionProvider provider; public enum CompletionType { @@ -51,35 +50,16 @@ internal static CompletionType ConvertCompletionType(ExternalCodeCompletionType internal IronPythonCompletionData(IExternalCodeCompletionData data) { this.Text = data.Text; - this._description = data.Description; + this.Description = data.Description; BuildCompletionTypeToIconMap(); - this._image = TypeToIcon[ConvertCompletionType(data.CompletionType)]; + Image = TypeToIcon[ConvertCompletionType(data.CompletionType)]; } - public IronPythonCompletionData(string text, string stub, bool isInstance, CompletionType type, IronPythonCompletionProvider provider) - { - this.Text = text; - this.Stub = stub; - this.IsInstance = isInstance; - this.provider = provider; - - BuildCompletionTypeToIconMap(); - - this._image = TypeToIcon[type]; - } - - // image - private readonly BitmapImage _image; - public System.Windows.Media.ImageSource Image - { - get - { - return _image; - } - } + public System.Windows.Media.ImageSource Image { get; } + public string Text { get; private set; } public string Stub { get; private set; } @@ -89,31 +69,17 @@ public System.Windows.Media.ImageSource Image // Use this property if you want to show a fancy UIElement in the drop down list. public object Content { - get { return this.Text; } + get { return Text; } } - // description - private string _description; - - public object Description - { - get - { - // lazily get the description - if (_description == null) - { - _description = provider.GetDescription(this.Stub, this.Text, this.IsInstance).TrimEnd('\r', '\n'); - } + public object Description { get; private set; } - return _description; - } - } public double Priority { get { return 0; } } public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) { - textArea.Document.Replace(completionSegment, this.Text); + textArea.Document.Replace(completionSegment, Text); } private static BitmapImage GetBitmapImage(Assembly assembly, string resourceFileName) diff --git a/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionProvider.cs b/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionProvider.cs deleted file mode 100644 index a5fd484f8fe..00000000000 --- a/src/Libraries/PythonNodeModelsWpf/IronPythonCompletionProvider.cs +++ /dev/null @@ -1,350 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Autodesk.DesignScript.Interfaces; -using Dynamo.Logging; -using Dynamo.PythonServices; -using ICSharpCode.AvalonEdit.CodeCompletion; -using PythonNodeModels; - -namespace Dynamo.Python -{ - //This class needs to stay here with a reference to IronPython for now, its use will be - //completely removed from Dynamo though - so the dependencey on Ironpython will ONLY be at compile time. - [Obsolete("Do Not Use! This class will be removed in a future version of Dynamo," + - "Instead Reference the completion providers for a specific scripting engine, which implement " + - "IExternalCodeCompletionProvider")] - /// - /// Provides code completion for the Python Editor - /// - public class IronPythonCompletionProvider : LogSourceBase - { - private readonly IExternalCodeCompletionProviderCore providerImplementation; - private const string providerTypeName = "Dynamo.PythonServices.PythonCodeCompletionProviderCommon, DynamoServices"; - - #region Properties and fields - - /// - /// The engine used for autocompletion. This essentially keeps - /// track of the state of the editor, allowing access to variable types and - /// imported symbols. - /// - public object Engine - { - get { return (providerImplementation as ILegacyPythonCompletionCore).Engine; } - set { (providerImplementation as ILegacyPythonCompletionCore).Engine = value; } - } - - /// - /// The scope used by the engine. This is where all the loaded symbols - /// are stored. It's essentially an environment dictionary. - /// - public object Scope - { - get { return (providerImplementation as ILegacyPythonCompletionCore).Scope; } - set { (providerImplementation as ILegacyPythonCompletionCore).Scope = value; } - } - - /// - /// Already discovered variable types - /// - public Dictionary VariableTypes - { - get => providerImplementation.VariableTypes; - set => providerImplementation.VariableTypes = value; - } - - - /// - /// Types that have already been imported into the scope - /// - public Dictionary ImportedTypes - { - get => providerImplementation.ImportedTypes; - set => providerImplementation.ImportedTypes = value; - } - - /// - /// Maps a regex to a particular python type. Useful for matching things like dicts, - /// floats, strings, etc. Initialized by - /// - public Dictionary RegexToType = new Dictionary(); - - #endregion - - #region Constructors - /// - /// Class constructor - /// - public IronPythonCompletionProvider() : this("") - { - } - - /// - /// Class constructor - /// - public IronPythonCompletionProvider(string dynamoCoreDir) - { - var versionName = PythonEngineManager.IronPython2EngineName; - var matchingCore = SharedCompletionProvider.FindMatchingCodeCompletionCore(versionName, this.AsLogger()); - if (matchingCore != null) - { - this.providerImplementation = matchingCore; - this.providerImplementation.Initialize(dynamoCoreDir); - } - } - - #endregion - - #region Methods - /// - /// Generates completion data for the specified text, while import the given types into the - /// scope and discovering variable assignments. - /// - /// The code to parse - /// Return a list of IronPythonCompletionData - public ICompletionData[] GetCompletionData(string line) - { - return GetCompletionData(line, false); - } - - /// - /// Generate completion data for the specified text, while import the given types into the - /// scope and discovering variable assignments. - /// - /// The code to parse - /// Determines if the entire namespace should be used - /// Return a list of IronPythonCompletionData - public ICompletionData[] GetCompletionData(string code, bool expand = false) - { - return this.providerImplementation.GetCompletionData(code, expand). - Select(x => new IronPythonCompletionData(x)).ToArray(); - } - - /// - /// List all of the members in a PythonModule - /// - /// A reference to the module - /// The name of the module - /// A list of completion data for the module - public List EnumerateMembers(object module, string name) - { - var items = new List(); - foreach (var completion in (providerImplementation as ILegacyPythonCompletionCore).EnumerateMembers(module, name)) - { - var convertedCompletionType = IronPythonCompletionData.ConvertCompletionType(completion.Item4); - - items.Add(new IronPythonCompletionData(completion.Item1, completion.Item2, completion.Item3, convertedCompletionType, this)); - } - return items; - } - - /// - /// List all of the members in a CLR Namespace - /// - /// A reference to the module - /// The name of the module - /// A list of completion data for the namespace - public List EnumerateMembersFromTracker(object ns, string name) - { - var items = new List(); - foreach (var completion in (providerImplementation as ILegacyPythonCompletionCore).EnumerateMembersFromTracker(ns, name)) - { - var convertedCompletionType = IronPythonCompletionData.ConvertCompletionType(completion.Item4); - - items.Add(new IronPythonCompletionData(completion.Item1, completion.Item2, completion.Item3, convertedCompletionType, this)); - - } - return items; - } - - /// - /// List all of the members in a CLR type - /// - /// The type - /// The name for the type - /// A list of completion data for the type - protected List EnumerateMembers(Type type, string name) - { - var items = new List(); - foreach (var completion in (providerImplementation as ILegacyPythonCompletionCore).EnumerateMembers(type, name)) - { - var convertedCompletionType = IronPythonCompletionData.ConvertCompletionType(completion.Item4); - - items.Add(new IronPythonCompletionData(completion.Item1, completion.Item2, completion.Item3, convertedCompletionType, this)); - - } - return items; - } - - /// - /// Recursively lookup a member in a given namespace. - /// - /// A name for a type, possibly delimited by periods. - /// The namespace - /// The type as an object - public object LookupMember(string name, object n) - { - return (this.providerImplementation as ILegacyPythonCompletionCore).LookupMember(name, n); - } - - /// - /// Recursively lookup a variable in the _scope - /// - /// A name for a type, possibly delimited by periods. - /// The type as an object - public object LookupMember(string name) - { - return (this.providerImplementation as ILegacyPythonCompletionCore).LookupMember(name); - } - - /// - /// Generates completion data for the specified text. The text should be everything before - /// the dot character that triggered the completion. The text can contain the command line prompt - /// '>>>' as this will be ignored. - /// - public void GetDescription(string stub, string item, DescriptionUpdateDelegate updateDescription, bool isInstance) - { - string description = this.GetDescription(stub, item, isInstance); - updateDescription(description); - } - - /// - /// Try to generate a description from a typename - /// - /// Everything before the last namespace or type name e.g. System.Collections in System.Collections.ArrayList - /// Everything after the stub - /// Whether it's an instance or not - public string GetDescription(string stub, string item, bool isInstance) - { - return this.providerImplementation.GetDescription(stub, item, isInstance); - } - - /// - /// A delegate used to update the description - useful for multi-threading - /// - /// - public delegate void DescriptionUpdateDelegate(string description); - - /// - /// Traverse the given source code and define variable types based on - /// the current scope - /// - /// The source code to look through - public void UpdateVariableTypes(string code) - { - (providerImplementation as ILegacyPythonCompletionCore).UpdateVariableTypes(code); - } - - /// - /// Returns a type from a name. For example: System.Collections or System.Collections.ArrayList - /// - /// The name - /// The type or null if its not a valid type - protected Type TryGetType(string name) - { - return (providerImplementation as ILegacyPythonCompletionCore).TryGetType(name); - } - - /// - /// Attempts to find all import statements in the code - /// - /// The code to search - /// A list of tuples that contain the namespace, the module, and the custom name - private static List> FindAllImportStatements(string code) - { - return Type.GetType(providerTypeName).GetMethod(nameof(FindAllImportStatements), - BindingFlags.NonPublic | BindingFlags.Static) - .Invoke(null, new[] { code }) as List>; - } - - /// - /// Attempts to find all variable assignments in the code. Has basic variable unpacking support. - /// We don't need to check the line indices because regex matches are ordered as per the code. - /// - /// The code to search - /// A dictionary of variable name and type pairs - public Dictionary FindAllVariableAssignments(string code) - { - return (providerImplementation as ILegacyPythonCompletionCore).FindAllVariableAssignments(code); - } - - /// - /// Attempts to find import statements that look like - /// from lib import * - /// - /// The code to search - /// A dictionary matching the lib to the code where lib is the library being imported from - public static Dictionary FindAllTypeImportStatements(string code) - { - return Type.GetType(providerTypeName).GetMethod(nameof(FindAllTypeImportStatements), - BindingFlags.NonPublic | BindingFlags.Static) - .Invoke(null, new[] { code }) as Dictionary; - - } - - /// - /// Attempts to find import statements that look like - /// from lib import type1, type2 - /// Doesn't currently match types with namespace qualifiers like Collections.ArrayList - /// - /// The code to search - /// A dictionary matching the lib to the code where lib is the library being imported from - public static Dictionary FindTypeSpecificImportStatements(string code) - { - return Type.GetType(providerTypeName).GetMethod(nameof(FindTypeSpecificImportStatements), - BindingFlags.NonPublic | BindingFlags.Static) - .Invoke(null, new[] { code }) as Dictionary; - } - - /// - /// Attempts to find import statements that look like - /// import lib - /// - /// The code to search - /// A dictionary matching the lib to the code where lib is the library being imported from - public static Dictionary FindBasicImportStatements(string code) - { - return Type.GetType(providerTypeName).GetMethod(nameof(FindBasicImportStatements), - BindingFlags.NonPublic | BindingFlags.Static) - .Invoke(null, new[] { code }) as Dictionary; - } - - /// - /// Find a variable assignment of the form "varName = bla" where bla is matched by - /// the given regex - /// - /// The code to search - /// Your regex to match the type - /// A dictionary of name to assignment line pairs - public static Dictionary FindVariableStatementWithRegex(string code, string valueRegex) - { - return Type.GetType(providerTypeName).GetMethod(nameof(FindVariableStatementWithRegex), - BindingFlags.NonPublic | BindingFlags.Static) - .Invoke(null, new[] { code, valueRegex }) as Dictionary; - } - - /// - /// Find all import statements and import into scope. If the type is already in the scope, this will be skipped. - /// - /// The code to discover the import statements. - public void UpdateImportedTypes(string code) - { - (providerImplementation as ILegacyPythonCompletionCore).UpdateImportedTypes(code); - - } - - /// - /// Find all variable assignments in the source code and attempt to discover their type - /// - /// The code from which to get the assignments - /// A dictionary matching the name of the variable to a tuple of typeName, character at which the assignment was found, and the CLR type - public Dictionary> FindAllVariables(string code) - { - return (providerImplementation as ILegacyPythonCompletionCore).FindAllVariables(code); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/NodeServices/PythonServices.cs b/src/NodeServices/PythonServices.cs index bb1774d7085..6b62a964466 100644 --- a/src/NodeServices/PythonServices.cs +++ b/src/NodeServices/PythonServices.cs @@ -9,20 +9,6 @@ using Autodesk.DesignScript.Runtime; using Dynamo.PythonServices.EventHandlers; -namespace PythonNodeModels -{ - /// - /// Enum of possible values of python engine versions. - /// - [Obsolete("This Enum will be remove in Dynamo 3.0")] - public enum PythonEngineVersion - { - Unspecified, - IronPython2, - CPython3, - Unknown - } -} namespace Dynamo.PythonServices.EventHandlers { diff --git a/test/Libraries/DynamoPythonTests/PythonEvalTests.cs b/test/Libraries/DynamoPythonTests/PythonEvalTests.cs index ad0ac963b7a..c89eedba616 100644 --- a/test/Libraries/DynamoPythonTests/PythonEvalTests.cs +++ b/test/Libraries/DynamoPythonTests/PythonEvalTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using NUnit.Framework; @@ -7,6 +7,7 @@ using System.IO; using Dynamo; using Dynamo.PythonServices; +using Dynamo.PythonServices.EventHandlers; namespace DSPythonTests { @@ -153,20 +154,20 @@ public void CPythonEngineWithErrorRaisesCorrectEvent() { var count = 0; - DSCPython.EvaluationEventHandler CPythonEvaluator_EvaluationEnd = (state, scope, codeString, bindings) => + EvaluationFinishedEventHandler handler = (state, scope, codeString, bindings) => { count = count + 1; if (count == 1) { - Assert.AreEqual(DSCPython.EvaluationState.Success, state); + Assert.AreEqual(EvaluationState.Success, state); } else if (count == 2) { - Assert.AreEqual(DSCPython.EvaluationState.Failed, state); + Assert.AreEqual(EvaluationState.Failed, state); } }; - CPythonEvaluator.EvaluationEnd += CPythonEvaluator_EvaluationEnd; + CPythonEvaluator.Instance.EvaluationFinished += handler; var code = @"1"; try @@ -189,7 +190,7 @@ public void CPythonEngineWithErrorRaisesCorrectEvent() } finally { - DSCPython.CPythonEvaluator.EvaluationEnd -= CPythonEvaluator_EvaluationEnd; + CPythonEvaluator.Instance.EvaluationFinished -= handler; Assert.AreEqual(2, count); } } diff --git a/test/Libraries/IronPythonTests/CodeCompletionTests.cs b/test/Libraries/IronPythonTests/CodeCompletionTests.cs deleted file mode 100644 index 4a82c33c78e..00000000000 --- a/test/Libraries/IronPythonTests/CodeCompletionTests.cs +++ /dev/null @@ -1,467 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using Dynamo.Logging; -using Dynamo.Python; -using Dynamo.PythonServices; -using Dynamo.Utilities; -using NUnit.Framework; - -namespace IronPythonTests -{ - [TestFixture] - internal class SharedCodeCompletionProviderTests : CodeCompletionTests - { - [Test] - public void SharedCoreCanFindLoadedProviders() - { - var provider = new SharedCompletionProvider(PythonNodeModels.PythonEngineVersion.IronPython2, ""); - Assert.IsNotNull(provider); - } - - [Test] - public void SharedCoreCanReturnCLRCompletionData() - { - var provider = new SharedCompletionProvider(PythonNodeModels.PythonEngineVersion.IronPython2, ""); - Assert.IsNotNull(provider); - var str = "\nimport System.Collections\nSystem.Collections."; - - var completionData = provider.GetCompletionData(str); - var completionList = completionData.Select(d => d.Text); - Assert.IsTrue(completionList.Any()); - Assert.IsTrue(completionList.Intersect(new[] { "Hashtable", "Queue", "Stack" }).Count() == 3); - Assert.AreEqual(29, completionData.Length); - } - } - - [TestFixture] - internal class CodeCompletionTests - { - private AssemblyHelper assemblyHelper; - - private class SimpleLogger : ILogger - { - - public string LogPath - { - get { return ""; } - } - - public void Log(string message) - { - - } - - public void Log(string message, LogLevel level) - { - - } - - public void Log(string tag, string message) - { - - } - - public void LogError(string error) - { - - } - - public void LogWarning(string warning, WarningLevel level) - { - - } - - public void Log(Exception e) - { - - } - - public void ClearLog() - { - - } - - public string LogText - { - get { return ""; } - } - - public string Warning - { - get - { - return ""; - } - set { return; } - } - } - - private ILogger logger; - - // List of expected default imported types - private List defaultImports = new List() - { - "None", - "System" - }; - - [SetUp] - public void SetupPythonTests() - { - this.logger = new SimpleLogger(); - - var assemblyPath = Assembly.GetExecutingAssembly().Location; - var moduleRootFolder = Path.GetDirectoryName(assemblyPath); - - var resolutionPaths = new[] - { - // These tests need "DSIronPythonNode.dll" under "nodes" folder. - Path.Combine(moduleRootFolder, "nodes") - }; - //for some legacy tests we'll need the DSIronPython binary loaded manually - //as the types are found using reflection - during normal dynamo use these types are already loaded. - Assembly.LoadFrom(Path.Combine(moduleRootFolder, "DSIronPython.dll")); - - assemblyHelper = new AssemblyHelper(moduleRootFolder, resolutionPaths); - AppDomain.CurrentDomain.AssemblyResolve += assemblyHelper.ResolveAssembly; - } - - [TearDown] - public void RunAfterAllTests() - { - AppDomain.CurrentDomain.AssemblyResolve -= assemblyHelper.ResolveAssembly; - assemblyHelper = null; - } - - [Test] - [Category("UnitTests")] - public void CanMatchBasicNumVarSingleLine() - { - var matchNumVar = "a = 5.0"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchNumVar, PythonCodeCompletionProviderCommon.doubleRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("5.0", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanMatchBasicArrayVarSingleLine() - { - var matchArray = "a = []"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchArray, PythonCodeCompletionProviderCommon.arrayRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("[]", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanMatchBasicDictVarSingleLine() - { - var matchDict = "a = {}"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchDict, PythonCodeCompletionProviderCommon.dictRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("{}", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanMatchIntSingleLine() - { - var matchDict = "a = 2"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchDict, PythonCodeCompletionProviderCommon.intRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("2", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanMatchComplexDictVarSingleLine() - { - var matchDict2 = "a = { 'Alice': 7, 'Toby': 'Nuts' }"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchDict2, PythonCodeCompletionProviderCommon.dictRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("{ 'Alice': 7, 'Toby': 'Nuts' }", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanMatchComplexDictVarMultiLine() - { - var matchDict2 = "\n\na = { 'Alice': 7, 'Toby': 'Nuts' }\nb = 5.0"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchDict2, PythonCodeCompletionProviderCommon.dictRegex); - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("a")); - Assert.AreEqual("{ 'Alice': 7, 'Toby': 'Nuts' }", matches["a"]); - } - - [Test] - [Category("UnitTests")] - public void DoesntMatchBadVariable() - { - var matchDict2 = "a! = { 'Alice': 7, 'Toby': 'Nuts' }"; - var matches = IronPythonCompletionProvider.FindVariableStatementWithRegex(matchDict2, PythonCodeCompletionProviderCommon.dictRegex); - Assert.AreEqual(0, matches.Count); - } - - [Test] - [Category("UnitTests")] - public void CanMatchAllVariablesSingleLine() - { - var str = "a = { 'Alice': 7, 'Toby': 'Nuts' }"; - var completionProvider = new IronPythonCompletionProvider(); - - var matches = completionProvider.FindAllVariables(str); - - Assert.AreEqual(1, matches.Count); - Assert.AreEqual(typeof(IronPython.Runtime.PythonDictionary), matches["a"].Item3); - } - - [Test] - [Category("UnitTests")] - public void CanMatchAllVariableTypes() - { - var str = "a = { 'Alice': 7, 'Toby': 'Nuts' }\nb = {}\nc = 5.0\nd = 'pete'\ne = []"; - var completionProvider = new IronPythonCompletionProvider(); - - var matches = completionProvider.FindAllVariables(str); - - Assert.AreEqual(5, matches.Count); - Assert.AreEqual(typeof(IronPython.Runtime.PythonDictionary), matches["a"].Item3); - Assert.AreEqual(typeof(IronPython.Runtime.PythonDictionary), matches["b"].Item3); - Assert.AreEqual(typeof(double), matches["c"].Item3); - Assert.AreEqual(typeof(string), matches["d"].Item3); - Assert.AreEqual(typeof(IronPython.Runtime.List), matches["e"].Item3); - } - - [Test] - [Category("UnitTests")] - public void CanMatchBasicImportStatement() - { - var str = "import System"; - var matches = IronPythonCompletionProvider.FindBasicImportStatements(str); - - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("System")); - } - - [Test] - [Category("UnitTests")] - public void CanMatchBasicImportStatementMultiLine() - { - var str = "\nimport System\n"; - var matches = IronPythonCompletionProvider.FindBasicImportStatements(str); - - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("System")); - } - - [Test] - [Category("UnitTests")] - public void CanImportLibrary() - { - var str = "\nimport System\n"; - var completionProvider = new IronPythonCompletionProvider(); - completionProvider.UpdateImportedTypes(str); - - Assert.AreEqual(2, completionProvider.ImportedTypes.Count); - Assert.IsTrue(completionProvider.ImportedTypes.ContainsKey("System")); - } - - [Test] - [Category("UnitTests")] - public void DuplicateCallsToImportShouldBeFine() - { - var str = "\nimport System\nimport System"; - var completionProvider = new IronPythonCompletionProvider(); - completionProvider.UpdateImportedTypes(str); - - Assert.AreEqual(2, completionProvider.ImportedTypes.Count); - Assert.IsTrue(defaultImports.SequenceEqual(completionProvider.ImportedTypes.Keys.ToList())); - } - - [Test] - [Category("UnitTests")] - public void CanImportSystemLibraryAndGetCompletionData() - { - var str = "\nimport System\nSystem."; - var completionProvider = new IronPythonCompletionProvider(); - - var completionData = completionProvider.GetCompletionData(str); - - // Randomly verify some namepsaces are in the completion list - var completionList = completionData.Select(d => d.Text); - Assert.IsTrue(completionList.Any()); - Assert.IsTrue(completionList.Intersect(new[] { "IO", "Console", "Reflection" }).Count() == 3); - Assert.AreEqual(2, completionProvider.ImportedTypes.Count); - Assert.IsTrue(defaultImports.SequenceEqual(completionProvider.ImportedTypes.Keys.ToList())); - } - - [Test] - [Category("UnitTests")] - public void CanImportSystemCollectionsLibraryAndGetCompletionData() - { - var str = "\nimport System.Collections\nSystem.Collections."; - var completionProvider = new IronPythonCompletionProvider(); - - var completionData = completionProvider.GetCompletionData(str); - var completionList = completionData.Select(d => d.Text); - Assert.IsTrue(completionList.Any()); - Assert.IsTrue(completionList.Intersect(new[] { "Hashtable", "Queue", "Stack" }).Count() == 3); - Assert.AreEqual(29, completionData.Length); - } - - [Test] - [Category("UnitTests")] - public void CanMatchImportSystemLibraryWithComment() - { - var str = "# Write your script here.\r\nimport System."; - var matches = IronPythonCompletionProvider.FindBasicImportStatements(str); - - Assert.AreEqual(1, matches.Count); - Assert.IsTrue(matches.ContainsKey("System")); - } - - [Test] - [Category("UnitTests")] - public void CanMatchImportSystemAndLoadLibraryAndWithComment() - { - var str = "# Write your script here.\r\nimport System."; - var completionProvider = new IronPythonCompletionProvider(); - completionProvider.UpdateImportedTypes(str); - - Assert.AreEqual(2, completionProvider.ImportedTypes.Count); - Assert.IsTrue(defaultImports.SequenceEqual(completionProvider.ImportedTypes.Keys.ToList())); - } - - [Test] - [Category("UnitTests")] - public void CanIdentifyVariableTypeAndGetCompletionData() - { - var str = "a = 5.0\na."; - - var completionProvider = new IronPythonCompletionProvider(); - var completionData = completionProvider.GetCompletionData(str); - - Assert.AreNotEqual(0, completionData.Length); - } - - [Test] - [Category("UnitTests")] - public void CanFindTypeSpecificImportsMultipleTypesSingleLine() - { - var str = "from math import sin, cos\n"; - - var imports = IronPythonCompletionProvider.FindTypeSpecificImportStatements(str); - Assert.IsTrue(imports.ContainsKey("sin")); - Assert.AreEqual("from math import sin", imports["sin"]); - Assert.IsTrue(imports.ContainsKey("cos")); - Assert.AreEqual("from math import cos", imports["cos"]); - } - - [Test] - [Category("UnitTests")] - public void CanFindTypeSpecificImportsSingleTypeSingleLine() - { - var str = "from math import sin\n"; - - var imports = IronPythonCompletionProvider.FindTypeSpecificImportStatements(str); - Assert.IsTrue(imports.ContainsKey("sin")); - Assert.AreEqual("from math import sin", imports["sin"]); - } - - [Test] - [Category("UnitTests")] - public void CanFindTypeSpecificAutodeskImportsSingleTypeSingleLine() - { - var str = "from Autodesk.Revit.DB import Events\n"; - - var imports = IronPythonCompletionProvider.FindTypeSpecificImportStatements(str); - Assert.IsTrue(imports.ContainsKey("Events")); - Assert.AreEqual("from Autodesk.Revit.DB import Events", imports["Events"]); - } - - [Test] - [Category("UnitTests")] - public void CanFindAllTypeImports() - { - var str = "from Autodesk.Revit.DB import *\n"; - - var imports = IronPythonCompletionProvider.FindAllTypeImportStatements(str); - Assert.IsTrue(imports.ContainsKey("Autodesk.Revit.DB")); - Assert.AreEqual("from Autodesk.Revit.DB import *", imports["Autodesk.Revit.DB"]); - } - - [Test] - [Category("UnitTests")] - public void CanFindDifferentTypesOfImportsAndLoad() - { - var str = "from itertools import *\nimport math\nfrom sys import callstats\n"; - - var completionProvider = new IronPythonCompletionProvider(); - completionProvider.UpdateImportedTypes(str); - - Assert.AreEqual(3, completionProvider.ImportedTypes.Count); - Assert.IsTrue(completionProvider.Scope.ContainsVariable("repeat")); - Assert.IsTrue(completionProvider.Scope.ContainsVariable("izip")); - Assert.IsTrue(completionProvider.Scope.ContainsVariable("math")); - Assert.IsTrue(completionProvider.Scope.ContainsVariable("callstats")); - } - - [Test] - [Category("UnitTests")] - public void CanFindSystemCollectionsAssignmentAndType() - { - var str = "from System.Collections import ArrayList\na = ArrayList()\n"; - var completionProvider = new IronPythonCompletionProvider(); - completionProvider.UpdateImportedTypes(str); - completionProvider.UpdateVariableTypes(str); - - Assert.IsTrue(completionProvider.VariableTypes.ContainsKey("a")); - Assert.AreEqual(typeof(System.Collections.ArrayList), completionProvider.VariableTypes["a"]); - } - - [Test] - [Category("UnitTests")] - public void CanGetCompletionDataForArrayListVariable() - { - var str = "from System.Collections import ArrayList\na = ArrayList()\na."; - var completionProvider = new IronPythonCompletionProvider(); - var matches = completionProvider.GetCompletionData(str); - - Assert.AreNotEqual(0, matches.Length); - //Assert.AreEqual(typeof(IronPython.Runtime.PythonDictionary), matches["a"].Item3); - } - - [Test] - [Category("UnitTests")] - public void VerifyIronPythonLoadedAssemblies() - { - // Verify IronPython assebmlies are loaded a single time - List matches = new List(); - - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly assembly in assemblies) - { - if (assembly.FullName.StartsWith("IronPython")) - { - if (matches.Contains(assembly.FullName)) - { - Assert.Fail("Attempted to load an IronPython assembly multiple times: " + assembly.FullName); - } - else - { - matches.Add(assembly.FullName); - } - } - } - } - } -} diff --git a/test/Libraries/IronPythonTests/IronPythonTests.csproj b/test/Libraries/IronPythonTests/IronPythonTests.csproj deleted file mode 100644 index 7060947a081..00000000000 --- a/test/Libraries/IronPythonTests/IronPythonTests.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - 8.0.30703 - 2.0 - {E6DF2FBD-7D4D-4465-94DC-D576D737E985} - Library - Properties - IronPythonTests - IronPythonTests - - - - - - - - - - - - - - - - - - - - ..\..\..\extern\prism\Microsoft.Practices.Prism.dll - False - - - - - {51BB6014-43F7-4F31-B8D3-E3C37EBEDAF4} - DynamoCoreWpf - False - - - {7858FA8C-475F-4B8E-B468-1F8200778CF8} - DynamoCore - False - - - {7A9E0314-966F-4584-BAA3-7339CBB849D1} - ProtoCore - False - - - {9eef4f42-6b3b-4358-9a8a-c2701539a822} - DSIronPython - False - - - {01DE9B06-0BCB-4D8A-862E-E8170F5D6B4F} - PythonNodeModelsWpf - False - - - {8872ca17-c10d-43b9-8393-5c5a57065eb0} - PythonNodeModels - False - - - {ef879a10-041d-4c68-83e7-3192685f1bae} - DynamoServices - False - - - {10af430d-0d3a-49ce-a63d-848912959745} - PythonMigrationViewExtension - False - - - {472084ed-1067-4b2c-8737-3839a6143eb2} - DynamoCoreTests - False - - - {B5F435CB-0D8A-40B1-A4F7-5ECB3CE792A9} - DynamoUtilities - False - - - {7dd8077a-201e-4c56-96c5-3c901a51bdf3} - DynamoCoreWpfTests - False - - - {89563cd0-509b-40a5-8728-9d3ec6fe8410} - SystemTestServices - False - - - - - - \ No newline at end of file diff --git a/test/Libraries/IronPythonTests/Properties/AssemblyInfo.cs b/test/Libraries/IronPythonTests/Properties/AssemblyInfo.cs deleted file mode 100644 index d6c377edd37..00000000000 --- a/test/Libraries/IronPythonTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("DynamoPythonTests")] -[assembly: AssemblyCulture("")] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5b25d050-5442-47de-9b49-c82a5616df5e")] diff --git a/test/Libraries/IronPythonTests/PythonEditTests.cs b/test/Libraries/IronPythonTests/PythonEditTests.cs deleted file mode 100644 index 64a212d779c..00000000000 --- a/test/Libraries/IronPythonTests/PythonEditTests.cs +++ /dev/null @@ -1,624 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Autodesk.DesignScript.Geometry; -using Dynamo.Graph; -using Dynamo.Graph.Nodes; -using Dynamo.Graph.Nodes.CustomNodes; -using Dynamo.Graph.Workspaces; -using Dynamo.Models; -using Dynamo.Tests; -using Newtonsoft.Json.Linq; -using NUnit.Framework; -using PythonNodeModels; -using DynCmd = Dynamo.Models.DynamoModel; - -namespace IronPythonTests -{ - [RequiresSTA] - public class PythonEditTests : DynamoViewModelUnitTest - { - protected override void GetLibrariesToPreload(List libraries) - { - libraries.Add("DesignScriptBuiltin.dll"); - libraries.Add("DSCoreNodes.dll"); - libraries.Add("ProtoGeometry.dll"); - libraries.Add("DSCPython.dll"); - base.GetLibrariesToPreload(libraries); - } - - /// - /// Returns a list of python engines from the PythonEngineVersion Enum. - /// - private IEnumerable GetPythonEnginesList() - { - return Enum.GetValues(typeof(PythonEngineVersion)).Cast(); - } - - /// - /// Updates Engine property for a single python node. - /// - private void UpdatePythonEngineAndRun(PythonNode pythonNode, PythonEngineVersion pythonEngineVersion) - { - pythonNode.Engine = pythonEngineVersion; - //to kick off a run node modified must be called - pythonNode.OnNodeModified(); - } - - /// - /// Updates Engine property for a list of python nodes. - /// - private void UpdateEngineAndRunForAllPythonNodes(List list, PythonEngineVersion pythonEngineVersion) - { - foreach (var pyNode in list) - { - pyNode.Engine = pythonEngineVersion; - pyNode.OnNodeModified(); - } - } - - private void UpdatePythonNodeContent(ModelBase pythonNode, string value) - { - var command = new DynCmd.UpdateModelValueCommand( - System.Guid.Empty, pythonNode.GUID, "ScriptContent", value); - - ViewModel.ExecuteCommand(command); - } - - [Test] - public void PythonScriptEdit_WorkspaceChangesReflected() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "python.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // get the python node - var workspace = model.CurrentWorkspace; - var nodeModel = workspace.NodeFromWorkspace("3bcad14e-d086-4278-9e08-ed2759ef92f3"); - var pynode = nodeModel as PythonNode; - Assert.NotNull(pynode); - - // make changes to python script - UpdatePythonNodeContent(pynode, @"print 'okay'"); - - // workspace has changes - Assert.IsTrue(model.CurrentWorkspace.HasUnsavedChanges); - } - - [Test] - public void PythonNodeEnginePropertyTest() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "python.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // get the python node and check Engine property - var workspace = model.CurrentWorkspace; - var nodeModel = workspace.NodeFromWorkspace("3bcad14e-d086-4278-9e08-ed2759ef92f3"); - var pynode = nodeModel as PythonNode; - Assert.AreEqual(pynode.Engine, PythonEngineVersion.IronPython2); - - // workspace has no changes - Assert.IsFalse(model.CurrentWorkspace.HasUnsavedChanges); - - // Serialize DYN and deserialize to double check check Engine field - var path = GetNewFileNameOnTempPath(); - ViewModel.Model.CurrentWorkspace.Save(path); - - var fileContents = File.ReadAllText(path); - if (string.IsNullOrWhiteSpace(fileContents)) - return; - - JObject dynObj = JObject.Parse(fileContents); - var pythonTokens = dynObj["Nodes"].Where(t => t.Value("NodeType") == "PythonScriptNode").Select(t => t); - Assert.IsNotNull(pythonTokens); - Assert.IsTrue(pythonTokens.Any(t => t.Value("Engine") == PythonEngineVersion.IronPython2.ToString())); - } - - [Test] - public void PythonScriptEdit_CustomNode() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "PythonCustomNodeHomeWorkspace.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - var homeWorkspace = model.CurrentWorkspace; - - // open custom node - var customNodeModel = homeWorkspace.NodeFromWorkspace("83c2b47d81e14226a93941f1e47dc47d") as Function; - ViewModel.GoToWorkspaceCommand.Execute(customNodeModel.Definition.FunctionId); - var customNodeWorkspace = model.CurrentWorkspace; - - // get the python node - var nodeModel = customNodeWorkspace.NodeFromWorkspace("439c4e7bd4ed45f49d5786209c2ec403"); - var pynode = nodeModel as PythonNode; - Assert.NotNull(pynode); - - // make changes to python script - UpdatePythonNodeContent(pynode, @"OUT = IN[0] * 2"); - - // custom node workspace should have changes, home workspace should not - Assert.IsTrue(customNodeWorkspace.HasUnsavedChanges); - Assert.IsFalse(homeWorkspace.HasUnsavedChanges); - - /* TODO: uncomment this section after undo issues are resolved - // undo change - ViewModel.UndoCommand.Execute(null); - - // custom node workspace should not have changes, and neither should home - Assert.IsFalse(customNodeWorkspace.HasUnsavedChanges); - Assert.IsFalse(homeWorkspace.HasUnsavedChanges); - - // make home workspace current - ViewModel.HomeCommand.Execute(null); - - // make changes to python script - UpdatePythonNodeContent(pynode, @"OUT = IN[0] * 2"); - - // custom node workspace should have changes, home workspace should not - Assert.IsTrue(customNodeWorkspace.HasUnsavedChanges); - Assert.IsFalse(homeWorkspace.HasUnsavedChanges); - */ - } - - - [Test] - public void PythonScriptEdit_UndoRedo() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "python.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // get the python node - var pynode = model.CurrentWorkspace.Nodes.OfType().First(); - Assert.NotNull(pynode); - - // save original script - var origScript = pynode.Script; - - // make changes to python script - var newScript = @"print 'okay'"; - UpdatePythonNodeContent(pynode, newScript); - - // workspace has changes - Assert.IsTrue(model.CurrentWorkspace.HasUnsavedChanges); - - // undo change - ViewModel.UndoCommand.Execute(null); - - // check value is back to original - Assert.AreEqual(pynode.Script, origScript); - - // redo change - ViewModel.RedoCommand.Execute(null); - - // script is edited - Assert.AreEqual(pynode.Script, newScript); - } - - [Test] - public void VarInPythonScriptEdit_WorkspaceChangesReflected() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "varinpython.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // get the python node - var pynode = model.CurrentWorkspace.Nodes.OfType().First(); - Assert.NotNull(pynode); - - // make changes to python script - UpdatePythonNodeContent(pynode, @"print 'okay'"); - - // workspace has changes - Assert.IsTrue(model.CurrentWorkspace.HasUnsavedChanges); - } - - [Test] - public void VarInPythonScriptEdit_UndoRedo() - { - // open file - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "varinpython.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // get the python node - var pynode = model.CurrentWorkspace.Nodes.OfType().First(); - Assert.NotNull(pynode); - - // save original script - var origScript = pynode.Script; - - // make changes to python script - var newScript = @"print 'okay'"; - UpdatePythonNodeContent(pynode, newScript); - - // workspace has changes - Assert.IsTrue(model.CurrentWorkspace.HasUnsavedChanges); - - // undo change - ViewModel.UndoCommand.Execute(null); - - // check value is back to original - Assert.AreEqual(pynode.Script, origScript); - - // redo change - ViewModel.RedoCommand.Execute(null); - - // script is edited - Assert.AreEqual(pynode.Script, newScript); - } - - [Test] - public void VerifyPythonLoadsFromCore() - { - // This test graphs verifies the following: - // 1 - IronPython version 2.7.9 is loaded - // 2 - IronPython StdLib 2.7.9 is loaded from Core location - // 3 - StdLib modules are loaded - // 4 - Legacy import statements are not influenced by 2.7.9 upgrade - - // open test graph - var model = ViewModel.Model; - var examplePath = Path.Combine(TestDirectory, @"core\python", "IronPythonInfo_TestGraph.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - // reference to specific testing nodes in test graph - string[] testingNodeGUIDS = new string[] - { - "845d532f-df87-4d93-9f2e-d66509413ea6", - "cb037a9d-ebd5-4ce7-9a40-07b6ea11de25", - "a9bb1b12-fbbd-4aa1-9299-f0d30c9f99b2", - "b6bd3049-034f-488a-9bed-0373f05fd021" - }; - - // get test nodes - var allNodes = model.CurrentWorkspace.Nodes; - - foreach (NodeModel node in allNodes) - { - var guid = node.GUID.ToString(); - - // if node is a test node, verify truth value - if (testingNodeGUIDS.Contains(guid)) - { - AssertPreviewValue(guid, true); - } - } - - var pynode = model.CurrentWorkspace.Nodes.OfType().First(); - Assert.NotNull(pynode); - } - - [Test] - public void ReturnPythonDictionary_AsDynamoDictionary() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "python_dict.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var guid = "490a8d54d0fa4782ae18c81f6eef8306"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(guid); - var pynode = nodeModel as PythonNode; - - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - AssertPreviewValue(guid, new Dictionary { { "abc", 123 }, { "def", 345 } }); - } - } - - [Test] - public void InputDynamoDictionary_AsPythonDictionary() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "python_dict2.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var guid = "490a8d54d0fa4782ae18c81f6eef8306"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(guid); - var pynode = nodeModel as PythonNode; - - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - AssertPreviewValue(guid, - new List { new Dictionary { { "abcd", 123 } }, new List { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }); - } - } - - [Test] - public void PythonGeometryTest() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "PythonGeometry.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var pythonGUID = "3bcad14ed08642789e08ed2759ef92f3"; - var lineGUID = "cac9ff74bed14ff285294878fa849cd0"; - var circleCenterPointGUID = "6bb5d21d7815467db1d2ccfc77713337"; - var circleRadiusGUID = "88746807ba6d4c81a37dbfb187acca81"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(pythonGUID); - var pynode = nodeModel as PythonNode; - - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - var line = GetPreviewValue(lineGUID) as Line; - Assert.AreEqual(line.Length, 5); - - AssertPreviewValue(circleCenterPointGUID, Point.ByCoordinates(0, 0, 0)); - AssertPreviewValue(circleRadiusGUID, 5); - } - } - - [Test] - public void PythonNodeEnginePropertyChangeTest() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "pythonEngineTest.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - var pythonGUID = "83a5b1d2-dc58-4d8f-823f-861ac7d565f1"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(pythonGUID); - var pynode = nodeModel as PythonNode; - - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - var nodeValue = GetPreviewValue(pythonGUID); - - if (pythonEngine == PythonEngineVersion.IronPython2) - { - Assert.AreEqual(nodeValue, "2.7.9"); - } - else if (pythonEngine == PythonEngineVersion.CPython3) - { - Assert.AreEqual(nodeValue, "3.9.12"); - } - } - } - - [Test] - public void ReturnIronPythonDictionary_AsDynamoDictionary() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "netDict_from_python.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var guid = "490a8d54d0fa4782ae18c81f6eef8306"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(guid); - var pynode = nodeModel as PythonNode; - - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - AssertPreviewValue(guid, new Dictionary { { "abc", 123 }, { "def", 10 } }); - } - } - - [Test] - public void BigInteger_CanBeMarshaledAsInt64() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "BigIntegerToLong.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var guid = "23088248d7b1441abbc5ada07fcdf154"; - var pythonGUID = "547d1dd9203746bbaa2b7bd448c8124a"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(pythonGUID); - var pynode = nodeModel as PythonNode; - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - AssertPreviewValue(guid, - new[] { "System.Int64", "System.Double", "System.Int64", "System.Int64", "System.Numerics.BigInteger" }); - } - } - - [Test] - public void TestWorkspaceWithMultiplePythonEngines() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "WorkspaceWithMultiplePythonEngines.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var pythonNode2GUID = "4050d23e529c43e9b6140506d8adb06b"; - - var nodeModels = ViewModel.Model.CurrentWorkspace.Nodes.Where(n => n.NodeType == "PythonScriptNode"); - List pythonNodes = nodeModels.Cast().ToList(); - - var pynode1 = pythonNodes.ElementAt(0); - var pynode2 = pythonNodes.ElementAt(1); - - AssertPreviewValue(pythonNode2GUID, new List { "2.7.9", "2.7.9" }); - - UpdatePythonEngineAndRun(pynode1, PythonEngineVersion.CPython3); - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - AssertPreviewValue(pythonNode2GUID, new List { "3.9.12", "2.7.9" }); - - UpdatePythonEngineAndRun(pynode2, PythonEngineVersion.CPython3); - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - AssertPreviewValue(pythonNode2GUID, new List { "3.9.12", "3.9.12" }); - - UpdateEngineAndRunForAllPythonNodes(pythonNodes, PythonEngineVersion.IronPython2); - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - AssertPreviewValue(pythonNode2GUID, new List { "2.7.9", "2.7.9" }); - } - - [Test] - - public void Python_CanReferenceDynamoServicesExecutionSession() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "python_refDynamoServices.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var guid = "296e339254e845b695caa1a116500be0"; - - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(guid); - var pynode = nodeModel as PythonNode; - var count = 0; - foreach (var pythonEngine in GetPythonEnginesList()) - { - UpdatePythonEngineAndRun(pynode, pythonEngine); - - ViewModel.HomeSpace.Run(); - count++; - Assert.AreEqual(count, (GetModel().CurrentWorkspace as HomeWorkspaceModel).EvaluationCount); - - // Python script returns list of paths contained in PathManager.PackageDirectories - AssertPreviewCount(guid, 3); - } - } - - [Test] - public void CPythonClassCanBeUsedInDownStreamNode() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "cpythoncustomclass.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var downstream1 = ViewModel.Model.CurrentWorkspace.Nodes.First(x => x.Name == "downstream1"); - var downstream2 = ViewModel.Model.CurrentWorkspace.Nodes.First(x => x.Name == "downstream2"); - - ViewModel.HomeSpace.Run(); - AssertPreviewValue(downstream1.GUID.ToString(), "firstName"); - AssertPreviewValue(downstream2.GUID.ToString(), "firstNamelastname"); - - } - [Test] - public void CPythonClassCanBeModifiedInDownStreamNode() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "cpythoncustomclass_modified.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var downstream1 = ViewModel.Model.CurrentWorkspace.Nodes.First(x => x.Name == "downstream1"); - var downstream2 = ViewModel.Model.CurrentWorkspace.Nodes.First(x => x.Name == "downstream2"); - - ViewModel.HomeSpace.Run(); - AssertPreviewValue(downstream2.GUID.ToString(), "joe"); - } - - [Test] - public void VerifySysPathValueForCPythonEngine() - { - // open test graph - var examplePath = Path.Combine(TestDirectory, @"core\python", "CPythonSysPath.dyn"); - ViewModel.OpenCommand.Execute(examplePath); - - var firstPythonNodeGUID = "07ea2d39-811e-4df7-a38c-8c784d5079b0"; - var secondPythonNodeGUID = "a3058920-586a-43d9-9806-7d41c36803bb"; - - var sysPathList = GetFlattenedPreviewValues(firstPythonNodeGUID); - - // Verify that the custom path is added to the 'sys.path'. - Assert.AreEqual(sysPathList.Count(), 4); - Assert.AreEqual(sysPathList.Last(), "C:\\Program Files\\dotnet"); - - // Change the python engine for the 2nd node and verify that the custom path is not reflected in the 2nd node. - // Only the default python paths would be present in 'sys.path' when a python node is evaluated. - var nodeModel = ViewModel.Model.CurrentWorkspace.NodeFromWorkspace(secondPythonNodeGUID); - var pynode = nodeModel as PythonNode; - UpdatePythonEngineAndRun(pynode, PythonEngineVersion.CPython3); - sysPathList = GetFlattenedPreviewValues(secondPythonNodeGUID); - Assert.AreEqual(sysPathList.Count(), 3); - Assert.AreNotEqual(sysPathList.Last(), "C:\\Program Files\\dotnet"); - } - - [Test] - public void Test_Hidden_Properties_Python() - { - RunModel(@"core\python\HiddenProperties_Python.dyn"); - - var getItemAtIndex2 = "ad1f2ed7-6373-4381-aa93-df707c5e6339"; - AssertPreviewValue(getItemAtIndex2, new string[] { "TSplineVertex", "TSplineVertex" }); - } - - [Test] - public void CpythonRestart_ReloadsModules() - { - var modName = "reload_test2"; - (ViewModel.CurrentSpace as HomeWorkspaceModel).RunSettings.RunType = RunType.Manual; - var tempPath = Path.Combine(TempFolder, $"{modName}.py"); - - //clear file. - File.WriteAllText(tempPath, "value ='Hello World!'\n"); - - //we have to shutdown python before this test to make sure we're starting in a clean state. - this.ViewModel.Model.OnRequestPythonReset(nameof(PythonEngineVersion.CPython3)); - try - { - var script = $@"import sys -sys.path.append(r'{Path.GetDirectoryName(tempPath)}') -import {modName} -OUT = {modName}.value"; - - - var pythonNode = new PythonNode(); - ViewModel.CurrentSpace.AddAndRegisterNode(pythonNode); - pythonNode.Engine = PythonEngineVersion.CPython3; - UpdatePythonNodeContent(pythonNode, script); - RunCurrentModel(); - AssertPreviewValue(pythonNode.GUID.ToString(), "Hello World!"); - - //now modify the file. - File.AppendAllLines(tempPath, new string[] { "value ='bye'" }); - - //user restarts manually, this will cause a dynamo and python engine reset - this.ViewModel.Model.OnRequestPythonReset(nameof(PythonEngineVersion.CPython3)); - - RunCurrentModel(); - AssertPreviewValue(pythonNode.GUID.ToString(), "bye"); - - } - finally - { - File.Delete(tempPath); - } - } - } -} \ No newline at end of file diff --git a/test/Libraries/IronPythonTests/PythonEngineSelectorTests.cs b/test/Libraries/IronPythonTests/PythonEngineSelectorTests.cs deleted file mode 100644 index 41aa3b1fd54..00000000000 --- a/test/Libraries/IronPythonTests/PythonEngineSelectorTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Dynamo; -using Dynamo.PythonServices; -using Dynamo.Utilities; -using NUnit.Framework; -using PythonNodeModels; -using static Dynamo.Models.DynamoModel; - -namespace IronPythonTests -{ - [TestFixture] - class PythonEngineSelectorTests : DynamoModelTestBase - { - protected override void GetLibrariesToPreload(List libraries) - { - // Add multiple libraries to better simulate typical Dynamo application usage. - libraries.Add("DSCPython.dll"); - libraries.Add("DSIronPython.dll"); - base.GetLibrariesToPreload(libraries); - } - - /// - /// This test will cover the use case of the API to query certain Python engine ability for evaluation - /// - [Test] - public void TestEngineSelectorInitialization() - { - PythonEngineManager.Instance.GetEvaluatorInfo(PythonEngineVersion.IronPython2, out string evaluatorClass, out string evaluationMethod); - Assert.AreEqual(true, PythonEngineManager.lazy.IsValueCreated); - Assert.AreEqual(evaluatorClass, PythonEngineManager.IronPythonEvaluatorClass); - Assert.AreEqual(evaluationMethod, PythonEngineManager.IronPythonEvaluationMethod); - - PythonEngineManager.Instance.GetEvaluatorInfo(PythonEngineVersion.CPython3, out evaluatorClass, out evaluationMethod); - Assert.AreEqual(evaluatorClass, PythonEngineManager.CPythonEvaluatorClass); - Assert.AreEqual(evaluationMethod, PythonEngineManager.CPythonEvaluationMethod); - - Assert.AreEqual(true, PythonEngineManager.Instance.AvailableEngines.Any(x => x.Version == PythonEngineVersion.CPython3)); - Assert.AreEqual(true, PythonEngineManager.Instance.AvailableEngines.Any(x => x.Version == PythonEngineVersion.IronPython2)); - } - - [Test] - public void CanCopydAndPasteAndUndoPythonEngine() - { - var pyNode = new PythonNode(); - - CurrentDynamoModel.ExecuteCommand(new Dynamo.Models.DynamoModel.CreateNodeCommand(pyNode, 0, 0, false, false)); - Assert.AreEqual(1, CurrentDynamoModel.CurrentWorkspace.Nodes.Count()); - - pyNode.Engine = PythonEngineVersion.CPython3; - CurrentDynamoModel.AddToSelection(pyNode); - - CurrentDynamoModel.Copy(); - Assert.AreEqual(1, CurrentDynamoModel.ClipBoard.Count); - - CurrentDynamoModel.Paste(); - Assert.AreEqual(2, CurrentDynamoModel.CurrentWorkspace.Nodes.Count()); - - Assert.IsTrue(CurrentDynamoModel.CurrentWorkspace.Nodes.OfType().All(x => x.Engine == PythonEngineVersion.CPython3)); - - CurrentDynamoModel.ExecuteCommand(new UndoRedoCommand(UndoRedoCommand.Operation.Undo)); - Assert.AreEqual(1, CurrentDynamoModel.CurrentWorkspace.Nodes.Count()); - pyNode.Engine = PythonEngineVersion.IronPython2; - - CurrentDynamoModel.ExecuteCommand( - new UpdateModelValueCommand( - Guid.Empty, pyNode.GUID, nameof(PythonNode.Engine), PythonEngineVersion.CPython3.ToString())); - Assert.AreEqual(pyNode.Engine,PythonEngineVersion.CPython3); - - CurrentDynamoModel.ExecuteCommand(new UndoRedoCommand(UndoRedoCommand.Operation.Undo)); - - Assert.AreEqual(pyNode.Engine, PythonEngineVersion.IronPython2); - } - - [Test] - public void IronPytonEngineManagerAPITest() - { - var ironPythonEng = PythonEngineManager.Instance.CreateEngineProxy( - Assembly.GetAssembly(typeof(DSIronPython.IronPythonEvaluator)), - PythonEngineVersion.IronPython2); - - Assert.IsNotNull(ironPythonEng); - - ironPythonEng.OnEvaluationBegin((code, bindings, scopeSet) => { scopeSet("IN", new ArrayList { " ", " " }); }); - - int counter = 0; - ironPythonEng.OnEvaluationEnd((state, code, bindings, scopeGet) => { counter++; }); - - var inputM = ironPythonEng.GetInputMarshaler() as DataMarshaler; - inputM.RegisterMarshaler((string s) => s.Length); - - var output = DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript( - "OUT = sum(IN)", new ArrayList(), new ArrayList()); - - inputM.UnregisterMarshalerOfType(); - - Assert.AreEqual(3, output); - - var outputM = ironPythonEng.GetOutputMarshaler() as DataMarshaler; - outputM.RegisterMarshaler((string s) => s.Length); - - ironPythonEng.OnEvaluationBegin((code, bindings, scopeSet) => { scopeSet("TEST", new ArrayList { "", " ", " " }); }); - - output = DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript( - "OUT = TEST", - new ArrayList(), - new ArrayList()); - - outputM.UnregisterMarshalerOfType(); - - Assert.AreEqual(new[] { 0, 1, 2 }, output); - Assert.AreEqual(2, counter); - } - } -} diff --git a/test/Libraries/IronPythonTests/PythonEvalTests.cs b/test/Libraries/IronPythonTests/PythonEvalTests.cs deleted file mode 100644 index 20f6b5c329a..00000000000 --- a/test/Libraries/IronPythonTests/PythonEvalTests.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using NUnit.Framework; -using Dynamo; - -namespace IronPythonTests -{ - public class PythonEvalTests : UnitTestBase - { - public delegate object PythonEvaluatorDelegate(string code, IList bindingNames, IList bindingValues); - - public IEnumerable Evaluators = new List { - DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript - }; - - [Test] - [Category("UnitTests")] - public void EvaluatorWorks() - { - foreach (var pythonEvaluator in Evaluators) - { - var empty = new ArrayList(); - var output = pythonEvaluator("OUT = 0", empty, empty); - Assert.AreEqual(0, output); - } - } - - [Test] - [Category("UnitTests")] - public void BindingsWork() - { - const string expected = "Hi!"; - - var names = new ArrayList { "test" }; - var vals = new ArrayList { expected }; - - foreach (var pythonEvaluator in Evaluators) - { - var output = pythonEvaluator( - "OUT = test", - names, - vals - ); - - Assert.AreEqual(expected, output); - } - } - - [Test] - [Category("UnitTests")] - public void DataMarshaling_Output() - { - var marshaler = DSIronPython.IronPythonEvaluator.OutputMarshaler; - marshaler.RegisterMarshaler((string s) => s.Length); - - const string script = "OUT = ['', ' ', ' ']"; - - object output = DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript( - script, - new ArrayList(), - new ArrayList()); - - Assert.AreEqual(new[] { 0, 1, 2 }, output); - - marshaler.UnregisterMarshalerOfType(); - } - - [Test] - [Category("UnitTests")] - public void DataMarshaling_Input() - { - var marshaler = DSIronPython.IronPythonEvaluator.InputMarshaler; - marshaler.RegisterMarshaler((string s) => s.Length); - - const string script = "OUT = sum(IN)"; - - object output = DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript( - script, - new ArrayList { "IN" }, - new ArrayList { new ArrayList { " ", " " } }); - - Assert.AreEqual(3, output); - - marshaler.UnregisterMarshalerOfType(); - } - - - [Test] - public void SliceOperator_Output() - { - var names = new ArrayList { "indx" }; - var vals = new ArrayList { 3 }; - - foreach (var pythonEvaluator in Evaluators) - { - var output = pythonEvaluator( - "OUT = [1,2,3,4,5,6,7][indx:indx+2]", - names, - vals); - - var expected = new ArrayList { 4, 5 }; - - Assert.AreEqual(expected, output); - } - } - - [Test] - public void IronPythonGivesCorrectErrorLineNumberAndLoadsStdLib() - { - var code = @" -from xml.dom.minidom import parseString -my_xml = parseString('invalid XML!') -"; - try - { - DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript(code, new ArrayList(), new ArrayList()); - Assert.Fail("An exception was expected"); - } - catch (Exception exc) - { - StringAssert.StartsWith(@"Traceback (most recent call last): - File """", line 3, in ", exc.Message); - StringAssert.EndsWith("Data at the root level is invalid. Line 1, position 1.", exc.Message); - } - } - - [Test] - public void NonListIterablesCanBeOutput() - { - var code = @" -s = { 'hello' } -fs = frozenset({ 'world' }) -d = { 'one': 1 } -dk = d.keys() -dv = d.values() -di = d.items() - -OUT = s,fs,dk,dv,di -"; - var expected = new ArrayList - { - new ArrayList { "hello" }, - new ArrayList { "world" }, - new ArrayList { "one" }, - new ArrayList { 1 }, - new ArrayList { new ArrayList { "one", 1 } } - }; - var empty = new ArrayList(); - foreach (var pythonEvaluator in Evaluators) - { - var output = pythonEvaluator(code, empty, empty); - Assert.AreEqual(expected, output); - } - } - } -} \ No newline at end of file diff --git a/test/Libraries/IronPythonTests/PythonEvalTestsWithLibraries.cs b/test/Libraries/IronPythonTests/PythonEvalTestsWithLibraries.cs deleted file mode 100644 index 6a7217bdb6a..00000000000 --- a/test/Libraries/IronPythonTests/PythonEvalTestsWithLibraries.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Numerics; -using Dynamo; -using NUnit.Framework; - -namespace IronPythonTests -{ - public class PythonEvalTestsWithLibraries : DynamoModelTestBase - { - public delegate object PythonEvaluatorDelegate(string code, IList bindingNames, IList bindingValues); - protected override void GetLibrariesToPreload(List libraries) - { - libraries.Add("FFITarget.dll"); - libraries.Add("DSCoreNodes.dll"); - } - - public IEnumerable Evaluators = new List { - DSIronPython.IronPythonEvaluator.EvaluateIronPythonScript - }; - - [Test] - public void TestBigIntegerEncodingDecoding() - { - string code = @" -import sys -import clr -clr.AddReference('FFITarget') -from FFITarget import DummyMath - -# Provide Python int as arguments: Python => .NET -sum = DummyMath.Sum(11111111111111111111, 11111111111111111111) -# sum contains a BigInteger and we use it in Python + operation: .NET => Python -sum = sum + 1 - -OUT = sum -"; - var empty = new ArrayList(); - var expected = BigInteger.Parse("22222222222222222223"); - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.AreEqual(expected, result); - } - } - - [Test] - public void TestListDecoding() - { - string code = @" -import sys -import clr -clr.AddReference('DSCoreNodes') -clr.AddReference('FFITarget') -from FFITarget import DummyCollection -from DSCore import List - -l = ['a'] -# Python list => .NET IList -untypedList = List.AddItemToEnd('b', l) -untypedList.Add('c') - -l2 = ['a','b'] -# Python list => .NET IList<> -typedList = List.SetDifference(l2, l) -typedList.Add('b') - -l3 = [[1,2],[3,4]] -# Python list (nested) => .NET IList> -flattenedList = List.Flatten(l3) - -l4 = [] -# Python list (empty) => .NET IList -elementCount = List.Count(l4) - -sum = 0 -# Python-wrapped .NET List can be iterated over -for i in flattenedList: - sum = sum + i - -l5 = [1,2,3,4] -# Python list => .NET IEnumerable<> -max = List.MaximumItem(l5) - -# Python list => .NET IEnumerable -enumerable = DummyCollection.ReturnIEnumerable(l2) - -OUT = untypedList, typedList, flattenedList, elementCount, sum, max, enumerable -"; - var empty = new ArrayList(); - var expected = new ArrayList { new ArrayList { "a", "b", "c" }, new ArrayList { "b", "b" }, new ArrayList { 1, 2, 3, 4 }, 0, 10, 4 - , new ArrayList { "a", "b" } }; - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.IsTrue(result is IEnumerable); - CollectionAssert.AreEqual(expected, result as IEnumerable); - } - } - - [Test] - public void TestArrayEncoding() - { - string code = @" -import sys -import clr -clr.AddReference('FFITarget') -clr.AddReference('DSCoreNodes') -from FFITarget import DummyCollection -from DSCore import List -from array import array - -# .NET array => Python list -a = DummyCollection.MakeArray(1,2) -a[0] = a[1] + 1 -b = len(a) -a[1] = b -a = List.AddItemToEnd(1, a) - -OUT = a -"; - var empty = new ArrayList(); - var expected = new ArrayList { 3, 2, 1 }; - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.IsTrue(result is IEnumerable); - CollectionAssert.AreEqual(expected, result as IEnumerable); - } - } - - [Test] - public void TestTupleDecoding() - { - string code = @" -import sys -import clr -clr.AddReference('FFITarget') -clr.AddReference('DSCoreNodes') -from FFITarget import DummyCollection -from DSCore import List - -t = (1,2,3) -# Python tuple => .NET array -a = DummyCollection.MakeArray(t) -# Python tuple => .NET IList -l = List.AddItemToEnd(4, t) - -OUT = a, l -"; - var empty = new ArrayList(); - var expected = new ArrayList { new ArrayList { 1, 2, 3 }, new ArrayList { 1, 2, 3, 4 } }; - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.IsTrue(result is IEnumerable); - CollectionAssert.AreEqual(expected, result as IEnumerable); - } - } - - [Test] - public void TestDictionaryViewsDecoding() - { - var code = @" -import clr -clr.AddReference('DSCoreNodes') -from DSCore import List - -d = {'one': 1, 'two': 2, 'three': 3} - -dk = List.AddItemToEnd('four', d.keys()) -dv = List.AddItemToEnd(4, d.values()) -di = List.AddItemToEnd(('four', 4), d.items()) - -OUT = dk, dv, di -"; - var empty = new ArrayList(); - var expected = new ArrayList[] { - new ArrayList { "one", "two", "three", "four" }, - new ArrayList { 1, 2, 3, 4 }, - new ArrayList { new ArrayList { "one", 1 }, new ArrayList { "two", 2 }, new ArrayList { "three", 3 }, new ArrayList { "four", 4 } } - }; - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.IsTrue(result is IEnumerable); - var i = 0; - foreach (var item in result as IEnumerable) - { - Assert.IsTrue(item is IEnumerable); - CollectionAssert.AreEquivalent(expected[i], item as IEnumerable); - i++; - } - } - } - - /// - /// Tests that the results from doing dir(DSCore) are somewhat equivalent between engines. - /// They are known not to be exactly the same. Namely the following differences have been found: - /// - Private (double underscore) attributes are different across engines - /// - IronPython does not define private attributes for namespaces at all - /// - PythonNET includes additional methods to classes (Overloads and Finalize) - /// - PythonNET also includes results from assemblies not explicitly added as references (DSCore.File) - /// - [Test] - public void TestDir() - { - var code = @" -import clr -clr.AddReference('DSCoreNodes') -import DSCore -ref = DSCore -dirAll = [] -dic = {} -for key in dir(ref) : - dir_str = getattr(ref, key) - dirAll.append(dir(dir_str)) - for value in dirAll : - dic[key] = value -OUT = dic -"; - var empty = new ArrayList(); - foreach (var pythonEvaluator in Evaluators) - { - var result = pythonEvaluator(code, empty, empty); - Assert.IsTrue(result is IDictionary); - var dsCore = result as IDictionary; - // Assertions for a Class - CollectionAssert.Contains(dsCore.Keys, "Color", "public class not found"); - Assert.IsTrue(dsCore["Color"] is IList); - var color = dsCore["Color"] as IList; - CollectionAssert.Contains(color, "ByARGB", "public static method not found"); - CollectionAssert.Contains(color, "Equals", "public instance method not found"); - CollectionAssert.Contains(color, "Alpha", "public property not found"); - CollectionAssert.Contains(color, "IndexedColor1D", "nested class not found"); - // Assertions for a Namespace - CollectionAssert.Contains(dsCore.Keys, "IO", "nested namespace not found"); - Assert.IsTrue(dsCore["IO"] is IList); - var dsCoreIO = dsCore["IO"] as IList; - CollectionAssert.Contains(dsCoreIO, "Image", "class in nested namespace not found"); - } - } - - private void DictionaryAssert(IDictionary expected, IDictionary actual) - { - Assert.AreEqual(expected.Count, actual.Count); - foreach (var key in expected.Keys) - { - Assert.AreEqual(expected[key], actual[key]); - } - } - } -} diff --git a/test/Libraries/IronPythonTests/PythonMigrationViewExtensionTests.cs b/test/Libraries/IronPythonTests/PythonMigrationViewExtensionTests.cs deleted file mode 100644 index 805f42937ad..00000000000 --- a/test/Libraries/IronPythonTests/PythonMigrationViewExtensionTests.cs +++ /dev/null @@ -1,306 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using Dynamo; -using Dynamo.Controls; -using Dynamo.Graph.Workspaces; -using Dynamo.Models; -using Dynamo.PythonMigration; -using Dynamo.PythonMigration.Controls; -using Dynamo.Utilities; -using Dynamo.Views; -using Dynamo.Wpf.Extensions; -using DynamoCoreWpfTests; -using DynamoCoreWpfTests.Utility; -using NUnit.Framework; -using PythonNodeModels; -using PythonNodeModelsWpf; - -namespace IronPythonTests -{ - class PythonMigrationViewExtensionTests : DynamoTestUIBase - { - private readonly PythonMigrationViewExtension viewExtension = new PythonMigrationViewExtension(); - private string CoreTestDirectory { get { return Path.Combine(GetTestDirectory(ExecutingDirectory), "core"); } } - - private List raisedEvents = new List(); - - private static void SetEngineViaContextMenu(NodeView nodeView, PythonEngineVersion engine) - { - var engineSelection = nodeView.MainContextMenu.Items - .OfType() - .Where(item => (item.Header as string) == PythonNodeModels.Properties.Resources.PythonNodeContextMenuEngineSwitcher).FirstOrDefault(); - switch (engine) - { - case PythonEngineVersion.IronPython2: - (engineSelection.Items[0] as MenuItem).RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); - break; - case PythonEngineVersion.CPython3: - (engineSelection.Items[1] as MenuItem).RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); - break; - } - DispatcherUtil.DoEvents(); - } - - /// - /// This test is created to check if a notification is logged to the Dynamo Logger - /// when adding a using the IronPython engine - /// - [Test] - public void WillLogNotificationWhenAddingAnIronPythonNode() - { - // Arrange - string pythonNodeName = "Python Script"; - raisedEvents = new List(); - // Act - // open file - this.ViewModel.Model.Logger.NotificationLogged += Logger_NotificationLogged; - - var nodesCountBeforeNodeAdded = this.ViewModel.CurrentSpace.Nodes.Count(); - - this.ViewModel.ExecuteCommand(new DynamoModel. - CreateNodeCommand(Guid.NewGuid().ToString(), pythonNodeName, 0, 0, false, false)); - - var nodesCountAfterNodeAdded = this.ViewModel.CurrentSpace.Nodes.Count(); - - // Assert - Assert.AreEqual(nodesCountBeforeNodeAdded + 1, nodesCountAfterNodeAdded); - Assert.AreEqual(raisedEvents.Count, 1); - Assert.IsTrue(raisedEvents.Any(x => x.Contains(nameof(PythonMigrationViewExtension)))); - raisedEvents.Clear(); - this.ViewModel.Model.Logger.NotificationLogged -= Logger_NotificationLogged; - DispatcherUtil.DoEvents(); - } - - private void Logger_NotificationLogged(Dynamo.Logging.NotificationMessage obj) - { - raisedEvents.Add(obj.Sender); - } - - /// - /// This test verifies an IronPython warning notification is logged to the Dynamo Logger - /// only one time per open graph - /// - [Test] - public void WillOnlyLogNotificationWhenAddingAnIronPythonNodeOnce() - { - // Arrange - string pythonNodeName = "Python Script"; - raisedEvents = new List(); - - // Act - // open file - this.ViewModel.Model.Logger.NotificationLogged += Logger_NotificationLogged; - - - var nodesCountBeforeNodeAdded = this.ViewModel.CurrentSpace.Nodes.Count(); - - this.ViewModel.ExecuteCommand(new DynamoModel. - CreateNodeCommand(Guid.NewGuid().ToString(), pythonNodeName, 0, 0, false, false)); - this.ViewModel.ExecuteCommand(new DynamoModel. - CreateNodeCommand(Guid.NewGuid().ToString(), pythonNodeName, 0, 0, false, false)); - - DispatcherUtil.DoEvents(); - - var nodesCountAfterNodeAdded = this.ViewModel.CurrentSpace.Nodes.Count(); - - // Assert - Assert.AreEqual(nodesCountBeforeNodeAdded + 2, nodesCountAfterNodeAdded); - Assert.AreEqual(raisedEvents.Count, 1); - Assert.IsTrue(raisedEvents.Any(x => x.Contains(nameof(PythonMigrationViewExtension)))); - raisedEvents.Clear(); - this.ViewModel.Model.Logger.NotificationLogged -= Logger_NotificationLogged; - DispatcherUtil.DoEvents(); - } - - /// - /// This tests checks if the extension can detect IronPython nodes in the graph - /// - [Test] - public void CanDetectIronPythonNodesInGraph() - { - var extensionManager = View.viewExtensionManager; - // Act - // open file - Open(@"core\python\python.dyn"); - - var pythonMigration = extensionManager.ViewExtensions - .FirstOrDefault(x => x.Name == viewExtension.Name) - as PythonMigrationViewExtension; - - // Assert - Assert.IsTrue(pythonMigration.PythonDependencies.CurrentWorkspaceHasIronPythonDependency()); - DispatcherUtil.DoEvents(); - } - - [Test] - public void CustomNodeContainsIronPythonDependencyTest() - { - // open file - var examplePath = Path.Combine(UnitTestBase.TestDirectory, @"core\python", "PythonCustomNodeHomeWorkspace.dyn"); - Open(examplePath); - - var pythonMigration = View.viewExtensionManager.ViewExtensions - .Where(x => x.Name == viewExtension.Name) - .Select(x => x) - .First() as PythonMigrationViewExtension; - - var result = pythonMigration.PythonDependencies.CurrentWorkspaceHasIronPythonDependency(); - - Assert.IsTrue(result); - DispatcherUtil.DoEvents(); - } - - [Test] - public void IronPythonPackageLoadedTest() - { - RaiseLoadedEvent(View); - - Open(Path.Combine(CoreTestDirectory, @"python\python.dyn")); - - var loadedParams = new ViewLoadedParams(View, ViewModel); - viewExtension.Loaded(loadedParams); - - var currentWorkspace = ViewModel.Model.CurrentWorkspace; - - var pkgDependencyInfo = currentWorkspace.OnRequestPackageDependencies().FirstOrDefault(); - - Assert.IsTrue(pkgDependencyInfo != null); - Assert.AreEqual(PackageDependencyState.Loaded, pkgDependencyInfo.State); - Assert.AreEqual(GraphPythonDependencies.PythonPackage, pkgDependencyInfo.Name); - Assert.AreEqual(GraphPythonDependencies.PythonPackageVersion, pkgDependencyInfo.Version); - } - - [Test] - public void MigratingPython2CodeWillSaveBackupFile() - { - // Arrange - var dynFileName = "2to3Test.dyn"; - var dynBackupFileName = "2to3Test.Python2.dyn"; - DynamoModel.IsTestMode = true; - - var python2dynPath = Path.Combine(UnitTestBase.TestDirectory, @"core\python", dynFileName); - var backupFilePath = Path.Combine(Model.PathManager.BackupDirectory, dynBackupFileName); - if (File.Exists(backupFilePath)) - File.Delete(backupFilePath); - - Open(python2dynPath); - DispatcherUtil.DoEvents(); - - var currentWs = View.ChildOfType(); - Assert.IsNotNull(currentWs, "DynamoView does not have any WorkspaceView"); - - var nodeView = currentWs.ChildOfType(); - - var editMenuItem = nodeView.MainContextMenu - .Items - .OfType() - .First(x => x.Header.ToString() == PythonNodeModels.Properties.Resources.EditHeader); - - editMenuItem.RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); - DispatcherUtil.DoEvents(); - - // Act - var scriptEditor = View.GetChildrenWindowsOfType().FirstOrDefault(); - scriptEditor.MigrationAssistantBtn.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); - DispatcherUtil.DoEvents(); - var assistantWindow = scriptEditor.GetChildrenWindowsOfType().FirstOrDefault(); - assistantWindow.AcceptButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); - - // Assert - Assert.That(File.Exists(backupFilePath)); - - // Clean up - File.Delete(backupFilePath); - } - - [Test] - public void MigratingPython2CodeThatResultsInImaginaryCaseDoesNotCrash() - { - // Arrange - var dynFileName = "pymigrateimaginarydiff.dyn"; - var dynBackupFileName = "pymigrateimaginarydiff.Python2.dyn"; - DynamoModel.IsTestMode = true; - - var python2dynPath = Path.Combine(UnitTestBase.TestDirectory, @"core\python", dynFileName); - var backupFilePath = Path.Combine(Model.PathManager.BackupDirectory, dynBackupFileName); - if (File.Exists(backupFilePath)) - File.Delete(backupFilePath); - - Open(python2dynPath); - DispatcherUtil.DoEvents(); - - var currentWs = View.ChildOfType(); - Assert.IsNotNull(currentWs, "DynamoView does not have any WorkspaceView"); - - var nodeView = currentWs.ChildOfType(); - - var editMenuItem = nodeView.MainContextMenu - .Items - .OfType() - .First(x => x.Header.ToString() == PythonNodeModels.Properties.Resources.EditHeader); - - editMenuItem.RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); - DispatcherUtil.DoEvents(); - - // Act - Assert.DoesNotThrow(() => { - var scriptEditor = View.GetChildrenWindowsOfType().FirstOrDefault(); - scriptEditor.MigrationAssistantBtn.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); - DispatcherUtil.DoEvents(); - var assistantWindow = scriptEditor.GetChildrenWindowsOfType().FirstOrDefault(); - assistantWindow.AcceptButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); - }); - // Assert - Assert.That(File.Exists(backupFilePath)); - - // Clean up - File.Delete(backupFilePath); - } - - [Test] - public void WorkspaceWithMultiplePythonEnginesUpdatesCorrectlyViaContextHandler() - { - // open test graph - Open(@"core\python\WorkspaceWithMultiplePythonEngines.dyn"); - - var nodeModels = ViewModel.Model.CurrentWorkspace.Nodes.Where(n => n.NodeType == "PythonScriptNode"); - List pythonNodes = nodeModels.Cast().ToList(); - var pynode1 = pythonNodes.ElementAt(0); - var pynode2 = pythonNodes.ElementAt(1); - var pynode1view = NodeViewWithGuid("d060e68f-510f-43fe-8990-c2c1ba7e0f80"); - var pynode2view = NodeViewWithGuid("4050d23e-529c-43e9-b614-0506d8adb06b"); - - - Assert.AreEqual(new List { "2.7.9", "2.7.9" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - - SetEngineViaContextMenu(pynode1view, PythonEngineVersion.CPython3); - - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - Assert.AreEqual(new List { "3.9.12", "2.7.9" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - - SetEngineViaContextMenu(pynode2view, PythonEngineVersion.CPython3); - - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - Assert.AreEqual(new List { "3.9.12", "3.9.12" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - - SetEngineViaContextMenu(pynode1view, PythonEngineVersion.IronPython2); - SetEngineViaContextMenu(pynode2view, PythonEngineVersion.IronPython2); - - Assert.IsTrue(ViewModel.Model.CurrentWorkspace.HasUnsavedChanges); - Assert.AreEqual(new List { "2.7.9", "2.7.9" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - DispatcherUtil.DoEvents(); - - Model.CurrentWorkspace.Undo(); - Assert.AreEqual(new List { "2.7.9", "3.9.12" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - DispatcherUtil.DoEvents(); - Model.CurrentWorkspace.Undo(); - Assert.AreEqual(new List { "3.9.12", "3.9.12" }, pynode2.CachedValue.GetElements().Select(x => x.Data)); - DispatcherUtil.DoEvents(); - - } - } -} diff --git a/test/Libraries/IronPythonTests/README.md b/test/Libraries/IronPythonTests/README.md deleted file mode 100644 index 798d3007a6b..00000000000 --- a/test/Libraries/IronPythonTests/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## IronPython Tests ## - -This project has been disabled from the main Dynamo solution because Iron Python is no longer distributed with Dynamo and is no longer maintained. -In case Iron Python needs to be re-enabled follow the listed steps: -1. Re-enable the project to build within the solution - just add back the `.Build.0` configurations in the Dynamo.sln (do the same thing for DSIronPython and IronPythonExtension) -2. Run the IronPython tests to make sure they pass -3. Modify the dll list at https://git.autodesk.com/Dynamo/DynamoBuildscripts/blob/master/eoJenkinsfile#L103 \ No newline at end of file diff --git a/test/Libraries/IronPythonTests/Setup.cs b/test/Libraries/IronPythonTests/Setup.cs deleted file mode 100644 index 9ffabe86d22..00000000000 --- a/test/Libraries/IronPythonTests/Setup.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using Dynamo.Utilities; -using NUnit.Framework; - -namespace IronPythonTests -{ - [SetUpFixture] - public class Setup - { - private AssemblyHelper assemblyHelper; - - [SetUp] - public void RunBeforeAllTests() - { - var assemblyPath = Assembly.GetExecutingAssembly().Location; - var moduleRootFolder = Path.GetDirectoryName(assemblyPath); - - var resolutionPaths = new[] - { - // These tests need "CoreNodeModelsWpf.dll" under "nodes" folder. - Path.Combine(moduleRootFolder, "nodes") - }; - - assemblyHelper = new AssemblyHelper(moduleRootFolder, resolutionPaths); - AppDomain.CurrentDomain.AssemblyResolve += assemblyHelper.ResolveAssembly; - } - - [TearDown] - public void RunAfterAllTests() - { - AppDomain.CurrentDomain.AssemblyResolve -= assemblyHelper.ResolveAssembly; - assemblyHelper = null; - } - } -}