public async Task ArrayWritePyInteger() { var array = new int[] { 1 }; await SubscriptHelper.StoreSubscript(interpreter, context, array, PyInteger.Create(0), 2); Assert.That(array[0], Is.EqualTo(2)); }
// This is the actual payload. public async Task <object> wrappedMethodBody(IInterpreter interpreter) { // We're just having it wait off one tick as a pause since we don't actually have something on the // other end of this that will block. await new YieldTick(((Interpreter)interpreter).Scheduler, context); return(PyInteger.Create(1)); // TODO: Helpers to box/unbox between .NET and Python types. }
public void SimpleAssignment() { runBasicTest("a = 10\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(10) } }), 1); }
public void WhileElse() { string program = "while a < 3:\n" + " a = a + 1\n" + "else:\n" + " a = a + 100\n"; // Runs while loop, then the else clause runBasicTest(program, new Dictionary <string, object> { { "a", PyInteger.Create(0) } }, new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(103) } }), 1); // Skips the while loop, runs the else clause runBasicTest(program, new Dictionary <string, object> { { "a", PyInteger.Create(10) } }, new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(110) } }), 1); }
public void AccessClassMethod() { //>>> def make_foo(): //... class Foo: //... def __init__(self): //... self.a = 1 //... def change_a(self, new_a): //... self.a = new_a //... //>>> dis(make_foo) // 2 0 LOAD_BUILD_CLASS // 2 LOAD_CONST 1 (<code object Foo at 0x0000021BD5908D20, file "<stdin>", line 2>) // 4 LOAD_CONST 2 ('Foo') // 6 MAKE_FUNCTION 0 // 8 LOAD_CONST 2 ('Foo') // 10 CALL_FUNCTION 2 // 12 STORE_FAST 0 (Foo) // 14 LOAD_CONST 0 (None) // 16 RETURN_VALUE var interpreter = runProgram("class Foo:\n" + " def __init__(self):\n" + " self.a = 1\n" + "\n" + " def change_a(self, new_a):\n" + " self.a = new_a\n" + "\n" + "bar = Foo()\n" + "bar.change_a(2)\n", new Dictionary <string, object>(), 1); var variables = new VariableMultimap(interpreter); var bar = (PyObject)variables.Get("bar"); Assert.That(bar.__dict__["a"], Is.EqualTo(PyInteger.Create(2))); }
public async Task DefaultsVargsArgsKwargs() { string program = "def mad1(initial, addon=0, *numbers, **kwargs):\n" + " ret_sum = initial\n" + " for number in numbers:\n" + " ret_sum += kwargs['mult1'] * number + addon\n" + " return ret_sum\n" + "\n" + "def mad2(initial, *numbers, addon=0, **kwargs):\n" + " ret_sum = initial\n" + " for number in numbers:\n" + " ret_sum += kwargs['mult2'] * number + addon\n" + " return ret_sum\n" + "\n" + "kwarg = { 'mult1': 10, 'mult2': 100 }\n" + "a = mad1(1, 7, 11, kwarg)\n" + "b = mad1(1, addon=6, 11, kwarg)\n" + "c = mad1(1, addon=1, 11, 12, kwarg)\n" + "d = mad2(1, 7, 11, kwarg)\n" + "e = mad2(1, 11, addon=6, kwarg)\n" + "f = mad2(1, 11, 12, addon=1, kwarg)\n"; await runBasicTest(program, new VariableMultimap(new TupleList <string, object> { // These values have not been properly established yet since we're not even sure what are legal calls and what they do yet. { "a", PyInteger.Create(19) }, { "b", PyInteger.Create(19) }, { "c", PyInteger.Create(19) }, { "d", PyInteger.Create(19) }, { "e", PyInteger.Create(19) }, { "f", PyInteger.Create(19) } }), 1); }
public void IsNoneIsNotNone() { runBasicTest("b = a is None\n" + "c = a is not None\n", new Dictionary <string, object> { { "a", NoneType.Instance } }, new VariableMultimap(new TupleList <string, object> { { "a", NoneType.Instance }, { "b", PyBool.True }, { "c", PyBool.False } }), 1); // Now let's flip A around and make sure we're still cool. runBasicTest("b = a is None\n" + "c = a is not None\n", new Dictionary <string, object> { { "a", PyInteger.Create(10) } }, new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(10) }, { "b", PyBool.False }, { "c", PyBool.True } }), 1); }
public void SchedulerParentContextPreserved() { // This test was added due to a lot of paranoia around how the subcontext call stack is created. // It's taking the existing call stack and just shoving on change_a. The interpreter then runs // through everything as normal. What I expect to happen then is that after change_a finishes, // it attempts to run the parent context. This is a no-no! This test will show if this happens // based on the result of the variable 'b'. If it's greater than 1, then it got run more than // once. // // We use an external entity to track this because its reference is independent of different // contexts. var intHaver = new GotAnInt(); runBasicTest( "import sys\n" + "\n" + "a = 0\n" + "def change_a():\n" + " global a\n" + " a = 1\n" + "\n" + "b.TheInt += 1\n" + "sys.scheduler.schedule(change_a)\n", new Dictionary <string, object>() { { "b", intHaver } }, new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(1) }, }), 2); Assert.That(intHaver.TheInt, Is.EqualTo(1)); }
public void DeclareBasicDictionary() { // The peephole optimizer figures out basic, constant dictionaries and diverts them to // BUILD_CONST_KEY_MAP, so I have to use a more obtuse example here to show BUILD_MAP. // return_foo() just returns "foo": // // >>> def dict_name_maker(): // ... return {return_foo(): "bar", "number": 1} // ... // >>> dis.dis(dict_name_maker) // 2 0 LOAD_GLOBAL 0 (return_foo) // 2 CALL_FUNCTION 0 // 4 LOAD_CONST 1 ('bar') // 6 LOAD_CONST 2 ('number') // 8 LOAD_CONST 3 (1) // 10 BUILD_MAP 2 // 12 RETURN_VALUE // var interpreter = runProgram("a = { \"foo\": \"bar\", \"number\": 1 }\n", new Dictionary <string, object>(), 1); var variables = interpreter.DumpVariables(); Assert.That(variables.ContainsKey("a")); Assert.That(variables["a"], Is.EquivalentTo(new Dictionary <PyString, object> { { PyString.Create("foo"), PyString.Create("bar") }, { PyString.Create("number"), PyInteger.Create(1) } })); }
public void ComprehensiveArithmeticOperators() { runBasicTest( "x = 10\n" + "a = x + 2\n" + "b = x - 2\n" + "c = x * 2\n" + "d = x / 2\n" + "e = x % 9\n" + "f = x // 3\n" + "g = x ** 2\n" + "h = x & 2\n" + "i = x | 14\n" + "j = x ^ 2\n" + "k = x >> 2\n" + "l = x << 2\n" , new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(12) }, { "b", PyInteger.Create(8) }, { "c", PyInteger.Create(20) }, { "d", PyFloat.Create(5.0) }, { "e", PyInteger.Create(1) }, { "f", PyInteger.Create(3) }, { "g", PyInteger.Create(100) }, { "h", PyInteger.Create(2) }, { "i", PyInteger.Create(14) }, { "j", PyInteger.Create(8) }, { "k", PyInteger.Create(2) }, { "l", PyInteger.Create(40) } }), 1); }
public async Task DefaultCombinations() { string program = "def defaults_math(a=1, b=3):\n" + " return a + 10 * b\n" + "a = defaults_math()\n" + "b = defaults_math(2)\n" + "c = defaults_math(2, 4)\n" + "d = defaults_math(a=2, b=4)\n" + "e = defaults_math(a=4, b=2)\n" + "f = defaults_math(a=2)\n" + "g = defaults_math(b=4)\n"; await runBasicTest(program, new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(31) }, { "b", PyInteger.Create(32) }, { "c", PyInteger.Create(42) }, { "d", PyInteger.Create(42) }, { "e", PyInteger.Create(24) }, { "f", PyInteger.Create(32) }, { "g", PyInteger.Create(41) }, }), 3); // a=1 and b=3 are all their own iterations AssertNoDotNetExceptions(); }
public void RepeatedArithmeticOperators() { // Making sure that we're properly parsing and generating all of these when there's multiples of the operator. runBasicTest( "x = 100\n" + "a = x + 2 + 3\n" + "b = x - 2 - 3\n" + "c = x * 2 * 3\n" + "d = x / 4 / 2\n" + "e = x % 9 % 3\n" + "f = x // 2 // 3\n" + "g = x ** 2 ** 3\n" + "h = x & 3 & 2\n" + "i = x | 13 | 1 \n" + "j = x ^ 2 ^ 1\n" + "k = x >> 2 >> 3\n" + "l = x << 2 << 3\n" , new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(100 + 2 + 3) }, { "b", PyInteger.Create(100 - 2 - 3) }, { "c", PyInteger.Create(100 * 2 * 3) }, { "d", PyFloat.Create(100.0 / 4.0 / 2.0) }, { "e", PyInteger.Create(100 % 9 % 3) }, { "f", PyInteger.Create(100 / 2 / 3) }, { "g", PyInteger.Create((BigInteger)Math.Pow(100.0, 8.0)) }, // 2 ** 3 gets evaluated first and becomes 8. This is what CPython does too! { "h", PyInteger.Create(100 & 3 & 2) }, { "i", PyInteger.Create(100 | 13 | 1) }, { "j", PyInteger.Create(100 ^ 2 ^ 1) }, { "k", PyInteger.Create(100 >> 2 >> 3) }, { "l", PyInteger.Create(100 << 2 << 3) } }), 1); }
public async Task SimpleAssignmentAndLoad() { await runBasicTest("a = 10\n" + "a\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(10) } }), 1); }
public static PyString readline(PyIOBase self, PyInteger size = null) { if (size == null) { size = PyInteger.Create(-1); } return(PyString.Create(self.Readline(size.number))); }
/// <summary> /// Implements the len() command to get the length of containers. /// </summary> /// <param name="o">The object to inspect</param> /// <returns>A PyList of the names of the methods and properties of this PyObject.</returns> public static async Task <PyInteger> len(IInterpreter interpreter, FrameContext context, object o) { var asPyObject = o as PyObject; if (asPyObject != null) { if (!asPyObject.__dict__.ContainsKey("__len__")) { throw new Exception("TypeError: object of type " + asPyObject.__class__.Name + " has no len()"); } else { var callable_len = asPyObject.__dict__["__len__"] as IPyCallable; if (callable_len == null) { // Yeah, same error as if __len__ was not found in the first place... throw new Exception("TypeError: object of type " + asPyObject.__class__.Name + " has no len()"); } else { var retVal = await callable_len.Call(interpreter, context, new object[] { o }); var asPyInteger = retVal as PyInteger; if (asPyInteger == null) { // Yeah, same error as if __len__ if it's a function but it returns moon crap. throw new Exception("TypeError: object of type " + asPyObject.__class__.Name + " has no len()"); } return(asPyInteger); } } } var asArray = o as Array; if (asArray != null) { return(PyInteger.Create(asArray.Length)); } // Still here? This might be, uh, an IEnumerable<T> with a Count property... var asCountProperty = o.GetType().GetProperty("Count"); if (asCountProperty != null) { return(PyInteger.Create((int)asCountProperty.GetValue(o))); } // No? Look for a Length var asLengthProperty = o.GetType().GetProperty("Length"); if (asLengthProperty != null) { return(PyInteger.Create((int)asLengthProperty.GetValue(o))); } throw new Exception("TypeError: cannot calculate length for object of type " + o.GetType().Name); }
public async Task Multiassign() { await runBasicTest( "a = b = 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(1) }, { "b", PyInteger.Create(1) }, }), 1); }
public async Task Unpack() { await runBasicTest( "a, b = [1, 2]\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(1) }, { "b", PyInteger.Create(2) }, }), 1); }
public async Task IDictReadPyInteger() { var dict = new Dictionary <PyInteger, int> { [PyInteger.Create(0)] = 1 }; var read = await SubscriptHelper.LoadSubscript(interpreter, context, dict, PyInteger.Create(0)); Assert.That(read, Is.EqualTo(1)); }
public async Task IDictWritePyInteger() { var dict = new Dictionary <PyInteger, int> { [PyInteger.Create(0)] = 1 }; await SubscriptHelper.StoreSubscript(interpreter, context, dict, PyInteger.Create(0), 2); Assert.That(dict[PyInteger.Create(0)], Is.EqualTo(2)); }
public async Task IListWritePyInteger() { var list = new List <int> { 1 }; await SubscriptHelper.StoreSubscript(interpreter, context, list, PyInteger.Create(0), 2); Assert.That(list[0], Is.EqualTo(2)); }
public void AssignmentOperators() { // https://www.w3schools.com/python/python_operators.asp // += x += 3 x = x + 3 // -= x -= 3 x = x - 3 // *= x *= 3 x = x * 3 // /= x /= 3 x = x / 3 // %= x %= 3 x = x % 3 // //= x //= 3 x = x // 3 // **= x **= 3 x = x ** 3 // &= x &= 3 x = x & 3 // |= x |= 3 x = x | 3 // ^= x ^= 3 x = x ^ 3 // >>= x >>= 3 x = x >> 3 // <<= x <<= 3 x = x << 3 runBasicTest( "a = 10\n" + "b = 10\n" + "c = 10\n" + "d = 10\n" + "e = 10\n" + "f = 10\n" + "g = 10\n" + "h = 10\n" + "i = 10\n" + "j = 10\n" + "k = 10\n" + "l = 10\n" + "a += 2\n" + "b -= 2\n" + "c *= 2\n" + "d /= 2\n" + "e %= 9\n" + "f //= 3\n" + "g **= 2\n" + "h &= 2\n" + "i |= 14\n" + "j ^= 2\n" + "k >>= 2\n" + "l <<= 2\n" , new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(12) }, { "b", PyInteger.Create(8) }, { "c", PyInteger.Create(20) }, { "d", PyFloat.Create(5.0) }, { "e", PyInteger.Create(1) }, { "f", PyInteger.Create(3) }, { "g", PyInteger.Create(100) }, { "h", PyInteger.Create(2) }, { "i", PyInteger.Create(14) }, { "j", PyInteger.Create(8) }, { "k", PyInteger.Create(2) }, { "l", PyInteger.Create(40) } }), 1); }
public static object CreateNumber(IParseTree context) { string rawText = context.GetText(); if (DecimalPointNumberRegex.Match(rawText).Success) { return(PyFloat.Create(Decimal.Parse(rawText))); } return(PyInteger.Create(BigInteger.Parse(context.GetText()))); }
public void ForLoopRange() { runBasicTest( "a = 0\n" + "for i in range(0, 10, 1):\n" + " a += i\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) } }), 1); }
public void WhileBasic() { runBasicTest( "a = 0\n" + "while a < 3:\n" + " a = a + 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(3) } }), 1); }
public async Task NegativeNumber() { await runBasicTest( "a = 10\n" + "b = -a\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(10) }, { "b", PyInteger.Create(-10) }, }), 1); }
public async Task PyListReadInt32() { var list = PyList.Create(); var stored = PyInteger.Create(1); PyListClass.append(list, stored); var read = await SubscriptHelper.LoadSubscript(interpreter, context, list, 0); Assert.That(read, Is.EqualTo(stored)); }
public async Task BasicConditionalTrue() { await runBasicTest( "a = 10\n" + "if a == 10:\n" + " a = 1\n" + "a = a + 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(2) } }), 1); }
public void BasicConditionalFalse() { runBasicTest( "a = 10\n" + "if a != 10:\n" + " a = 1\n" + "a = a + 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(11) } }), 1); }
public void BasicConditionalOffTheEnd() { // Conditional is last opcode. We want to fall-through without going out of bounds runBasicTest( "a = 9\n" + "if a == 10:\n" + " a = a + 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(9) } }), 1); }
public void BasicConditionalExplicitTrue() { runBasicTest( "a = 10\n" + "if True:\n" + " a = 1\n" + "a = a + 1\n", new VariableMultimap(new TupleList <string, object> { { "a", PyInteger.Create(2) } }), 1); }