20 using System.Collections.Generic;
22 using System.Text.RegularExpressions;
25 using System.Globalization;
34 private static Regex LineRegex =
new Regex(
"line (\\d+)", RegexOptions.Compiled);
35 private static Regex StackTraceFileLineRegex =
new Regex(
"\"(.+)\", line (\\d+), in (.+)", RegexOptions.Compiled | RegexOptions.Singleline);
36 private static readonly Lazy<dynamic> lazyInspect =
new Lazy<dynamic>(() => Py.Import(
"inspect"));
54 if (!TryGetArgLength(pyObject, out count) || count != 1)
58 dynamic method = GetModule().GetAttr(
"to_action1");
59 return method(pyObject, typeof(T1)).AsManagedObject(typeof(Action<T1>));
75 if (!TryGetArgLength(pyObject, out count) || count != 2)
79 dynamic method = GetModule().GetAttr(
"to_action2");
80 return method(pyObject, typeof(T1), typeof(T2)).AsManagedObject(typeof(Action<T1, T2>));
96 if (!TryGetArgLength(pyObject, out count) || count != 1)
100 dynamic method = GetModule().GetAttr(
"to_func1");
101 return method(pyObject, typeof(T1), typeof(T2)).AsManagedObject(typeof(Func<T1, T2>));
118 if (!TryGetArgLength(pyObject, out count) || count != 2)
122 dynamic method = GetModule().GetAttr(
"to_func2");
123 return method(pyObject, typeof(T1), typeof(T2), typeof(T3)).AsManagedObject(typeof(Func<T1, T2, T3>));
134 var selector = ToFunc<IEnumerable<CoarseFundamental>,
Symbol[]>(pyObject);
135 if (selector ==
null)
139 throw new ArgumentException($
"{pyObject.Repr()} is not a valid coarse fundamental universe selector method.");
152 var selector = ToFunc<IEnumerable<FineFundamental>,
Symbol[]>(pyObject);
153 if (selector ==
null)
157 throw new ArgumentException($
"{pyObject.Repr()} is not a valid fine fundamental universe selector method.");
180 var match = LineRegex.Match(message);
183 foreach (Match lineCapture
in match.Captures)
186 message = Regex.Replace(message, lineCapture.ToString(), $
"line {newLineNumber}");
189 else if (message.Contains(
" value cannot be converted to ", StringComparison.InvariantCulture))
191 message +=
": This error is often encountered when assigning to a member defined in the base QCAlgorithm class. For example, self.universe conflicts with 'QCAlgorithm.Universe' but can be fixed by prefixing private variables with an underscore, self._universe.";
204 if (
string.IsNullOrWhiteSpace(value))
211 var endIndex = value.IndexOf(
"at Python.Runtime.", StringComparison.InvariantCulture);
212 var neededStackTrace = endIndex > 0 ? value.Substring(0, endIndex) : value;
215 var blocks = neededStackTrace.Split(
" File ", StringSplitOptions.RemoveEmptyEntries)
218 var trimedTrace = fileTrace.Trim();
219 if (
string.IsNullOrWhiteSpace(trimedTrace))
224 var match = StackTraceFileLineRegex.Match(trimedTrace);
230 var capture = match.Captures[0] as Match;
232 var filePath = capture.Groups[1].Value;
233 var lastFileSeparatorIndex = Math.Max(filePath.LastIndexOf(
'/'), filePath.LastIndexOf(
'\\'));
234 if (lastFileSeparatorIndex < 0)
239 var fileName = filePath.Substring(lastFileSeparatorIndex + 1);
240 var lineNumber =
int.Parse(capture.Groups[2].Value, CultureInfo.InvariantCulture) +
ExceptionLineShift;
241 var locationAndInfo = capture.Groups[3].Value.Trim();
243 return $
" at {locationAndInfo}{Environment.NewLine} in {fileName}: line {lineNumber}";
245 .Where(x => !
string.IsNullOrWhiteSpace(x));
247 var result =
string.Join(Environment.NewLine, blocks);
248 result = Logging.Log.ClearLeanPaths(result);
250 return string.IsNullOrWhiteSpace(result)
252 : $
"{Environment.NewLine}{result}{Environment.NewLine}";
261 private static bool TryGetArgLength(PyObject pyObject, out
long length)
265 var inspect = lazyInspect.Value;
266 if (inspect.isfunction(pyObject))
268 var args = inspect.getfullargspec(pyObject).args as PyObject;
269 var pyList =
new PyList(args);
270 length = pyList.Length();
276 if (inspect.ismethod(pyObject))
278 var args = inspect.getfullargspec(pyObject).args as PyObject;
279 var pyList =
new PyList(args);
280 length = pyList.Length() - 1;
294 private static PyObject GetModule()
296 return PyModule.FromString(
"x",
297 "from clr import AddReference\n" +
298 "AddReference(\"System\")\n" +
299 "from System import Action, Func\n" +
300 "def to_action1(pyobject, t1):\n" +
301 " return Action[t1](pyobject)\n" +
302 "def to_action2(pyobject, t1, t2):\n" +
303 " return Action[t1, t2](pyobject)\n" +
304 "def to_func1(pyobject, t1, t2):\n" +
305 " return Func[t1, t2](pyobject)\n" +
306 "def to_func2(pyobject, t1, t2, t3):\n" +
307 " return Func[t1, t2, t3](pyobject)");
317 List<Symbol> symbolsList;
323 if (PyList.IsListType(input))
325 List<string> symbolsStringList;
328 if (PyString.IsStringType(input[0]) && input.TryConvert(out symbolsStringList))
330 symbolsList =
new List<Symbol>();
331 foreach (var stringSymbol
in symbolsStringList)
334 symbolsList.Add(symbol);
338 else if (!input.TryConvert(out symbolsList))
340 throw new ArgumentException($
"Cannot convert list {input.Repr()} to symbols");
347 if (PyString.IsStringType(input) && input.TryConvert(out symbolString))
350 symbolsList =
new List<Symbol> { symbol };
352 else if (input.TryConvert(out symbol))
354 symbolsList =
new List<Symbol> { symbol };
358 throw new ArgumentException($
"Cannot convert object {input.Repr()} to symbol");